From 7232f271f8748d281d2909e5016e251217e88e39 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Wed, 14 Aug 2024 20:03:35 +0200 Subject: [PATCH] feat(config): make wallet application and paths configurable (#230) Refs: #226 Co-authored-by: Evelyn Gurschler Reviewed-by: Evelyn Gurschler --- charts/ssi-credential-issuer/README.md | 5 +++ .../templates/cronjob-issuer-processes.yaml | 10 ++++++ .../templates/deployment-issuer-service.yaml | 10 ++++++ charts/ssi-credential-issuer/values.yaml | 10 ++++++ .../DependencyInjection/WalletSettings.cs | 15 ++++++++ .../Wallet.Service/Services/WalletService.cs | 36 ++++++++----------- .../appsettings.json | 7 +++- .../Processes.Worker/appsettings.json | 7 +++- .../Services/WalletServiceTests.cs | 7 +++- .../appsettings.IntegrationTests.json | 7 +++- 10 files changed, 89 insertions(+), 25 deletions(-) diff --git a/charts/ssi-credential-issuer/README.md b/charts/ssi-credential-issuer/README.md index 3114029c..fd984e47 100644 --- a/charts/ssi-credential-issuer/README.md +++ b/charts/ssi-credential-issuer/README.md @@ -93,6 +93,11 @@ dependencies: | processesworker.wallet.grantType | string | `"client_credentials"` | | | processesworker.wallet.clientId | string | `"wallet-client-id"` | Provide wallet client-id from CX IAM centralidp. | | processesworker.wallet.clientSecret | string | `""` | Client-secret for wallet client-id. Secret-key 'wallet-client-secret'. | +| processesworker.wallet.application | string | `"catena-x-portal"` | the application set in the wallet | +| processesworker.wallet.createCredentialPath | string | `"api/v2.0.0/credentials"` | path to create a credential | +| processesworker.wallet.signCredentialPath | string | `"/api/v2.0.0/credentials/{0}"` | path to sign a specific credential; {0} will be replaced by the credential id | +| processesworker.wallet.getCredentialPath | string | `"/api/v2.0.0/credentials/{0}"` | path to get a specific credential; {0} will be replaced by the credential id | +| processesworker.wallet.revokeCredentialPath | string | `"/api/v2.0.0/credentials/{0}"` | path to revoke a specific credential; {0} will be replaced by the credential id | | credentialExpiry.name | string | `"expiry"` | | | credentialExpiry.image.name | string | `"docker.io/tractusx/ssi-credential-expiry-app"` | | | credentialExpiry.image.tag | string | `""` | | diff --git a/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml b/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml index 3fb0b945..5cd85504 100644 --- a/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml +++ b/charts/ssi-credential-issuer/templates/cronjob-issuer-processes.yaml @@ -136,6 +136,16 @@ spec: secretKeyRef: name: "{{ template "issuer.secretName" . }}" key: "credential-encryption-key0" + - name: "WALLET__WALLETAPPLICATION" + value: "{{ .Values.processesworker.wallet.application }}" + - name: "WALLET__CREATECREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.createCredentialPath }}" + - name: "WALLET__SIGNCREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.signCredentialPath }}" + - name: "WALLET__GETCREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.getCredentialPath }}" + - name: "WALLET__REVOKECREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.revokeCredentialPath }}" - name: "SERILOG__MINIMUMLEVEL__Default" value: "{{ .Values.processesworker.logging.default }}" - name: "PROCESSES__IDENTITYID" diff --git a/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml b/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml index 2431f6c0..9631a3a4 100644 --- a/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml +++ b/charts/ssi-credential-issuer/templates/deployment-issuer-service.yaml @@ -163,6 +163,16 @@ spec: secretKeyRef: name: "{{ template "issuer.secretName" . }}" key: "credential-encryption-key0" + - name: "WALLET__WALLETAPPLICATION" + value: "{{ .Values.processesworker.wallet.application }}" + - name: "WALLET__CREATECREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.createCredentialPath }}" + - name: "WALLET__SIGNCREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.signCredentialPath }}" + - name: "WALLET__GETCREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.getCredentialPath }}" + - name: "WALLET__REVOKECREDENTIALPATH" + value: "{{ .Values.processesworker.wallet.revokeCredentialPath }}" ports: - name: http containerPort: {{ .Values.portContainer }} diff --git a/charts/ssi-credential-issuer/values.yaml b/charts/ssi-credential-issuer/values.yaml index 6424b67c..ed139024 100644 --- a/charts/ssi-credential-issuer/values.yaml +++ b/charts/ssi-credential-issuer/values.yaml @@ -124,6 +124,16 @@ processesworker: clientId: "wallet-client-id" # -- Client-secret for wallet client-id. Secret-key 'wallet-client-secret'. clientSecret: "" + # -- the application set in the wallet + application: "catena-x-portal" + # -- path to create a credential + createCredentialPath: "api/v2.0.0/credentials" + # -- path to sign a specific credential; {0} will be replaced by the credential id + signCredentialPath: "/api/v2.0.0/credentials/{0}" + # -- path to get a specific credential; {0} will be replaced by the credential id + getCredentialPath: "/api/v2.0.0/credentials/{0}" + # -- path to revoke a specific credential; {0} will be replaced by the credential id + revokeCredentialPath: "/api/v2.0.0/credentials/{0}" credentialExpiry: name: "expiry" diff --git a/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs b/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs index 62de2244..e8ece8b8 100644 --- a/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs +++ b/src/externalservices/Wallet.Service/DependencyInjection/WalletSettings.cs @@ -33,4 +33,19 @@ public class WalletSettings : BasicAuthSettings [Required] public int EncryptionConfigIndex { get; set; } + + [Required] + public string WalletApplication { get; set; } = null!; + + [Required] + public string CreateCredentialPath { get; set; } = null!; + + [Required] + public string SignCredentialPath { get; set; } = null!; + + [Required] + public string GetCredentialPath { get; set; } = null!; + + [Required] + public string RevokeCredentialPath { get; set; } = null!; } diff --git a/src/externalservices/Wallet.Service/Services/WalletService.cs b/src/externalservices/Wallet.Service/Services/WalletService.cs index f0a132a7..80bbaebd 100644 --- a/src/externalservices/Wallet.Service/Services/WalletService.cs +++ b/src/externalservices/Wallet.Service/Services/WalletService.cs @@ -28,25 +28,19 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Wallet.Service.Services; -public class WalletService : IWalletService +public class WalletService(IBasicAuthTokenService basicAuthTokenService, IOptions options) + : IWalletService { private const string NoIdErrorMessage = "Response must contain a valid id"; private static readonly JsonSerializerOptions Options = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; - private readonly IBasicAuthTokenService _basicAuthTokenService; - private readonly WalletSettings _settings; - - public WalletService(IBasicAuthTokenService basicAuthTokenService, IOptions options) - { - _basicAuthTokenService = basicAuthTokenService; - _settings = options.Value; - } + private readonly WalletSettings _settings = options.Value; public async Task CreateCredential(JsonDocument payload, CancellationToken cancellationToken) { - using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); - var data = new CreateCredentialRequest("catena-x-portal", new CredentialPayload(payload)); - var result = await client.PostAsJsonAsync("api/v2.0.0/credentials", data, Options, cancellationToken) + using var client = await basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + var data = new CreateCredentialRequest(_settings.WalletApplication, new CredentialPayload(payload)); + var result = await client.PostAsJsonAsync(_settings.CreateCredentialPath, data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("create-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); @@ -61,9 +55,9 @@ public async Task CreateCredential(JsonDocument payload, CancellationToken public async Task SignCredential(Guid credentialId, CancellationToken cancellationToken) { - using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + using var client = await basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); var data = new SignCredentialRequest(new SignPayload(new SignUpdate("external", "jwt"))); - var result = await client.PatchAsJsonAsync($"/api/v2.0.0/credentials/{credentialId}", data, Options, cancellationToken) + var result = await client.PatchAsJsonAsync(string.Format(_settings.SignCredentialPath, credentialId), data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("sign-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); @@ -78,8 +72,8 @@ public async Task SignCredential(Guid credentialId, CancellationToken ca public async Task GetCredential(Guid externalCredentialId, CancellationToken cancellationToken) { - using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); - var result = await client.GetAsync($"/api/v2.0.0/credentials/{externalCredentialId}", cancellationToken) + using var client = await basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + var result = await client.GetAsync(string.Format(_settings.GetCredentialPath, externalCredentialId), cancellationToken) .CatchingIntoServiceExceptionFor("get-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); @@ -100,9 +94,9 @@ public async Task CreateCredentialForHolder(string holderWalletUrl, string ClientSecret = clientSecret, TokenAddress = $"{holderWalletUrl}/oauth/token" }; - using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(authSettings, cancellationToken); - var data = new DeriveCredentialData("catena-x-portal", new DeriveCredentialPayload(new DeriveCredential(credential))); - var result = await client.PostAsJsonAsync("/api/v2.0.0/credentials", data, Options, cancellationToken) + using var client = await basicAuthTokenService.GetBasicAuthorizedClient(authSettings, cancellationToken); + var data = new DeriveCredentialData(_settings.WalletApplication, new DeriveCredentialPayload(new DeriveCredential(credential))); + var result = await client.PostAsJsonAsync(_settings.CreateCredentialPath, data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("create-holder-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); @@ -117,9 +111,9 @@ public async Task CreateCredentialForHolder(string holderWalletUrl, string public async Task RevokeCredentialForIssuer(Guid externalCredentialId, CancellationToken cancellationToken) { - using var client = await _basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); + using var client = await basicAuthTokenService.GetBasicAuthorizedClient(_settings, cancellationToken); var data = new RevokeCredentialRequest(new RevokePayload(true)); - await client.PatchAsJsonAsync($"/api/v2.0.0/credentials/{externalCredentialId}", data, Options, cancellationToken) + await client.PatchAsJsonAsync(string.Format(_settings.RevokeCredentialPath, externalCredentialId), data, Options, cancellationToken) .CatchingIntoServiceExceptionFor("revoke-credential", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, async x => (false, await x.Content.ReadAsStringAsync().ConfigureAwait(ConfigureAwaitOptions.None))) .ConfigureAwait(false); diff --git a/src/issuer/SsiCredentialIssuer.Service/appsettings.json b/src/issuer/SsiCredentialIssuer.Service/appsettings.json index 191d8b6d..fcac2380 100644 --- a/src/issuer/SsiCredentialIssuer.Service/appsettings.json +++ b/src/issuer/SsiCredentialIssuer.Service/appsettings.json @@ -63,7 +63,12 @@ "TokenAddress": "", "BaseAddress": "", "EncryptionConfigIndex": 0, - "EncryptionConfigs": [] + "EncryptionConfigs": [], + "WalletApplication": "", + "CreateCredentialPath": "", + "SignCredentialPath": "", + "GetCredentialPath": "", + "RevokeCredentialPath": "" }, "Credential": { "IssuerDid": "", diff --git a/src/processes/Processes.Worker/appsettings.json b/src/processes/Processes.Worker/appsettings.json index db783398..76c9e70f 100644 --- a/src/processes/Processes.Worker/appsettings.json +++ b/src/processes/Processes.Worker/appsettings.json @@ -47,6 +47,11 @@ "TokenAddress": "", "BaseAddress": "", "EncryptionConfigIndex": 0, - "EncryptionConfigs": [] + "EncryptionConfigs": [], + "WalletApplication": "", + "CreateCredentialPath": "", + "SignCredentialPath": "", + "GetCredentialPath": "", + "RevokeCredentialPath": "" } } diff --git a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs index 08f65963..31e19fed 100644 --- a/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs +++ b/tests/externalservices/Wallet.Service.Tests/Services/WalletServiceTests.cs @@ -38,7 +38,12 @@ public WalletServiceTests() ClientId = "CatenaX", ClientSecret = "pass@Secret", TokenAddress = "https://example.org/token", - EncryptionConfigIndex = 0 + EncryptionConfigIndex = 0, + WalletApplication = "catena-x-portal", + CreateCredentialPath = "api/v2.0.0/credentials", + SignCredentialPath = "/api/v2.0.0/credentials/{0}", + GetCredentialPath = "/api/v2.0.0/credentials/{0}", + RevokeCredentialPath = "/api/v2.0.0/credentials/{0}" }); _sut = new WalletService(_basicAuthTokenService, _options); } diff --git a/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json b/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json index 78b30caa..427e5599 100644 --- a/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/issuer/SsiCredentialIssuer.Service.Tests/appsettings.IntegrationTests.json @@ -62,6 +62,11 @@ "CipherMode": "CBC", "PaddingMode": "PKCS7" } - ] + ], + "WalletApplication": "catena-x-portal", + "CreateCredentialPath": "api/v2.0.0/credentials", + "SignCredentialPath": "/api/v2.0.0/credentials/{0}", + "GetCredentialPath": "/api/v2.0.0/credentials/{0}", + "RevokeCredentialPath": "/api/v2.0.0/credentials/{0}" } }