Skip to content

Commit

Permalink
feat(technicalUser): adjust service account to new provisioning api
Browse files Browse the repository at this point in the history
Refs: #79
  • Loading branch information
Phil91 committed Oct 1, 2024
1 parent 1b90e37 commit 347e187
Show file tree
Hide file tree
Showing 37 changed files with 884 additions and 152 deletions.
4 changes: 2 additions & 2 deletions src/clients/Dim.Clients/Api/Dim/DimClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task<CompanyData> GetCompanyData(BasicAuthSettings dimAuth, string
{
var response = await result.Content
.ReadFromJsonAsync<CompanyIdentitiesResponse>(JsonSerializerExtensions.Options, cancellationToken)
.ConfigureAwait(false);
.ConfigureAwait(ConfigureAwaitOptions.None);
if (response?.Data == null || response.Data.Count() != 1)
{
throw new ConflictException("There is no matching company");
Expand Down Expand Up @@ -85,7 +85,7 @@ public async Task<string> CreateStatusList(BasicAuthSettings dimAuth, string dim
.CatchingIntoServiceExceptionFor("assign-application", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE,
async m =>
{
var message = await m.Content.ReadAsStringAsync().ConfigureAwait(false);
var message = await m.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None);
return (false, message);
}).ConfigureAwait(false);
try
Expand Down
1 change: 1 addition & 0 deletions src/clients/Dim.Clients/Api/Div/IProvisioningClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ public interface IProvisioningClient
{
public Task<Guid> CreateOperation(Guid customerId, string customerName, string applicationName, string companyName, string didDocumentLocation, bool isIssuer, CancellationToken cancellationToken);
public Task<OperationResponse> GetOperation(Guid operationId, CancellationToken cancellationToken);
Task<Guid> CreateServiceKey(string technicalUserName, Guid walletId, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Dim.Clients.Api.Dim;
using System.Text.Json.Serialization;

namespace Dim.Clients.Api.Div.Models;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/********************************************************************************
* Copyright (c) 2024 BMW Group AG
* Copyright 2024 SAP SE or an SAP affiliate company and ssi-dim-middle-layer contributors.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System.Text.Json.Serialization;

namespace Dim.Clients.Api.Div.Models;

public record ServiceKeyOperationCreationRequest(
[property: JsonPropertyName("entity")] string Entity,
[property: JsonPropertyName("action")] string Action,
[property: JsonPropertyName("payload")] ServiceKeyPayloadData Payload
);

public record ServiceKeyPayloadData(
[property: JsonPropertyName("customerWalletId")] Guid CustomerWalletId,
[property: JsonPropertyName("divWalletServiceName")] string ServiceKeyName
);
44 changes: 42 additions & 2 deletions src/clients/Dim.Clients/Api/Div/ProvisioningClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ [new ApplicationCompanyService("CredentialService", "https://dis-agent-prod.eu10
);
var client = await basicAuthTokenService
.GetBasicAuthorizedClient<ProvisioningClient>(_settings, cancellationToken)
.ConfigureAwait(false);
.ConfigureAwait(ConfigureAwaitOptions.None);
var result = await client.PostAsJsonAsync("/api/v1.0.0/operations", data, JsonSerializerExtensions.Options, cancellationToken)
.CatchingIntoServiceExceptionFor("create-operation", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE,
async response =>
Expand Down Expand Up @@ -99,7 +99,7 @@ public async Task<OperationResponse> GetOperation(Guid operationId, Cancellation
{
var client = await basicAuthTokenService
.GetBasicAuthorizedClient<ProvisioningClient>(_settings, cancellationToken)
.ConfigureAwait(false);
.ConfigureAwait(ConfigureAwaitOptions.None);
var result = await client.GetAsync($"/api/v1.0.0/operations/{operationId}", cancellationToken)
.CatchingIntoServiceExceptionFor("get-operation", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE,
async response =>
Expand Down Expand Up @@ -129,4 +129,44 @@ public async Task<OperationResponse> GetOperation(Guid operationId, Cancellation
throw new ServiceException(je.Message);
}
}

public async Task<Guid> CreateServiceKey(string technicalUserName, Guid walletId, CancellationToken cancellationToken)
{
var data = new ServiceKeyOperationCreationRequest(
"customer-wallet-key",
"create",
new ServiceKeyPayloadData(
walletId,
technicalUserName
)
);
var client = await basicAuthTokenService
.GetBasicAuthorizedClient<ProvisioningClient>(_settings, cancellationToken)
.ConfigureAwait(ConfigureAwaitOptions.None);
var result = await client.PostAsJsonAsync("/api/v1.0.0/operations", data, JsonSerializerExtensions.Options, cancellationToken)
.CatchingIntoServiceExceptionFor("create-service-key", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE,
async response =>
{
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None);
return (false, content);
})
.ConfigureAwait(false);
try
{
var response = await result.Content
.ReadFromJsonAsync<CreateOperationRequest>(JsonSerializerExtensions.Options, cancellationToken)
.ConfigureAwait(ConfigureAwaitOptions.None);

if (response == null)
{
throw new ServiceException("response should never be null here");
}

return response.OperationId;
}
catch (JsonException je)
{
throw new ServiceException(je.Message);
}
}
}
33 changes: 33 additions & 0 deletions src/database/Dim.DbAccess/Models/ProcessData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/********************************************************************************
* Copyright (c) 2024 BMW Group AG
* Copyright 2024 SAP SE or an SAP affiliate company and ssi-dim-middle-layer contributors.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Dim.Entities.Enums;

namespace Dim.DbAccess.Models;

public record ProcessData(
Guid ProcessId,
IEnumerable<ProcessStepData> ProcessStepData
);

public record ProcessStepData(
ProcessStepTypeId ProcessStepTypeId,
ProcessStepStatusId ProcessStepStatusId
);
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

using Dim.Entities.Entities;

namespace Dim.Processes.Library;
namespace Dim.DbAccess.Models;

public record VerifyProcessData(
Process? Process,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Dim.DbAccess.Models;
using Dim.Entities.Entities;
using Dim.Entities.Enums;

Expand All @@ -35,4 +36,7 @@ public interface IProcessStepRepository
void AttachAndModifyProcessSteps(IEnumerable<(Guid ProcessStepId, Action<ProcessStep>? Initialize, Action<ProcessStep> Modify)> processStepIdsInitializeModifyData);
IAsyncEnumerable<Process> GetActiveProcesses(IEnumerable<ProcessTypeId> processTypeIds, IEnumerable<ProcessStepTypeId> processStepTypeIds, DateTimeOffset lockExpiryDate);
IAsyncEnumerable<(Guid ProcessStepId, ProcessStepTypeId ProcessStepTypeId)> GetProcessStepData(Guid processId);
Task<ProcessData?> GetWalletProcessForTenant(string bpn, string companyName);
Task<ProcessData?> GetTechnicalUserProcess(string bpn, string companyName, string technicalUserName);
Task<(bool ProcessExists, VerifyProcessData ProcessData)> IsValidProcess(Guid processId, ProcessTypeId processTypeId, IEnumerable<ProcessStepTypeId> processSetpTypeIds);
}
3 changes: 2 additions & 1 deletion src/database/Dim.DbAccess/Repositories/ITenantRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ public interface ITenantRepository
Task<Guid> GetExternalIdForTechnicalUser(Guid technicalUserId);
void RemoveTechnicalUser(Guid technicalUserId);
Task<bool> IsTenantExisting(string companyName, string bpn);
Task<string> GetTenantBpn(Guid tenantId);
Task<Guid?> GetOperationId(Guid tenantId);
Task<(string? BaseUrl, WalletData WalletData)> GetCompanyRequestData(Guid tenantId);
Task<(bool Exists, Guid? CompanyId, string? BaseUrl, WalletData WalletData)> GetCompanyAndWalletDataForBpn(string bpn);
Task<(Guid? CompanyId, string? BaseUrl, WalletData WalletData)> GetStatusListCreationData(Guid tenantId);
Task<(string Bpn, string? BaseUrl, WalletData WalletData, string? Did, string? DownloadUrl)> GetCallbackData(Guid tenantId);
Task<(string? DownloadUrl, bool IsIssuer)> GetDownloadUrlAndIsIssuer(Guid tenantId);
Task<(Guid? WalletId, string TechnicalUserName)> GetTechnicalUserNameAndWalletId(Guid technicalUserId);
Task<Guid?> GetOperationIdForTechnicalUser(Guid technicalUserId);
}
43 changes: 43 additions & 0 deletions src/database/Dim.DbAccess/Repositories/ProcessStepRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Dim.DbAccess.Models;
using Dim.Entities;
using Dim.Entities.Entities;
using Dim.Entities.Enums;
Expand Down Expand Up @@ -88,4 +89,46 @@ public IAsyncEnumerable<Process> GetActiveProcesses(IEnumerable<ProcessTypeId> p
step.Id,
step.ProcessStepTypeId))
.AsAsyncEnumerable();

public Task<ProcessData?> GetWalletProcessForTenant(string bpn, string companyName) =>
dbContext.Tenants
.Where(x =>
x.Bpn == bpn &&
x.CompanyName == companyName &&
x.Process!.ProcessTypeId == ProcessTypeId.SETUP_DIM)
.Select(x => new ProcessData(
x.ProcessId,
x.Process!.ProcessSteps.Select(ps => new ProcessStepData(
ps.ProcessStepTypeId,
ps.ProcessStepStatusId))))
.SingleOrDefaultAsync();

public Task<ProcessData?> GetTechnicalUserProcess(string bpn, string companyName, string technicalUserName) =>
dbContext.TechnicalUsers
.Where(x =>
x.TechnicalUserName == technicalUserName &&
x.Tenant!.Bpn == bpn &&
x.Tenant!.CompanyName == companyName &&
x.Process!.ProcessTypeId == ProcessTypeId.TECHNICAL_USER)
.Select(x => new ProcessData(
x.ProcessId,
x.Process!.ProcessSteps.Select(ps => new ProcessStepData(
ps.ProcessStepTypeId,
ps.ProcessStepStatusId))))
.SingleOrDefaultAsync();

public Task<(bool ProcessExists, VerifyProcessData ProcessData)> IsValidProcess(Guid processId, ProcessTypeId processTypeId, IEnumerable<ProcessStepTypeId> processStepTypeIds) =>
dbContext.Processes
.AsNoTracking()
.Where(x => x.Id == processId && x.ProcessTypeId == processTypeId)
.Select(x => new ValueTuple<bool, VerifyProcessData>(
true,
new VerifyProcessData(
x,
x.ProcessSteps
.Where(step =>
processStepTypeIds.Contains(step.ProcessStepTypeId) &&
step.ProcessStepStatusId == ProcessStepStatusId.TODO))
))
.SingleOrDefaultAsync();
}
18 changes: 12 additions & 6 deletions src/database/Dim.DbAccess/Repositories/TenantRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,6 @@ public Task<bool> IsTenantExisting(string companyName, string bpn) =>
dbContext.Tenants
.AnyAsync(x => x.CompanyName == companyName && x.Bpn == bpn);

public Task<string> GetTenantBpn(Guid tenantId) =>
dbContext.Tenants
.Where(x => x.Id == tenantId)
.Select(x => x.Bpn)
.SingleAsync();

public Task<Guid?> GetOperationId(Guid tenantId) =>
dbContext.Tenants
.Where(x => x.Id == tenantId)
Expand Down Expand Up @@ -185,4 +179,16 @@ public Task<string> GetTenantBpn(Guid tenantId) =>
.Where(x => x.Id == tenantId)
.Select(x => new ValueTuple<string?, bool>(x.DidDownloadUrl, x.IsIssuer))
.SingleOrDefaultAsync();

public Task<(Guid? WalletId, string TechnicalUserName)> GetTechnicalUserNameAndWalletId(Guid technicalUserId) =>
dbContext.TechnicalUsers
.Where(x => x.Id == technicalUserId)
.Select(x => new ValueTuple<Guid?, string>(x.Tenant!.WalletId, x.TechnicalUserName))
.SingleOrDefaultAsync();

public Task<Guid?> GetOperationIdForTechnicalUser(Guid technicalUserId) =>
dbContext.TechnicalUsers
.Where(x => x.Id == technicalUserId)
.Select(x => x.OperationId)
.SingleOrDefaultAsync();
}
1 change: 1 addition & 0 deletions src/database/Dim.Entities/Entities/TechnicalUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class TechnicalUser(
public Guid TenantId { get; set; } = tenantId;
public Guid ExternalId { get; set; } = externalId;
public string TechnicalUserName { get; set; } = technicalUserName;
public Guid? OperationId { get; set; }
public string? TokenAddress { get; set; }
public string? ClientId { get; set; }
public byte[]? ClientSecret { get; set; }
Expand Down
1 change: 1 addition & 0 deletions src/database/Dim.Entities/Entities/Tenant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class Tenant(
public Guid OperatorId { get; set; } = operatorId;
public Guid ProcessId { get; set; } = processId;
public Guid? OperationId { get; set; }
public Guid? WalletId { get; set; }
public string? TokenAddress { get; set; }
public string? BaseUrl { get; set; }
public string? ClientId { get; set; }
Expand Down
13 changes: 12 additions & 1 deletion src/database/Dim.Entities/Enums/ProcessStepTypeId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,24 @@ public enum ProcessStepTypeId
GET_DID_DOCUMENT = 4,
CREATE_STATUS_LIST = 5,
SEND_CALLBACK = 6,
RETRIGGER_CREATE_WALLET = 7,
RETRIGGER_CHECK_OPERATION = 8,
RETRIGGER_GET_COMPANY = 9,
RETRIGGER_GET_DID_DOCUMENT = 10,
RETRIGGER_CREATE_STATUS_LIST = 11,
RETRIGGER_SEND_CALLBACK = 12,

// Create Technical User
CREATE_TECHNICAL_USER = 100,
GET_TECHNICAL_USER_DATA = 101,
SEND_TECHNICAL_USER_CREATION_CALLBACK = 102,
RETRIGGER_CREATE_TECHNICAL_USER = 103,
RETRIGGER_GET_TECHNICAL_USER_DATA = 104,
RETRIGGER_SEND_TECHNICAL_USER_CREATION_CALLBACK = 105,

// Delete Technical User
DELETE_TECHNICAL_USER = 200,
SEND_TECHNICAL_USER_DELETION_CALLBACK = 201
SEND_TECHNICAL_USER_DELETION_CALLBACK = 201,
RETRIGGER_DELETE_TECHNICAL_USER = 202,
RETRIGGER_SEND_TECHNICAL_USER_DELETION_CALLBACK = 203
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Dim.Entities.Enums;

namespace Dim.Entities.Extensions;

public static class ProcessStepTypeIdExtensions
{
public static ProcessStepTypeId GetRetriggerStep(this ProcessStepTypeId processStepTypeId, ProcessTypeId processTypeId) =>
processStepTypeId switch
{
ProcessStepTypeId.CREATE_WALLET when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.RETRIGGER_CREATE_WALLET,
ProcessStepTypeId.CHECK_OPERATION when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.RETRIGGER_CHECK_OPERATION,
ProcessStepTypeId.GET_COMPANY when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.RETRIGGER_GET_COMPANY,
ProcessStepTypeId.GET_DID_DOCUMENT when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.RETRIGGER_GET_DID_DOCUMENT,
ProcessStepTypeId.CREATE_STATUS_LIST when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.RETRIGGER_CREATE_STATUS_LIST,
ProcessStepTypeId.SEND_CALLBACK when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.RETRIGGER_SEND_CALLBACK,
ProcessStepTypeId.CREATE_TECHNICAL_USER when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.RETRIGGER_CREATE_TECHNICAL_USER,
ProcessStepTypeId.GET_TECHNICAL_USER_DATA when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.RETRIGGER_GET_TECHNICAL_USER_DATA,
ProcessStepTypeId.SEND_TECHNICAL_USER_CREATION_CALLBACK when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.RETRIGGER_SEND_TECHNICAL_USER_CREATION_CALLBACK,
ProcessStepTypeId.DELETE_TECHNICAL_USER when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.RETRIGGER_DELETE_TECHNICAL_USER,
ProcessStepTypeId.SEND_TECHNICAL_USER_DELETION_CALLBACK when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.RETRIGGER_SEND_TECHNICAL_USER_DELETION_CALLBACK,
_ => throw new ArgumentOutOfRangeException(nameof(processStepTypeId), processStepTypeId, null)
};

public static ProcessStepTypeId GetStepForRetrigger(this ProcessStepTypeId processStepTypeId, ProcessTypeId processTypeId) =>
processStepTypeId switch
{
ProcessStepTypeId.RETRIGGER_CREATE_WALLET when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.CREATE_WALLET,
ProcessStepTypeId.RETRIGGER_CHECK_OPERATION when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.CHECK_OPERATION,
ProcessStepTypeId.RETRIGGER_GET_COMPANY when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.GET_COMPANY,
ProcessStepTypeId.RETRIGGER_GET_DID_DOCUMENT when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.GET_DID_DOCUMENT,
ProcessStepTypeId.RETRIGGER_CREATE_STATUS_LIST when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.CREATE_STATUS_LIST,
ProcessStepTypeId.RETRIGGER_SEND_CALLBACK when processTypeId is ProcessTypeId.SETUP_DIM => ProcessStepTypeId.SEND_CALLBACK,
ProcessStepTypeId.RETRIGGER_CREATE_TECHNICAL_USER when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.CREATE_TECHNICAL_USER,
ProcessStepTypeId.RETRIGGER_GET_TECHNICAL_USER_DATA when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.GET_TECHNICAL_USER_DATA,
ProcessStepTypeId.RETRIGGER_SEND_TECHNICAL_USER_CREATION_CALLBACK when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.SEND_TECHNICAL_USER_CREATION_CALLBACK,
ProcessStepTypeId.RETRIGGER_DELETE_TECHNICAL_USER when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.DELETE_TECHNICAL_USER,
ProcessStepTypeId.RETRIGGER_SEND_TECHNICAL_USER_DELETION_CALLBACK when processTypeId is ProcessTypeId.TECHNICAL_USER => ProcessStepTypeId.SEND_TECHNICAL_USER_DELETION_CALLBACK,
_ => throw new ArgumentOutOfRangeException(nameof(processStepTypeId), processStepTypeId, null)
};
}
Loading

0 comments on commit 347e187

Please sign in to comment.