diff --git a/CHANGELOG.md b/CHANGELOG.md index fbebfffbdb..35862989d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,30 @@ New features, fixed bugs, known defects and other noteworthy changes to each release of the Catena-X Portal Backend. +## 2.0.0-RC9 + +### Changes +* **Administration Service** +* enhanced companyDetailsWithAddress endpoint +* **Apps Service** +* added roleId for existing activeRoleDetails +* **Services Service** +* updated permissions for api endpoints + +### Bugfix +* **Invitation** +* added decline url for invite process +* **Seeding** +* added self description document to initial company +* **DIM Process Worker** +* stopped creating technical users for dim +* **Role assignment** +* fixed query for core offer to prevent role assignment triggering cascading role assignments +* **Token lifetime** +* set ClockSkew (security configuration jwtBearerOptions) to 5 minutes for token expiration +* **Offersubscription** +* fixed queries throwing a system exception instead of returning default value + ## 2.0.0-RC8 ### Changes diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 02ae4aacc4..aab938b2ba 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -20,6 +20,6 @@ 2.0.0 - RC8 + RC9 diff --git a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs index 826669d4b3..abd7a95014 100644 --- a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs @@ -99,10 +99,10 @@ public Task GetCompanyWithAddressAsync(Guid applicationI private async Task GetCompanyWithAddressAsyncInternal(Guid applicationId) { - var companyWithAddress = await _portalRepositories.GetInstance().GetCompanyUserRoleWithAddressUntrackedAsync(applicationId).ConfigureAwait(ConfigureAwaitOptions.None); + var companyWithAddress = await _portalRepositories.GetInstance().GetCompanyUserRoleWithAddressUntrackedAsync(applicationId, _settings.DocumentTypeIds).ConfigureAwait(ConfigureAwaitOptions.None); if (companyWithAddress == null) { - throw NotFoundException.Create(AdministrationRegistrationErrors.APPLICATION_NOT_FOUND, new ErrorParameter[] { new("applicationId", applicationId.ToString()) }); + throw NotFoundException.Create(AdministrationRegistrationErrors.APPLICATION_NOT_FOUND, [new("applicationId", applicationId.ToString())]); } if (!string.IsNullOrEmpty(companyWithAddress.Name) && !Company.IsMatch(companyWithAddress.Name)) { @@ -134,7 +134,10 @@ private async Task GetCompanyWithAddressAsyncInternal(Gu x.FirstName ?? "", x.LastName ?? "", x.Email ?? "")), - companyWithAddress.CompanyIdentifiers.Select(identifier => new CompanyUniqueIdData(identifier.UniqueIdentifierId, identifier.Value)) + companyWithAddress.CompanyIdentifiers.Select(identifier => new CompanyUniqueIdData(identifier.UniqueIdentifierId, identifier.Value)), + companyWithAddress.DocumentData.Select(data => new DocumentDetails(data.DocumentId, data.DocumentTypeId)), + companyWithAddress.Created, + companyWithAddress.LastChanged ); } @@ -165,9 +168,6 @@ private async Task GetCompanyWithAddressAsyncInternal(Gu application.ApplicationStatusId, application.DateCreated, application.Company!.Name, - application.Invitations.SelectMany(invitation => - invitation.CompanyUser!.Documents.Where(document => _settings.DocumentTypeIds.Contains(document.DocumentTypeId)).Select(document => - new DocumentDetails(document.Id, document.DocumentTypeId))), application.Company!.CompanyAssignedRoles.Select(companyAssignedRoles => companyAssignedRoles.CompanyRoleId), application.ApplicationChecklistEntries.Where(x => x.ApplicationChecklistEntryTypeId != ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION).OrderBy(x => x.ApplicationChecklistEntryTypeId).Select(x => new ApplicationChecklistEntryDetails(x.ApplicationChecklistEntryTypeId, x.ApplicationChecklistEntryStatusId)), application.Invitations @@ -268,22 +268,22 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn) .VerifyChecklistEntryAndProcessSteps( applicationId, ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER, - new[] { + [ ApplicationChecklistEntryStatusId.TO_DO, ApplicationChecklistEntryStatusId.IN_PROGRESS, ApplicationChecklistEntryStatusId.FAILED - }, + ], ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_MANUAL, - entryTypeIds: new[] { + entryTypeIds: [ ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION - }, - processStepTypeIds: new[] { + ], + processStepTypeIds: [ ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PUSH, ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PULL, ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PULL, ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PUSH, ProcessStepTypeId.CREATE_IDENTITY_WALLET - }) + ]) .ConfigureAwait(ConfigureAwaitOptions.None); _portalRepositories.GetInstance().AttachAndModifyCompany(applicationCompanyData.CompanyId, null, @@ -293,12 +293,12 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn) _checklistService.SkipProcessSteps( context, - new[] { + [ ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PUSH, ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PULL, ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PULL, ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PUSH - }); + ]); _checklistService.FinalizeChecklistEntryAndProcessSteps( context, @@ -386,9 +386,9 @@ private async Task TriggerChecklistInternal(Guid applicationId, ApplicationCheck .VerifyChecklistEntryAndProcessSteps( applicationId, entryTypeId, - new[] { ApplicationChecklistEntryStatusId.FAILED }, + [ApplicationChecklistEntryStatusId.FAILED], processStepTypeId, - processStepTypeIds: new[] { nextProcessStepTypeId }) + processStepTypeIds: [nextProcessStepTypeId]) .ConfigureAwait(ConfigureAwaitOptions.None); _checklistService.FinalizeChecklistEntryAndProcessSteps( @@ -405,7 +405,7 @@ private async Task TriggerChecklistInternal(Guid applicationId, ApplicationCheck item.ApplicationChecklistEntryStatusId = checklistEntryStatusId; item.Comment = null; }, - new[] { nextProcessStepTypeId }); + [nextProcessStepTypeId]); await _portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None); } @@ -438,10 +438,10 @@ public async Task ApproveRegistrationVerification(Guid applicationId) .VerifyChecklistEntryAndProcessSteps( applicationId, ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION, - new[] { ApplicationChecklistEntryStatusId.TO_DO }, + [ApplicationChecklistEntryStatusId.TO_DO], ProcessStepTypeId.VERIFY_REGISTRATION, - new[] { ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER }, - new[] { CreateWalletStep() }) + [ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER], + [CreateWalletStep()]) .ConfigureAwait(ConfigureAwaitOptions.None); var businessPartnerSuccess = context.Checklist[ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER] == new ValueTuple(ApplicationChecklistEntryStatusId.DONE, null); @@ -474,13 +474,13 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com .VerifyChecklistEntryAndProcessSteps( applicationId, ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION, - new[] { ApplicationChecklistEntryStatusId.TO_DO, ApplicationChecklistEntryStatusId.DONE }, + [ApplicationChecklistEntryStatusId.TO_DO, ApplicationChecklistEntryStatusId.DONE], ProcessStepTypeId.DECLINE_APPLICATION, null, - new[] { ProcessStepTypeId.VERIFY_REGISTRATION, }) + [ProcessStepTypeId.VERIFY_REGISTRATION,]) .ConfigureAwait(ConfigureAwaitOptions.None); - _checklistService.SkipProcessSteps(context, new[] { ProcessStepTypeId.VERIFY_REGISTRATION }); + _checklistService.SkipProcessSteps(context, [ProcessStepTypeId.VERIFY_REGISTRATION]); var identityProviderRepository = _portalRepositories.GetInstance(); var userRepository = _portalRepositories.GetInstance(); @@ -572,15 +572,15 @@ private static IEnumerable GetCompanyApplicationStat { case CompanyApplicationStatusFilter.Closed: { - return new[] { CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED }; + return [CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED]; } case CompanyApplicationStatusFilter.InReview: { - return new[] { CompanyApplicationStatusId.SUBMITTED }; + return [CompanyApplicationStatusId.SUBMITTED]; } default: { - return new[] { CompanyApplicationStatusId.SUBMITTED, CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED }; + return [CompanyApplicationStatusId.SUBMITTED, CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED]; } } } diff --git a/src/administration/Administration.Service/Models/CompanyApplicationDetails.cs b/src/administration/Administration.Service/Models/CompanyApplicationDetails.cs index 075717c072..5c28b23c79 100644 --- a/src/administration/Administration.Service/Models/CompanyApplicationDetails.cs +++ b/src/administration/Administration.Service/Models/CompanyApplicationDetails.cs @@ -28,18 +28,12 @@ public record CompanyApplicationDetails( [property: JsonPropertyName("applicationStatus")] CompanyApplicationStatusId CompanyApplicationStatusId, [property: JsonPropertyName("dateCreated")] DateTimeOffset DateCreated, [property: JsonPropertyName("companyName")] string CompanyName, - [property: JsonPropertyName("documents")] IEnumerable Documents, [property: JsonPropertyName("companyRoles")] IEnumerable CompanyRoles, [property: JsonPropertyName("applicationChecklist")] IEnumerable ApplicationChecklist, [property: JsonPropertyName("email")] string? Email, [property: JsonPropertyName("bpn")] string? BusinessPartnerNumber ); -public record DocumentDetails( - [property: JsonPropertyName("documentId")] Guid DocumentId, - [property: JsonPropertyName("documentType")] DocumentTypeId? DocumentTypeId -); - public record ApplicationChecklistEntryDetails( ApplicationChecklistEntryTypeId TypeId, ApplicationChecklistEntryStatusId StatusId diff --git a/src/administration/Administration.Service/Models/CompanyWithAddressData.cs b/src/administration/Administration.Service/Models/CompanyWithAddressData.cs index 86baabf28e..4750ae060e 100644 --- a/src/administration/Administration.Service/Models/CompanyWithAddressData.cs +++ b/src/administration/Administration.Service/Models/CompanyWithAddressData.cs @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2022 Contributors to the CatenaX (ng) GitHub Organisation. + * Copyright (c) 2022 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -40,6 +40,9 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models; /// /// /// +/// +/// +/// /// public record CompanyWithAddressData( @@ -56,7 +59,10 @@ public record CompanyWithAddressData( string ZipCode, [property: JsonPropertyName("companyRoles")] IEnumerable AgreementsRoleData, [property: JsonPropertyName("companyUser")] IEnumerable InvitedUserData, - IEnumerable UniqueIds + IEnumerable UniqueIds, + [property: JsonPropertyName("documents")] IEnumerable Documents, + DateTimeOffset? Created, + DateTimeOffset? LastChanged ); /// @@ -95,3 +101,14 @@ public record InvitedUserData( string LastName, string Email ); + +/// +/// +/// +/// +/// +/// +public record DocumentDetails( + [property: JsonPropertyName("documentId")] Guid DocumentId, + [property: JsonPropertyName("documentType")] DocumentTypeId? DocumentTypeId +); diff --git a/src/administration/Administration.Service/appsettings.json b/src/administration/Administration.Service/appsettings.json index e8e3bf6da9..c700d96794 100644 --- a/src/administration/Administration.Service/appsettings.json +++ b/src/administration/Administration.Service/appsettings.json @@ -57,7 +57,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "Provisioning": { diff --git a/src/marketplace/Services.Service/Controllers/ServicesController.cs b/src/marketplace/Services.Service/Controllers/ServicesController.cs index c11e0b7fa9..923c30c5e6 100644 --- a/src/marketplace/Services.Service/Controllers/ServicesController.cs +++ b/src/marketplace/Services.Service/Controllers/ServicesController.cs @@ -262,7 +262,7 @@ public async Task GetServiceDocumentContentAsync([FromRoute] Guid se /// User's company does not provide the service. /// No service or subscription found. [HttpGet] - [Authorize(Roles = "add_service_offering")] + [Authorize(Roles = "service_management")] [Authorize(Policy = PolicyTypes.ValidCompany)] [Route("{serviceId}/subscription/{subscriptionId}/provider")] [ProducesResponseType(typeof(ProviderSubscriptionDetailData), StatusCodes.Status200OK)] @@ -282,7 +282,7 @@ public Task GetSubscriptionDetailForProvider([Fr /// User's company does not provide the service. /// No service or subscription found. [HttpGet] - [Authorize(Roles = "add_service_offering")] + [Authorize(Roles = "subscribe_service")] [Authorize(Policy = PolicyTypes.ValidCompany)] [Route("{serviceId}/subscription/{subscriptionId}/subscriber")] [ProducesResponseType(typeof(SubscriberSubscriptionDetailData), StatusCodes.Status200OK)] @@ -299,7 +299,7 @@ public Task GetSubscriptionDetailForSubscriber /// If sub claim is empty/invalid or user does not exist. [HttpGet] [Route("subscribed/subscription-status")] - [Authorize(Roles = "view_subscription")] + [Authorize(Roles = "view_service_subscriptions")] [Authorize(Policy = PolicyTypes.ValidCompany)] [ProducesResponseType(typeof(Pagination.Response), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)] diff --git a/src/notifications/Notifications.Service/appsettings.json b/src/notifications/Notifications.Service/appsettings.json index c94a36512a..0cdc02d33f 100644 --- a/src/notifications/Notifications.Service/appsettings.json +++ b/src/notifications/Notifications.Service/appsettings.json @@ -56,7 +56,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "Notifications": { diff --git a/src/portalbackend/PortalBackend.DBAccess/Models/CompanyUserRoleWithAddress.cs b/src/portalbackend/PortalBackend.DBAccess/Models/CompanyUserRoleWithAddress.cs index b011739cbc..6b5b5cba17 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Models/CompanyUserRoleWithAddress.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Models/CompanyUserRoleWithAddress.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * Copyright (c) 2022 BMW Group AG * Copyright (c) 2022 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional @@ -37,7 +36,10 @@ public record CompanyUserRoleWithAddress( string? CountryDe, IEnumerable AgreementsData, IEnumerable InvitedCompanyUserData, - IEnumerable<(UniqueIdentifierId UniqueIdentifierId, string Value)> CompanyIdentifiers + IEnumerable<(UniqueIdentifierId UniqueIdentifierId, string Value)> CompanyIdentifiers, + IEnumerable<(Guid DocumentId, DocumentTypeId DocumentTypeId)> DocumentData, + DateTimeOffset? Created, + DateTimeOffset? LastChanged ); public record AgreementsData(CompanyRoleId CompanyRoleId, Guid AgreementId, ConsentStatusId? ConsentStatusId); diff --git a/src/portalbackend/PortalBackend.DBAccess/Models/OfferRoleInfos.cs b/src/portalbackend/PortalBackend.DBAccess/Models/OfferRoleInfos.cs index 3d76f0cfd0..c8eefc307a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Models/OfferRoleInfos.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Models/OfferRoleInfos.cs @@ -30,6 +30,7 @@ public record OfferRoleInfos( [property: JsonPropertyName("roles")] IEnumerable RoleInfos); public record ActiveAppRoleDetails( + [property: JsonPropertyName("roleId")] Guid RoleId, [property: JsonPropertyName("role")] string Role, [property: JsonPropertyName("descriptions")] IEnumerable Descriptions); diff --git a/src/portalbackend/PortalBackend.DBAccess/Models/UserRoleData.cs b/src/portalbackend/PortalBackend.DBAccess/Models/UserRoleData.cs index d30b2ed502..893130dd80 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Models/UserRoleData.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Models/UserRoleData.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * Copyright (c) 2022 BMW Group AG * Copyright (c) 2022 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional @@ -18,7 +17,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; using System.Text.Json.Serialization; namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models; diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs index 1561f22485..d98c77f9d7 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs @@ -264,7 +264,7 @@ public IQueryable GetAllCompanyApplicationsDetailsQuery(stri .AsNoTracking() .Where(application => companyName == null || EF.Functions.ILike(application.Company!.Name, $"%{companyName.EscapeForILike()}%")); - public Task GetCompanyUserRoleWithAddressUntrackedAsync(Guid companyApplicationId) => + public Task GetCompanyUserRoleWithAddressUntrackedAsync(Guid companyApplicationId, IEnumerable documentTypeIds) => portalDbContext.CompanyApplications .AsSplitQuery() .Where(companyApplication => companyApplication.Id == companyApplicationId) @@ -294,7 +294,12 @@ public IQueryable GetAllCompanyApplicationsDetailsQuery(stri x.CompanyUser!.Firstname, x.CompanyUser.Lastname, x.CompanyUser.Email)), - companyApplication.Company.CompanyIdentifiers.Select(identifier => new ValueTuple(identifier.UniqueIdentifierId, identifier.Value)))) + companyApplication.Company.CompanyIdentifiers.Select(identifier => new ValueTuple(identifier.UniqueIdentifierId, identifier.Value)), + companyApplication.Invitations.SelectMany(invitation => + invitation.CompanyUser!.Documents.Where(document => documentTypeIds.Contains(document.DocumentTypeId)).Select(document => + new ValueTuple(document.Id, document.DocumentTypeId))), + companyApplication.DateCreated, + companyApplication.DateLastChanged)) .AsNoTracking() .SingleOrDefaultAsync(); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyInvitationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyInvitationRepository.cs index 7dcc20cbcf..8c23f7ab12 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyInvitationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyInvitationRepository.cs @@ -38,9 +38,10 @@ public CompanyInvitation CreateCompanyInvitation(string firstName, string lastNa } public Task GetCompanyInvitationForProcessId(Guid processId) => - _context.Processes - .Where(process => process.Id == processId) - .Select(process => process.CompanyInvitation!.Id) + _context.CompanyInvitations + .AsNoTracking() + .Where(i => i.ProcessId == processId) + .Select(i => i.Id) .SingleOrDefaultAsync(); public Task GetOrganisationNameForInvitation(Guid invitationId) => diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs index f16e5e7d7f..9e6e942f9a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * Copyright (c) 2022 BMW Group AG * Copyright (c) 2022 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional @@ -43,7 +42,7 @@ public interface IApplicationRepository IAsyncEnumerable GetInvitedUsersDataByApplicationIdUntrackedAsync(Guid applicationId); IAsyncEnumerable GetEmailDataUntrackedAsync(Guid applicationId); IQueryable GetAllCompanyApplicationsDetailsQuery(string? companyName = null); - Task GetCompanyUserRoleWithAddressUntrackedAsync(Guid companyApplicationId); + Task GetCompanyUserRoleWithAddressUntrackedAsync(Guid companyApplicationId, IEnumerable documentTypeIds); Task<(bool IsValidApplicationId, bool IsValidCompany, RegistrationData? Data)> GetRegistrationDataUntrackedAsync(Guid applicationId, Guid userCompanyId, IEnumerable documentTypes); Task<(string? Bpn, IEnumerable ExistingChecklistEntryTypeIds)> GetBpnAndChecklistCheckForApplicationIdAsync(Guid applicationId); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IServiceAccountRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IServiceAccountRepository.cs index fde2b6f795..368502d740 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IServiceAccountRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IServiceAccountRepository.cs @@ -43,6 +43,6 @@ CompanyServiceAccount CreateCompanyServiceAccount(Guid identityId, public Task<(Guid IdentityId, Guid CompanyId)> GetServiceAccountDataByClientId(string clientId); void CreateDimCompanyServiceAccount(Guid serviceAccountId, string authenticationServiceUrl, byte[] secret, byte[] initializationVector, int encryptionMode); void CreateDimUserCreationData(Guid serviceAccountId, Guid processId); - Task<(bool IsValid, string? Bpn, string? ClientClientId)> GetDimServiceAccountData(Guid dimServiceAccountId); + Task<(bool IsValid, string? Bpn, string Name)> GetDimServiceAccountData(Guid dimServiceAccountId); Task GetDimServiceAccountIdForProcess(Guid processId); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs index 8ba9cf3959..f5906ae231 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs @@ -45,10 +45,10 @@ public Task CheckExternalIdExists(string externalId, Guid onboardingServic /// public Task GetNetworkRegistrationDataForProcessIdAsync(Guid processId) => - _context.Processes + _context.NetworkRegistrations .AsNoTracking() - .Where(process => process.Id == processId) - .Select(process => process.NetworkRegistration!.Id) + .Where(nr => nr.ProcessId == processId) + .Select(nr => nr.Id) .SingleOrDefaultAsync(); public Task<(bool RegistrationIdExists, VerifyProcessData processData)> IsValidRegistration(string externalId, IEnumerable processStepTypeIds) => diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs index eebb679b8c..ac73f4818a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs @@ -332,10 +332,10 @@ public void AttachAndModifyAppSubscriptionDetail(Guid detailId, Guid subscriptio /// public Task GetOfferSubscriptionDataForProcessIdAsync(Guid processId) => - _context.Processes + _context.OfferSubscriptions .AsNoTracking() - .Where(process => process.Id == processId) - .Select(process => process.OfferSubscription!.Id) + .Where(os => os.ProcessId == processId) + .Select(os => os.Id) .SingleOrDefaultAsync(); /// diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs index 8a2bff66ac..22c8c7c3e2 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ServiceAccountRepository.cs @@ -224,13 +224,13 @@ public void CreateDimCompanyServiceAccount(Guid serviceAccountId, string authent public void CreateDimUserCreationData(Guid serviceAccountId, Guid processId) => _dbContext.DimUserCreationData.Add(new DimUserCreationData(Guid.NewGuid(), serviceAccountId, processId)); - public Task<(bool IsValid, string? Bpn, string? ClientClientId)> GetDimServiceAccountData(Guid dimServiceAccountId) => + public Task<(bool IsValid, string? Bpn, string Name)> GetDimServiceAccountData(Guid dimServiceAccountId) => _dbContext.DimUserCreationData .Where(x => x.Id == dimServiceAccountId) - .Select(x => new ValueTuple( + .Select(x => new ValueTuple( true, x.ServiceAccount!.Identity!.Company!.BusinessPartnerNumber, - x.ServiceAccount!.ClientClientId)) + x.ServiceAccount!.Name)) .SingleOrDefaultAsync(); public Task GetDimServiceAccountIdForProcess(Guid processId) => diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRolesRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRolesRepository.cs index 2cc0dad89e..0f4637f53b 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRolesRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRolesRepository.cs @@ -154,13 +154,16 @@ public IAsyncEnumerable GetAssignedAndMatchingCoreOffe .Select(role => new { Role = role, + IsRequested = userRoles.Contains(role.UserRoleText), IsAssigned = role.IdentityAssignedRoles.Any(iar => iar.IdentityId == identityId), IsAssignable = role.UserRoleCollections.Any(collection => collection.CompanyRoleAssignedRoleCollection!.CompanyRole!.CompanyAssignedRoles.Any(assigned => assigned.Company!.Identities.Any(identity => identity.Id == identityId))) }) - .Where(x => - userRoles.Contains(x.Role.UserRoleText) || - x.IsAssigned || - x.IsAssignable) + // x.IsRequested && x.IsAssigned && x.IsAssignable || // no change but required to detect duplicates + // x.IsRequested && !x.IsAssigned && x.IsAssignable || // to be assigned + // !x.IsRequested && x.IsAssigned || // to be unassigned + // x.IsRequested && !x.IsAssignable // invalid + // can be simplified to: + .Where(x => x.IsRequested || x.IsAssigned) .Select(x => new UserRoleModificationData( x.Role.UserRoleText, x.Role.Id, @@ -299,6 +302,7 @@ public IAsyncEnumerable GetRolesForClient(string technicalUserProfileClien x.Active ? x.Roles.Select(role => new ActiveAppRoleDetails( + role.Id, role.UserRoleText, role.UserRoleDescriptions.Where(description => (languageShortName != null && description.LanguageShortName == languageShortName) || @@ -325,6 +329,7 @@ public IAsyncEnumerable GetRolesForClient(string technicalUserProfileClien x.Provider ? x.Roles.Select(role => new ActiveAppRoleDetails( + role.Id, role.UserRoleText, role.UserRoleDescriptions.Where(description => (languageShortName != null && description.LanguageShortName == languageShortName) || diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/companies.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/companies.json index 77ad96b823..764213b56b 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/companies.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/companies.json @@ -7,6 +7,6 @@ "shortname": "Catena-X", "company_status_id": 2, "address_id": "b4db3945-19a7-4a50-97d6-e66e8dfd04fb", - "self_description_document_id": null + "self_description_document_id": "00000000-0000-0000-0000-000000000009" } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json index 7940cb8cb5..bde3e1621f 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json @@ -97,5 +97,17 @@ "document_hash": "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", "document_content": "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MDAwMDAwMDkzMyAwMDAwMCBuIAowMDAwMDExNzI2IDAwMDAwIG4gCjAwMDAwMTQ1NTggMDAwMDAgbiAKMDAwMDAxNTA2NiAwMDAwMCBuIAowMDAwMDE0NzcwIDAwMDAwIG4gCjAwMDAwMTUzMDIgMDAwMDAgbiAKMDAwMDAyMjcyMyAwMDAwMCBuIAowMDAwMDIyMzQ0IDAwMDAwIG4gCjAwMDAwMjI5NTkgMDAwMDAgbiAKMDAwMDAzMzI4NSAwMDAwMCBuIAowMDAwMDMyOTc4IDAwMDAwIG4gCjAwMDAwMzM1MjEgMDAwMDAgbiAKMDAwMDA0MDk5MiAwMDAwMCBuIAowMDAwMDQwNjM3IDAwMDAwIG4gCjAwMDAwNDEyMjggMDAwMDAgbiAKMDAwMDA0OTg5MyAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDMwIC9Sb290IDE2IDAgUiAvSW5mbyAyOSAwIFIgL0lEIFsgPDQzZjZkMjJmYzFiM2NiZjk1MDhjNTliMWE0NjViYTdjPgo8NDNmNmQyMmZjMWIzY2JmOTUwOGM1OWIxYTQ2NWJhN2M+IF0gPj4Kc3RhcnR4cmVmCjUwMTEwCiUlRU9GCg==", "document_status_id": 2 + }, + { + "id": "00000000-0000-0000-0000-000000000009", + "date_created": "2024-01-01T19:29:08.602237+00:00", + "document_name": "SelfDescription_LegalPerson.json", + "media_type_id": 7, + "document_type_id": 8, + "company_user_id": null, + "document_hash": "81a212e6bc3121779f67abfefe7b586240c094412760a1faeb05ae2d4a30de5a781217cdf1be8b21416861819fa15d306fcb5bc62c62044f673d649e569a1dbb", + "document_content": "ewogICJzZWxmRGVzY3JpcHRpb25DcmVkZW50aWFsIjogewogICAgIkxlZ2FsUGVyc29uIjogewogICAgICAiQGNvbnRleHQiOiBbCiAgICAgICAgImh0dHBzOi8vY2FybGEuZGloLWNsb3VkLmNvbS9kZXYvY29tcGxpYW5jZV9zZXJ2aWNlL2NvbnRleHQtanNvbi9jcmVkZW50aWFsc192MV9jb250ZXh0Lmpzb24iLAogICAgICAgICJodHRwczovL2YxYzgyNzg1LTU1OTgtNDFjNy1hMDgzLTAxYThlMWE4MGUxOS5tb2NrLnBzdG1uLmlvL2N0eHNkIgogICAgICBdLAogICAgICAidHlwZSI6IFsKICAgICAgICAiVmVyaWZpYWJsZUNyZWRlbnRpYWwiCiAgICAgIF0sCiAgICAgICJpZCI6ICJodHRwczovL2NhcmxhLmRpaC1jbG91ZC5jb20vdGVzdC9jb21wbGlhbmNlX3NlcnZpY2UvcGFydGljaXBhbnQvQlBOTDAwMDAwMDAzQ1JIS19wYXJ0aWNpcGFudC5qc29uIiwKICAgICAgImNyZWRlbnRpYWxTdWJqZWN0IjogewogICAgICAgICJ0eXBlIjogIkxlZ2FsUGFydGljaXBhbnQiLAogICAgICAgICJicG4iOiAiQlBOTDAwMDAwMDAzQ1JISyIsCiAgICAgICAgInJlZ2lzdHJhdGlvbk51bWJlciI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgInR5cGUiOiAidmF0SUQiLAogICAgICAgICAgICAidmFsdWUiOiAiREUwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiaGVhZHF1YXJ0ZXJBZGRyZXNzIjogewogICAgICAgICAgImNvdW50cnlDb2RlIjogIkRFIgogICAgICAgIH0sCiAgICAgICAgImxlZ2FsQWRkcmVzcyI6IHsKICAgICAgICAgICJjb3VudHJ5Q29kZSI6ICJERSIKICAgICAgICB9LAogICAgICAgICJpZCI6ICJCUE5MMDAwMDAwMDNDUkhLIgogICAgICB9LAogICAgICAiaXNzdWVyIjogImRpZDp3ZWI6b25seV90ZXN0IiwKICAgICAgImlzc3VhbmNlRGF0ZSI6ICIyMDI0LTA0LTI0VDEwOjI1OjQ4WiIsCiAgICAgICJwcm9vZiI6IHsKICAgICAgICAidHlwZSI6ICJKc29uV2ViU2lnbmF0dXJlMjAyMCIsCiAgICAgICAgImNyZWF0ZWQiOiAiMjAyNC0wNC0yNFQxMDoyNTo0OS43MTFaIiwKICAgICAgICAicHJvb2ZQdXJwb3NlIjogImFzc2VydGlvbk1ldGhvZCIsCiAgICAgICAgImp3cyI6ICJleUpoYkdjaU9pSlFVekkxTmlJc0ltSTJOQ0k2Wm1Gc2MyVXNJbU55YVhRaU9sc2lZalkwSWwxOS4uOGFzZm10VnpmWDQ0OHdtUy16SmZfZ190dF9XZFF0eXREcU1LSDNpNU1xU2drZ1Q4eWhLVUxOYzQ2d3dDbnJoZUk5cGRLUGNmZnJoRTVpeHV0WTZ5MV9UYW5hbEJrTk9GTUN3Sjl6VVFtR0FSamcxTE1kMXNPUnZGR3dyanBwOVUtSHlmWEJQT1BIVUJhelJGNVJjLVZyWmZVTGJGbEpNb05mdnV3UTRhejlzazhhdTZleDJLUnppSnVUWVlDUU43M2s1YTNES3hjNEQ2V09VYmJKWGZub3FLMkhEWDBtRzNZTm1sWHA4UEFjN0R2MXFyV1QyR1QzazlRTDB3OFE3QzByQ29zcDdVMnBiZVdpVUZjQTFYUTFucmg1MF9ScHNCbVprMDhCMkVSdEdvaDlhUTFkUGxLdThXQjRDcHZMLVJVWmEtek5mYUFOYlFEY3BoRFVhNEFBdDRrcHo2WlRlQm4zQUxFbWJLcW53Vk1ZU3VHMUpDOFphZkxRSWo5b1IzWS04Z3V6S3RQYTgwa3JJUTBQekZEbnZrVjQ4WjZqTFNRYm5TVDZrWXczVlFMYVF2TGpWYkFTZzBvZUlrTUFRQ250MjdmRTZYZFlobFVxSENxSDZodk5JZko4c0h6VTNTcUstUDdiWmJVSkhmS3pLY0tENVV4eHdwcHBFalBYN0U2clAtenJ1dERBejdEREdMNWo1THpEQjczcXNFbmk3amhWN3pCOTEzdS13bTItcFZPc0RuaDVQUnQ4Y00yZXlKT011Y1M3TE4tQ21mTTctWDk5UVZ5cXBKTURTcFk0YkZhQUoycTJhZjNwUllZV1hLQzh0bmdFZ3l6ek5qbHBHYm5XM19IQmFiYVpPZWF0b3ctOGFmYW0ydTdJWjlmbEJnSGJlTnRraEtrMWciLAogICAgICAgICJ2ZXJpZmljYXRpb25NZXRob2QiOiAiZGlkOndlYjpvbmx5X3Rlc3QiCiAgICAgIH0KICAgIH0KICB9LAogICJjb21wbGlhbmNlQ3JlZGVudGlhbCI6IHsKICAgICJAY29udGV4dCI6IFsKICAgICAgImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwKICAgICAgImh0dHBzOi8vZ3gtcmVnaXN0cnkudGVzdC5kaWgtY2xvdWQuY29tL3YxL2FwaS90cnVzdGVkLXNoYXBlLXJlZ2lzdHJ5L3YxL3NoYXBlcy9qc29ubGQvdHJ1c3RmcmFtZXdvcmsjIgogICAgXSwKICAgICJ0eXBlIjogWwogICAgICAiVmVyaWZpYWJsZUNyZWRlbnRpYWwiCiAgICBdLAogICAgImlkIjogImh0dHBzOi8vY2FybGEuZGloLWNsb3VkLmNvbS90ZXN0L2NvbXBsaWFuY2Vfc2VydmljZS9jcmVkZW50aWFsL0JQTkwwMDAwMDAwM0NSSEtfcGFydGljaXBhbnQuanNvbiIsCiAgICAiY3JlZGVudGlhbFN1YmplY3QiOiBbCiAgICAgIHsKICAgICAgICAidHlwZSI6ICJneDpjb21wbGlhbmNlIiwKICAgICAgICAiaWQiOiAiQlBOTDAwMDAwMDAzQ1JISyIsCiAgICAgICAgImludGVncml0eSI6ICJzaGEyNTYtZDhlZWEzOTlkODAxNzkwMWJlNzk5MGQ1YmU1YTU1ODA5NzlhOGI4OWQ2NWMxZWIzODk5NzU2MGNlNzU2OTFmZCIKICAgICAgfQogICAgXSwKICAgICJpc3N1ZXIiOiAiZGlkOndlYjpvbmx5X3Rlc3QiLAogICAgImlzc3VhbmNlRGF0ZSI6ICIyMDI0LTA0LTI0VDEwOjI1OjUxLjE1MloiLAogICAgImV4cGlyYXRpb25EYXRlIjogIjIwMjUtMDQtMjRUMTA6MjU6NTEuMTUyWiIsCiAgICAicHJvb2YiOiB7CiAgICAgICJ0eXBlIjogIkpzb25XZWJTaWduYXR1cmUyMDIwIiwKICAgICAgImNyZWF0ZWQiOiAiMjAyNC0wNC0yNFQxMDoyNTo1MS4zNzNaIiwKICAgICAgInByb29mUHVycG9zZSI6ICJhc3NlcnRpb25NZXRob2QiLAogICAgICAiandzIjogImV5SmhiR2NpT2lKUVV6STFOaUlzSW1JMk5DSTZabUZzYzJVc0ltTnlhWFFpT2xzaVlqWTBJbDE5Li43SXFTNjZoVDhFbjdqZ2U3LUx4dHIxSFZJTHFCSzlUdjJFUEltdWFsTzhEQ1V6dnBVbHlKaTlncVJiNFhDTkMxanl3Slc5ZEwxR1lxUFRQSTJkZG1KSUhGd20zNmREeVlJWHVwdG42VS0zWFEtRGhUYjVkYXBGOFNyQnRFdUJMakNfQnNTR2ZEdXpMUWdXSDdKb0ZkVmJIX2FLZ0Joa3lrSTZRU2xCbGpILXFWSVZadFBPMkVCQzlHQWFCaHpVVmE3RFBxY1hudUcwQVliN0dYNnBmZDdzZ2lNQjdoeWFPZ3lpaG42eFZxR0c5WFk0Nk50b3dxUkZHZGNMQ0pQZ05iSXlmOGdyVHZNSXRaWUJ3N2ppMlJtcWVjR1pXd0Roc2g3Y3RUcDMzdkNkNHFYeEZuU1ZpbFNUY29lOUJDa1llNnlmSDBvdlZPeHJlY2duNXBXME54aDNreEJmX0tselF3bEhfVktCSHhEWjl3ckV1eHI5VE1fZFVDWlhHOFVyOHRPaENhNzNaMklmUXpsaFhMTENZbm1BclY2bl81UGNVZmZjMTBVMk5Ca1hPY0tEVEx1WGg2N3RhNVVxLVoyT2hnS3JIWEt3SXI4aDdtcm9ncXcwMllTSFNSOW1xNXNEdFNMcU9ZTEVHdEFDdC1ycW1Dc3I2VHhIMUduMnR5ZlQxTWZNSUJKSktQT1drRVA1UUhuUnc5Tk4zOE1hN25vVWN0VlQ3N1ExV25wU0NlNlNuTDQyV1p6WUVZbEdpd3VsRFBoTjQ4S3JiM1hRNk1TLWdmSmRmZkJjZFRIeFVPcW9wTW1XdU5sYjd1VHhDaVZJSzl5QVJGOU1NSXZvel9XUm54QWd0aGYtLVphQmoyMVhQLW0xWXVrd1VrUkU3endQTXR1MkgxOFFsVXZxVSIsCiAgICAgICJ2ZXJpZmljYXRpb25NZXRob2QiOiAiZGlkOndlYjpvbmx5X3Rlc3QiCiAgICB9CiAgfQp9", + "document_status_id": 2, + "last_editor_id": "7e85a0b8-0001-ab67-10d1-0ef508201027" } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json index 3402e881ac..228e7a5064 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json @@ -182,5 +182,21 @@ { "user_role_collection_id": "1a24eca5-901f-4191-84a7-4ef09a894575", "user_role_id": "ec3a3005-b59c-4319-a8eb-3228984cd6e5" + }, + { + "user_role_collection_id": "ec428950-8b64-4646-b336-28af869b5d73", + "user_role_id": "a6b6a5b6-d7fe-42af-94ce-35c16b3ae128" + }, + { + "user_role_collection_id": "ec428950-8b64-4646-b336-28af869b5d73", + "user_role_id": "9956fa8d-e454-49ca-a3b1-45e2c106fe59" + }, + { + "user_role_collection_id": "a5b8b1de-7759-4620-9c87-6b6d74fb4fbc", + "user_role_id": "a6b6a5b6-d7fe-42af-94ce-35c16b3ae128" + }, + { + "user_role_collection_id": "a5b8b1de-7759-4620-9c87-6b6d74fb4fbc", + "user_role_id": "9956fa8d-e454-49ca-a3b1-45e2c106fe59" } ] diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/DocumentTypeId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/DocumentTypeId.cs index 783ae56c77..104d52dc7e 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/DocumentTypeId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/DocumentTypeId.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * Copyright (c) 2022 BMW Group AG * Copyright (c) 2022 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional diff --git a/src/processes/DimUserCreationProcess.Executor/DimUserCreationProcessService.cs b/src/processes/DimUserCreationProcess.Executor/DimUserCreationProcessService.cs index 4dd361e0a1..3a1c589c03 100644 --- a/src/processes/DimUserCreationProcess.Executor/DimUserCreationProcessService.cs +++ b/src/processes/DimUserCreationProcess.Executor/DimUserCreationProcessService.cs @@ -33,7 +33,7 @@ public class DimUserCreationProcessService( public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> CreateDimUser(Guid processId, Guid dimServiceAccountId, CancellationToken cancellationToken) { var serviceAccountRepository = portalRepositories.GetInstance(); - var (isValid, bpn, clientClientId) = await serviceAccountRepository.GetDimServiceAccountData(dimServiceAccountId) + var (isValid, bpn, name) = await serviceAccountRepository.GetDimServiceAccountData(dimServiceAccountId) .ConfigureAwait(ConfigureAwaitOptions.None); if (!isValid) @@ -46,12 +46,13 @@ public class DimUserCreationProcessService( throw new ConflictException("Bpn must not be null"); } - if (string.IsNullOrWhiteSpace(clientClientId)) + if (string.IsNullOrWhiteSpace(name)) { - throw new ConflictException("Service Account Name must not be null"); + throw new ConflictException("Service Account Name must not be empty"); } - await dimService.CreateTechnicalUser(bpn, new TechnicalUserData(processId, $"dim-{clientClientId}"), cancellationToken).ConfigureAwait(false); + var dimName = string.Concat(name.Where(c => !char.IsWhiteSpace(c))); // DIM doesn't accept whitespace chars in name + await dimService.CreateTechnicalUser(bpn, new TechnicalUserData(processId, dimName), cancellationToken).ConfigureAwait(false); return (Enumerable.Repeat(ProcessStepTypeId.AWAIT_CREATE_DIM_TECHNICAL_USER_RESPONSE, 1), ProcessStepStatusId.DONE, true, null); } } diff --git a/src/processes/Invitation.Executor/DependencyInjection/InvitationSettings.cs b/src/processes/Invitation.Executor/DependencyInjection/InvitationSettings.cs index e830f942ec..1c247b74b6 100644 --- a/src/processes/Invitation.Executor/DependencyInjection/InvitationSettings.cs +++ b/src/processes/Invitation.Executor/DependencyInjection/InvitationSettings.cs @@ -46,6 +46,9 @@ public class InvitationSettings [Required] [DistinctValues("x => x.Index")] public IEnumerable EncryptionConfigs { get; set; } = null!; + + [Required(AllowEmptyStrings = false)] + public string CloseApplicationAddress { get; set; } = null!; } public static class InvitationSettingsExtension diff --git a/src/processes/Invitation.Executor/InvitationProcessService.cs b/src/processes/Invitation.Executor/InvitationProcessService.cs index e98516589a..a2323af1b9 100644 --- a/src/processes/Invitation.Executor/InvitationProcessService.cs +++ b/src/processes/Invitation.Executor/InvitationProcessService.cs @@ -360,6 +360,7 @@ await _idpManagement KeyValuePair.Create("companyName", companyName), KeyValuePair.Create("url", _settings.RegistrationAppAddress), KeyValuePair.Create("passwordResendUrl", _settings.PasswordResendAddress), + KeyValuePair.Create("closeApplicationUrl", _settings.CloseApplicationAddress) }); _mailingProcessCreation.CreateMailProcess(userInformation.Email, template, mailParameters); } diff --git a/src/processes/Processes.Worker.Library/IProcessTypeExecutor.cs b/src/processes/Processes.Worker.Library/IProcessTypeExecutor.cs index 16ecb5ef80..3487a64d48 100644 --- a/src/processes/Processes.Worker.Library/IProcessTypeExecutor.cs +++ b/src/processes/Processes.Worker.Library/IProcessTypeExecutor.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * Copyright (c) 2022 Microsoft and BMW Group AG * Copyright (c) 2022 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional @@ -18,7 +17,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; namespace Org.Eclipse.TractusX.Portal.Backend.Processes.Worker.Library; diff --git a/src/provisioning/Provisioning.Library/Service/ServiceAccountCreation.cs b/src/provisioning/Provisioning.Library/Service/ServiceAccountCreation.cs index 4cfb8c5708..53f117c01e 100644 --- a/src/provisioning/Provisioning.Library/Service/ServiceAccountCreation.cs +++ b/src/provisioning/Provisioning.Library/Service/ServiceAccountCreation.cs @@ -59,30 +59,36 @@ public class ServiceAccountCreation( var userRolesRepository = portalRepositories.GetInstance(); var userRoleData = await GetAndValidateUserRoleData(userRolesRepository, userRoleIds).ConfigureAwait(ConfigureAwaitOptions.None); - var serviceAccounts = ImmutableList.CreateBuilder(); + var dimConfigRoles = _settings.DimUserRoles.SelectMany(x => x.UserRoleNames.Select(userRoleName => (x.ClientId, userRoleName))); - var (clientId, enhancedName, serviceAccountData) = await CreateKeycloakServiceAccount(bpns, enhanceTechnicalUserName, enabled, name, description, iamClientAuthMethod, userRoleData).ConfigureAwait(ConfigureAwaitOptions.None); - var serviceAccountId = CreateDatabaseServiceAccount(companyId, UserStatusId.ACTIVE, companyServiceAccountTypeId, CompanyServiceAccountKindId.INTERNAL, name, clientId, description, userRoleData, serviceAccountsRepository, userRolesRepository, setOptionalParameter); - serviceAccounts.Add(new CreatedServiceAccountData( - serviceAccountId, - enhancedName, - description, - UserStatusId.ACTIVE, - clientId, - serviceAccountData, - userRoleData)); + var serviceAccounts = ImmutableList.CreateBuilder(); - var dimRoles = userRoleData - .Join(_settings.DimUserRoles, data => data.ClientClientId, config => config.ClientId, - (data, config) => new { data, config }) - .Where(@t => t.config.UserRoleNames.Contains(@t.data.UserRoleText)) - .Select(@t => t.data) - .ToImmutableList(); + if (userRoleData.ExceptBy(dimConfigRoles, roleData => (roleData.ClientClientId, roleData.UserRoleText)).IfAny( + async roleData => + { + var keycloakRoleData = roleData.ToImmutableList(); + var (clientId, enhancedName, serviceAccountData) = await CreateKeycloakServiceAccount(bpns, enhanceTechnicalUserName, enabled, name, description, iamClientAuthMethod, keycloakRoleData).ConfigureAwait(ConfigureAwaitOptions.None); + var serviceAccountId = CreateDatabaseServiceAccount(companyId, UserStatusId.ACTIVE, companyServiceAccountTypeId, CompanyServiceAccountKindId.INTERNAL, name, clientId, description, keycloakRoleData, serviceAccountsRepository, userRolesRepository, setOptionalParameter); + serviceAccounts.Add(new CreatedServiceAccountData( + serviceAccountId, + enhancedName, + description, + UserStatusId.ACTIVE, + clientId, + serviceAccountData, + keycloakRoleData)); + }, + out var keycloakRolesTask)) + { + await keycloakRolesTask!.ConfigureAwait(ConfigureAwaitOptions.None); + } - var hasExternalServiceAccount = dimRoles.IfAny(roles => + var hasExternalServiceAccount = userRoleData.IntersectBy(dimConfigRoles, roleData => (roleData.ClientClientId, roleData.UserRoleText)).IfAny( + roleData => { + var dimRoleData = roleData.ToImmutableList(); var dimSaName = $"dim-{name}"; - var dimServiceAccountId = CreateDatabaseServiceAccount(companyId, UserStatusId.PENDING, companyServiceAccountTypeId, CompanyServiceAccountKindId.EXTERNAL, dimSaName, null, description, roles, serviceAccountsRepository, userRolesRepository, setOptionalParameter); + var dimServiceAccountId = CreateDatabaseServiceAccount(companyId, UserStatusId.PENDING, companyServiceAccountTypeId, CompanyServiceAccountKindId.EXTERNAL, dimSaName, null, description, dimRoleData, serviceAccountsRepository, userRolesRepository, setOptionalParameter); var processStepRepository = portalRepositories.GetInstance(); if (processData?.ProcessTypeId is not null) { @@ -98,7 +104,7 @@ public class ServiceAccountCreation( processId = processData.ProcessId.Value; } - portalRepositories.GetInstance().CreateDimUserCreationData(serviceAccountId, processId); + portalRepositories.GetInstance().CreateDimUserCreationData(dimServiceAccountId, processId); } serviceAccounts.Add(new CreatedServiceAccountData( @@ -108,7 +114,7 @@ public class ServiceAccountCreation( UserStatusId.PENDING, null, null, - roles)); + dimRoleData)); }); return (hasExternalServiceAccount, serviceAccounts.ToImmutable()); diff --git a/src/registration/Registration.Service/appsettings.json b/src/registration/Registration.Service/appsettings.json index bb32ceaa5a..edff4031b9 100644 --- a/src/registration/Registration.Service/appsettings.json +++ b/src/registration/Registration.Service/appsettings.json @@ -63,7 +63,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "Provisioning": { diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index 10f32a29a4..090d0cb93a 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -192,14 +192,14 @@ public async Task GetCompanyWithAddressAsync_WithDefaultRequest_GetsExpectedResu .With(x => x.AgreementsData, _fixture.CreateMany(20)) .With(x => x.CompanyIdentifiers, Enumerable.Repeat(new ValueTuple(identifierIdType, companyUniqueIds), 1)) .Create(); - A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(applicationId)) + A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(A._, A>._)) .Returns(data); // Act var result = await _logic.GetCompanyWithAddressAsync(applicationId); // Assert - A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(applicationId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(applicationId, _options.Value.DocumentTypeIds)).MustHaveHappenedOnceExactly(); result.Should().BeOfType(); result.Should().Match(r => r.CompanyId == data.CompanyId && @@ -238,14 +238,14 @@ public async Task GetCompanyWithAddressAsync_WithDefaultRequest_GetsExpectedResu .With(x => x.CountryDe, default(string?)) .With(x => x.InvitedCompanyUserData, _fixture.CreateMany().Select(id => new InvitedCompanyUserData(id, null, null, null))) .Create(); - A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(applicationId)) + A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(A._, A>._)) .Returns(data); // Act var result = await _logic.GetCompanyWithAddressAsync(applicationId); // Assert - A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(applicationId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _applicationRepository.GetCompanyUserRoleWithAddressUntrackedAsync(applicationId, _options.Value.DocumentTypeIds)).MustHaveHappenedOnceExactly(); result.Should().BeOfType(); result.Should().Match(r => r.CompanyId == data.CompanyId && diff --git a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json index 4fac7a9735..632ec19dfa 100644 --- a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json @@ -40,7 +40,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "Provisioning": { diff --git a/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppChangeBusinessLogicTest.cs b/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppChangeBusinessLogicTest.cs index d92dfe3f3a..0ffc884c67 100644 --- a/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppChangeBusinessLogicTest.cs +++ b/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppChangeBusinessLogicTest.cs @@ -1192,10 +1192,12 @@ public async Task GetActiveAppRolesAsync_ReturnsExpected() { // Arrange var appId = _fixture.Create(); - var userRole1 = new ActiveAppRoleDetails("TestRole1", [ + var roleId1 = _fixture.Create(); + var roleId2 = _fixture.Create(); + var userRole1 = new ActiveAppRoleDetails(roleId1, "TestRole1", [ new ActiveAppUserRoleDescription("en", "TestRole1 description") ]); - var userRole2 = new ActiveAppRoleDetails("TestRole2", [ + var userRole2 = new ActiveAppRoleDetails(roleId2, "TestRole2", [ new ActiveAppUserRoleDescription("en", "TestRole2 description") ]); var activeAppRoleDetails = (true, true, new[] { @@ -1212,8 +1214,8 @@ public async Task GetActiveAppRolesAsync_ReturnsExpected() // Assert result.Should().HaveCount(2) .And.Satisfy( - x => x.Role == "TestRole1" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole1 description", - x => x.Role == "TestRole2" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole2 description"); + x => x.RoleId == roleId1 && x.Role == "TestRole1" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole1 description", + x => x.RoleId == roleId2 && x.Role == "TestRole2" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole2 description"); A.CallTo(() => _userRolesRepository.GetActiveOfferRolesAsync(appId, OfferTypeId.APP, "de", "en")) .MustHaveHappenedOnceExactly(); } diff --git a/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppReleaseBusinessLogicTest.cs b/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppReleaseBusinessLogicTest.cs index d8e1802e67..436180017d 100644 --- a/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppReleaseBusinessLogicTest.cs +++ b/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppReleaseBusinessLogicTest.cs @@ -1252,10 +1252,12 @@ public async Task GetAppProviderRolesAsync_ReturnsExpected() { // Arrange var appId = _fixture.Create(); - var userRole1 = new ActiveAppRoleDetails("TestRole1", [ + var roleId1 = _fixture.Create(); + var roleId2 = _fixture.Create(); + var userRole1 = new ActiveAppRoleDetails(roleId1, "TestRole1", [ new ActiveAppUserRoleDescription("en", "TestRole1 description") ]); - var userRole2 = new ActiveAppRoleDetails("TestRole2", [ + var userRole2 = new ActiveAppRoleDetails(roleId2, "TestRole2", [ new ActiveAppUserRoleDescription("en", "TestRole2 description") ]); var activeAppRoleDetails = (true, true, new[] { @@ -1272,8 +1274,8 @@ public async Task GetAppProviderRolesAsync_ReturnsExpected() // Assert result.Should().HaveCount(2) .And.Satisfy( - x => x.Role == "TestRole1" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole1 description", - x => x.Role == "TestRole2" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole2 description"); + x => x.RoleId == roleId1 && x.Role == "TestRole1" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole1 description", + x => x.RoleId == roleId2 && x.Role == "TestRole2" && x.Descriptions.Count() == 1 && x.Descriptions.Single().Description == "TestRole2 description"); A.CallTo(() => _userRolesRepository.GetOfferProviderRolesAsync(appId, OfferTypeId.APP, _identity.CompanyId, "de", "en")) .MustHaveHappenedOnceExactly(); } diff --git a/tests/marketplace/Apps.Service.Tests/appsettings.IntegrationTests.json b/tests/marketplace/Apps.Service.Tests/appsettings.IntegrationTests.json index bc1fa85148..1f00b30b42 100644 --- a/tests/marketplace/Apps.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/marketplace/Apps.Service.Tests/appsettings.IntegrationTests.json @@ -28,7 +28,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "ConnectionStrings": { diff --git a/tests/marketplace/Services.Service.Tests/appsettings.IntegrationTests.json b/tests/marketplace/Services.Service.Tests/appsettings.IntegrationTests.json index 34444dda34..a697823515 100644 --- a/tests/marketplace/Services.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/marketplace/Services.Service.Tests/appsettings.IntegrationTests.json @@ -28,7 +28,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "ConnectionStrings": { diff --git a/tests/notifications/Notifications.Service.Tests/appsettings.IntegrationTests.json b/tests/notifications/Notifications.Service.Tests/appsettings.IntegrationTests.json index b4dc0a8f24..c059467684 100644 --- a/tests/notifications/Notifications.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/notifications/Notifications.Service.Tests/appsettings.IntegrationTests.json @@ -55,7 +55,7 @@ "ValidAudience": "", "ValidateAudience": true, "ValidateLifetime": true, - "ClockSkew": 600000 + "ClockSkew": "00:05:00" } }, "Notifications": { diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/ApplicationRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/ApplicationRepositoryTests.cs index 1653cf0df5..f8db8b2c39 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/ApplicationRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/ApplicationRepositoryTests.cs @@ -18,6 +18,7 @@ ********************************************************************************/ using Microsoft.EntityFrameworkCore; +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.DBAccess.Tests.Setup; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities; @@ -55,7 +56,7 @@ public async Task GetCompanyUserRoleWithAddressUntrackedAsync_WithExistingEntry_ // Act var result = await sut - .GetCompanyUserRoleWithAddressUntrackedAsync(new Guid("4f0146c6-32aa-4bb1-b844-df7e8babdcb2")); + .GetCompanyUserRoleWithAddressUntrackedAsync(new Guid("4f0146c6-32aa-4bb1-b844-df7e8babdcb2"), [DocumentTypeId.ADDITIONAL_DETAILS]); // Assert result.Should().NotBeNull(); @@ -76,10 +77,14 @@ public async Task GetCompanyUserRoleWithAddressUntrackedAsync_WithExistingEntry_ result.AgreementsData.Where(x => x.CompanyRoleId == CompanyRoleId.APP_PROVIDER).Should().HaveCount(1); result.AgreementsData.Where(x => x.CompanyRoleId == CompanyRoleId.ACTIVE_PARTICIPANT).Should().HaveCount(3); - result.InvitedCompanyUserData.Should().BeEmpty(); + result.InvitedCompanyUserData.Should().ContainSingle() + .Which.Should().Match(x => x.UserId == new Guid("8b42e6de-7b59-4217-a63c-198e83d93776") && x.FirstName == "First" && x.LastName == "User" && x.Email == "test@email.com"); - result.CompanyIdentifiers.Should().HaveCount(1); - result.CompanyIdentifiers.First().Should().Match<(UniqueIdentifierId UniqueIdentifierId, string Value)>(identifier => identifier.UniqueIdentifierId == UniqueIdentifierId.VAT_ID && identifier.Value == "DE123456789"); + result.CompanyIdentifiers.Should().ContainSingle() + .Which.Should().Match<(UniqueIdentifierId UniqueIdentifierId, string Value)>(identifier => identifier.UniqueIdentifierId == UniqueIdentifierId.VAT_ID && identifier.Value == "DE123456789"); + + result.DocumentData.Should().ContainSingle() + .Which.Should().Match<(Guid DocumentId, DocumentTypeId DocumentTypeId)>(x => x.DocumentId == new Guid("ec12dc7e-a8fa-4aa5-945a-f7e64be30841") && x.DocumentTypeId == DocumentTypeId.ADDITIONAL_DETAILS); } #endregion GetRegistrationDataUntrackedAsync diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRoleCollectionRolesViewTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRoleCollectionRolesViewTests.cs index 65f77cddcc..5017cb887e 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRoleCollectionRolesViewTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRoleCollectionRolesViewTests.cs @@ -45,7 +45,7 @@ public async Task CompanyRoleCollectionRolesView_GetAll_ReturnsExpected() // Act var result = await sut.CompanyRoleCollectionRolesView.ToListAsync(); - result.Should().HaveCount(46); + result.Should().HaveCount(50); } [Fact] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/documents.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/documents.test.json index ea83ba55e9..12b413e172 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/documents.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/documents.test.json @@ -141,5 +141,27 @@ "document_hash": "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", "document_content": "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", "document_status_id": 2 + }, + { + "id": "ec12dc7e-a8fa-4aa5-945a-f7e64be30841", + "date_created": "2023-10-08T08:00:00.000000+00:00", + "document_name": "ApplicationDetails.pdf", + "media_type_id": 6, + "document_type_id": 5, + "company_user_id": "8b42e6de-7b59-4217-a63c-198e83d93776", + "document_hash": "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", + "document_content": "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", + "document_status_id": 2 + }, + { + "id": "ec12dc7e-a8fa-4aa5-945a-f7e64be30842", + "date_created": "2023-10-08T08:00:00.000000+00:00", + "document_name": "OtherCertificate.pdf", + "media_type_id": 6, + "document_type_id": 15, + "company_user_id": "8b42e6de-7b59-4217-a63c-198e83d93776", + "document_hash": "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", + "document_content": "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", + "document_status_id": 2 } ] \ No newline at end of file diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json index c0e1e7fd58..81a6a65e60 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json @@ -26,5 +26,12 @@ "invitation_status_id": 1, "company_application_id": "6b2d1263-c073-4a48-bfaf-704dc154ca9e", "company_user_id": "1dceacb8-c5a5-4573-a77d-e2487ac4a8aa" + }, + { + "id": "e92b54ed-fbbe-4259-9747-efd8613ce61f", + "date_created": "2022-03-24 18:01:33.439000 +00:00", + "invitation_status_id": 1, + "company_application_id": "4f0146c6-32aa-4bb1-b844-df7e8babdcb2", + "company_user_id": "8b42e6de-7b59-4217-a63c-198e83d93776" } ] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/UserRolesRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/UserRolesRepositoryTests.cs index c8ef51116c..524cec69bf 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/UserRolesRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/UserRolesRepositoryTests.cs @@ -229,8 +229,8 @@ public async Task GetActiveOfferRolesAsync_ActiveApp_ReturnsExpected() data.IsActive.Should().BeTrue(); data.AppRoleDetails.Should().HaveCount(2) .And.Satisfy( - x => x.Role == "EarthCommerce.AdministratorRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en"), - x => x.Role == "EarthCommerce.Advanced.BuyerRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en")); + x => x.RoleId == new Guid("efc20368-9e82-46ff-b88f-6495b9810253") && x.Role == "EarthCommerce.AdministratorRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en"), + x => x.RoleId == new Guid("aabcdfeb-6669-4c74-89f0-19cda090873f") && x.Role == "EarthCommerce.Advanced.BuyerRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en")); } #endregion @@ -281,8 +281,8 @@ public async Task GetOfferProviderRolesAsync_ValidAppAndProvider_ReturnsExpected data.IsProvider.Should().BeTrue(); data.AppRoleDetails.Should().HaveCount(2) .And.Satisfy( - x => x.Role == "EarthCommerce.AdministratorRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en"), - x => x.Role == "EarthCommerce.Advanced.BuyerRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en")); + x => x.RoleId == new Guid("efc20368-9e82-46ff-b88f-6495b9810253") && x.Role == "EarthCommerce.AdministratorRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en"), + x => x.RoleId == new Guid("aabcdfeb-6669-4c74-89f0-19cda090873f") && x.Role == "EarthCommerce.Advanced.BuyerRC_QAS2" && x.Descriptions.Count() == 2 && x.Descriptions.Any(x => x.LanguageCode == "de") && x.Descriptions.Any(x => x.LanguageCode == "en")); } #endregion diff --git a/tests/processes/DimUserCreationProcess.Executor.Tests/DimUserCreationProcessServiceTests.cs b/tests/processes/DimUserCreationProcess.Executor.Tests/DimUserCreationProcessServiceTests.cs index f64e7fb518..39a8a4e843 100644 --- a/tests/processes/DimUserCreationProcess.Executor.Tests/DimUserCreationProcessServiceTests.cs +++ b/tests/processes/DimUserCreationProcess.Executor.Tests/DimUserCreationProcessServiceTests.cs @@ -60,9 +60,9 @@ public async Task CreateDimUser_WithValid_ReturnsExpected() // Arrange var dimServiceAccountId = Guid.NewGuid(); var processId = Guid.NewGuid(); - var expectedServiceAccountName = "dim-sa-test"; + var expectedServiceAccountName = "dim-sa-testFooBar"; A.CallTo(() => _serviceAccountRepository.GetDimServiceAccountData(A._)) - .Returns((true, Bpn, "sa-test")); + .Returns((true, Bpn, "dim-sa-test Foo Bar")); // Act var result = await _sut.CreateDimUser(processId, dimServiceAccountId, CancellationToken.None); @@ -86,7 +86,7 @@ public async Task CreateDimUser_WithInvalidDimServiceAccountId_ThrowsNotFoundExc var dimServiceAccountId = Guid.NewGuid(); var processId = Guid.NewGuid(); A.CallTo(() => _serviceAccountRepository.GetDimServiceAccountData(A._)) - .Returns(default((bool, string?, string?))); + .Returns(default((bool, string?, string))); Task Act() => _sut.CreateDimUser(processId, dimServiceAccountId, CancellationToken.None); // Act @@ -107,7 +107,7 @@ public async Task CreateDimUser_WithBpnNotSet_ThrowsConflictException() var dimServiceAccountId = Guid.NewGuid(); var processId = Guid.NewGuid(); A.CallTo(() => _serviceAccountRepository.GetDimServiceAccountData(A._)) - .Returns((true, null, null)); + .Returns((true, null, "foo")); Task Act() => _sut.CreateDimUser(processId, dimServiceAccountId, CancellationToken.None); // Act @@ -128,14 +128,14 @@ public async Task CreateDimUser_WithValidMissingServiceAccountName_ThrowsConflic var dimServiceAccountId = Guid.NewGuid(); var processId = Guid.NewGuid(); A.CallTo(() => _serviceAccountRepository.GetDimServiceAccountData(A._)) - .Returns((true, Bpn, null)); + .Returns((true, Bpn, " ")); Task Act() => _sut.CreateDimUser(processId, dimServiceAccountId, CancellationToken.None); // Act var ex = await Assert.ThrowsAsync(Act); // Act - ex.Message.Should().Be("Service Account Name must not be null"); + ex.Message.Should().Be("Service Account Name must not be empty"); A.CallTo(() => _serviceAccountRepository.GetDimServiceAccountData(dimServiceAccountId)) .MustHaveHappenedOnceExactly(); A.CallTo(() => _dimService.CreateTechnicalUser(Bpn, A._, A._)) diff --git a/tests/provisioning/Provisioning.Library.Tests/Extensions/ServiceAccountCreationTests.cs b/tests/provisioning/Provisioning.Library.Tests/Extensions/ServiceAccountCreationTests.cs index 287b3f132a..72213be07a 100644 --- a/tests/provisioning/Provisioning.Library.Tests/Extensions/ServiceAccountCreationTests.cs +++ b/tests/provisioning/Provisioning.Library.Tests/Extensions/ServiceAccountCreationTests.cs @@ -39,15 +39,21 @@ public class ServiceAccountCreationTests private const string Bpn = "CAXSDUMMYCATENAZZ"; private readonly string _iamUserId = Guid.NewGuid().ToString(); private readonly Guid _companyId = Guid.NewGuid(); - private readonly Guid _serviceAccountId = Guid.NewGuid(); private readonly Guid _identityId = Guid.NewGuid(); + private readonly Guid _secondId = Guid.NewGuid(); + private readonly string _validClientId; private readonly Guid _validUserRoleId = Guid.NewGuid(); + private readonly string _dimClient; + private readonly string _dimRoleText; + private readonly Guid _dimUserRoleId = Guid.NewGuid(); private readonly Guid _invalidUserRoleId = Guid.NewGuid(); + private readonly Guid _processId = Guid.NewGuid(); + private readonly Guid _processStepId = Guid.NewGuid(); private readonly IServiceAccountRepository _serviceAccountRepository; private readonly IUserRepository _userRepository; private readonly IUserRolesRepository _userRolesRepository; - + private readonly IProcessStepRepository _processStepRepository; private readonly IProvisioningManager _provisioningManager; private readonly IPortalRepositories _portalRepositories; private readonly IProvisioningDBAccess _provisioningDbAccess; @@ -60,9 +66,14 @@ public ServiceAccountCreationTests() .ForEach(b => fixture.Behaviors.Remove(b)); fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + _validClientId = fixture.Create(); + _dimClient = fixture.Create(); + _dimRoleText = fixture.Create(); + _serviceAccountRepository = A.Fake(); _userRepository = A.Fake(); _userRolesRepository = A.Fake(); + _processStepRepository = A.Fake(); _provisioningManager = A.Fake(); _portalRepositories = A.Fake(); @@ -71,42 +82,57 @@ public ServiceAccountCreationTests() var settings = new ServiceAccountCreationSettings { ServiceAccountClientPrefix = "sa", - DimUserRoles = [new UserRoleConfig("technical_user_management", ["Identity Wallet Management"])] + DimUserRoles = [new UserRoleConfig(_dimClient, [_dimRoleText])] }; A.CallTo(() => _portalRepositories.GetInstance()).Returns(_serviceAccountRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_userRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_userRolesRepository); + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_processStepRepository); _sut = new ServiceAccountCreation(_provisioningManager, _portalRepositories, _provisioningDbAccess, Options.Create(settings)); } + private void ServiceAccountCreationAction(CompanyServiceAccount _) { } + [Fact] public async Task CreateServiceAccountAsync_WithInvalidRole_ThrowsNotFoundException() { // Arrange - var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, new[] { _invalidUserRoleId }); + var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, [_invalidUserRoleId]); Setup(); // Act - async Task Act() => await _sut.CreateServiceAccountAsync(creationData, _companyId, Enumerable.Empty(), CompanyServiceAccountTypeId.OWN, false, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null)); + async Task Act() => await _sut.CreateServiceAccountAsync(creationData, _companyId, Enumerable.Empty(), CompanyServiceAccountTypeId.OWN, false, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null), ServiceAccountCreationAction); // Assert var ex = await Assert.ThrowsAsync(Act); ex.Message.Should().Be(ProvisioningServiceErrors.USER_NOT_VALID_USERROLEID.ToString()); - A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(A._, A>._)).MustNotHaveHappened(); - A.CallTo(() => _provisioningManager.AddProtocolMapperAsync(A._)).MustNotHaveHappened(); - A.CallTo(() => _userRolesRepository.DeleteCompanyUserAssignedRoles(A>._)).MustNotHaveHappened(); + + A.CallTo(() => _userRepository.CreateIdentity(A._, A._, A._, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(A._, A._, A._, A._, A._, A._, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _provisioningManager.SetupCentralServiceAccountClientAsync(A._, A._, A._)) + .MustNotHaveHappened(); + A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(A._, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _provisioningManager.AddProtocolMapperAsync(A._)) + .MustNotHaveHappened(); A.CallTo(() => _portalRepositories.SaveAsync()).MustNotHaveHappened(); } - [Fact] - public async Task CreateServiceAccountAsync_WithValidData_ReturnsExpected() + [Theory] + [InlineData(false, "testName")] + [InlineData(true, "sa1-testName")] + public async Task CreateServiceAccountAsync_WithValidData_ReturnsExpected(bool enhance, string serviceAccountName) { // Arrange var serviceAccounts = new List(); var identities = new List(); - var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, new[] { _validUserRoleId }); + var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, [_validUserRoleId]); var bpns = new[] { Bpn @@ -114,21 +140,64 @@ public async Task CreateServiceAccountAsync_WithValidData_ReturnsExpected() Setup(serviceAccounts, identities); // Act - var result = await _sut.CreateServiceAccountAsync(creationData, _companyId, bpns, CompanyServiceAccountTypeId.OWN, false, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null)); + var result = await _sut.CreateServiceAccountAsync(creationData, _companyId, bpns, CompanyServiceAccountTypeId.OWN, enhance, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null), ServiceAccountCreationAction); // Assert - result.ServiceAccounts.Should().ContainSingle(); - var serviceAccount = result.ServiceAccounts.Single(); - serviceAccount.UserRoleData.Should().ContainSingle(x => x.UserRoleId == _validUserRoleId && x.UserRoleText == "UserRole"); - serviceAccount.ServiceAccountData.InternalClientId.Should().Be("internal-sa1"); - serviceAccount.ServiceAccountData.IamUserId.Should().Be(_iamUserId); - serviceAccount.ServiceAccountData.AuthData.IamClientAuthMethod.Should().Be(IamClientAuthMethod.SECRET); - A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(_iamUserId, bpns)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _provisioningManager.AddProtocolMapperAsync("internal-sa1")).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.SaveAsync()).MustNotHaveHappened(); + + result.ServiceAccounts.Should().ContainSingle() + .Which.Should().Match(x => + x.ClientId == "sa1" && + x.Description == "abc" && + x.UserRoleData.SequenceEqual(new[] { new UserRoleData(_validUserRoleId, _validClientId, "UserRole") }) && + x.Name == serviceAccountName && + x.ServiceAccountData != null && + x.ServiceAccountData.InternalClientId == "internal-sa1" && + x.ServiceAccountData.IamUserId == _iamUserId && + x.ServiceAccountData.AuthData.IamClientAuthMethod == IamClientAuthMethod.SECRET + ); + + A.CallTo(() => _userRepository.CreateIdentity(_companyId, UserStatusId.ACTIVE, IdentityTypeId.COMPANY_SERVICE_ACCOUNT, null)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(_identityId, "testName", "abc", "sa1", CompanyServiceAccountTypeId.OWN, CompanyServiceAccountKindId.INTERNAL, ServiceAccountCreationAction)) + .MustHaveHappenedOnceExactly(); + var expectedRolesIds = new[] { (_identityId, _validUserRoleId) }; + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>.That.IsSameSequenceAs(expectedRolesIds))) + .MustHaveHappenedOnceExactly(); + IEnumerable? userRoles; + A.CallTo(() => _provisioningManager.SetupCentralServiceAccountClientAsync( + "sa1", + A.That.Matches(x => + x.IamClientAuthMethod == IamClientAuthMethod.SECRET && + x.Name == serviceAccountName && + x.Description == "abc" && + x.ClientRoles.Count() == 1 && + x.ClientRoles.TryGetValue(_validClientId, out userRoles) && + userRoles.SequenceEqual(new[] { "UserRole" })), + true)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(_iamUserId, bpns)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.AddProtocolMapperAsync("internal-sa1")) + .MustHaveHappenedOnceExactly(); + + A.CallTo(() => _userRepository.CreateIdentity(A._, UserStatusId.PENDING, A._, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(A._, A._, A._, A._, A._, CompanyServiceAccountKindId.EXTERNAL, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>.That.Matches(x => x.Any(y => y.Item2 != _validUserRoleId)))) + .MustNotHaveHappened(); + A.CallTo(() => _processStepRepository.CreateProcess(A._)) + .MustNotHaveHappened(); + A.CallTo(() => _processStepRepository.CreateProcessStep(A._, A._, A._)) + .MustNotHaveHappened(); + A.CallTo(() => _serviceAccountRepository.CreateDimUserCreationData(A._, A._)) + .MustNotHaveHappened(); + A.CallTo(() => _portalRepositories.SaveAsync()) + .MustNotHaveHappened(); serviceAccounts.Should().ContainSingle().Which.Should().Match( x => x.Name == "testName" && - x.ClientClientId == "sa1"); + x.ClientClientId == "sa1" && + x.CompanyServiceAccountKindId == CompanyServiceAccountKindId.INTERNAL); identities.Should().ContainSingle().Which.Should().Match( x => x.CompanyId == _companyId && x.UserStatusId == UserStatusId.ACTIVE && @@ -136,12 +205,12 @@ public async Task CreateServiceAccountAsync_WithValidData_ReturnsExpected() } [Fact] - public async Task CreateServiceAccountAsync_WithNameSetAndValidData_ReturnsExpected() + public async Task CreateServiceAccountAsync_WithValidDimData_ReturnsExpected() { // Arrange var serviceAccounts = new List(); var identities = new List(); - var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, new[] { _validUserRoleId }); + var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, [_dimUserRoleId]); var bpns = new[] { Bpn @@ -149,48 +218,169 @@ public async Task CreateServiceAccountAsync_WithNameSetAndValidData_ReturnsExpec Setup(serviceAccounts, identities); // Act - var result = await _sut.CreateServiceAccountAsync(creationData, _companyId, bpns, CompanyServiceAccountTypeId.OWN, true, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null)); + var result = await _sut.CreateServiceAccountAsync(creationData, _companyId, bpns, CompanyServiceAccountTypeId.OWN, false, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null), ServiceAccountCreationAction); // Assert - result.ServiceAccounts.Should().ContainSingle(); - var technicalUser = result.ServiceAccounts.Single(); - technicalUser.UserRoleData.Should().ContainSingle(x => x.UserRoleId == _validUserRoleId && x.UserRoleText == "UserRole"); - technicalUser.ServiceAccountData.InternalClientId.Should().Be("internal-sa1"); - technicalUser.ServiceAccountData.IamUserId.Should().Be(_iamUserId); - technicalUser.ServiceAccountData.AuthData.IamClientAuthMethod.Should().Be(IamClientAuthMethod.SECRET); - A.CallTo(() => _provisioningManager.SetupCentralServiceAccountClientAsync(A._, A.That.Matches(x => x.Name == "sa1-testName"), A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(_iamUserId, bpns)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _provisioningManager.AddProtocolMapperAsync("internal-sa1")).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.SaveAsync()).MustNotHaveHappened(); + result.ServiceAccounts.Should().ContainSingle() + .Which.Should().Match(x => + x.ClientId == null && + x.Description == "abc" && + x.UserRoleData.SequenceEqual(new[] { new UserRoleData(_dimUserRoleId, _dimClient, _dimRoleText) }) && + x.Name == "dim-testName" && + x.ServiceAccountData == null && + x.Status == UserStatusId.PENDING + ); + + A.CallTo(() => _userRepository.CreateIdentity(A._, UserStatusId.ACTIVE, A._, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(A._, A._, A._, A._, A._, CompanyServiceAccountKindId.INTERNAL, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>.That.Matches(x => x.Any(y => y.Item2 != _dimUserRoleId)))) + .MustNotHaveHappened(); + + A.CallTo(() => _provisioningManager.SetupCentralServiceAccountClientAsync(A._, A._, A._)) + .MustNotHaveHappened(); + A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(A._, A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _provisioningManager.AddProtocolMapperAsync(A._)) + .MustNotHaveHappened(); + + A.CallTo(() => _userRepository.CreateIdentity(_companyId, UserStatusId.PENDING, IdentityTypeId.COMPANY_SERVICE_ACCOUNT, null)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(_identityId, "dim-testName", "abc", null, CompanyServiceAccountTypeId.OWN, CompanyServiceAccountKindId.EXTERNAL, ServiceAccountCreationAction)) + .MustHaveHappenedOnceExactly(); + var expectedRolesIds = new[] { (_identityId, _dimUserRoleId) }; + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>.That.IsSameSequenceAs(expectedRolesIds))) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _processStepRepository.CreateProcess(ProcessTypeId.DIM_TECHNICAL_USER)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _processStepRepository.CreateProcessStep(ProcessStepTypeId.CREATE_DIM_TECHNICAL_USER, ProcessStepStatusId.TODO, A._)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _serviceAccountRepository.CreateDimUserCreationData(_identityId, _processId)) + .MustHaveHappenedOnceExactly(); + + A.CallTo(() => _portalRepositories.SaveAsync()) + .MustNotHaveHappened(); + serviceAccounts.Should().ContainSingle().Which.Should().Match( - x => x.Name == "testName" && - x.ClientClientId == "sa1"); + x => x.Name == "dim-testName" && + x.ClientClientId == null && + x.CompanyServiceAccountKindId == CompanyServiceAccountKindId.EXTERNAL); identities.Should().ContainSingle().Which.Should().Match( x => x.CompanyId == _companyId && - x.UserStatusId == UserStatusId.ACTIVE && + x.UserStatusId == UserStatusId.PENDING && x.IdentityTypeId == IdentityTypeId.COMPANY_SERVICE_ACCOUNT); } + [Fact] + public async Task CreateServiceAccountAsync_WithValidDataPlus_ReturnsExpected() + { + // Arrange + var serviceAccounts = new List(); + var identities = new List(); + var creationData = new ServiceAccountCreationInfo("testName", "abc", IamClientAuthMethod.SECRET, [_validUserRoleId, _dimUserRoleId]); + var bpns = new[] + { + Bpn + }; + Setup(serviceAccounts, identities); + + // Act + var result = await _sut.CreateServiceAccountAsync(creationData, _companyId, bpns, CompanyServiceAccountTypeId.OWN, false, true, new ServiceAccountCreationProcessData(ProcessTypeId.DIM_TECHNICAL_USER, null), ServiceAccountCreationAction); + + // Assert + result.ServiceAccounts.Should().HaveCount(2) + .And.Satisfy( + x => x.ClientId == "sa1" && + x.Description == "abc" && + x.UserRoleData.SequenceEqual(new[] { new UserRoleData(_validUserRoleId, _validClientId, "UserRole") }) && + x.Name == "testName" && + x.ServiceAccountData != null && + x.ServiceAccountData.InternalClientId == "internal-sa1" && + x.ServiceAccountData.IamUserId == _iamUserId && + x.ServiceAccountData.AuthData.IamClientAuthMethod == IamClientAuthMethod.SECRET, + x => x.ClientId == null && + x.Description == "abc" && + x.UserRoleData.SequenceEqual(new[] { new UserRoleData(_dimUserRoleId, _dimClient, _dimRoleText) }) && + x.Name == "dim-testName" && + x.ServiceAccountData == null); + + A.CallTo(() => _userRepository.CreateIdentity(_companyId, UserStatusId.ACTIVE, IdentityTypeId.COMPANY_SERVICE_ACCOUNT, null)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(_identityId, "testName", "abc", "sa1", CompanyServiceAccountTypeId.OWN, CompanyServiceAccountKindId.INTERNAL, ServiceAccountCreationAction)) + .MustHaveHappenedOnceExactly(); + var expectedRolesIds = new[] { (_identityId, _validUserRoleId) }; + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>.That.IsSameSequenceAs(expectedRolesIds))) + .MustHaveHappenedOnceExactly(); + IEnumerable? userRoles; + A.CallTo(() => _provisioningManager.SetupCentralServiceAccountClientAsync( + "sa1", + A.That.Matches(x => + x.IamClientAuthMethod == IamClientAuthMethod.SECRET && + x.Name == "testName" && + x.Description == "abc" && + x.ClientRoles.Count() == 1 && + x.ClientRoles.TryGetValue(_validClientId, out userRoles) && + userRoles.SequenceEqual(new[] { "UserRole" })), + true)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.AddBpnAttributetoUserAsync(_iamUserId, bpns)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.AddProtocolMapperAsync("internal-sa1")) + .MustHaveHappenedOnceExactly(); + + A.CallTo(() => _userRepository.CreateIdentity(_companyId, UserStatusId.ACTIVE, IdentityTypeId.COMPANY_SERVICE_ACCOUNT, null)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(_secondId, "dim-testName", "abc", null, CompanyServiceAccountTypeId.OWN, CompanyServiceAccountKindId.EXTERNAL, ServiceAccountCreationAction)) + .MustHaveHappenedOnceExactly(); + var expectedDimRolesIds = new[] { (_secondId, _dimUserRoleId) }; + A.CallTo(() => _userRolesRepository.CreateIdentityAssignedRoleRange(A>.That.IsSameSequenceAs(expectedDimRolesIds))) + .MustHaveHappenedOnceExactly(); + + A.CallTo(() => _portalRepositories.SaveAsync()) + .MustNotHaveHappened(); + + serviceAccounts.Should().HaveCount(2) + .And.Satisfy( + x => x.Name == "testName" && x.ClientClientId == "sa1" && x.CompanyServiceAccountKindId == CompanyServiceAccountKindId.INTERNAL, + x => x.Name == "dim-testName" && x.ClientClientId == null && x.CompanyServiceAccountKindId == CompanyServiceAccountKindId.EXTERNAL + ); + identities.Should().HaveCount(2) + .And.AllSatisfy(x => x.Should().Match(x => x.CompanyId == _companyId && x.IdentityTypeId == IdentityTypeId.COMPANY_SERVICE_ACCOUNT)) + .And.Satisfy( + x => x.Id == _identityId && x.UserStatusId == UserStatusId.ACTIVE, + x => x.Id == _secondId && x.UserStatusId == UserStatusId.PENDING + ); + } + #region Setup private void Setup(ICollection? serviceAccounts = null, ICollection? identities = null) { A.CallTo(() => _provisioningDbAccess.GetNextClientSequenceAsync()) - .Returns(1); + .Returns(1).Once(); A.CallTo(() => _provisioningManager.SetupCentralServiceAccountClientAsync(A._, A._, A._)) - .Returns(new ServiceAccountData("internal-sa1", _iamUserId, new ClientAuthData(IamClientAuthMethod.SECRET))); + .Returns(new ServiceAccountData("internal-sa1", _iamUserId, new ClientAuthData(IamClientAuthMethod.SECRET))).Once(); - A.CallTo(() => _userRepository.CreateIdentity(_companyId, A._, IdentityTypeId.COMPANY_SERVICE_ACCOUNT, A>._)) - .Invokes((Guid companyId, UserStatusId userStatusId, IdentityTypeId identityTypeId, Action? setOptionalFields) => + A.CallTo(() => _userRepository.CreateIdentity(A._, A._, A._, A>._)) + .ReturnsLazily((Guid companyId, UserStatusId userStatusId, IdentityTypeId identityTypeId, Action? setOptionalFields) => { - var identity = new Identity(Guid.NewGuid(), DateTimeOffset.UtcNow, companyId, userStatusId, identityTypeId); + var identity = new Identity(_identityId, DateTimeOffset.UtcNow, companyId, userStatusId, identityTypeId); setOptionalFields?.Invoke(identity); identities?.Add(identity); - }) - .Returns(new Identity(_identityId, default, default, default, default)); - A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(_identityId, A._, A._, A._, A._, A._, A>._)) - .Invokes((Guid identityId, string name, string description, string clientClientId, CompanyServiceAccountTypeId companyServiceAccountTypeId, CompanyServiceAccountKindId companyServiceAccountKindId, Action? setOptionalParameters) => + return identity; + }).Once() + .Then.ReturnsLazily((Guid companyId, UserStatusId userStatusId, IdentityTypeId identityTypeId, Action? setOptionalFields) => + { + var identity = new Identity(_secondId, DateTimeOffset.UtcNow, companyId, userStatusId, identityTypeId); + setOptionalFields?.Invoke(identity); + identities?.Add(identity); + return identity; + }).Once(); + + A.CallTo(() => _serviceAccountRepository.CreateCompanyServiceAccount(A._, A._, A._, A._, A._, A._, A>._)) + .ReturnsLazily((Guid identityId, string name, string description, string clientClientId, CompanyServiceAccountTypeId companyServiceAccountTypeId, CompanyServiceAccountKindId companyServiceAccountKindId, Action? setOptionalParameters) => { var sa = new CompanyServiceAccount( identityId, @@ -203,13 +393,26 @@ private void Setup(ICollection? serviceAccounts = null, I }; setOptionalParameters?.Invoke(sa); serviceAccounts?.Add(sa); - }) - .Returns(new CompanyServiceAccount(_serviceAccountId, null!, null!, default, default)); + return sa; + }); - A.CallTo(() => _userRolesRepository.GetUserRoleDataUntrackedAsync(A>.That.Matches(x => x.Count(y => y == _validUserRoleId) == 1))) - .Returns(new[] { new UserRoleData(_validUserRoleId, Guid.NewGuid().ToString(), "UserRole") }.ToAsyncEnumerable()); - A.CallTo(() => _userRolesRepository.GetUserRoleDataUntrackedAsync(A>.That.Matches(x => x.Count(y => y == _invalidUserRoleId) == 1))) + A.CallTo(() => _userRolesRepository.GetUserRoleDataUntrackedAsync(A>.That.Contains(_validUserRoleId))) + .Returns(new[] { new UserRoleData(_validUserRoleId, _validClientId, "UserRole") }.ToAsyncEnumerable()); + A.CallTo(() => _userRolesRepository.GetUserRoleDataUntrackedAsync(A>.That.Contains(_dimUserRoleId))) + .Returns(new[] { new UserRoleData(_dimUserRoleId, _dimClient, _dimRoleText) }.ToAsyncEnumerable()); + A.CallTo(() => _userRolesRepository.GetUserRoleDataUntrackedAsync(A>.That.Contains(_invalidUserRoleId))) .Returns(Enumerable.Empty().ToAsyncEnumerable()); + A.CallTo(() => _userRolesRepository.GetUserRoleDataUntrackedAsync(A>.That.IsSameSequenceAs(new[] { _validUserRoleId, _dimUserRoleId }))) + .Returns(new UserRoleData[] + { + new(_validUserRoleId, _validClientId, "UserRole"), + new(_dimUserRoleId, _dimClient, _dimRoleText) + }.ToAsyncEnumerable()); + + A.CallTo(() => _processStepRepository.CreateProcess(A._)) + .ReturnsLazily((ProcessTypeId processTypeId) => new Process(_processId, processTypeId, Guid.NewGuid())).Once(); + A.CallTo(() => _processStepRepository.CreateProcessStep(A._, A._, A._)) + .ReturnsLazily((ProcessStepTypeId processStepTypeId, ProcessStepStatusId processStepStatusId, Guid processId) => new ProcessStep(_processStepId, processStepTypeId, processStepStatusId, processId, DateTimeOffset.UtcNow)).Once(); } #endregion