diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index 87cb569978..bd35b608c6 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -70,6 +70,6 @@ jobs:
./.sonar/scanner/dotnet-sonarscanner begin /k:"${{ vars.SONAR_PROJECT_KEY }}" /o:"${{ vars.SONAR_ORGANIZATION }}" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths=src/coverage.xml
dotnet build src
cd src
- dotnet-coverage collect 'dotnet test --filter FullyQualifiedName\!~Org.Eclipse.TractusX.Portal.Backend.EndToEnd.Tests --no-restore --verbosity normal' -s 'settings-coverage.xml' -f xml -o 'coverage.xml'
+ dotnet-coverage collect 'dotnet test --filter Category!=PortalHC&Category!=InterfaceHC&Category!=Portal&Category!=Registration --no-restore --verbosity normal' -s 'settings-coverage.xml' -f xml -o 'coverage.xml'
cd ..
./.sonar/scanner/dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60e16d895b..c97e5eff21 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,54 @@
New features, fixed bugs, known defects and other noteworthy changes to each release of the Catena-X Portal Backend.
+## 1.7.0-RC1
+
+### Change
+* Apps Service
+ * instead of creating the notification for an app subscription after triggering the provider, the notification will directly be created when subscribing to an offer
+ * enhanced POST /{appId}/subscribe endpoint business logic enhanced to set offer_subscriptions.date_created value when running the endpoint
+ * enhanced GET /api/apps/{appId} logic to fetch the "isSubscribe" value by the latest subscription record
+ * enhanced GET /api/Apps/provided/subscription-status & GET /api/Apps/{appId}/subscription/{subscriptionId}/provider by adding processStepTypeId responding with the latest subscription processStepTypeId
+* Services Service
+ * instead of creating the notification for an app subscription after triggering the provider, the notification will directly be created when subscribing to an offer
+ * POST {appId}/subscribe endpoint business logic enhanced to set offer_subscriptions.date_created value when running the endpoint
+* Administration
+ * endpoint GET api/administration/partnernetwork/memberCompanies enhanced to allow to send specific set of BPNs inside the request payload to request membership status for those BPNLs only
+* implemented business/backend logic to set/update company_applications.date_last_changed when running an update on the companyApplication
+
+### Feature
+* App Service
+ * added endpoint to AppChange controller to allow app document change process - fetch app documents api: GET /apps/appchange/{appId}/documents
+* Onboarding Service Provider *new function since 1.7.0 alpha* - released onboarding service provider functionality, incl.:
+ * moved creation of the users for network registrations in keycloak to the process step; if the call to keycloak fails operator can retrigger the process without impact to OSP/3rd party
+ * added /api/administration/identityprovider/network/identityproviders/managed/{identityProviderId} endpoint to retrieve idp information regarding IdP connected companies
+
+### Technical Support
+* Removed auth trail from the provisioning settings and added the use of the keycloak settings to set the correct useAuthTrail value
+* adjusted process worker workflow to build the process worker when changes within the networkRegistration directory appear
+* Controller slimlined
+ * removse all identity related code from controllers
+ * added identityservice to buisnessLogic to access idenitity
+* Mask sensitive information in portal logs
+* Extended logs for external service/component calls
+* Portal DB
+ * added inside portal.offer_subscription new attribute "date_created", incl. a migration to set all existing offer subscriptiond dates to "1970-01-01"
+* check constraints is_external_type_use_case, is_credential_type_use_case & is_connector_managed changed from function constraint to trigger function constraint
+* Add new process to synchronize keycloak user with company service account to set the correct user entity id
+
+### Bugfix
+* Application approval/verification process: adjusted bpdm businessPartnerNumber pull process to handle an unset SharingProcessStarted and retry the process
+* Onboarding Service Provider *new function since 1.7.0 alpha*
+ * OSP 3rd party customer registration submit endpoint run fixed by adding NetworkBusinessLogic Registration
+ * updated POST /partnerregistration endpoint - bpn propoerty value NULL allowed
+* Seeding data typo fixes (agreements.json)
+* Updated userRole for service endpoint PUT api/services/{subscriptionId}/unsubscribe to "unsubscribe_services"
+* Add user entity id when creating a company service account
+
+### Known Knowns
+* POST /api/registration/application/{applicationId}/inviteNewUser runs on error if user email is already known/existing in the portal db (no matter to which company the user is connected)
+
+
## 1.7.0 alpha
### Change
@@ -40,16 +88,16 @@ New features, fixed bugs, known defects and other noteworthy changes to each rel
* Notification Service
* GET /api/notifications search string enabled to support search by notification content
* Onboarding Service Provider *new function* - released onboarding service provider functionality, incl.:
- * add new database structure for network to network
- * add seeding for n2n
+ * added new database structure for network to network
+ * added seeding for n2n
* enhanced POST /api/administration/identityprovider/owncompany/identityproviders endpoint by identityProviderType (managed; own; shared)
* network process worker registered to use process worker for onboarding service provider registration flow
- * add seeding (test data only) for the osp realm and company including users
+ * added seeding (test data only) for the osp realm and company including users
* added POST /api/administration/registration/network/partnerRegistration/submit endpoint
* added POST registration/network/partnerRegistration to register partners to the network
- * add new process to synchronize users with central keycloak instance for the partnerRegistration
- * add endpoint to get the callback url of an osp
- * add endpoint to set the callback url of an osp
+ * added new process to synchronize users with central keycloak instance for the partnerRegistration
+ * added endpoint to get the callback url of an osp
+ * added endpoint to set the callback url of an osp
* Email templates
* released new email template 'offer release approval'
* released new email tempülate 'welcome onboarding service provider registration company' (connected to feature release Onboarding Service Provider)
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 2586121a24..ee9e80d8a6 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -35,6 +35,7 @@ nuget/nuget/-/Serilog.AspNetCore/7.0.0, Apache-2.0 AND MIT, approved, #10084
nuget/nuget/-/Serilog.Enrichers.CorrelationId/3.0.1, MIT, approved, clearlydefined
nuget/nuget/-/Serilog.Enrichers.Environment/2.2.0, Apache-2.0, approved, clearlydefined
nuget/nuget/-/Serilog.Enrichers.Process/2.0.2, Apache-2.0, approved, clearlydefined
+nuget/nuget/-/Serilog.Enrichers.Sensitive/1.7.3, MIT, approved, clearlydefined
nuget/nuget/-/Serilog.Enrichers.Thread/3.1.0, Apache-2.0, approved, clearlydefined
nuget/nuget/-/Serilog.Extensions.Hosting/7.0.0, Apache-2.0, approved, #10078
nuget/nuget/-/Serilog.Extensions.Logging/7.0.0, Apache-2.0, approved, #10070
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index af0536aea8..475a70a66e 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -21,6 +21,6 @@
1.7.0
- alpha
+ RC1
diff --git a/src/Portal.Backend.sln b/src/Portal.Backend.sln
index b493ebc00f..dc58bb4387 100644
--- a/src/Portal.Backend.sln
+++ b/src/Portal.Backend.sln
@@ -232,6 +232,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnboardingServiceProvider.L
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetworkRegistration.Executor.Tests", "..\tests\processes\NetworkRegistration.Executor.Tests\NetworkRegistration.Executor.Tests.csproj", "{F1A5A73C-2B8C-4959-A128-CC5A8DECCB1B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Framework.Logging.Tests", "..\tests\framework\Framework.Logging.Tests\Framework.Logging.Tests.csproj", "{146865E5-7DFF-4CC2-8521-9E22CFCEEA20}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceAccountSync.Executor", "processes\ServiceAccountSync.Executor\ServiceAccountSync.Executor.csproj", "{B2E5EBAB-AE49-47B6-8220-4844AC9DA456}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceAccountSync.Executor.Tests", "..\tests\processes\ServiceAccountSync.Executor.Tests\ServiceAccountSync.Executor.Tests.csproj", "{571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1466,6 +1472,42 @@ Global
{F1A5A73C-2B8C-4959-A128-CC5A8DECCB1B}.Release|x64.Build.0 = Release|Any CPU
{F1A5A73C-2B8C-4959-A128-CC5A8DECCB1B}.Release|x86.ActiveCfg = Release|Any CPU
{F1A5A73C-2B8C-4959-A128-CC5A8DECCB1B}.Release|x86.Build.0 = Release|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Debug|x64.Build.0 = Debug|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Debug|x86.Build.0 = Debug|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Release|Any CPU.Build.0 = Release|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Release|x64.ActiveCfg = Release|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Release|x64.Build.0 = Release|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Release|x86.ActiveCfg = Release|Any CPU
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20}.Release|x86.Build.0 = Release|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Debug|x64.Build.0 = Debug|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Debug|x86.Build.0 = Debug|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Release|x64.ActiveCfg = Release|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Release|x64.Build.0 = Release|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Release|x86.ActiveCfg = Release|Any CPU
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456}.Release|x86.Build.0 = Release|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Debug|x64.Build.0 = Debug|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Debug|x86.Build.0 = Debug|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Release|x64.ActiveCfg = Release|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Release|x64.Build.0 = Release|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Release|x86.ActiveCfg = Release|Any CPU
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1474,6 +1516,7 @@ Global
SolutionGuid = {2EB6265F-323A-4BF3-969E-003D64A14B64}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {146865E5-7DFF-4CC2-8521-9E22CFCEEA20} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
{A43B5ACA-1209-46E9-84DB-A48553ED623E} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
{1EAF34DA-6D16-4F5E-86F4-344185F53942} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
{A5BEDD89-7280-466E-8D14-EC5E177AAD07} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
@@ -1576,5 +1619,7 @@ Global
{D22934D7-59B7-4779-AB59-E5BE12DE2F06} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
{B06A4F63-FE8C-40D2-B39F-8C15031A55CC} = {C8957230-4203-452C-A085-34091C5E370B}
{F1A5A73C-2B8C-4959-A128-CC5A8DECCB1B} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
+ {B2E5EBAB-AE49-47B6-8220-4844AC9DA456} = {282CEF03-292F-4A49-83C6-997567D0FF5F}
+ {571DA63A-6B96-4C6C-8D82-D2C1F10BDAE5} = {323C198D-A8C6-4EB0-8B79-72624275E35F}
EndGlobalSection
EndGlobal
diff --git a/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs
index cd6dbd3e40..c41887bbaf 100644
--- a/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs
@@ -18,7 +18,6 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
-using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Async;
@@ -44,6 +43,7 @@ public class ConnectorsBusinessLogic : IConnectorsBusinessLogic
private readonly IPortalRepositories _portalRepositories;
private readonly ISdFactoryBusinessLogic _sdFactoryBusinessLogic;
private readonly IIdentityService _identityService;
+ private readonly ILogger _logger;
private readonly ConnectorsSettings _settings;
private static readonly Regex bpnRegex = new(@"(\w|\d){16}", RegexOptions.None, TimeSpan.FromSeconds(1));
@@ -54,12 +54,14 @@ public class ConnectorsBusinessLogic : IConnectorsBusinessLogic
/// The options
/// Access to the connectorsSdFactory
/// Access to the current logged in user
- public ConnectorsBusinessLogic(IPortalRepositories portalRepositories, IOptions options, ISdFactoryBusinessLogic sdFactoryBusinessLogic, IIdentityService identityService)
+ /// Access to the logger
+ public ConnectorsBusinessLogic(IPortalRepositories portalRepositories, IOptions options, ISdFactoryBusinessLogic sdFactoryBusinessLogic, IIdentityService identityService, ILogger logger)
{
_portalRepositories = portalRepositories;
_settings = options.Value;
_sdFactoryBusinessLogic = sdFactoryBusinessLogic;
_identityService = identityService;
+ _logger = logger;
}
///
@@ -351,6 +353,8 @@ public IAsyncEnumerable GetCompanyConnectorEndPointAsync(
///
public async Task ProcessClearinghouseSelfDescription(SelfDescriptionResponseData data, CancellationToken cancellationToken)
{
+ _logger.LogInformation("Process SelfDescription called with the following data {Data}", data);
+
var result = await _portalRepositories.GetInstance()
.GetConnectorDataById(data.ExternalId)
.ConfigureAwait(false);
diff --git a/src/administration/Administration.Service/BusinessLogic/DocumentsBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/DocumentsBusinessLogic.cs
index cf32908b8a..ebdd4d233d 100644
--- a/src/administration/Administration.Service/BusinessLogic/DocumentsBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/DocumentsBusinessLogic.cs
@@ -26,6 +26,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
+using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;
@@ -35,22 +36,24 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public class DocumentsBusinessLogic : IDocumentsBusinessLogic
{
private readonly IPortalRepositories _portalRepositories;
+ private readonly IIdentityService _identityService;
private readonly DocumentSettings _settings;
///
/// Creates a new instance
///
- public DocumentsBusinessLogic(IPortalRepositories portalRepositories, IOptions options)
+ public DocumentsBusinessLogic(IPortalRepositories portalRepositories, IIdentityService identityService, IOptions options)
{
_portalRepositories = portalRepositories;
+ _identityService = identityService;
_settings = options.Value;
}
///
- public async Task<(string FileName, byte[] Content, string MediaType)> GetDocumentAsync(Guid documentId, Guid companyId)
+ public async Task<(string FileName, byte[] Content, string MediaType)> GetDocumentAsync(Guid documentId)
{
var documentDetails = await _portalRepositories.GetInstance()
- .GetDocumentDataAndIsCompanyUserAsync(documentId, companyId)
+ .GetDocumentDataAndIsCompanyUserAsync(documentId, _identityService.IdentityData.CompanyId)
.ConfigureAwait(false);
if (documentDetails == default)
{
@@ -84,10 +87,10 @@ public DocumentsBusinessLogic(IPortalRepositories portalRepositories, IOptions
- public async Task DeleteDocumentAsync(Guid documentId, Guid companyUserId)
+ public async Task DeleteDocumentAsync(Guid documentId)
{
var documentRepository = _portalRepositories.GetInstance();
- var details = await documentRepository.GetDocumentDetailsForIdUntrackedAsync(documentId, companyUserId).ConfigureAwait(false);
+ var details = await documentRepository.GetDocumentDetailsForIdUntrackedAsync(documentId, _identityService.IdentityData.UserId).ConfigureAwait(false);
if (details.DocumentId == Guid.Empty)
{
diff --git a/src/administration/Administration.Service/BusinessLogic/IDocumentsBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IDocumentsBusinessLogic.cs
index cefe377cfe..cd90e89744 100644
--- a/src/administration/Administration.Service/BusinessLogic/IDocumentsBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IDocumentsBusinessLogic.cs
@@ -31,9 +31,8 @@ public interface IDocumentsBusinessLogic
/// Gets the document with the given id
///
/// Id of the document to get
- /// Company of the user
/// Returns the filename and content of the file
- Task<(string FileName, byte[] Content, string MediaType)> GetDocumentAsync(Guid documentId, Guid companyId);
+ Task<(string FileName, byte[] Content, string MediaType)> GetDocumentAsync(Guid documentId);
///
/// Gets the selfdescription document with the given id
@@ -46,9 +45,8 @@ public interface IDocumentsBusinessLogic
/// Deletes the document and the corresponding consent from the persistence layer.
///
/// Id of the document that should be deleted
- ///
/// Returns true if the document and corresponding consent were deleted successfully. Otherwise a specific error is thrown.
- Task DeleteDocumentAsync(Guid documentId, Guid companyUserId);
+ Task DeleteDocumentAsync(Guid documentId);
///
/// Gets the document as json for the seeding data
diff --git a/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs
index 07fa0078d3..d80c8a3ca8 100644
--- a/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs
@@ -33,11 +33,12 @@ public interface IIdentityProviderBusinessLogic
ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled);
ValueTask UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details);
ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId);
- IAsyncEnumerable GetOwnCompanyUsersIdentityProviderDataAsync(IEnumerable identityProviderIds, Guid companyId, bool unlinkedUsersOnly);
- (Stream FileStream, string ContentType, string FileName, Encoding Encoding) GetOwnCompanyUsersIdentityProviderLinkDataStream(IEnumerable identityProviderIds, Guid companyId, bool unlinkedUsersOnly);
- ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataAsync(IFormFile document, Guid companyId, CancellationToken cancellationToken);
- ValueTask CreateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, UserIdentityProviderLinkData identityProviderLinkData, Guid companyId);
- ValueTask CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId, UserLinkData userLinkData, Guid companyId);
- ValueTask GetOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId, Guid companyId);
- ValueTask DeleteOwnCompanyUserIdentityProviderDataAsync(Guid companyUserId, Guid identityProviderId, Guid companyId);
+ IAsyncEnumerable GetOwnCompanyUsersIdentityProviderDataAsync(IEnumerable identityProviderIds, bool unlinkedUsersOnly);
+ (Stream FileStream, string ContentType, string FileName, Encoding Encoding) GetOwnCompanyUsersIdentityProviderLinkDataStream(IEnumerable identityProviderIds, bool unlinkedUsersOnly);
+ ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataAsync(IFormFile document, CancellationToken cancellationToken);
+ ValueTask CreateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, UserIdentityProviderLinkData identityProviderLinkData);
+ ValueTask CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId, UserLinkData userLinkData);
+ ValueTask GetOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId);
+ ValueTask DeleteOwnCompanyUserIdentityProviderDataAsync(Guid companyUserId, Guid identityProviderId);
+ ValueTask GetOwnIdentityProviderWithConnectedCompanies(Guid identityProviderId);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/INetworkBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/INetworkBusinessLogic.cs
index 180e8df421..5446b619d4 100644
--- a/src/administration/Administration.Service/BusinessLogic/INetworkBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/INetworkBusinessLogic.cs
@@ -1,5 +1,4 @@
/********************************************************************************
- * Copyright (c) 2021, 2023 BMW Group AG
* Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -26,7 +25,5 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public interface INetworkBusinessLogic
{
Task HandlePartnerRegistration(PartnerRegistrationData data);
-
Task RetriggerProcessStep(Guid externalId, ProcessStepTypeId processStepTypeId);
- Task Submit(PartnerSubmitData submitData, CancellationToken cancellationToken);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/IPartnerNetworkBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IPartnerNetworkBusinessLogic.cs
index 886a6d3448..17ef29b9fa 100644
--- a/src/administration/Administration.Service/BusinessLogic/IPartnerNetworkBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IPartnerNetworkBusinessLogic.cs
@@ -22,6 +22,10 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
{
public interface IPartnerNetworkBusinessLogic
{
- IAsyncEnumerable GetAllMemberCompaniesBPNAsync();
+ ///
+ /// Get all member activecompanies bpn
+ ///
+ /// Ids of BPN
+ IAsyncEnumerable GetAllMemberCompaniesBPNAsync(IEnumerable? bpnIds);
}
}
diff --git a/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs
index 74972bb9df..3e80897454 100644
--- a/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs
@@ -27,11 +27,11 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public interface IServiceAccountBusinessLogic
{
- Task CreateOwnCompanyServiceAccountAsync(ServiceAccountCreationInfo serviceAccountCreationInfos, Guid companyId);
- Task DeleteOwnCompanyServiceAccountAsync(Guid serviceAccountId, Guid companyId);
- Task GetOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, Guid companyId);
- Task UpdateOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, ServiceAccountEditableDetails serviceAccountDetails, Guid companyId);
- Task ResetOwnCompanyServiceAccountSecretAsync(Guid serviceAccountId, Guid companyId);
- Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, Guid companyId, string? clientId, bool? isOwner);
- IAsyncEnumerable GetServiceAccountRolesAsync(Guid companyId, string? languageShortName);
+ Task CreateOwnCompanyServiceAccountAsync(ServiceAccountCreationInfo serviceAccountCreationInfos);
+ Task DeleteOwnCompanyServiceAccountAsync(Guid serviceAccountId);
+ Task GetOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId);
+ Task UpdateOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, ServiceAccountEditableDetails serviceAccountDetails);
+ Task ResetOwnCompanyServiceAccountSecretAsync(Guid serviceAccountId);
+ Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, string? clientId, bool? isOwner);
+ IAsyncEnumerable GetServiceAccountRolesAsync(string? languageShortName);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/ISubscriptionConfigurationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ISubscriptionConfigurationBusinessLogic.cs
index c2ee708094..a4163be04e 100644
--- a/src/administration/Administration.Service/BusinessLogic/ISubscriptionConfigurationBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/ISubscriptionConfigurationBusinessLogic.cs
@@ -60,12 +60,12 @@ public interface ISubscriptionConfigurationBusinessLogic
///
/// Id of the users company
/// The detail data
- Task GetProviderCompanyDetailsAsync(Guid companyId);
+ Task GetProviderCompanyDetailsAsync();
///
/// Sets service provider company details
///
/// Detail data for the service provider
/// Id of the users company
- Task SetProviderCompanyDetailsAsync(ProviderDetailData data, Guid companyId);
+ Task SetProviderCompanyDetailsAsync(ProviderDetailData data);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/IUserBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IUserBusinessLogic.cs
index cbf8b21a2f..ce4289f661 100644
--- a/src/administration/Administration.Service/BusinessLogic/IUserBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IUserBusinessLogic.cs
@@ -29,16 +29,16 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
///
public interface IUserBusinessLogic
{
- IAsyncEnumerable CreateOwnCompanyUsersAsync(IEnumerable userList, (Guid UserId, Guid CompanyId) identity);
- Task CreateOwnCompanyIdpUserAsync(Guid identityProviderId, UserCreationInfoIdp userCreationInfo, (Guid UserId, Guid CompanyId) identity);
- Task> GetOwnCompanyUserDatasAsync(Guid companyId, int page, int size, GetOwnCompanyUsersFilter filter);
+ IAsyncEnumerable CreateOwnCompanyUsersAsync(IEnumerable userList);
+ Task CreateOwnCompanyIdpUserAsync(Guid identityProviderId, UserCreationInfoIdp userCreationInfo);
+ Task> GetOwnCompanyUserDatasAsync(int page, int size, GetOwnCompanyUsersFilter filter);
[Obsolete("to be replaced by UserRolesBusinessLogic.GetAppRolesAsync. Remove as soon frontend is adjusted")]
IAsyncEnumerable GetClientRolesAsync(Guid appId, string? languageShortName = null);
- Task GetOwnCompanyUserDetailsAsync(Guid userId, Guid companyId);
- Task AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId, IEnumerable businessPartnerNumbers, Guid companyId);
- Task AddOwnCompanyUsersBusinessPartnerNumberAsync(Guid userId, string businessPartnerNumber, Guid companyId);
- Task GetOwnUserDetails(Guid userId);
- Task UpdateOwnUserDetails(Guid companyUserId, OwnCompanyUserEditableDetails ownCompanyUserEditableDetails, Guid userId);
+ Task GetOwnCompanyUserDetailsAsync(Guid userId);
+ Task AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId, IEnumerable businessPartnerNumbers);
+ Task AddOwnCompanyUsersBusinessPartnerNumberAsync(Guid userId, string businessPartnerNumber);
+ Task GetOwnUserDetails();
+ Task UpdateOwnUserDetails(Guid companyUserId, OwnCompanyUserEditableDetails ownCompanyUserEditableDetails);
///
/// Delete User Own Account using userId
@@ -46,9 +46,9 @@ public interface IUserBusinessLogic
///
///
///
- Task DeleteOwnUserAsync(Guid companyUserId, Guid userId);
- IAsyncEnumerable DeleteOwnCompanyUsersAsync(IEnumerable userIds, Guid companyId);
- Task ExecuteOwnCompanyUserPasswordReset(Guid companyUserId, (Guid UserId, Guid CompanyId) identity);
- Task> GetOwnCompanyAppUsersAsync(Guid appId, Guid userId, int page, int size, CompanyUserFilter filter);
- Task DeleteOwnUserBusinessPartnerNumbersAsync(Guid userId, string businessPartnerNumber, (Guid UserId, Guid CompanyId) identity);
+ Task DeleteOwnUserAsync(Guid companyUserId);
+ IAsyncEnumerable DeleteOwnCompanyUsersAsync(IEnumerable userIds);
+ Task ExecuteOwnCompanyUserPasswordReset(Guid companyUserId);
+ Task> GetOwnCompanyAppUsersAsync(Guid appId, int page, int size, CompanyUserFilter filter);
+ Task DeleteOwnUserBusinessPartnerNumbersAsync(Guid userId, string businessPartnerNumber);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/IUserRolesBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IUserRolesBusinessLogic.cs
index 1334043b2b..76f6022206 100644
--- a/src/administration/Administration.Service/BusinessLogic/IUserRolesBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IUserRolesBusinessLogic.cs
@@ -25,8 +25,8 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public interface IUserRolesBusinessLogic
{
- IAsyncEnumerable GetCoreOfferRoles(Guid companyId, string? languageShortName);
- IAsyncEnumerable GetAppRolesAsync(Guid appId, Guid companyId, string? languageShortName);
+ IAsyncEnumerable GetCoreOfferRoles(string? languageShortName);
+ IAsyncEnumerable GetAppRolesAsync(Guid appId, string? languageShortName);
///
/// Update Role to User
@@ -34,9 +34,8 @@ public interface IUserRolesBusinessLogic
///
///
///
- /// CompanyId of Admin User
/// messages
- Task> ModifyCoreOfferUserRolesAsync(Guid offerId, Guid companyUserId, IEnumerable roles, Guid companyId);
+ Task> ModifyCoreOfferUserRolesAsync(Guid offerId, Guid companyUserId, IEnumerable roles);
///
/// Update Role to User
@@ -44,17 +43,15 @@ public interface IUserRolesBusinessLogic
///
///
///
- /// CompanyId of Admin User
/// messages
- Task> ModifyAppUserRolesAsync(Guid appId, Guid companyUserId, IEnumerable roles, Guid companyId);
+ Task> ModifyAppUserRolesAsync(Guid appId, Guid companyUserId, IEnumerable roles);
///
/// Update Role to User
///
/// app Id
/// User and Role Information like CompanyUser Id and Role Name
- /// CompanyId of Admin User
/// messages
[Obsolete("to be replaced by endpoint UserRolesBusinessLogic.ModifyAppUserRolesAsync. Remove as soon frontend is adjusted")]
- Task> ModifyUserRoleAsync(Guid appId, UserRoleInfo userRoleInfo, Guid companyId);
+ Task> ModifyUserRoleAsync(Guid appId, UserRoleInfo userRoleInfo);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/IUserUploadBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IUserUploadBusinessLogic.cs
index d984353291..95628f3ba7 100644
--- a/src/administration/Administration.Service/BusinessLogic/IUserUploadBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IUserUploadBusinessLogic.cs
@@ -24,6 +24,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public interface IUserUploadBusinessLogic
{
- ValueTask UploadOwnCompanyIdpUsersAsync(Guid identityProviderId, IFormFile document, (Guid UserId, Guid CompanyId) identity, CancellationToken cancellationToken);
- ValueTask UploadOwnCompanySharedIdpUsersAsync(IFormFile document, (Guid UserId, Guid CompanyId) identity, CancellationToken cancellationToken);
+ ValueTask UploadOwnCompanyIdpUsersAsync(Guid identityProviderId, IFormFile document, CancellationToken cancellationToken);
+ ValueTask UploadOwnCompanySharedIdpUsersAsync(IFormFile document, CancellationToken cancellationToken);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs
index af53fd38a1..b9f3c6e231 100644
--- a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs
@@ -138,8 +138,7 @@ private async ValueTask CreateOwnCompanyIdentityProvide
public async ValueTask GetOwnCompanyIdentityProviderAsync(Guid identityProviderId)
{
- var companyId = _identityService.IdentityData.CompanyId;
- var (alias, category, typeId) = await ValidateGetOwnCompanyIdentityProviderArguments(identityProviderId, companyId).ConfigureAwait(false);
+ var (alias, category, typeId) = await ValidateGetOwnCompanyIdentityProviderArguments(identityProviderId).ConfigureAwait(false);
return category switch
{
@@ -149,8 +148,9 @@ public async ValueTask GetOwnCompanyIdentityProviderAsy
};
}
- private async ValueTask<(string Alias, IdentityProviderCategoryId Category, IdentityProviderTypeId TypeId)> ValidateGetOwnCompanyIdentityProviderArguments(Guid identityProviderId, Guid companyId)
+ private async ValueTask<(string Alias, IdentityProviderCategoryId Category, IdentityProviderTypeId TypeId)> ValidateGetOwnCompanyIdentityProviderArguments(Guid identityProviderId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var (alias, category, isOwnOrOwnerCompany, typeId) = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false);
if (!isOwnOrOwnerCompany)
{
@@ -172,8 +172,7 @@ public async ValueTask GetOwnCompanyIdentityProviderAsy
public async ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled)
{
- var companyId = _identityService.IdentityData.CompanyId;
- var (category, alias, typeId) = await ValidateSetOwnCompanyIdentityProviderStatusArguments(identityProviderId, enabled, companyId).ConfigureAwait(false);
+ var (category, alias, typeId) = await ValidateSetOwnCompanyIdentityProviderStatusArguments(identityProviderId, enabled).ConfigureAwait(false);
switch (category)
{
@@ -191,8 +190,9 @@ public async ValueTask SetOwnCompanyIdentityProviderSta
}
}
- private async ValueTask<(IdentityProviderCategoryId Category, string Alias, IdentityProviderTypeId TypeId)> ValidateSetOwnCompanyIdentityProviderStatusArguments(Guid identityProviderId, bool enabled, Guid companyId)
+ private async ValueTask<(IdentityProviderCategoryId Category, string Alias, IdentityProviderTypeId TypeId)> ValidateSetOwnCompanyIdentityProviderStatusArguments(Guid identityProviderId, bool enabled)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false);
if (result == default)
{
@@ -323,7 +323,7 @@ private async ValueTask ValidateOtherActiveIdentityProvider(string? alias,
public async ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId)
{
var companyId = _identityService.IdentityData.CompanyId;
- var (alias, typeId) = await ValidateDeleteOwnCompanyIdentityProviderArguments(identityProviderId, companyId).ConfigureAwait(false);
+ var (alias, typeId) = await ValidateDeleteOwnCompanyIdentityProviderArguments(identityProviderId).ConfigureAwait(false);
_portalRepositories.Remove(new CompanyIdentityProvider(companyId, identityProviderId));
@@ -341,8 +341,9 @@ public async ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderI
await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
- private async ValueTask<(string? Alias, IdentityProviderTypeId TypeId)> ValidateDeleteOwnCompanyIdentityProviderArguments(Guid identityProviderId, Guid companyId)
+ private async ValueTask<(string? Alias, IdentityProviderTypeId TypeId)> ValidateDeleteOwnCompanyIdentityProviderArguments(Guid identityProviderId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false);
if (result == default)
{
@@ -470,8 +471,9 @@ private async ValueTask GetIdentityProviderDetailsSaml(
};
}
- public async ValueTask CreateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, UserIdentityProviderLinkData identityProviderLinkData, Guid companyId)
+ public async ValueTask CreateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, UserIdentityProviderLinkData identityProviderLinkData)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var (userEntityId, alias) = await GetUserAliasDataAsync(companyUserId, identityProviderLinkData.identityProviderId, companyId).ConfigureAwait(false);
try
@@ -495,8 +497,9 @@ await _provisioningManager.AddProviderUserLinkToCentralUserAsync(
identityProviderLinkData.userName);
}
- public async ValueTask CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId, UserLinkData userLinkData, Guid companyId)
+ public async ValueTask CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId, UserLinkData userLinkData)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var (userEntityId, alias) = await GetUserAliasDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false);
try
@@ -521,8 +524,9 @@ await _provisioningManager.AddProviderUserLinkToCentralUserAsync(
userLinkData.userName);
}
- public async ValueTask GetOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId, Guid companyId)
+ public async ValueTask GetOwnCompanyUserIdentityProviderLinkDataAsync(Guid companyUserId, Guid identityProviderId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var (userEntityId, alias) = await GetUserAliasDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false);
var result = await _provisioningManager.GetProviderUserLinkDataForCentralUserIdAsync(userEntityId).FirstOrDefaultAsync(identityProviderLink => identityProviderLink.Alias == alias).ConfigureAwait(false);
@@ -537,8 +541,9 @@ public async ValueTask GetOwnCompanyUserIdentityPr
result.UserName);
}
- public async ValueTask DeleteOwnCompanyUserIdentityProviderDataAsync(Guid companyUserId, Guid identityProviderId, Guid companyId)
+ public async ValueTask DeleteOwnCompanyUserIdentityProviderDataAsync(Guid companyUserId, Guid identityProviderId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var (userEntityId, alias) = await GetUserAliasDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false);
try
{
@@ -550,8 +555,39 @@ public async ValueTask DeleteOwnCompanyUserIdentityProviderDataAsync(Guid compan
}
}
- public async IAsyncEnumerable GetOwnCompanyUsersIdentityProviderDataAsync(IEnumerable identityProviderIds, Guid companyId, bool unlinkedUsersOnly)
+ public async ValueTask GetOwnIdentityProviderWithConnectedCompanies(Guid identityProviderId)
+ {
+ var companyId = _identityService.IdentityData.CompanyId;
+
+ var (alias, category, isOwnerCompany, typeId, connectedCompanies) = await _portalRepositories.GetInstance().GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, companyId).ConfigureAwait(false);
+ if (!isOwnerCompany)
+ {
+ throw new ConflictException($"identityProvider {identityProviderId} is not associated with company {companyId}");
+ }
+
+ if (alias == null)
+ {
+ throw new NotFoundException($"identityProvider {identityProviderId} does not exist");
+ }
+
+ if (category == IdentityProviderCategoryId.KEYCLOAK_SAML && typeId is IdentityProviderTypeId.SHARED)
+ {
+ throw new ConflictException("Shared Idps must not use SAML");
+ }
+
+ var details = category switch
+ {
+ IdentityProviderCategoryId.KEYCLOAK_OIDC => await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false),
+ IdentityProviderCategoryId.KEYCLOAK_SAML => await GetIdentityProviderDetailsSaml(identityProviderId, alias, typeId).ConfigureAwait(false),
+ _ => throw new UnexpectedConditionException($"unexpected value for category '{category}' of identityProvider '{identityProviderId}'")
+ };
+
+ return new(details.identityProviderId, details.alias, details.identityProviderCategoryId, details.IdentityProviderTypeId, details.displayName, details.redirectUrl, details.enabled, connectedCompanies);
+ }
+
+ public async IAsyncEnumerable GetOwnCompanyUsersIdentityProviderDataAsync(IEnumerable identityProviderIds, bool unlinkedUsersOnly)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var identityProviderAliasDatas = await GetOwnCompanyUsersIdentityProviderAliasDataInternalAsync(identityProviderIds, companyId).ConfigureAwait(false);
var idPerAlias = identityProviderAliasDatas.ToDictionary(item => item.Alias, item => item.IdentityProviderId);
var aliase = identityProviderAliasDatas.Select(item => item.Alias).ToList();
@@ -577,24 +613,26 @@ public async IAsyncEnumerable GetOwnCompanyUsersIdenti
}
}
- public (Stream FileStream, string ContentType, string FileName, Encoding Encoding) GetOwnCompanyUsersIdentityProviderLinkDataStream(IEnumerable identityProviderIds, Guid companyId, bool unlinkedUsersOnly)
+ public (Stream FileStream, string ContentType, string FileName, Encoding Encoding) GetOwnCompanyUsersIdentityProviderLinkDataStream(IEnumerable identityProviderIds, bool unlinkedUsersOnly)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var csvSettings = _settings.CsvSettings;
return (new AsyncEnumerableStringStream(GetOwnCompanyUsersIdentityProviderDataLines(identityProviderIds, unlinkedUsersOnly, companyId), csvSettings.Encoding), csvSettings.ContentType, csvSettings.FileName, csvSettings.Encoding);
}
- public ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataAsync(IFormFile document, Guid companyId, CancellationToken cancellationToken)
+ public ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataAsync(IFormFile document, CancellationToken cancellationToken)
{
if (!document.ContentType.Equals(_settings.CsvSettings.ContentType, StringComparison.OrdinalIgnoreCase))
{
throw new UnsupportedMediaTypeException($"Only contentType {_settings.CsvSettings.ContentType} files are allowed.");
}
- return UploadOwnCompanyUsersIdentityProviderLinkDataInternalAsync(document, companyId, cancellationToken);
+ return UploadOwnCompanyUsersIdentityProviderLinkDataInternalAsync(document, cancellationToken);
}
- private async ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataInternalAsync(IFormFile document, Guid companyId, CancellationToken cancellationToken)
+ private async ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataInternalAsync(IFormFile document, CancellationToken cancellationToken)
{
var userRepository = _portalRepositories.GetInstance();
+ var companyId = _identityService.IdentityData.CompanyId;
var (sharedIdpAlias, existingAliase) = await GetCompanyAliasDataAsync(companyId).ConfigureAwait(false);
using var stream = document.OpenReadStream();
diff --git a/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs
index 84e8f3c8cd..6aa306ea19 100644
--- a/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs
@@ -1,5 +1,4 @@
/********************************************************************************
- * Copyright (c) 2021, 2023 BMW Group AG
* Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
@@ -24,7 +23,6 @@
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Models;
-using Org.Eclipse.TractusX.Portal.Backend.Mailing.SendMail;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
@@ -33,7 +31,6 @@
using Org.Eclipse.TractusX.Portal.Backend.Processes.NetworkRegistration.Library;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Service;
-using System.Collections.Immutable;
using System.Text.RegularExpressions;
namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;
@@ -48,16 +45,14 @@ public class NetworkBusinessLogic : INetworkBusinessLogic
private readonly IIdentityService _identityService;
private readonly IUserProvisioningService _userProvisioningService;
private readonly INetworkRegistrationProcessHelper _processHelper;
- private readonly IMailingService _mailingService;
private readonly PartnerRegistrationSettings _settings;
- public NetworkBusinessLogic(IPortalRepositories portalRepositories, IIdentityService identityService, IUserProvisioningService userProvisioningService, INetworkRegistrationProcessHelper processHelper, IMailingService mailingService, IOptions options)
+ public NetworkBusinessLogic(IPortalRepositories portalRepositories, IIdentityService identityService, IUserProvisioningService userProvisioningService, INetworkRegistrationProcessHelper processHelper, IOptions options)
{
_portalRepositories = portalRepositories;
_identityService = identityService;
_userProvisioningService = userProvisioningService;
_processHelper = processHelper;
- _mailingService = mailingService;
_settings = options.Value;
}
@@ -71,8 +66,6 @@ public async Task HandlePartnerRegistration(PartnerRegistrationData data)
var (roleData, identityProviderIdAliase, singleIdentityProviderIdAlias, allIdentityProviderIds) = await ValidatePartnerRegistrationData(data, networkRepository, identityProviderRepository, ownerCompanyId).ConfigureAwait(false);
- var (_, companyName) = await companyRepository.GetCompanyNameUntrackedAsync(ownerCompanyId).ConfigureAwait(false);
-
var companyId = CreatePartnerCompany(companyRepository, data);
var applicationId = _portalRepositories.GetInstance().CreateCompanyApplication(companyId, CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.EXTERNAL,
@@ -98,13 +91,27 @@ string GetIdpAlias(Guid? identityProviderId) =>
? singleIdentityProviderIdAlias?.Alias ?? throw new UnexpectedConditionException("singleIdentityProviderIdAlias should never be null here")
: identityProviderIdAliase?[identityProviderId.Value] ?? throw new UnexpectedConditionException("identityProviderIdAliase should never be null here and should always contain an entry for identityProviderId");
- async IAsyncEnumerable<(Guid CompanyUserId, string UserName, string? Password, Exception? Error)> CreateUsers()
+ async IAsyncEnumerable<(Guid CompanyUserId, Exception? Error)> CreateUsers()
{
- foreach (var user in GetUserCreationData(companyId, GetIdpId, GetIdpAlias, data, roleData))
+ var userRepository = _portalRepositories.GetInstance();
+ await foreach (var (aliasData, creationInfos) in GetUserCreationData(companyId, GetIdpId, GetIdpAlias, data, roleData).ToAsyncEnumerable())
{
- await foreach (var result in _userProvisioningService.CreateOwnCompanyIdpUsersAsync(user.AliasData, user.CreationInfos.ToAsyncEnumerable()))
+ foreach (var creationInfo in creationInfos)
{
- yield return result;
+ var identityId = Guid.Empty;
+ Exception? error = null;
+ try
+ {
+ var (_, companyUserId) = await _userProvisioningService.GetOrCreateCompanyUser(userRepository, aliasData.IdpAlias,
+ creationInfo, companyId, aliasData.IdpId, data.Bpn).ConfigureAwait(false);
+ identityId = companyUserId;
+ }
+ catch (Exception ex)
+ {
+ error = ex;
+ }
+
+ yield return (identityId, error);
}
}
}
@@ -113,7 +120,6 @@ string GetIdpAlias(Guid? identityProviderId) =>
userCreationErrors.IfAny(errors => throw new ServiceException($"Errors occured while saving the users: ${string.Join("", errors.Select(x => x.Message))}", errors.First()));
await _portalRepositories.SaveAsync().ConfigureAwait(false);
- await SendMails(data.UserDetails.Select(x => new ValueTuple(x.Email, x.FirstName, x.LastName)), companyName).ConfigureAwait(false);
}
private Guid CreatePartnerCompany(ICompanyRepository companyRepository, PartnerRegistrationData data)
@@ -169,35 +175,22 @@ private Guid CreatePartnerCompany(ICompanyRepository companyRepository, PartnerR
return (AliasData: companyNameIdpAliasData, CreationInfos: userCreationInfos);
});
- private async Task SendMails(IEnumerable<(string Email, string? FirstName, string? LastName)> companyUserWithRoleIdForCompany, string ospName)
- {
- foreach (var (receiver, firstName, lastName) in companyUserWithRoleIdForCompany)
- {
- var userName = string.Join(" ", firstName, lastName);
- var mailParameters = new Dictionary
- {
- { "userName", !string.IsNullOrWhiteSpace(userName) ? userName : receiver },
- { "hostname", _settings.BasePortalAddress },
- { "osp", ospName },
- { "url", _settings.BasePortalAddress }
- };
- await _mailingService.SendMails(receiver, mailParameters, Enumerable.Repeat("OspWelcomeMail", 1)).ConfigureAwait(false);
- }
- }
-
public Task RetriggerProcessStep(Guid externalId, ProcessStepTypeId processStepTypeId) =>
_processHelper.TriggerProcessStep(externalId, processStepTypeId);
private async Task<(IEnumerable RoleData, IDictionary? IdentityProviderIdAliase, (Guid IdentityProviderId, string Alias)? SingleIdentityProviderIdAlias, IEnumerable AllIdentityProviderIds)> ValidatePartnerRegistrationData(PartnerRegistrationData data, INetworkRepository networkRepository, IIdentityProviderRepository identityProviderRepository, Guid ownerCompanyId)
{
- if (string.IsNullOrWhiteSpace(data.Bpn) || !BpnRegex.IsMatch(data.Bpn))
+ if (data.Bpn != null)
{
- throw new ControllerArgumentException("BPN must contain exactly 16 characters and must be prefixed with BPNL", nameof(data.Bpn));
- }
+ if (!BpnRegex.IsMatch(data.Bpn))
+ {
+ throw new ControllerArgumentException("BPN must contain exactly 16 characters and must be prefixed with BPNL", nameof(data.Bpn));
+ }
- if (await _portalRepositories.GetInstance().CheckBpnExists(data.Bpn).ConfigureAwait(false))
- {
- throw new ControllerArgumentException($"The Bpn {data.Bpn} already exists", nameof(data.Bpn));
+ if (await _portalRepositories.GetInstance().CheckBpnExists(data.Bpn).ConfigureAwait(false))
+ {
+ throw new ControllerArgumentException($"The Bpn {data.Bpn} already exists", nameof(data.Bpn));
+ }
}
if (!data.CompanyRoles.Any())
@@ -307,72 +300,4 @@ private static void ValidateUsers(UserDetailData user)
throw new ControllerArgumentException("Lastname does not match expected format");
}
}
-
- public async Task Submit(PartnerSubmitData submitData, CancellationToken cancellationToken)
- {
- var companyId = _identityService.IdentityData.CompanyId;
- var userId = _identityService.IdentityData.UserId;
- var userRoleIds = await _portalRepositories.GetInstance()
- .GetUserRoleIdsUntrackedAsync(_settings.InitialRoles)
- .ToListAsync(cancellationToken)
- .ConfigureAwait(false);
- var data = await _portalRepositories.GetInstance()
- .GetSubmitData(companyId, userId, userRoleIds)
- .ConfigureAwait(false);
- if (!data.Exists)
- {
- throw new NotFoundException($"Company {companyId} not found");
- }
-
- if (!data.IsUserInRole)
- {
- throw new ForbiddenException($"User must be in role {string.Join(",", _settings.InitialRoles.SelectMany(x => x.UserRoleNames))}");
- }
-
- if (data.CompanyApplications.Count() != 1)
- {
- throw new ConflictException($"Company {companyId} has no or more than one application");
- }
-
- if (data.ProcessId == null)
- {
- throw new ConflictException("There must be an process");
- }
-
- var companyApplication = data.CompanyApplications.Single();
- if (companyApplication.CompanyApplicationStatusId != CompanyApplicationStatusId.CREATED)
- {
- throw new ConflictException($"Application {companyApplication.CompanyApplicationId} is not in state CREATED");
- }
-
- submitData.Agreements.Where(x => x.ConsentStatusId != ConsentStatusId.ACTIVE).IfAny(inactive =>
- throw new ControllerArgumentException($"All agreements must be agreed to. Agreements that are not active: {string.Join(",", inactive.Select(x => x.AgreementId))}", nameof(submitData.Agreements)));
-
- data.CompanyRoleAgreementIds
- .ExceptBy(submitData.CompanyRoles, x => x.CompanyRoleId)
- .IfAny(missing =>
- throw new ControllerArgumentException($"CompanyRoles {string.Join(",", missing.Select(x => x.CompanyRoleId))} are missing", nameof(submitData.CompanyRoles)));
-
- var requiredAgreementIds = data.CompanyRoleAgreementIds
- .SelectMany(x => x.AgreementIds)
- .Distinct().ToImmutableList();
-
- requiredAgreementIds.Except(submitData.Agreements.Where(x => x.ConsentStatusId == ConsentStatusId.ACTIVE).Select(x => x.AgreementId))
- .IfAny(missing =>
- throw new ControllerArgumentException($"All Agreements for the company roles must be agreed to, missing agreementIds: {string.Join(",", missing)}", nameof(submitData.Agreements)));
-
- _portalRepositories.GetInstance()
- .CreateConsents(requiredAgreementIds.Select(agreementId => (agreementId, companyId, userId, ConsentStatusId.ACTIVE)));
-
- var processId = _portalRepositories.GetInstance().CreateProcess(ProcessTypeId.APPLICATION_CHECKLIST).Id;
- _portalRepositories.GetInstance().AttachAndModifyCompanyApplication(companyApplication.CompanyApplicationId,
- ca =>
- {
- ca.ApplicationStatusId = CompanyApplicationStatusId.SUBMITTED;
- ca.ChecklistProcessId = processId;
- });
- _portalRepositories.GetInstance().CreateProcessStepRange(Enumerable.Repeat(new ValueTuple(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED, ProcessStepStatusId.TODO, data.ProcessId.Value), 1));
-
- await _portalRepositories.SaveAsync().ConfigureAwait(false);
- }
}
diff --git a/src/administration/Administration.Service/BusinessLogic/PartnerNetworkBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/PartnerNetworkBusinessLogic.cs
index 84da8945dd..819436a29f 100644
--- a/src/administration/Administration.Service/BusinessLogic/PartnerNetworkBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/PartnerNetworkBusinessLogic.cs
@@ -37,6 +37,6 @@ public PartnerNetworkBusinessLogic(IPortalRepositories portalRepositories)
}
///
- public IAsyncEnumerable GetAllMemberCompaniesBPNAsync() =>
- _portalRepositories.GetInstance().GetAllMemberCompaniesBPNAsync();
+ public IAsyncEnumerable GetAllMemberCompaniesBPNAsync(IEnumerable? bpnIds) =>
+ _portalRepositories.GetInstance().GetAllMemberCompaniesBPNAsync(bpnIds);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs
index 361003fa40..8e5a021842 100644
--- a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs
@@ -48,6 +48,7 @@ public sealed class RegistrationBusinessLogic : IRegistrationBusinessLogic
private readonly IApplicationChecklistService _checklistService;
private readonly IClearinghouseBusinessLogic _clearinghouseBusinessLogic;
private readonly ISdFactoryBusinessLogic _sdFactoryBusinessLogic;
+ private readonly ILogger _logger;
public RegistrationBusinessLogic(
IPortalRepositories portalRepositories,
@@ -55,7 +56,8 @@ public RegistrationBusinessLogic(
IMailingService mailingService,
IApplicationChecklistService checklistService,
IClearinghouseBusinessLogic clearinghouseBusinessLogic,
- ISdFactoryBusinessLogic sdFactoryBusinessLogic)
+ ISdFactoryBusinessLogic sdFactoryBusinessLogic,
+ ILogger logger)
{
_portalRepositories = portalRepositories;
_settings = configuration.Value;
@@ -63,6 +65,7 @@ public RegistrationBusinessLogic(
_checklistService = checklistService;
_clearinghouseBusinessLogic = clearinghouseBusinessLogic;
_sdFactoryBusinessLogic = sdFactoryBusinessLogic;
+ _logger = logger;
}
public Task GetCompanyWithAddressAsync(Guid applicationId)
@@ -277,6 +280,7 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn)
///
public async Task ProcessClearinghouseResponseAsync(ClearinghouseResponseData data, CancellationToken cancellationToken)
{
+ _logger.LogInformation("Process SelfDescription called with the following data {Data}", data);
var result = await _portalRepositories.GetInstance().GetSubmittedApplicationIdsByBpn(data.BusinessPartnerNumber).ToListAsync(cancellationToken).ConfigureAwait(false);
if (!result.Any())
{
@@ -359,6 +363,8 @@ private async Task TriggerChecklistInternal(Guid applicationId, ApplicationCheck
///
public async Task ProcessClearinghouseSelfDescription(SelfDescriptionResponseData data, CancellationToken cancellationToken)
{
+ _logger.LogInformation("Process SelfDescription called with the following data {Data}", data);
+
var result = await _portalRepositories.GetInstance()
.GetCompanyIdSubmissionStatusForApplication(data.ExternalId)
.ConfigureAwait(false);
diff --git a/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs
index 4004f04cbc..917b3d3da1 100644
--- a/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs
@@ -26,6 +26,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
+using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Enums;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models;
@@ -38,21 +39,24 @@ public class ServiceAccountBusinessLogic : IServiceAccountBusinessLogic
private readonly IProvisioningManager _provisioningManager;
private readonly IPortalRepositories _portalRepositories;
private readonly IServiceAccountCreation _serviceAccountCreation;
+ private readonly IIdentityService _identityService;
private readonly ServiceAccountSettings _settings;
public ServiceAccountBusinessLogic(
IProvisioningManager provisioningManager,
IPortalRepositories portalRepositories,
IOptions options,
- IServiceAccountCreation serviceAccountCreation)
+ IServiceAccountCreation serviceAccountCreation,
+ IIdentityService identityService)
{
_provisioningManager = provisioningManager;
_portalRepositories = portalRepositories;
_serviceAccountCreation = serviceAccountCreation;
+ _identityService = identityService;
_settings = options.Value;
}
- public async Task CreateOwnCompanyServiceAccountAsync(ServiceAccountCreationInfo serviceAccountCreationInfos, Guid companyId)
+ public async Task CreateOwnCompanyServiceAccountAsync(ServiceAccountCreationInfo serviceAccountCreationInfos)
{
if (serviceAccountCreationInfos.IamClientAuthMethod != IamClientAuthMethod.SECRET)
{
@@ -63,6 +67,7 @@ public async Task CreateOwnCompanyServiceAccountAsync(Ser
throw new ControllerArgumentException("name must not be empty", "name");
}
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await _portalRepositories.GetInstance().GetBpnAndTechnicalUserRoleIds(companyId, _settings.ClientId).ConfigureAwait(false);
if (result == default)
{
@@ -94,9 +99,10 @@ public async Task CreateOwnCompanyServiceAccountAsync(Ser
serviceAccountData.AuthData.Secret);
}
- public async Task DeleteOwnCompanyServiceAccountAsync(Guid serviceAccountId, Guid companyId)
+ public async Task DeleteOwnCompanyServiceAccountAsync(Guid serviceAccountId)
{
var serviceAccountRepository = _portalRepositories.GetInstance();
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await serviceAccountRepository.GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(serviceAccountId, companyId).ConfigureAwait(false);
if (result == default)
{
@@ -139,8 +145,9 @@ public async Task DeleteOwnCompanyServiceAccountAsync(Guid serviceAccountId
return await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
- public async Task GetOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, Guid companyId)
+ public async Task GetOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await _portalRepositories.GetInstance().GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(serviceAccountId, companyId);
if (result == null)
{
@@ -165,8 +172,9 @@ public async Task GetOwnCompanyServiceAccountD
result.SubscriptionId);
}
- public async Task ResetOwnCompanyServiceAccountSecretAsync(Guid serviceAccountId, Guid companyId)
+ public async Task ResetOwnCompanyServiceAccountSecretAsync(Guid serviceAccountId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await _portalRepositories.GetInstance().GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(serviceAccountId, companyId);
if (result == null)
{
@@ -189,7 +197,7 @@ public async Task ResetOwnCompanyServiceAccountSecretAsyn
result.SubscriptionId);
}
- public async Task UpdateOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, ServiceAccountEditableDetails serviceAccountDetails, Guid companyId)
+ public async Task UpdateOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, ServiceAccountEditableDetails serviceAccountDetails)
{
if (serviceAccountDetails.IamClientAuthMethod != IamClientAuthMethod.SECRET)
{
@@ -199,6 +207,8 @@ public async Task UpdateOwnCompanyServiceAccountDetailsAs
{
throw new ArgumentException($"serviceAccountId {serviceAccountId} from path does not match the one in body {serviceAccountDetails.ServiceAccountId}", nameof(serviceAccountId));
}
+
+ var companyId = _identityService.IdentityData.CompanyId;
var serviceAccountRepository = _portalRepositories.GetInstance();
var result = await serviceAccountRepository.GetOwnCompanyServiceAccountWithIamClientIdAsync(serviceAccountId, companyId).ConfigureAwait(false);
if (result == null)
@@ -254,13 +264,13 @@ await _provisioningManager.UpdateCentralClientAsync(
result.OfferSubscriptionId);
}
- public Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, Guid companyId, string? clientId, bool? isOwner) =>
+ public Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, string? clientId, bool? isOwner) =>
Pagination.CreateResponseAsync(
page,
size,
15,
- _portalRepositories.GetInstance().GetOwnCompanyServiceAccountsUntracked(companyId, clientId, isOwner));
+ _portalRepositories.GetInstance().GetOwnCompanyServiceAccountsUntracked(_identityService.IdentityData.CompanyId, clientId, isOwner));
- IAsyncEnumerable IServiceAccountBusinessLogic.GetServiceAccountRolesAsync(Guid companyId, string? languageShortName) =>
- _portalRepositories.GetInstance().GetServiceAccountRolesAsync(companyId, _settings.ClientId, languageShortName ?? Constants.DefaultLanguage);
+ public IAsyncEnumerable GetServiceAccountRolesAsync(string? languageShortName) =>
+ _portalRepositories.GetInstance().GetServiceAccountRolesAsync(_identityService.IdentityData.CompanyId, _settings.ClientId, languageShortName ?? Constants.DefaultLanguage);
}
diff --git a/src/administration/Administration.Service/BusinessLogic/SubscriptionConfigurationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/SubscriptionConfigurationBusinessLogic.cs
index 049e25c8cd..e349e01f19 100644
--- a/src/administration/Administration.Service/BusinessLogic/SubscriptionConfigurationBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/SubscriptionConfigurationBusinessLogic.cs
@@ -24,6 +24,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
+using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using Org.Eclipse.TractusX.Portal.Backend.Processes.OfferSubscription.Library;
using Org.Eclipse.TractusX.Portal.Backend.Processes.OfferSubscription.Library.Extensions;
@@ -33,16 +34,19 @@ public class SubscriptionConfigurationBusinessLogic : ISubscriptionConfiguration
{
private readonly IOfferSubscriptionProcessService _offerSubscriptionProcessService;
private readonly IPortalRepositories _portalRepositories;
+ private readonly IIdentityService _identityService;
- public SubscriptionConfigurationBusinessLogic(IOfferSubscriptionProcessService offerSubscriptionProcessService, IPortalRepositories portalRepositories)
+ public SubscriptionConfigurationBusinessLogic(IOfferSubscriptionProcessService offerSubscriptionProcessService, IPortalRepositories portalRepositories, IIdentityService identityService)
{
_offerSubscriptionProcessService = offerSubscriptionProcessService;
_portalRepositories = portalRepositories;
+ _identityService = identityService;
}
///
- public async Task GetProviderCompanyDetailsAsync(Guid companyId)
+ public async Task GetProviderCompanyDetailsAsync()
{
+ var companyId = _identityService.IdentityData.CompanyId;
var result = await _portalRepositories.GetInstance()
.GetProviderCompanyDetailAsync(CompanyRoleId.SERVICE_PROVIDER, companyId)
.ConfigureAwait(false);
@@ -59,7 +63,7 @@ public async Task GetProviderCompanyDetailsAsync(Guid
}
///
- public Task SetProviderCompanyDetailsAsync(ProviderDetailData data, Guid companyId)
+ public Task SetProviderCompanyDetailsAsync(ProviderDetailData data)
{
data.Url.EnsureValidHttpsUrl(() => nameof(data.Url));
data.CallbackUrl?.EnsureValidHttpsUrl(() => nameof(data.CallbackUrl));
@@ -70,7 +74,7 @@ public Task SetProviderCompanyDetailsAsync(ProviderDetailData data, Guid company
"the maximum allowed length is 100 characters", nameof(data.Url));
}
- return SetOfferProviderCompanyDetailsInternalAsync(data, companyId);
+ return SetOfferProviderCompanyDetailsInternalAsync(data, _identityService.IdentityData.CompanyId);
}
private async Task SetOfferProviderCompanyDetailsInternalAsync(ProviderDetailData data, Guid companyId)
diff --git a/src/administration/Administration.Service/BusinessLogic/UserBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/UserBusinessLogic.cs
index bf8ad2fa48..4fe574bad2 100644
--- a/src/administration/Administration.Service/BusinessLogic/UserBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/UserBusinessLogic.cs
@@ -28,6 +28,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
+using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models;
@@ -44,6 +45,7 @@ public class UserBusinessLogic : IUserBusinessLogic
private readonly IUserProvisioningService _userProvisioningService;
private readonly IProvisioningDBAccess _provisioningDbAccess;
private readonly IPortalRepositories _portalRepositories;
+ private readonly IIdentityService _identityService;
private readonly IMailingService _mailingService;
private readonly ILogger _logger;
private readonly UserSettings _settings;
@@ -54,6 +56,7 @@ public class UserBusinessLogic : IUserBusinessLogic
/// Provisioning Manager
/// User Provisioning Service
/// Provisioning DBAccess
+ /// Access to the identity
/// Mailing Service
/// logger
/// Settings
@@ -63,6 +66,7 @@ public UserBusinessLogic(
IUserProvisioningService userProvisioningService,
IProvisioningDBAccess provisioningDbAccess,
IPortalRepositories portalRepositories,
+ IIdentityService identityService,
IMailingService mailingService,
ILogger logger,
IOptions settings)
@@ -71,12 +75,13 @@ public UserBusinessLogic(
_userProvisioningService = userProvisioningService;
_provisioningDbAccess = provisioningDbAccess;
_portalRepositories = portalRepositories;
+ _identityService = identityService;
_mailingService = mailingService;
_logger = logger;
_settings = settings.Value;
}
- public IAsyncEnumerable CreateOwnCompanyUsersAsync(IEnumerable userList, (Guid UserId, Guid CompanyId) identity)
+ public IAsyncEnumerable CreateOwnCompanyUsersAsync(IEnumerable userList)
{
var noUserNameAndEmail = userList.Where(user => string.IsNullOrEmpty(user.userName) && string.IsNullOrEmpty(user.eMail));
if (noUserNameAndEmail.Any())
@@ -88,16 +93,16 @@ public IAsyncEnumerable CreateOwnCompanyUsersAsync(IEnumerable user.userName ?? user.eMail))}'");
}
- return CreateOwnCompanyUsersInternalAsync(userList, identity);
+ return CreateOwnCompanyUsersInternalAsync(userList);
}
- private async IAsyncEnumerable CreateOwnCompanyUsersInternalAsync(IEnumerable userList, (Guid UserId, Guid CompanyId) identity)
+ private async IAsyncEnumerable CreateOwnCompanyUsersInternalAsync(IEnumerable userList)
{
- var (companyNameIdpAliasData, nameCreatedBy) = await _userProvisioningService.GetCompanyNameSharedIdpAliasData(identity.UserId).ConfigureAwait(false);
+ var (companyNameIdpAliasData, nameCreatedBy) = await _userProvisioningService.GetCompanyNameSharedIdpAliasData(_identityService.IdentityData.UserId).ConfigureAwait(false);
var distinctRoles = userList.SelectMany(user => user.Roles).Distinct().ToList();
- var roleDatas = await GetOwnCompanyUserRoleData(distinctRoles, identity.CompanyId).ConfigureAwait(false);
+ var roleDatas = await GetOwnCompanyUserRoleData(distinctRoles).ConfigureAwait(false);
var userCreationInfoIdps = userList.Select(user =>
new UserCreationRoleDataIdpInfo(
@@ -148,18 +153,19 @@ private async IAsyncEnumerable CreateOwnCompanyUsersInternalAsync(IEnume
}
}
- private Task> GetOwnCompanyUserRoleData(IEnumerable roles, Guid companyId)
+ private Task> GetOwnCompanyUserRoleData(IEnumerable roles)
{
if (!roles.Any())
{
Task.FromResult(Enumerable.Empty());
}
- return _userProvisioningService.GetOwnCompanyPortalRoleDatas(_settings.Portal.KeycloakClientID, roles, companyId);
+
+ return _userProvisioningService.GetOwnCompanyPortalRoleDatas(_settings.Portal.KeycloakClientID, roles, _identityService.IdentityData.CompanyId);
}
- public async Task CreateOwnCompanyIdpUserAsync(Guid identityProviderId, UserCreationInfoIdp userCreationInfo, (Guid UserId, Guid CompanyId) identity)
+ public async Task CreateOwnCompanyIdpUserAsync(Guid identityProviderId, UserCreationInfoIdp userCreationInfo)
{
- var (companyNameIdpAliasData, nameCreatedBy) = await _userProvisioningService.GetCompanyNameIdpAliasData(identityProviderId, identity.UserId).ConfigureAwait(false);
+ var (companyNameIdpAliasData, nameCreatedBy) = await _userProvisioningService.GetCompanyNameIdpAliasData(identityProviderId, _identityService.IdentityData.UserId).ConfigureAwait(false);
var displayName = await _userProvisioningService.GetIdentityProviderDisplayName(companyNameIdpAliasData.IdpAlias).ConfigureAwait(false);
if (!userCreationInfo.Roles.Any())
@@ -167,7 +173,7 @@ public async Task CreateOwnCompanyIdpUserAsync(Guid identityProviderId, Us
throw new ControllerArgumentException($"at least one role must be specified", nameof(userCreationInfo.Roles));
}
- var roleDatas = await GetOwnCompanyUserRoleData(userCreationInfo.Roles, identity.CompanyId).ConfigureAwait(false);
+ var roleDatas = await GetOwnCompanyUserRoleData(userCreationInfo.Roles).ConfigureAwait(false);
var result = await _userProvisioningService.CreateOwnCompanyIdpUsersAsync(
companyNameIdpAliasData,
@@ -217,11 +223,10 @@ public async Task CreateOwnCompanyIdpUserAsync(Guid identityProviderId, Us
return result.CompanyUserId;
}
- public Task> GetOwnCompanyUserDatasAsync(Guid companyId, int page, int size, GetOwnCompanyUsersFilter filter)
+ public Task> GetOwnCompanyUserDatasAsync(int page, int size, GetOwnCompanyUsersFilter filter)
{
-
var companyUsers = _portalRepositories.GetInstance().GetOwnCompanyUserQuery(
- companyId,
+ _identityService.IdentityData.CompanyId,
filter.CompanyUserId,
filter.UserEntityId,
filter.FirstName,
@@ -271,8 +276,9 @@ public async IAsyncEnumerable GetClientRolesAsync(Guid appId, strin
}
}
- public async Task GetOwnCompanyUserDetailsAsync(Guid userId, Guid companyId)
+ public async Task GetOwnCompanyUserDetailsAsync(Guid userId)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var details = await _portalRepositories.GetInstance().GetOwnCompanyUserDetailsUntrackedAsync(userId, companyId).ConfigureAwait(false);
if (details == null)
{
@@ -281,12 +287,13 @@ public async Task GetOwnCompanyUserDetailsAsync(Guid userId,
return details;
}
- public async Task AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId, IEnumerable businessPartnerNumbers, Guid companyId)
+ public async Task AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId, IEnumerable businessPartnerNumbers)
{
if (businessPartnerNumbers.Any(businessPartnerNumber => businessPartnerNumber.Length > 20))
{
throw new ControllerArgumentException("businessPartnerNumbers must not exceed 20 characters", nameof(businessPartnerNumbers));
}
+ var companyId = _identityService.IdentityData.CompanyId;
var user = await _portalRepositories.GetInstance().GetOwnCompanyUserWithAssignedBusinessPartnerNumbersUntrackedAsync(userId, companyId).ConfigureAwait(false);
if (user == null || user.UserEntityId == null)
{
@@ -303,11 +310,12 @@ public async Task AddOwnCompanyUsersBusinessPartnerNumbersAsync(Guid userId
return await _portalRepositories.SaveAsync();
}
- public Task AddOwnCompanyUsersBusinessPartnerNumberAsync(Guid userId, string businessPartnerNumber, Guid companyId) =>
- AddOwnCompanyUsersBusinessPartnerNumbersAsync(userId, Enumerable.Repeat(businessPartnerNumber, 1), companyId);
+ public Task AddOwnCompanyUsersBusinessPartnerNumberAsync(Guid userId, string businessPartnerNumber) =>
+ AddOwnCompanyUsersBusinessPartnerNumbersAsync(userId, Enumerable.Repeat(businessPartnerNumber, 1));
- public async Task GetOwnUserDetails(Guid userId)
+ public async Task GetOwnUserDetails()
{
+ var userId = _identityService.IdentityData.UserId;
var userRoleIds = await _portalRepositories.GetInstance()
.GetUserRoleIdsUntrackedAsync(_settings.UserAdminRoles).ToListAsync().ConfigureAwait(false);
var details = await _portalRepositories.GetInstance().GetUserDetailsUntrackedAsync(userId, userRoleIds).ConfigureAwait(false);
@@ -318,8 +326,9 @@ public async Task GetOwnUserDetails(Guid userId)
return details;
}
- public async Task UpdateOwnUserDetails(Guid companyUserId, OwnCompanyUserEditableDetails ownCompanyUserEditableDetails, Guid userId)
+ public async Task UpdateOwnUserDetails(Guid companyUserId, OwnCompanyUserEditableDetails ownCompanyUserEditableDetails)
{
+ var userId = _identityService.IdentityData.UserId;
if (companyUserId != userId)
{
throw new ForbiddenException($"invalid userId {companyUserId} for user {userId}");
@@ -376,8 +385,9 @@ await _provisioningManager.UpdateSharedRealmUserAsync(
};
}
- public async Task DeleteOwnUserAsync(Guid companyUserId, Guid userId)
+ public async Task DeleteOwnUserAsync(Guid companyUserId)
{
+ var userId = _identityService.IdentityData.UserId;
if (companyUserId != userId)
{
throw new ForbiddenException($"companyUser {companyUserId} is not the id of user {userId}");
@@ -392,8 +402,9 @@ public async Task DeleteOwnUserAsync(Guid companyUserId, Guid userId)
return await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
- public async IAsyncEnumerable DeleteOwnCompanyUsersAsync(IEnumerable userIds, Guid companyId)
+ public async IAsyncEnumerable DeleteOwnCompanyUsersAsync(IEnumerable userIds)
{
+ var companyId = _identityService.IdentityData.CompanyId;
var iamIdpAlias = await _portalRepositories.GetInstance().GetSharedIdentityProviderIamAliasDataUntrackedAsync(companyId);
await foreach (var accountData in _portalRepositories.GetInstance().GetCompanyUserAccountDataUntrackedAsync(userIds, companyId).ConfigureAwait(false))
@@ -493,8 +504,9 @@ private async Task CanResetPassword(Guid userId)
return false;
}
- public async Task ExecuteOwnCompanyUserPasswordReset(Guid companyUserId, (Guid UserId, Guid CompanyId) identity)
+ public async Task ExecuteOwnCompanyUserPasswordReset(Guid companyUserId)
{
+ var identity = _identityService.IdentityData;
var idpUserName = await _portalRepositories.GetInstance().GetIdpCategoryIdByUserIdAsync(companyUserId, identity.CompanyId).ConfigureAwait(false);
if (idpUserName != null && !string.IsNullOrWhiteSpace(idpUserName.TargetIamUserId) && !string.IsNullOrWhiteSpace(idpUserName.IdpName))
{
@@ -508,20 +520,21 @@ public async Task ExecuteOwnCompanyUserPasswordReset(Guid companyUserId, (
throw new NotFoundException($"Cannot identify companyId or shared idp : userId {companyUserId} is not associated with admin users company {identity.CompanyId}");
}
- public Task> GetOwnCompanyAppUsersAsync(Guid appId, Guid userId, int page, int size, CompanyUserFilter filter) =>
+ public Task> GetOwnCompanyAppUsersAsync(Guid appId, int page, int size, CompanyUserFilter filter) =>
Pagination.CreateResponseAsync(
page,
size,
15,
_portalRepositories.GetInstance().GetOwnCompanyAppUsersPaginationSourceAsync(
appId,
- userId,
+ _identityService.IdentityData.UserId,
new[] { OfferSubscriptionStatusId.ACTIVE },
new[] { UserStatusId.ACTIVE, UserStatusId.INACTIVE },
filter));
- public async Task DeleteOwnUserBusinessPartnerNumbersAsync(Guid userId, string businessPartnerNumber, (Guid UserId, Guid CompanyId) identity)
+ public async Task DeleteOwnUserBusinessPartnerNumbersAsync(Guid userId, string businessPartnerNumber)
{
+ var identity = _identityService.IdentityData;
var userBusinessPartnerRepository = _portalRepositories.GetInstance();
var userWithBpn = await userBusinessPartnerRepository.GetOwnCompanyUserWithAssignedBusinessPartnerNumbersAsync(userId, identity.CompanyId, businessPartnerNumber).ConfigureAwait(false);
diff --git a/src/administration/Administration.Service/BusinessLogic/UserRolesBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/UserRolesBusinessLogic.cs
index ea4d9e4157..0e24a9b480 100644
--- a/src/administration/Administration.Service/BusinessLogic/UserRolesBusinessLogic.cs
+++ b/src/administration/Administration.Service/BusinessLogic/UserRolesBusinessLogic.cs
@@ -28,6 +28,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
+using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library;
using System.Text.Json;
@@ -38,26 +39,29 @@ public class UserRolesBusinessLogic : IUserRolesBusinessLogic
private static readonly JsonSerializerOptions _options = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
private readonly IPortalRepositories _portalRepositories;
private readonly IProvisioningManager _provisioningManager;
+ private readonly IIdentityService _identityService;
private readonly UserSettings _settings;
- public UserRolesBusinessLogic(IPortalRepositories portalRepositories, IProvisioningManager provisioningManager, IOptions options)
+ public UserRolesBusinessLogic(IPortalRepositories portalRepositories, IProvisioningManager provisioningManager, IIdentityService identityService, IOptions options)
{
_portalRepositories = portalRepositories;
_provisioningManager = provisioningManager;
+ _identityService = identityService;
_settings = options.Value;
}
- public IAsyncEnumerable GetCoreOfferRoles(Guid companyId, string? languageShortName) =>
- _portalRepositories.GetInstance().GetCoreOfferRolesAsync(companyId, languageShortName ?? Constants.DefaultLanguage, _settings.Portal.KeycloakClientID)
+ public IAsyncEnumerable GetCoreOfferRoles(string? languageShortName) =>
+ _portalRepositories.GetInstance().GetCoreOfferRolesAsync(_identityService.IdentityData.CompanyId, languageShortName ?? Constants.DefaultLanguage, _settings.Portal.KeycloakClientID)
.PreSortedGroupBy(x => x.OfferId)
.Select(x => new OfferRoleInfos(x.Key, x.Select(s => new OfferRoleInfo(s.RoleId, s.RoleText, s.Description))));
- public IAsyncEnumerable GetAppRolesAsync(Guid appId, Guid companyId, string? languageShortName) =>
+ public IAsyncEnumerable GetAppRolesAsync(Guid appId, string? languageShortName) =>
_portalRepositories.GetInstance()
- .GetAppRolesAsync(appId, companyId, languageShortName ?? Constants.DefaultLanguage);
+ .GetAppRolesAsync(appId, _identityService.IdentityData.CompanyId, languageShortName ?? Constants.DefaultLanguage);
- public Task> ModifyCoreOfferUserRolesAsync(Guid offerId, Guid companyUserId, IEnumerable roles, Guid companyId)
+ public Task> ModifyCoreOfferUserRolesAsync(Guid offerId, Guid companyUserId, IEnumerable roles)
{
+ var companyId = _identityService.IdentityData.CompanyId;
return ModifyUserRolesInternal(
async () =>
{
@@ -92,13 +96,13 @@ public Task> ModifyCoreOfferUserRolesAsync(Guid offe
});
}
- public Task> ModifyAppUserRolesAsync(Guid appId, Guid companyUserId, IEnumerable roles, Guid companyId) =>
+ public Task> ModifyAppUserRolesAsync(Guid appId, Guid companyUserId, IEnumerable roles) =>
ModifyUserRolesInternal(
() => _portalRepositories.GetInstance()
- .GetAppAssignedIamClientUserDataUntrackedAsync(appId, companyUserId, companyId),
+ .GetAppAssignedIamClientUserDataUntrackedAsync(appId, companyUserId, _identityService.IdentityData.CompanyId),
(Guid companyUserId, IEnumerable roles, Guid offerId) => _portalRepositories.GetInstance()
.GetAssignedAndMatchingAppRoles(companyUserId, roles, offerId),
- appId, companyUserId, roles, companyId,
+ appId, companyUserId, roles, _identityService.IdentityData.CompanyId,
data =>
{
var userName = $"{data.firstname} {data.lastname}";
@@ -113,13 +117,13 @@ public Task> ModifyAppUserRolesAsync(Guid appId, Gui
});
[Obsolete("to be replaced by endpoint UserRolesBusinessLogic.ModifyAppUserRolesAsync. Remove as soon frontend is adjusted")]
- public Task> ModifyUserRoleAsync(Guid appId, UserRoleInfo userRoleInfo, Guid companyId) =>
+ public Task> ModifyUserRoleAsync(Guid appId, UserRoleInfo userRoleInfo) =>
ModifyUserRolesInternal(
() => _portalRepositories.GetInstance