From 5ba95e70344b2b65c5d206c6fb71ac5f3b25ad3a Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 22 Jan 2024 09:12:41 +0100 Subject: [PATCH 01/10] fix(marketplace): set company policy for agreementConsents (#423) set the companyId of the logged in user for POST: /api/apps/appreleaseprocess/consent/{appId}/agreementConsents POST: /api/services/servicerelease/consent/{serviceId}/agreementConsents Refs: CPLP-3722 --- .../Apps.Service/Controllers/AppReleaseProcessController.cs | 1 + .../Services.Service/Controllers/ServiceReleaseController.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/marketplace/Apps.Service/Controllers/AppReleaseProcessController.cs b/src/marketplace/Apps.Service/Controllers/AppReleaseProcessController.cs index e7930cd835..4ba2962955 100644 --- a/src/marketplace/Apps.Service/Controllers/AppReleaseProcessController.cs +++ b/src/marketplace/Apps.Service/Controllers/AppReleaseProcessController.cs @@ -146,6 +146,7 @@ public Task GetOfferAgreementConsentById([FromRoute] Guid [HttpPost] [Authorize(Roles = "edit_apps")] [Authorize(Policy = PolicyTypes.CompanyUser)] + [Authorize(Policy = PolicyTypes.ValidCompany)] [Route("consent/{appId}/agreementConsents")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)] diff --git a/src/marketplace/Services.Service/Controllers/ServiceReleaseController.cs b/src/marketplace/Services.Service/Controllers/ServiceReleaseController.cs index efc3359958..22b01dadb5 100644 --- a/src/marketplace/Services.Service/Controllers/ServiceReleaseController.cs +++ b/src/marketplace/Services.Service/Controllers/ServiceReleaseController.cs @@ -144,6 +144,7 @@ public Task GetServiceDetailsForStatusAsync([FromRoute] [Route("consent/{serviceId}/agreementConsents")] [Authorize(Roles = "add_service_offering")] [Authorize(Policy = PolicyTypes.CompanyUser)] + [Authorize(Policy = PolicyTypes.ValidCompany)] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status403Forbidden)] From 41d2648ef777f5748f3c747b78bf6b0c62f880b5 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 22 Jan 2024 11:15:00 +0100 Subject: [PATCH 02/10] feat(bpdm): adjust bpdm push type (#404) * feat(bpdm): adjust bpdm push type * feat(bpdm): remove short name from name parts Refs: CPLP-3438 --- .../Bpdm.Library/BpdmService.cs | 82 ++++++----- .../Models/BpdmLegalEntityData.cs | 128 +++++++++--------- .../Models/BpdmLegalEntityOutputData.cs | 67 ++++++++- .../UserUploadBusinessLogicTests.cs | 1 + 4 files changed, 179 insertions(+), 99 deletions(-) diff --git a/src/externalsystems/Bpdm.Library/BpdmService.cs b/src/externalsystems/Bpdm.Library/BpdmService.cs index 54ef384863..55f4d1c9fd 100644 --- a/src/externalsystems/Bpdm.Library/BpdmService.cs +++ b/src/externalsystems/Bpdm.Library/BpdmService.cs @@ -57,49 +57,57 @@ public async Task PutInputLegalEntity(BpdmTransferData data, CancellationT { new( data.ExternalId, // Index - Enumerable.Repeat(data.CompanyName, 1), // LegalName - data.ShortName, // LegalShortName - null, // LegalForm + new [] + { + data.CompanyName // LegalName + }, data.Identifiers.Select(x => new BpdmIdentifier( - x.Value, // Value x.BpdmIdentifierId, // Type + x.Value, // Value null)), // IssuingBody - Enumerable.Empty(), // Status - Enumerable.Empty(), // Classifications + Enumerable.Empty(), // Status Enumerable.Empty(), // Roles - new BpdmLegalAddress( - Enumerable.Empty(), // Name - Enumerable.Empty(), // States - Enumerable.Empty(), // Identifiers - new BpdmAddressPhysicalPostalAddress( // PhysicalPostalAddress - null, // GeographicCoordinates - data.AlphaCode2, // Country - data.ZipCode, // PostalCode - data.City, // City - new BpdmLegalEntityStreet( - null, // NamePrefix - null, // AdditionalNamePrefix - data.StreetName, // Name - null, // NameSuffix - null, // AdditionalNameSuffix - data.StreetNumber, // StreetNumber - null, // Milestone - null // Direction - ), - data.Region, // AdministrativeAreaLevel1 - null, // AdministrativeAreaLevel2 - null, // AdministrativeAreaLevel3 - null, // District - null, // CompanyPostalCode - null, // IndustrialZone - null, // Building - null, // Floor - null // Door + new BpdmLegalEntity( + null, + data.CompanyName, + data.ShortName, + null, + Enumerable.Empty() + ), + null, + new BpdmAddress( + null, + null, + null, + new BpdmPutPhysicalPostalAddress( + null, + data.AlphaCode2, + null, + null, + null, + data.ZipCode, + data.City, + data.Region, + new BpdmPutStreet( + null, + null, + data.StreetName, + null, + null, + data.StreetNumber, + null, + null, + null), + null, + null, + null, + null, + null ), - null, // AlternativePostalAddress - Enumerable.Empty() - ) + null + ), + true ) }; diff --git a/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityData.cs b/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityData.cs index 7f8c4797b6..65c19678d6 100644 --- a/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityData.cs +++ b/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityData.cs @@ -22,68 +22,52 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library.Models; -public record BpdmLegalEntityData( - string ExternalId, - IEnumerable LegalNameParts, - string? LegalShortName, - string? LegalForm, - IEnumerable Identifiers, - IEnumerable States, - IEnumerable Classifications, - IEnumerable Roles, - BpdmLegalAddress LegalAddress -); - public record BpdmIdentifier( - string Value, BpdmIdentifierId Type, + string Value, string? IssuingBody ); -public record BpdmStatus( - string OfficialDenotation, - DateTimeOffset ValidFrom, - DateTimeOffset ValidUntil, +public record BpdmState( + DateTime ValidFrom, + DateTime ValidTo, string Type ); -public record BpdmProfileClassification( - string Value, +public record BpdmClassification( + string Type, string Code, - string Type -); - -public record BpdmLegalAddress( - IEnumerable NameParts, - IEnumerable States, - IEnumerable Identifiers, - BpdmAddressPhysicalPostalAddress PhysicalPostalAddress, - BpdmAddressAlternativePostalAddress? AlternativePostalAddress, - IEnumerable Roles + string Value ); -public record BpdmAddressState( - string Description, - DateTimeOffset? ValidFrom, - DateTimeOffset? ValidTo, - string Type +public record BpdmGeographicCoordinates( + double Longitude, + double Latitude, + double Altitude ); -public record BpdmAddressIdentifier( - string Value, - BpdmIdentifierId Type +public record BpdmPutStreet( + string? NamePrefix, + string? AdditionalNamePrefix, + string Name, + string? NameSuffix, + string? AdditionalNameSuffix, + string? HouseNumber, + string? HouseNumberSupplement, + string? Milestone, + string? Direction ); -public record BpdmAddressPhysicalPostalAddress( - BpdmGeographicCoordinatesDto? GeographicCoordinates, - string? Country, - string? PostalCode, - string? City, - BpdmLegalEntityStreet? Street, +public record BpdmPutPhysicalPostalAddress( + BpdmGeographicCoordinates? GeographicCoordinates, + string Country, string? AdministrativeAreaLevel1, string? AdministrativeAreaLevel2, string? AdministrativeAreaLevel3, + string? PostalCode, + string? City, string? District, + BpdmPutStreet Street, string? CompanyPostalCode, string? IndustrialZone, string? Building, @@ -91,24 +75,46 @@ public record BpdmAddressPhysicalPostalAddress( string? Door ); -public record BpdmAddressAlternativePostalAddress( - BpdmGeographicCoordinatesDto? GeographicCoordinates, - string? Country, - string? PostalCode, - string? City, - string? AdministrativeAreaLevel1, - string? DeliveryServiceNumber, - string? DeliveryServiceType, - string? DeliveryServiceQualifier +public record BpdmPutAlternativePostalAddress( + BpdmGeographicCoordinates? GeographicCoordinates, + string Country, + string AdministrativeAreaLevel1, + string PostalCode, + string City, + string DeliveryServiceType, + string DeliveryServiceQualifier, + string DeliveryServiceNumber ); -public record BpdmLegalEntityStreet( - string? NamePrefix, - string? AdditionalNamePrefix, - string Name, - string? NameSuffix, - string? AdditionalNameSuffix, - string? HouseNumber, - string? Milestone, - string? Direction +public record BpdmAddress( + string? AddressBpn, + string? Name, + string? AddressType, + BpdmPutPhysicalPostalAddress PhysicalPostalAddress, + BpdmPutAlternativePostalAddress? AlternativePostalAddress +); + +public record BpdmLegalEntity( + string? LegalEntityBpn, + string LegalName, + string? ShortName, + string? LegalForm, + IEnumerable Classifications +); + +public record BpdmSite( + string SiteBpn, + string Name +); + +public record BpdmLegalEntityData( + string ExternalId, + IEnumerable NameParts, + IEnumerable Identifiers, + IEnumerable States, + IEnumerable Roles, + BpdmLegalEntity LegalEntity, + BpdmSite? Site, + BpdmAddress Address, + bool OwnCompanyData ); diff --git a/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityOutputData.cs b/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityOutputData.cs index ac86dc1ccb..d31185d26e 100644 --- a/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityOutputData.cs +++ b/src/externalsystems/Bpdm.Library/Models/BpdmLegalEntityOutputData.cs @@ -1,6 +1,6 @@ /******************************************************************************** * Copyright (c) 2021, 2023 Microsoft and BMW Group AG - * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -18,6 +18,7 @@ * 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.Bpdm.Library.Models; @@ -52,8 +53,72 @@ public record BpdmLegalAddressResponse( [property: JsonPropertyName("roles")] IEnumerable Roles ); +public record BpdmStatus( + string OfficialDenotation, + DateTimeOffset ValidFrom, + DateTimeOffset ValidUntil, + string Type +); + public record BpdmCountry ( string TechnicalKey, string Name ); + +public record BpdmProfileClassification( + string Value, + string Code, + string Type +); + +public record BpdmAddressState( + string Description, + DateTimeOffset? ValidFrom, + DateTimeOffset? ValidTo, + string Type +); + +public record BpdmAddressIdentifier( + string Value, + BpdmIdentifierId Type +); + +public record BpdmAddressPhysicalPostalAddress( + BpdmGeographicCoordinatesDto? GeographicCoordinates, + string? Country, + string? PostalCode, + string? City, + BpdmLegalEntityStreet? Street, + string? AdministrativeAreaLevel1, + string? AdministrativeAreaLevel2, + string? AdministrativeAreaLevel3, + string? District, + string? CompanyPostalCode, + string? IndustrialZone, + string? Building, + string? Floor, + string? Door +); + +public record BpdmLegalEntityStreet( + string? NamePrefix, + string? AdditionalNamePrefix, + string Name, + string? NameSuffix, + string? AdditionalNameSuffix, + string? HouseNumber, + string? Milestone, + string? Direction +); + +public record BpdmAddressAlternativePostalAddress( + BpdmGeographicCoordinatesDto? GeographicCoordinates, + string? Country, + string? PostalCode, + string? City, + string? AdministrativeAreaLevel1, + string? DeliveryServiceNumber, + string? DeliveryServiceType, + string? DeliveryServiceQualifier +); diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/UserUploadBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/UserUploadBusinessLogicTests.cs index bb7baa6b4d..2d7c1c88e4 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/UserUploadBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/UserUploadBusinessLogicTests.cs @@ -87,6 +87,7 @@ public UserUploadBusinessLogicTests() } #region UploadOwnCompanyIdpUsersAsync + [Fact] public async Task TestSetup() { From 89273b03f7d664a9cddfb0af84a9d7643028a667 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 22 Jan 2024 11:37:36 +0100 Subject: [PATCH 03/10] feat(invitation): add decline url to invitation mail (#424) Refs: CPLP-3726 --- .../BusinessLogic/InvitationBusinessLogic.cs | 1 + .../BusinessLogic/InvitationSettings.cs | 3 +++ .../Administration.Service/appsettings.json | 3 ++- .../EmailTemplates/cx_admin_invitation.html | 20 +++++++++++++++++++ .../appsettings.IntegrationTests.json | 3 ++- 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs index e7236a78c3..1e4f2c7ccf 100644 --- a/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs @@ -139,6 +139,7 @@ private async Task ExecuteInvitationInternalAsync(CompanyInvitationData invitati { "companyName", invitationData.organisationName }, { "url", _settings.RegistrationAppAddress }, { "passwordResendUrl", _settings.PasswordResendAddress }, + { "closeApplicationUrl", _settings.CloseApplicationAddress }, }; await _mailingService.SendMails(invitationData.email, mailParameters, new List { "RegistrationTemplate", "PasswordForRegistrationTemplate" }).ConfigureAwait(false); diff --git a/src/administration/Administration.Service/BusinessLogic/InvitationSettings.cs b/src/administration/Administration.Service/BusinessLogic/InvitationSettings.cs index 25f984af13..bf64739f9c 100644 --- a/src/administration/Administration.Service/BusinessLogic/InvitationSettings.cs +++ b/src/administration/Administration.Service/BusinessLogic/InvitationSettings.cs @@ -46,6 +46,9 @@ public InvitationSettings() [Required(AllowEmptyStrings = false)] public string PasswordResendAddress { get; set; } + + [Required(AllowEmptyStrings = false)] + public string CloseApplicationAddress { get; set; } = null!; } public static class InvitationSettingsExtension diff --git a/src/administration/Administration.Service/appsettings.json b/src/administration/Administration.Service/appsettings.json index b445e1186b..26ebfe575d 100644 --- a/src/administration/Administration.Service/appsettings.json +++ b/src/administration/Administration.Service/appsettings.json @@ -258,7 +258,8 @@ "Invitation": { "RegistrationAppAddress": "https://portal.example.org/registration", "InvitedUserInitialRoles": [], - "InitialLoginTheme": "" + "InitialLoginTheme": "", + "CloseApplicationAddress": "" }, "UserManagement": { "ApplicationsMaxPageSize": 20, diff --git a/src/mailing/Mailing.Template/EmailTemplates/cx_admin_invitation.html b/src/mailing/Mailing.Template/EmailTemplates/cx_admin_invitation.html index bc5509381f..f96806df00 100644 --- a/src/mailing/Mailing.Template/EmailTemplates/cx_admin_invitation.html +++ b/src/mailing/Mailing.Template/EmailTemplates/cx_admin_invitation.html @@ -226,6 +226,26 @@ + + + + + +
+
diff --git a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json index 1149a213f9..2803a51a66 100644 --- a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json @@ -254,7 +254,8 @@ } ], "InitialLoginTheme": "test", - "PasswordResendAddress": "https://test.com/home/passwordResend" + "PasswordResendAddress": "https://test.com/home/passwordResend", + "CloseApplicationAddress": "https://test.com/decline" }, "UserManagement": { "ApplicationsMaxPageSize": 20, From 66969ce6840d93a40c903b35bc7e3546fb9d153e Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 22 Jan 2024 15:27:29 +0100 Subject: [PATCH 04/10] feat(idp): adjust delete idp endpoint (#379) * fix(registration): delete idp on application decline * enable delete of managed idps * feat(idp): add deactivation for managed idps * fix deletion of identityprovider linked entities * feat(managedIdp): adjust idp user link deletion * feat(idps): delete role assignement for users * tests: add DeleteCompanyIdentityProvider tests Refs: TEST-1642 Refs: CPLP-3329 Refs: CPLP-3323 --------- Co-authored-by: Norbert Truchsess --- .../Administration.Service.csproj | 1 + .../IdentityProviderBusinessLogic.cs | 175 +++++++-- .../BusinessLogic/IdentityProviderSettings.cs | 3 + .../RegistrationBusinessLogic.cs | 23 +- .../Administration.Service/Program.cs | 2 + .../Administration.Service/appsettings.json | 18 +- .../Mailing.Service/IRoleBaseMailService.cs | 4 +- .../Mailing.Service/Mailing.Service.csproj | 14 +- .../Mailing.Service/RoleBaseMailService.cs | 51 ++- .../deactivate_managed_idp.html | 248 +++++++++++++ .../EmailTemplates/delete_managed_idp.html | 248 +++++++++++++ .../Enums/EmailTemplateType.cs | 14 +- .../OfferSetupServiceExtensions.cs | 3 +- .../Offers.Library/Service/OfferService.cs | 4 +- .../Service/OfferSubscriptionService.cs | 2 +- .../Repositories/ApplicationRepository.cs | 6 +- .../Repositories/IApplicationRepository.cs | 2 +- .../IIdentityProviderRepository.cs | 6 +- .../Repositories/IIdentityRepository.cs | 1 + .../Repositories/IUserRepository.cs | 1 + .../IdentityProviderRepository.cs | 51 ++- .../Repositories/IdentityRepository.cs | 10 + .../Repositories/UserRepository.cs | 3 + .../IdentityProviderBusinessLogicTests.cs | 346 +++++++++++++++--- .../RegistrationBusinessLogicTest.cs | 36 +- .../appsettings.IntegrationTests.json | 14 +- .../RoleBaseMailServiceTests.cs | 99 ++++- .../Service/OfferServiceTests.cs | 4 +- .../Service/OfferSubscriptionServiceTests.cs | 4 +- .../IdentityProviderRepositoryTests.cs | 16 +- 30 files changed, 1250 insertions(+), 159 deletions(-) create mode 100644 src/mailing/Mailing.Template/EmailTemplates/deactivate_managed_idp.html create mode 100644 src/mailing/Mailing.Template/EmailTemplates/delete_managed_idp.html diff --git a/src/administration/Administration.Service/Administration.Service.csproj b/src/administration/Administration.Service/Administration.Service.csproj index 7f95b4a5ba..b30882330e 100644 --- a/src/administration/Administration.Service/Administration.Service.csproj +++ b/src/administration/Administration.Service/Administration.Service.csproj @@ -53,6 +53,7 @@ + diff --git a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs index cea1132430..795b86798d 100644 --- a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs @@ -23,7 +23,10 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Library; using Org.Eclipse.TractusX.Portal.Backend.Framework.IO; using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration; using Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling; +using Org.Eclipse.TractusX.Portal.Backend.Mailing.SendMail; +using Org.Eclipse.TractusX.Portal.Backend.Mailing.Service; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; @@ -44,17 +47,29 @@ public class IdentityProviderBusinessLogic : IIdentityProviderBusinessLogic private readonly IProvisioningManager _provisioningManager; private readonly IIdentityData _identityData; private readonly IErrorMessageService _errorMessageService; - private readonly ILogger _logger; + private readonly IRoleBaseMailService _roleBaseMailService; + private readonly IMailingService _mailingService; private readonly IdentityProviderSettings _settings; + private readonly ILogger _logger; private static readonly Regex DisplayNameValidationExpression = new(@"^[a-zA-Z0-9\!\?\@\&\#\'\x22\(\)_\-\=\/\*\.\,\;\: ]+$", RegexOptions.None, TimeSpan.FromSeconds(1)); - public IdentityProviderBusinessLogic(IPortalRepositories portalRepositories, IProvisioningManager provisioningManager, IIdentityService identityService, IErrorMessageService errorMessageService, IOptions options, ILogger logger) + public IdentityProviderBusinessLogic( + IPortalRepositories portalRepositories, + IProvisioningManager provisioningManager, + IIdentityService identityService, + IErrorMessageService errorMessageService, + IRoleBaseMailService roleBaseMailService, + IMailingService mailingService, + IOptions options, + ILogger logger) { _portalRepositories = portalRepositories; _provisioningManager = provisioningManager; _identityData = identityService.IdentityData; _errorMessageService = errorMessageService; + _roleBaseMailService = roleBaseMailService; + _mailingService = mailingService; _settings = options.Value; _logger = logger; } @@ -175,7 +190,7 @@ public async ValueTask GetOwnCompanyIdentityProviderAsy public async ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled) { - var (category, alias, typeId) = await ValidateSetOwnCompanyIdentityProviderStatusArguments(identityProviderId, enabled).ConfigureAwait(false); + var (category, alias, typeId, companyUsersLinked, ownerCompanyName) = await ValidateSetOwnCompanyIdentityProviderStatusArguments(identityProviderId, enabled).ConfigureAwait(false); switch (category) { @@ -184,16 +199,32 @@ public async ValueTask SetOwnCompanyIdentityProviderSta return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false); case IdentityProviderCategoryId.KEYCLOAK_OIDC: await _provisioningManager.SetCentralIdentityProviderStatusAsync(alias, enabled).ConfigureAwait(false); + if (typeId == IdentityProviderTypeId.MANAGED && !enabled && companyUsersLinked) + { + await SendIdpMail(identityProviderId, alias, ownerCompanyName, _settings.DeactivateIdpRoles).ConfigureAwait(false); + } return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false); case IdentityProviderCategoryId.KEYCLOAK_SAML: await _provisioningManager.SetCentralIdentityProviderStatusAsync(alias, enabled).ConfigureAwait(false); + if (typeId == IdentityProviderTypeId.MANAGED && !enabled && companyUsersLinked) + { + await SendIdpMail(identityProviderId, alias, ownerCompanyName, _settings.DeactivateIdpRoles).ConfigureAwait(false); + } return await GetIdentityProviderDetailsSaml(identityProviderId, alias, typeId).ConfigureAwait(false); default: throw new ControllerArgumentException($"unexpected value for category '{category}' of identityProvider '{identityProviderId}'"); } } - private async ValueTask<(IdentityProviderCategoryId Category, string Alias, IdentityProviderTypeId TypeId)> ValidateSetOwnCompanyIdentityProviderStatusArguments(Guid identityProviderId, bool enabled) + private Task SendIdpMail(Guid identityProviderId, string? alias, string ownerCompanyName, IEnumerable idpRoles) => + _roleBaseMailService.RoleBaseSendMailForIdp( + idpRoles, + new[] { ("idpAlias", alias ?? identityProviderId.ToString()), ("ownerCompanyName", ownerCompanyName) }, + ("username", "User"), + new[] { "DeactivateManagedIdp" }, + identityProviderId); + + private async ValueTask<(IdentityProviderCategoryId Category, string Alias, IdentityProviderTypeId TypeId, bool CompanyUsersLinked, string OwnerCompanyName)> ValidateSetOwnCompanyIdentityProviderStatusArguments(Guid identityProviderId, bool enabled) { var companyId = _identityData.CompanyId; var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false); @@ -201,7 +232,7 @@ public async ValueTask SetOwnCompanyIdentityProviderSta { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - var (isOwner, alias, identityProviderCategory, identityProviderTypeId, companyIdAliase) = result; + var (isOwner, alias, identityProviderCategory, identityProviderTypeId, companyIdAliase, companyUsersLinked, ownerCompanyName) = result; if (!isOwner) { throw new ForbiddenException($"company {companyId} is not the owner of identityProvider {identityProviderId}"); @@ -210,14 +241,15 @@ public async ValueTask SetOwnCompanyIdentityProviderSta { throw new ConflictException($"identityprovider {identityProviderId} does not have an iamIdentityProvider.alias"); } - if (!enabled && + if (identityProviderTypeId != IdentityProviderTypeId.MANAGED && + !enabled && !await ValidateOtherActiveIdentityProvider( alias, companyIdAliase ?? throw new UnexpectedConditionException("CompanyIdAliase should never be null here")).ConfigureAwait(false)) { throw new ControllerArgumentException($"cannot disable indentityProvider {identityProviderId} as no other active identityProvider exists for this company"); } - return new ValueTuple(identityProviderCategory, alias, identityProviderTypeId); + return new ValueTuple(identityProviderCategory, alias, identityProviderTypeId, companyUsersLinked, ownerCompanyName); } public async ValueTask UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details) @@ -250,16 +282,16 @@ public async ValueTask UpdateOwnCompanyIdentityProvider { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - var (isOwner, alias, identityProviderCategory, identityProviderTypeId, _) = result; - if (!isOwner) + + if (!result.IsOwner) { throw new ForbiddenException($"User not allowed to run the change for identity provider {identityProviderId}"); } - if (alias == null) + if (result.Alias == null) { throw new ConflictException($"identityprovider {identityProviderId} does not have an iamIdentityProvider.alias"); } - return new ValueTuple(identityProviderCategory, alias, identityProviderTypeId); + return new ValueTuple(result.IdentityProviderCategory, result.Alias, result.IdentityProviderTypeId); } private async ValueTask UpdateIdentityProviderOidc(string alias, IdentityProviderEditableDetails details) @@ -325,60 +357,134 @@ private async ValueTask ValidateOtherActiveIdentityProvider(string? alias, public async ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId) { - var companyId = _identityData.CompanyId; - var (alias, typeId) = await ValidateDeleteOwnCompanyIdentityProviderArguments(identityProviderId).ConfigureAwait(false); - - _portalRepositories.Remove(new CompanyIdentityProvider(companyId, identityProviderId)); + var identityProviderRepository = _portalRepositories.GetInstance(); + var (alias, typeId, ownerCompanyName) = await ValidateDeleteOwnCompanyIdentityProviderArguments(identityProviderId, identityProviderRepository).ConfigureAwait(false); if (alias != null) { - _portalRepositories.Remove(new IamIdentityProvider(alias, Guid.Empty)); + identityProviderRepository.DeleteIamIdentityProvider(alias); if (typeId == IdentityProviderTypeId.SHARED) { await _provisioningManager.DeleteSharedIdpRealmAsync(alias).ConfigureAwait(false); } await _provisioningManager.DeleteCentralIdentityProviderAsync(alias).ConfigureAwait(false); } - _portalRepositories.Remove(_portalRepositories.Attach(new IdentityProvider(identityProviderId, default, default, default, default))); + + if (typeId == IdentityProviderTypeId.MANAGED) + { + await DeleteManagedIdpLinks(identityProviderId, alias, ownerCompanyName, identityProviderRepository).ConfigureAwait(false); + } + else + { + await DeleteOwnCompanyIdpLinks(identityProviderId, identityProviderRepository).ConfigureAwait(false); + } + + identityProviderRepository.DeleteIdentityProvider(identityProviderId); await _portalRepositories.SaveAsync().ConfigureAwait(false); } - private async ValueTask<(string? Alias, IdentityProviderTypeId TypeId)> ValidateDeleteOwnCompanyIdentityProviderArguments(Guid identityProviderId) + private async Task DeleteOwnCompanyIdpLinks(Guid identityProviderId, IIdentityProviderRepository identityProviderRepository) { var companyId = _identityData.CompanyId; - var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false); + var companyUserIds = await identityProviderRepository.GetIdpLinkedCompanyUserIds(identityProviderId, companyId).ToListAsync(); + + identityProviderRepository.DeleteCompanyIdentityProvider(companyId, identityProviderId); + _portalRepositories.GetInstance().RemoveCompanyUserAssignedIdentityProviders(companyUserIds.Select(id => (id, identityProviderId))); + } + + private async Task DeleteManagedIdpLinks(Guid identityProviderId, string? alias, string ownerCompanyName, IIdentityProviderRepository identityProviderRepository) + { + var roleIds = await _roleBaseMailService.GetRoleData(_settings.DeleteIdpRoles).ConfigureAwait(false); + var idpLinkedData = identityProviderRepository.GetManagedIdpLinkedData(identityProviderId, roleIds.Distinct()); + + async IAsyncEnumerable<(string Email, IDictionary Parameters)> DeleteLinksReturningMaildata() + { + var companyRepository = _portalRepositories.GetInstance(); + var userRepository = _portalRepositories.GetInstance(); + var userRolesRepository = _portalRepositories.GetInstance(); + + await foreach (var data in idpLinkedData.ConfigureAwait(false)) + { + if (!data.HasMoreIdentityProviders) + { + companyRepository.AttachAndModifyCompany(data.CompanyId, + c => { c.CompanyStatusId = data.CompanyStatusId; }, + c => { c.CompanyStatusId = CompanyStatusId.INACTIVE; }); + userRepository.AttachAndModifyIdentities(data.Identities.Select(x => new ValueTuple>(x.IdentityId, identity => { identity.UserStatusId = UserStatusId.INACTIVE; }))); + userRolesRepository.DeleteCompanyUserAssignedRoles(data.Identities.SelectMany(i => i.UserRoleIds.Select(ur => new ValueTuple(i.IdentityId, ur)))); + await DeleteKeycloakUsers(data.Identities.Select(i => i.IdentityId)); + } + identityProviderRepository.DeleteCompanyIdentityProvider(data.CompanyId, identityProviderId); + userRepository.RemoveCompanyUserAssignedIdentityProviders(data.Identities.Where(x => x.IsLinkedCompanyUser).Select(x => (x.IdentityId, identityProviderId))); + + foreach (var userData in data.Identities.Where(i => i is { IsInUserRoles: true, Userdata.UserMail: not null }).Select(i => i.Userdata)) + { + var userName = string.Join(" ", new[] { userData.FirstName, userData.LastName }.Where(item => !string.IsNullOrWhiteSpace(item))); + var mailParameters = new Dictionary + { + {"idpAlias", alias ?? identityProviderId.ToString()}, + {"ownerCompanyName", ownerCompanyName}, + { "username", string.IsNullOrWhiteSpace(userName) ? "User" : userName } + }; + yield return (userData.UserMail!, mailParameters); + } + } + } + + var mailTemplates = Enumerable.Repeat("DeleteManagedIdp", 1); + + foreach (var mailData in await DeleteLinksReturningMaildata().ToListAsync().ConfigureAwait(false)) + { + await _mailingService.SendMails(mailData.Email, mailData.Parameters, mailTemplates).ConfigureAwait(false); + } + } + + private async Task DeleteKeycloakUsers(IEnumerable identityIds) + { + foreach (var identityId in identityIds) + { + string? userId; + if ((userId = await _provisioningManager.GetUserByUserName(identityId.ToString()).ConfigureAwait(false)) != null) + { + await _provisioningManager.DeleteCentralRealmUserAsync(userId).ConfigureAwait(false); + } + } + } + + private async ValueTask<(string? Alias, IdentityProviderTypeId TypeId, string OwnerCompanyName)> ValidateDeleteOwnCompanyIdentityProviderArguments(Guid identityProviderId, IIdentityProviderRepository identityProviderRepository) + { + var companyId = _identityData.CompanyId; + var result = await identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false); if (result == default) { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - var (isOwner, alias, _, typeId, aliase) = result; + + var (isOwner, alias, _, typeId, aliase, _, ownerCompanyName) = result; if (!isOwner) { throw new ForbiddenException($"company {companyId} is not the owner of identityProvider {identityProviderId}"); } - if (typeId == IdentityProviderTypeId.MANAGED) + if (alias == null || typeId == IdentityProviderTypeId.MANAGED) { - throw new ConflictException($"IdentityProviders of type {typeId} can not be deleted"); + return (alias, typeId, ownerCompanyName); } - if (alias != null) + if (await _provisioningManager.IsCentralIdentityProviderEnabled(alias).ConfigureAwait(false)) { - if (await _provisioningManager.IsCentralIdentityProviderEnabled(alias).ConfigureAwait(false)) - { - throw new ControllerArgumentException($"cannot delete identityProvider {identityProviderId} as it is enabled"); - } + throw new ControllerArgumentException($"cannot delete identityProvider {identityProviderId} as it is enabled"); + } - if (!await ValidateOtherActiveIdentityProvider( + if (!await ValidateOtherActiveIdentityProvider( alias, aliase ?? throw new UnexpectedConditionException("CompanyIdAliase should never be null here")).ConfigureAwait(false)) - { - throw new ControllerArgumentException($"cannot delete indentityProvider {identityProviderId} as no other active identityProvider exists for this company"); - } + { + throw new ControllerArgumentException($"cannot delete indentityProvider {identityProviderId} as no other active identityProvider exists for this company"); } - return (alias, typeId); + return (alias, typeId, ownerCompanyName); } private async ValueTask GetIdentityProviderDetailsOidc(Guid identityProviderId, string? alias, IdentityProviderCategoryId categoryId, IdentityProviderTypeId typeId) @@ -431,7 +537,6 @@ private async ValueTask GetIdentityProviderDetailsOidc( private async ValueTask GetIdentityProviderDetailsSaml(Guid identityProviderId, string? alias, IdentityProviderTypeId typeId) { - IdentityProviderConfigSaml? identityProviderDataSaml = null; IEnumerable? identityProviderMapper = null; if (!string.IsNullOrWhiteSpace(alias)) @@ -513,6 +618,7 @@ public async ValueTask CreateOrUpdateOwnCompanyUse { // for create-and-update semantics this is expected and not an error } + await _provisioningManager.AddProviderUserLinkToCentralUserAsync( iamUserId, new IdentityProviderLink( @@ -533,11 +639,11 @@ public async ValueTask GetOwnCompanyUserIdentityPr var (iamUserId, alias) = await GetUserAliasDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); var result = await _provisioningManager.GetProviderUserLinkDataForCentralUserIdAsync(iamUserId).FirstOrDefaultAsync(identityProviderLink => identityProviderLink.Alias == alias).ConfigureAwait(false); - if (result == default) { throw new NotFoundException($"identityProviderLink for identityProvider {identityProviderId} not found in keycloak for user {companyUserId}"); } + return new UserIdentityProviderLinkData( identityProviderId, result.UserId, @@ -629,6 +735,7 @@ public ValueTask UploadOwnCompanyUsersIdentityProvi { throw new UnsupportedMediaTypeException($"Only contentType {_settings.CsvSettings.ContentType} files are allowed."); } + return UploadOwnCompanyUsersIdentityProviderLinkDataInternalAsync(document, cancellationToken); } diff --git a/src/administration/Administration.Service/BusinessLogic/IdentityProviderSettings.cs b/src/administration/Administration.Service/BusinessLogic/IdentityProviderSettings.cs index 355361cc40..5063083c49 100644 --- a/src/administration/Administration.Service/BusinessLogic/IdentityProviderSettings.cs +++ b/src/administration/Administration.Service/BusinessLogic/IdentityProviderSettings.cs @@ -19,6 +19,7 @@ ********************************************************************************/ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration; using System.Text; namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic; @@ -26,6 +27,8 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog public class IdentityProviderSettings { public IdentityProviderCsvSettings CsvSettings { get; init; } = null!; + public IEnumerable DeactivateIdpRoles { get; init; } = null!; + public IEnumerable DeleteIdpRoles { get; init; } = null!; public bool Validate() { diff --git a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs index 5a1144c38a..9dd6e36b36 100644 --- a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs @@ -80,6 +80,7 @@ public Task GetCompanyWithAddressAsync(Guid applicationI { throw new ArgumentNullException(nameof(applicationId)); } + return GetCompanyWithAddressAsyncInternal(applicationId); } @@ -90,6 +91,7 @@ private async Task GetCompanyWithAddressAsyncInternal(Gu { throw NotFoundException.Create(AdministrationRegistrationErrors.APPLICATION_NOT_FOUND, new ErrorParameter[] { new("applicationId", applicationId.ToString()) }); } + return new CompanyWithAddressData( companyWithAddress.CompanyId, companyWithAddress.Name, @@ -201,6 +203,7 @@ public Task UpdateCompanyBpn(Guid applicationId, string bpn) { throw new ControllerArgumentException("BPN must contain exactly 16 characters long.", nameof(bpn)); } + if (!bpn.StartsWith("BPNL", StringComparison.OrdinalIgnoreCase)) { throw new ControllerArgumentException("businessPartnerNumbers must prefixed with BPNL", nameof(bpn)); @@ -292,10 +295,12 @@ public async Task ProcessClearinghouseResponseAsync(ClearinghouseResponseData da { throw new NotFoundException($"No companyApplication for BPN {data.BusinessPartnerNumber} is not in status SUBMITTED"); } + if (result.Count > 1) { throw new ConflictException($"more than one companyApplication in status SUBMITTED found for BPN {data.BusinessPartnerNumber} [{string.Join(", ", result)}]"); } + await _clearinghouseBusinessLogic.ProcessEndClearinghouse(result.Single(), data, cancellationToken).ConfigureAwait(false); await _portalRepositories.SaveAsync().ConfigureAwait(false); } @@ -335,8 +340,10 @@ public Task TriggerChecklistAsync(Guid applicationId, ApplicationChecklistEntryT { throw new UnexpectedConditionException($"While the processStep {processStepTypeId} is configured to be retriggerable there is no next step configured"); } + return TriggerChecklistInternal(applicationId, entryTypeId, processStepTypeId, nextStepData.ProcessStepTypeId, nextStepData.ChecklistEntryStatusId); } + private async Task TriggerChecklistInternal(Guid applicationId, ApplicationChecklistEntryTypeId entryTypeId, ProcessStepTypeId processStepTypeId, ProcessStepTypeId nextProcessStepTypeId, ApplicationChecklistEntryStatusId checklistEntryStatusId) { var context = await _checklistService @@ -378,6 +385,7 @@ public async Task ProcessClearinghouseSelfDescription(SelfDescriptionResponseDat { throw new NotFoundException($"companyApplication {data.ExternalId} not found"); } + if (!result.IsSubmitted) { throw new ConflictException($"companyApplication {data.ExternalId} is not in status SUBMITTED"); @@ -449,19 +457,22 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com null); var identityProviderRepository = _portalRepositories.GetInstance(); - foreach (var (idpId, idpAlias, idpType) in idps) + var userRepository = _portalRepositories.GetInstance(); + foreach (var (idpId, idpAlias, idpType, linkedUserIds) in idps) { if (idpType == IdentityProviderTypeId.SHARED) { await _provisioningManager.DeleteSharedIdpRealmAsync(idpAlias).ConfigureAwait(false); } + identityProviderRepository.DeleteCompanyIdentityProvider(companyId, idpId); - if (idpType == IdentityProviderTypeId.OWN || idpType == IdentityProviderTypeId.SHARED) + if (idpType is IdentityProviderTypeId.OWN or IdentityProviderTypeId.SHARED) { await _provisioningManager.DeleteCentralIdentityProviderAsync(idpAlias).ConfigureAwait(false); identityProviderRepository.DeleteIamIdentityProvider(idpAlias); identityProviderRepository.DeleteIdentityProvider(idpId); } + userRepository.RemoveCompanyUserAssignedIdentityProviders(linkedUserIds.Select(userId => (userId, idpId))); } _portalRepositories.GetInstance().AttachAndModifyCompanyApplication(applicationId, application => @@ -482,11 +493,11 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com await _provisioningManager.DeleteCentralRealmUserAsync(iamUserId).ConfigureAwait(false); } } - _portalRepositories.GetInstance().AttachAndModifyIdentities(companyUserIds.Select(userId => new ValueTuple>(userId, identity => { identity.UserStatusId = UserStatusId.DELETED; }))); + userRepository.AttachAndModifyIdentities(companyUserIds.Select(userId => new ValueTuple>(userId, identity => { identity.UserStatusId = UserStatusId.DELETED; }))); if (processId != null) { - _portalRepositories.GetInstance().CreateProcessStepRange(Enumerable.Repeat(new ValueTuple(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepStatusId.TODO, processId.Value), 1)); + _portalRepositories.GetInstance().CreateProcessStep(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepStatusId.TODO, processId.Value); } await _portalRepositories.SaveAsync().ConfigureAwait(false); @@ -511,9 +522,9 @@ private async Task PostRegistrationCancelEmailAsync(Guid applicationId, string c var mailParameters = new Dictionary { - { "userName", !string.IsNullOrWhiteSpace(userName) ? userName : user.Email }, + { "userName", !string.IsNullOrWhiteSpace(userName) ? userName : user.Email }, { "companyName", companyName }, - { "declineComment", comment}, + { "declineComment", comment }, { "helpUrl", _settings.HelpAddress } }; diff --git a/src/administration/Administration.Service/Program.cs b/src/administration/Administration.Service/Program.cs index a84aee9149..960e1f8465 100644 --- a/src/administration/Administration.Service/Program.cs +++ b/src/administration/Administration.Service/Program.cs @@ -24,6 +24,7 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Library; using Org.Eclipse.TractusX.Portal.Backend.Framework.Web; using Org.Eclipse.TractusX.Portal.Backend.Mailing.SendMail; +using Org.Eclipse.TractusX.Portal.Backend.Mailing.Service.DependencyInjection; using Org.Eclipse.TractusX.Portal.Backend.Notifications.Library; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess; using Org.Eclipse.TractusX.Portal.Backend.Processes.ApplicationChecklist.Config.DependencyInjection; @@ -41,6 +42,7 @@ { builder.Services .AddMailingAndTemplateManager(builder.Configuration) + .AddMailingService() .AddPortalRepositories(builder.Configuration) .AddProvisioningManager(builder.Configuration); diff --git a/src/administration/Administration.Service/appsettings.json b/src/administration/Administration.Service/appsettings.json index 26ebfe575d..47c6302efe 100644 --- a/src/administration/Administration.Service/appsettings.json +++ b/src/administration/Administration.Service/appsettings.json @@ -368,6 +368,20 @@ "Subject": "Company Wallet - SSI Credential Request Rejected", "EmailTemplateType": "CredentialRejected" } + }, + { + "Name": "DeactivateManagedIdp", + "Setting": { + "Subject": "IdentityProvider deactivation", + "EmailTemplateType": "DeactivateManagedIdp" + } + }, + { + "Name": "DeleteManagedIdp", + "Setting": { + "Subject": "IdentityProvider deletion", + "EmailTemplateType": "DeleteManagedIdp" + } } ], "Mail": { @@ -390,7 +404,9 @@ "HeaderProviderAlias": "", "HeaderProviderUserId": "", "HeaderProviderUserName": "" - } + }, + "DeactivateIdpRoles": [], + "DeleteIdpRoles": [] }, "Document": { "FrameDocumentTypeIds": [] diff --git a/src/mailing/Mailing.Service/IRoleBaseMailService.cs b/src/mailing/Mailing.Service/IRoleBaseMailService.cs index 58b71419ab..c0e7d9fce8 100644 --- a/src/mailing/Mailing.Service/IRoleBaseMailService.cs +++ b/src/mailing/Mailing.Service/IRoleBaseMailService.cs @@ -24,5 +24,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Mailing.Service; public interface IRoleBaseMailService { - Task RoleBaseSendMail(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid companyId); + Task RoleBaseSendMailForCompany(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid companyId); + Task RoleBaseSendMailForIdp(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid identityProviderId); + Task> GetRoleData(IEnumerable receiverRoles); } diff --git a/src/mailing/Mailing.Service/Mailing.Service.csproj b/src/mailing/Mailing.Service/Mailing.Service.csproj index a1de10af95..5888853152 100644 --- a/src/mailing/Mailing.Service/Mailing.Service.csproj +++ b/src/mailing/Mailing.Service/Mailing.Service.csproj @@ -18,16 +18,18 @@ - SPDX-License-Identifier: Apache-2.0 --> - - - - - - Org.Eclipse.TractusX.Portal.Backend.Mailing.Service + Org.Eclipse.TractusX.Portal.Backend.Mailing.Service net7.0 enable enable + + + + + + + \ No newline at end of file diff --git a/src/mailing/Mailing.Service/RoleBaseMailService.cs b/src/mailing/Mailing.Service/RoleBaseMailService.cs index 4ae8d85ae2..6e416dc1d9 100644 --- a/src/mailing/Mailing.Service/RoleBaseMailService.cs +++ b/src/mailing/Mailing.Service/RoleBaseMailService.cs @@ -39,36 +39,57 @@ public RoleBaseMailService(IPortalRepositories portalRepositories, IMailingServi _mailingService = mailingService; } - public async Task RoleBaseSendMail(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid companyId) + public async Task RoleBaseSendMailForCompany(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid companyId) + { + var roleData = await GetRoleData(receiverRoles).ConfigureAwait(false); + var companyUserWithRoleIdForCompany = _portalRepositories.GetInstance() + .GetCompanyUserEmailForCompanyAndRoleId(roleData, companyId); + await SendMailsToUsers(parameters, userNameParameter, template, companyUserWithRoleIdForCompany).ConfigureAwait(false); + } + + public async Task RoleBaseSendMailForIdp(IEnumerable receiverRoles, IEnumerable<(string ParameterName, string ParameterValue)> parameters, (string ParameterName, string ParameterValue)? userNameParameter, IEnumerable template, Guid identityProviderId) + { + var roleData = await GetRoleData(receiverRoles).ConfigureAwait(false); + var companyUserWithRoleIdForCompany = _portalRepositories.GetInstance().GetCompanyUserEmailForIdpWithoutOwnerAndRoleId(roleData, identityProviderId); + await SendMailsToUsers(parameters, userNameParameter, template, companyUserWithRoleIdForCompany).ConfigureAwait(false); + } + + public async Task> GetRoleData(IEnumerable receiverRoles) { - var receiverUserRoles = receiverRoles; var userRolesRepository = _portalRepositories.GetInstance(); var roleData = await userRolesRepository - .GetUserRoleIdsUntrackedAsync(receiverUserRoles) + .GetUserRoleIdsUntrackedAsync(receiverRoles) .ToListAsync() .ConfigureAwait(false); - if (roleData.Count < receiverUserRoles.Sum(clientRoles => clientRoles.UserRoleNames.Count())) + if (roleData.Count < receiverRoles.Sum(clientRoles => clientRoles.UserRoleNames.Count())) { throw new ConfigurationException( - $"invalid configuration, at least one of the configured roles does not exist in the database: {string.Join(", ", receiverUserRoles.Select(clientRoles => $"client: {clientRoles.ClientId}, roles: [{string.Join(", ", clientRoles.UserRoleNames)}]"))}"); + $"invalid configuration, at least one of the configured roles does not exist in the database: {string.Join(", ", receiverRoles.Select(clientRoles => $"client: {clientRoles.ClientId}, roles: [{string.Join(", ", clientRoles.UserRoleNames)}]"))}"); } - var companyUserWithRoleIdForCompany = _portalRepositories.GetInstance() - .GetCompanyUserEmailForCompanyAndRoleId(roleData, companyId); + return roleData; + } - await foreach (var (receiver, firstName, lastName) in companyUserWithRoleIdForCompany) + private async Task SendMailsToUsers( + IEnumerable<(string ParameterName, string ParameterValue)> parameters, + (string ParameterName, string ParameterValue)? userNameParameter, + IEnumerable template, + IAsyncEnumerable<(string Email, string? FirstName, string? LastName)> companyUserWithRoleId) + { + await foreach (var (receiver, firstName, lastName) in companyUserWithRoleId) { IEnumerable<(string ParameterName, string ParameterValue)> ParametersWithUserName() { - if (userNameParameter.HasValue) + if (!userNameParameter.HasValue) { - var userName = string.Join(" ", new[] { firstName, lastName }.Where(item => !string.IsNullOrWhiteSpace(item))); - return parameters.Append( - string.IsNullOrWhiteSpace(userName) - ? userNameParameter.Value - : new(userNameParameter.Value.ParameterName, userName)); + return parameters; } - return parameters; + + var userName = string.Join(" ", new[] { firstName, lastName }.Where(item => !string.IsNullOrWhiteSpace(item))); + return parameters.Append( + string.IsNullOrWhiteSpace(userName) + ? userNameParameter.Value + : new(userNameParameter.Value.ParameterName, userName)); } await _mailingService.SendMails(receiver, ParametersWithUserName().ToImmutableDictionary(x => x.ParameterName, x => x.ParameterValue), template).ConfigureAwait(false); diff --git a/src/mailing/Mailing.Template/EmailTemplates/deactivate_managed_idp.html b/src/mailing/Mailing.Template/EmailTemplates/deactivate_managed_idp.html new file mode 100644 index 0000000000..ea03f15ab1 --- /dev/null +++ b/src/mailing/Mailing.Template/EmailTemplates/deactivate_managed_idp.html @@ -0,0 +1,248 @@ + + + + + + + + + + OSP Welcome Email + + + +
+ + + + + +
+ + + \ No newline at end of file diff --git a/src/mailing/Mailing.Template/EmailTemplates/delete_managed_idp.html b/src/mailing/Mailing.Template/EmailTemplates/delete_managed_idp.html new file mode 100644 index 0000000000..d819fb96da --- /dev/null +++ b/src/mailing/Mailing.Template/EmailTemplates/delete_managed_idp.html @@ -0,0 +1,248 @@ + + + + + + + + + + OSP Welcome Email + + + +
+ + + + + +
+ + + \ No newline at end of file diff --git a/src/mailing/Mailing.Template/Enums/EmailTemplateType.cs b/src/mailing/Mailing.Template/Enums/EmailTemplateType.cs index 88e5c53477..3969b7dd9f 100644 --- a/src/mailing/Mailing.Template/Enums/EmailTemplateType.cs +++ b/src/mailing/Mailing.Template/Enums/EmailTemplateType.cs @@ -147,6 +147,18 @@ public enum EmailTemplateType /// Email template for the welcome email of an osp registered company /// [Path("osp_welcome_email.html")] - OspWelcomeMail + OspWelcomeMail, + + /// + /// Email template for the welcome email of an osp registered company + /// + [Path("deactivate_managed_idp.html")] + DeactivateManagedIdp, + + /// + /// Email template for the welcome email of an osp registered company + /// + [Path("delete_managed_idp.html")] + DeleteManagedIdp } } diff --git a/src/marketplace/Offers.Library/DependencyInjection/OfferSetupServiceExtensions.cs b/src/marketplace/Offers.Library/DependencyInjection/OfferSetupServiceExtensions.cs index ec176e1c93..d605fa3597 100644 --- a/src/marketplace/Offers.Library/DependencyInjection/OfferSetupServiceExtensions.cs +++ b/src/marketplace/Offers.Library/DependencyInjection/OfferSetupServiceExtensions.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.DependencyInjection; using Org.Eclipse.TractusX.Portal.Backend.Framework.Logging; using Org.Eclipse.TractusX.Portal.Backend.Mailing.Service; +using Org.Eclipse.TractusX.Portal.Backend.Mailing.Service.DependencyInjection; using Org.Eclipse.TractusX.Portal.Backend.Offers.Library.Service; using Org.Eclipse.TractusX.Portal.Backend.Processes.OfferSubscription.Library.DependencyInjection; @@ -36,8 +37,8 @@ public static IServiceCollection AddOfferServices(this IServiceCollection servic return services .AddTransient() .AddTransient() - .AddTransient() .AddTransient() + .AddMailingService() .AddOfferSubscriptionProcess(); } } diff --git a/src/marketplace/Offers.Library/Service/OfferService.cs b/src/marketplace/Offers.Library/Service/OfferService.cs index decb668752..b95d99b578 100644 --- a/src/marketplace/Offers.Library/Service/OfferService.cs +++ b/src/marketplace/Offers.Library/Service/OfferService.cs @@ -522,7 +522,7 @@ public async Task ApproveOfferRequestAsync(Guid offerId, OfferTypeId offerTypeId await _portalRepositories.SaveAsync().ConfigureAwait(false); - await _roleBaseMailService.RoleBaseSendMail( + await _roleBaseMailService.RoleBaseSendMailForCompany( notificationRecipients, new[] { @@ -597,7 +597,7 @@ public async Task DeclineOfferAsync(Guid offerId, OfferDeclineRequest data, Offe await _portalRepositories.SaveAsync().ConfigureAwait(false); - await _roleBaseMailService.RoleBaseSendMail( + await _roleBaseMailService.RoleBaseSendMailForCompany( notificationRecipients, new[] { diff --git a/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs b/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs index 3f41f16b6f..0cb85190e6 100644 --- a/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs +++ b/src/marketplace/Offers.Library/Service/OfferSubscriptionService.cs @@ -87,7 +87,7 @@ public async Task AddOfferSubscriptionAsync(Guid offerId, IEnumerable GetSubmittedApplicationIdsByBpn(string bpn) => /// /// Id of the application /// Returns the company id - public Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId, IEnumerable<(Guid IdentityProviderId, string IamAlias, IdentityProviderTypeId TypeId)> Idps, IEnumerable CompanyUserIds)> GetCompanyIdNameForSubmittedApplication(Guid applicationId) => + public Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId, IEnumerable<(Guid IdentityProviderId, string IamAlias, IdentityProviderTypeId TypeId, IEnumerable LinkedCompanyUserIds)> Idps, IEnumerable CompanyUserIds)> GetCompanyIdNameForSubmittedApplication(Guid applicationId) => _dbContext.CompanyApplications .AsSplitQuery() .Where(x => x.Id == applicationId && x.ApplicationStatusId == CompanyApplicationStatusId.SUBMITTED) - .Select(x => new ValueTuple, IEnumerable>( + .Select(x => new ValueTuple)>, IEnumerable>( x.CompanyId, x.Company!.Name, x.Company.NetworkRegistration!.ProcessId, - x.Company.IdentityProviders.Select(idp => new ValueTuple(idp.Id, idp.IamIdentityProvider!.IamIdpAlias, idp.IdentityProviderTypeId)), + x.Company.IdentityProviders.Select(idp => new ValueTuple>(idp.Id, idp.IamIdentityProvider!.IamIdpAlias, idp.IdentityProviderTypeId, idp.CompanyUserAssignedIdentityProviders.Select(assigned => assigned.CompanyUserId))), x.Company.Identities.Where(i => i.IdentityTypeId == IdentityTypeId.COMPANY_USER && i.UserStatusId != UserStatusId.DELETED).Select(i => i.Id))) .SingleOrDefaultAsync(); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs index 30e091d4ab..e4a288085c 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs @@ -97,7 +97,7 @@ public interface IApplicationRepository /// /// Id of the application /// The id of the company for the given application - Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId, IEnumerable<(Guid IdentityProviderId, string IamAlias, IdentityProviderTypeId TypeId)> Idps, IEnumerable CompanyUserIds)> GetCompanyIdNameForSubmittedApplication(Guid applicationId); + Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId, IEnumerable<(Guid IdentityProviderId, string IamAlias, IdentityProviderTypeId TypeId, IEnumerable LinkedCompanyUserIds)> Idps, IEnumerable CompanyUserIds)> GetCompanyIdNameForSubmittedApplication(Guid applicationId); Task IsValidApplicationForCompany(Guid applicationId, Guid companyId); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs index 39d230fcd9..9020c0ab76 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs @@ -39,7 +39,7 @@ public interface IIdentityProviderRepository Task<(string? Alias, bool IsValidUser)> GetIdpCategoryIdByUserIdAsync(Guid companyUserId, Guid userCompanyId); Task<(string? Alias, IdentityProviderCategoryId IamIdentityProviderCategory, bool IsOwnOrOwnerCompany, IdentityProviderTypeId TypeId)> GetOwnCompanyIdentityProviderAliasUntrackedAsync(Guid identityProviderId, Guid companyId); Task<(string? Alias, IdentityProviderCategoryId IamIdentityProviderCategory, bool IsOwnerCompany, IdentityProviderTypeId TypeId, IEnumerable ConnectedCompanies)> GetOwnIdentityProviderWithConnectedCompanies(Guid identityProviderId, Guid companyId); - Task<(bool IsOwner, string? Alias, IdentityProviderCategoryId IdentityProviderCategory, IdentityProviderTypeId IdentityProviderTypeId, IEnumerable<(Guid CompanyId, IEnumerable Aliase)>? CompanyIdAliase)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId, bool queryAliase); + Task<(bool IsOwner, string? Alias, IdentityProviderCategoryId IdentityProviderCategory, IdentityProviderTypeId IdentityProviderTypeId, IEnumerable<(Guid CompanyId, IEnumerable Aliase)>? CompanyIdAliase, bool CompanyUsersLinked, string IdpOwnerName)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId, bool queryAliase); IAsyncEnumerable<(Guid IdentityProviderId, IdentityProviderCategoryId CategoryId, string? Alias, IdentityProviderTypeId TypeId)> GetCompanyIdentityProviderCategoryDataUntracked(Guid companyId); IAsyncEnumerable<(Guid IdentityProviderId, string Alias)> GetOwnCompanyIdentityProviderAliasDataUntracked(Guid companyId, IEnumerable identityProviderIds); Task<(Guid IdentityProviderId, string? Alias)> GetSingleManagedIdentityProviderAliasDataUntracked(Guid companyId); @@ -52,4 +52,8 @@ public interface IIdentityProviderRepository (Guid CompanyUserId, string? FirstName, string? LastName, string? Email) CompanyUser, (string? IdpAlias, bool IsSharedIdp) IdentityProvider)> GetCompanyNameIdpAliasUntrackedAsync(Guid identityProviderId, Guid companyUserId); + + IAsyncEnumerable GetIdpLinkedCompanyUserIds(Guid identityProviderId, Guid companyId); + IAsyncEnumerable<(Guid CompanyId, CompanyStatusId CompanyStatusId, bool HasMoreIdentityProviders, IEnumerable<(Guid IdentityId, bool IsLinkedCompanyUser, (string? UserMail, string? FirstName, string? LastName) Userdata, bool IsInUserRoles, IEnumerable UserRoleIds)> Identities)> GetManagedIdpLinkedData(Guid identityProviderId, IEnumerable userRoleIds); + IAsyncEnumerable<(string Email, string? FirstName, string? LastName)> GetCompanyUserEmailForIdpWithoutOwnerAndRoleId(IEnumerable userRoleIds, Guid identityProviderId); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityRepository.cs index 3834bad891..31fb9ae277 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityRepository.cs @@ -26,4 +26,5 @@ public interface IIdentityRepository Task GetActiveCompanyIdByIdentityId(Guid identityId); Task<(IdentityTypeId IdentityTypeId, Guid CompanyId)> GetActiveIdentityDataByIdentityId(Guid identityId); Task<(Guid IdentityId, IdentityTypeId IdentityTypeId, Guid CompanyId)> GetActiveIdentityDataByUserEntityId(string userEntityId); + IAsyncEnumerable<(string Email, string? FirstName, string? LastName)> GetCompanyUserEmailForIdentityIdsWithoutOwnerAndRoleId(IEnumerable userRoleIds, IEnumerable identityIds); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs index 00daabde15..15bd7abdb9 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs @@ -121,6 +121,7 @@ public interface IUserRepository Identity AttachAndModifyIdentity(Guid identityId, Action? initialize, Action modify); CompanyUserAssignedIdentityProvider AddCompanyUserAssignedIdentityProvider(Guid companyUserId, Guid identityProviderId, string providerId, string userName); + void RemoveCompanyUserAssignedIdentityProviders(IEnumerable<(Guid CompanyUserId, Guid IdentityProviderId)> companyUserIdentityProviderIds); IAsyncEnumerable GetUserAssignedIdentityProviderForNetworkRegistration(Guid networkRegistrationId); void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action Modify)> identityData); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs index 98be8c920c..d13d2554c1 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs @@ -128,18 +128,25 @@ public void DeleteIamIdentityProvider(string idpAlias) => )) .SingleOrDefaultAsync(); - public Task<(bool IsOwner, string? Alias, IdentityProviderCategoryId IdentityProviderCategory, IdentityProviderTypeId IdentityProviderTypeId, IEnumerable<(Guid CompanyId, IEnumerable Aliase)>? CompanyIdAliase)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId, bool queryAliase) => + public Task<(bool IsOwner, string? Alias, IdentityProviderCategoryId IdentityProviderCategory, IdentityProviderTypeId IdentityProviderTypeId, IEnumerable<(Guid CompanyId, IEnumerable Aliase)>? CompanyIdAliase, bool CompanyUsersLinked, string IdpOwnerName)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId, bool queryAliase) => _context.IdentityProviders .Where(identityProvider => identityProvider.Id == identityProviderId) .Select(identityProvider => - new ValueTuple)>?>( + new ValueTuple)>?, bool, string>( identityProvider.OwnerId == companyId, identityProvider.IamIdentityProvider!.IamIdpAlias, identityProvider.IdentityProviderCategoryId, identityProvider.IdentityProviderTypeId, queryAliase - ? identityProvider.Companies.Select(c => new ValueTuple>(c.Id, c.IdentityProviders.Where(i => i.IamIdentityProvider != null).Select(i => i.IamIdentityProvider!.IamIdpAlias))) - : null + ? identityProvider.Companies + .Select(c => new ValueTuple>( + c.Id, + c.IdentityProviders + .Where(i => i.IamIdentityProvider != null) + .Select(i => i.IamIdentityProvider!.IamIdpAlias))) + : null, + identityProvider.CompanyUserAssignedIdentityProviders.Any(), + identityProvider.Owner!.Name )) .SingleOrDefaultAsync(); @@ -257,4 +264,40 @@ public void DeleteIamIdentityProvider(string idpAlias) => s.IdentityProvider!.IamIdentityProvider!.IamIdpAlias, s.IdentityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED))) .SingleOrDefaultAsync(); + + public IAsyncEnumerable GetIdpLinkedCompanyUserIds(Guid identityProviderId, Guid companyId) => + _context.CompanyUserAssignedIdentityProviders + .Where(x => + x.IdentityProviderId == identityProviderId && + x.CompanyUser!.Identity!.CompanyId == companyId) + .Select(x => x.CompanyUserId) + .ToAsyncEnumerable(); + + public IAsyncEnumerable<(Guid CompanyId, CompanyStatusId CompanyStatusId, bool HasMoreIdentityProviders, IEnumerable<(Guid IdentityId, bool IsLinkedCompanyUser, (string? UserMail, string? FirstName, string? LastName) Userdata, bool IsInUserRoles, IEnumerable UserRoleIds)> Identities)> GetManagedIdpLinkedData(Guid identityProviderId, IEnumerable userRoleIds) => + _context.IdentityProviders + .AsSplitQuery() + .Where(x => x.Id == identityProviderId) + .SelectMany(x => x.Companies.Select(c => new ValueTuple, bool, IEnumerable)>>( + c.Id, + c.CompanyStatusId, + c.IdentityProviders.Any(idp => idp.Id != identityProviderId), + c.Identities + .Select(i => new ValueTuple, bool, IEnumerable>( + i.Id, + i.CompanyUser!.CompanyUserAssignedIdentityProviders.Any(cuIdp => cuIdp.IdentityProviderId == identityProviderId), + new ValueTuple(i.CompanyUser.Email, i.CompanyUser.Firstname, i.CompanyUser.Lastname), + i.IdentityAssignedRoles.Any(assigned => userRoleIds.Contains(assigned.UserRoleId)), + i.IdentityAssignedRoles.Select(u => u.UserRoleId)))))) + .ToAsyncEnumerable(); + + /// + public IAsyncEnumerable<(string Email, string? FirstName, string? LastName)> GetCompanyUserEmailForIdpWithoutOwnerAndRoleId(IEnumerable userRoleIds, Guid identityProviderId) => + _context.CompanyUsers + .Where(x => + x.Identity!.Company!.IdentityProviders.Any(idp => idp.Id == identityProviderId && idp.OwnerId != x.Identity!.CompanyId) && + x.Identity!.UserStatusId == UserStatusId.ACTIVE && + x.Identity!.IdentityAssignedRoles.Any(assigned => userRoleIds.Contains(assigned.UserRoleId)) && + x.Email != null) + .Select(x => new ValueTuple(x.Email!, x.Firstname, x.Lastname)) + .ToAsyncEnumerable(); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityRepository.cs index a7e736746f..6c652b7f7a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityRepository.cs @@ -51,4 +51,14 @@ public Task GetActiveCompanyIdByIdentityId(Guid identityId) => x.IdentityTypeId, x.CompanyId)) .SingleOrDefaultAsync(); + + /// + public IAsyncEnumerable<(string Email, string? FirstName, string? LastName)> GetCompanyUserEmailForIdentityIdsWithoutOwnerAndRoleId(IEnumerable userRoleIds, IEnumerable identityIds) => + _context.CompanyUsers + .Where(x => + identityIds.Contains(x.Id) && + x.Identity!.IdentityAssignedRoles.Select(u => u.UserRoleId).Any(u => userRoleIds.Any(ur => ur == u)) && + x.Email != null) + .Select(x => new ValueTuple(x.Email!, x.Firstname, x.Lastname)) + .ToAsyncEnumerable(); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs index db05337950..8133ef8a8a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs @@ -429,6 +429,9 @@ public Identity AttachAndModifyIdentity(Guid identityId, Action? initi public CompanyUserAssignedIdentityProvider AddCompanyUserAssignedIdentityProvider(Guid companyUserId, Guid identityProviderId, string providerId, string userName) => _dbContext.CompanyUserAssignedIdentityProviders.Add(new CompanyUserAssignedIdentityProvider(companyUserId, identityProviderId, providerId, userName)).Entity; + public void RemoveCompanyUserAssignedIdentityProviders(IEnumerable<(Guid CompanyUserId, Guid IdentityProviderId)> companyUserIdentityProviderIds) => + _dbContext.CompanyUserAssignedIdentityProviders.RemoveRange(companyUserIdentityProviderIds.Select(x => new CompanyUserAssignedIdentityProvider(x.CompanyUserId, x.IdentityProviderId, null!, null!))); + public IAsyncEnumerable GetUserAssignedIdentityProviderForNetworkRegistration(Guid networkRegistrationId) => _dbContext.CompanyUsers .Where(cu => diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs index 7f370cae3d..c88c27ccfb 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs @@ -25,7 +25,10 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Library; using Org.Eclipse.TractusX.Portal.Backend.Framework.IO; +using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration; using Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling; +using Org.Eclipse.TractusX.Portal.Backend.Mailing.SendMail; +using Org.Eclipse.TractusX.Portal.Backend.Mailing.Service; 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; @@ -48,6 +51,7 @@ public class IdentityProviderBusinessLogicTests private readonly IPortalRepositories _portalRepositories; private readonly IIdentityProviderRepository _identityProviderRepository; private readonly IUserRepository _userRepository; + private readonly IUserRolesRepository _userRolesRepository; private readonly IOptions _options; private readonly IdentityProviderCsvSettings _csvSettings; private readonly IIdentityService _identityService; @@ -63,6 +67,8 @@ public class IdentityProviderBusinessLogicTests private readonly Guid _otherIdentityProviderId; private readonly string _otherIdpAlias; private readonly Guid _identityProviderId; + private readonly IRoleBaseMailService _roleBaseMailService; + private readonly IMailingService _mailingService; public IdentityProviderBusinessLogicTests() { @@ -76,7 +82,10 @@ public IdentityProviderBusinessLogicTests() _companyRepository = A.Fake(); _identityProviderRepository = A.Fake(); _userRepository = A.Fake(); + _userRolesRepository = A.Fake(); _identityService = A.Fake(); + _roleBaseMailService = A.Fake(); + _mailingService = A.Fake(); _options = A.Fake>(); _document = A.Fake(); _logger = A.Fake>(); @@ -118,6 +127,12 @@ public IdentityProviderBusinessLogicTests() A.CallTo(() => _portalRepositories.GetInstance()) .Returns(_identityProviderRepository); + A.CallTo(() => _portalRepositories.GetInstance()) + .Returns(_companyRepository); + A.CallTo(() => _portalRepositories.GetInstance()) + .Returns(_userRepository); + A.CallTo(() => _portalRepositories.GetInstance()) + .Returns(_userRolesRepository); } #region UploadOwnCompanyUsersIdentityProviderLinkDataAsync @@ -138,6 +153,8 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncAllUncha _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -175,6 +192,8 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncWrongCon _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -225,6 +244,8 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncEmailCha _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -272,6 +293,8 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncSharedId _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -319,6 +342,8 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncOtherIdp _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -363,6 +388,8 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncUnknownC _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -398,6 +425,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithNotSupportedProtocol _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -420,6 +449,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithDisplayNameToLong_Th _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -440,6 +471,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithInvalidCharacterInDi _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -464,6 +497,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithInvalidCompany_Throw _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -485,6 +520,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithNotAllowedCompanyFor _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -509,6 +546,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithShared_ThrowsForbidd _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -534,6 +573,8 @@ public async Task CreateOwnCompanyIdentityProviderAsync_WithValidData_ExecutesEx _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); @@ -616,10 +657,12 @@ public async Task DeleteCompanyIdentityProviderAsync_WithNotExistingProvider_Thr _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?, bool, string))default); // Act async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(invalidId).ConfigureAwait(false); @@ -640,10 +683,12 @@ public async Task DeleteCompanyIdentityProviderAsync_WithInvalidCompany_ThrowsCo _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((false, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((false, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); @@ -655,7 +700,7 @@ public async Task DeleteCompanyIdentityProviderAsync_WithInvalidCompany_ThrowsCo } [Fact] - public async Task DeleteCompanyIdentityProviderAsync_WithManagedIdp_ThrowsConflictException() + public async Task DeleteCompanyIdentityProviderAsync_WithDisabledIdp_ThrowsControllerArgumentException() { // Arrange var identityProviderId = Guid.NewGuid(); @@ -664,22 +709,27 @@ public async Task DeleteCompanyIdentityProviderAsync_WithManagedIdp_ThrowsConfli _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.MANAGED, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled(A._)) + .Returns(true); // Act async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); // Assert - var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Be($"IdentityProviders of type MANAGED can not be deleted"); + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"cannot delete identityProvider {identityProviderId} as it is enabled"); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")).MustHaveHappenedOnceExactly(); } [Fact] - public async Task DeleteCompanyIdentityProviderAsync_WithDisabledIdp_ThrowsControllerArgumentException() + public async Task DeleteCompanyIdentityProviderAsync_WithSharedKeycloakValid_CallsExpected() { // Arrange var identityProviderId = Guid.NewGuid(); @@ -688,25 +738,38 @@ public async Task DeleteCompanyIdentityProviderAsync_WithDisabledIdp_ThrowsContr _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); + A.CallTo(() => _identityProviderRepository.GetIdpLinkedCompanyUserIds(identityProviderId, _companyId)) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); - A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled(A._)) + .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, new[] { (_companyId, new[] { "other-alias" }.AsEnumerable()) }, false, string.Empty)); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")) + .Returns(false); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")) .Returns(true); // Act - async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); + await sut.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); // Assert - var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Be($"cannot delete identityProvider {identityProviderId} as it is enabled"); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.DeleteSharedIdpRealmAsync("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.DeleteCentralIdentityProviderAsync("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _userRepository.RemoveCompanyUserAssignedIdentityProviders(A>.That.Matches(x => x.Count() == 3))) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteCompanyIdentityProvider(_companyId, identityProviderId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteIamIdentityProvider("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteIdentityProvider(identityProviderId)).MustHaveHappenedOnceExactly(); } [Fact] - public async Task DeleteCompanyIdentityProviderAsync_WithSharedKeycloakValid_CallsExpected() + public async Task DeleteCompanyIdentityProviderAsync_WithValid_CallsExpected() { // Arrange var identityProviderId = Guid.NewGuid(); @@ -715,10 +778,14 @@ public async Task DeleteCompanyIdentityProviderAsync_WithSharedKeycloakValid_Cal _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, new[] { (_companyId, new[] { "other-alias" }.AsEnumerable()) })); + .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "other-alias" }.AsEnumerable()) }, false, string.Empty)); + A.CallTo(() => _identityProviderRepository.GetIdpLinkedCompanyUserIds(identityProviderId, _companyId)) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")) .Returns(false); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")) @@ -728,49 +795,89 @@ public async Task DeleteCompanyIdentityProviderAsync_WithSharedKeycloakValid_Cal await sut.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); // Assert - A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")).MustHaveHappenedOnceExactly(); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")).MustHaveHappenedOnceExactly(); - A.CallTo(() => _provisioningManager.DeleteSharedIdpRealmAsync("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.DeleteSharedIdpRealmAsync("test")).MustNotHaveHappened(); A.CallTo(() => _provisioningManager.DeleteCentralIdentityProviderAsync("test")).MustHaveHappenedOnceExactly(); A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _userRepository.RemoveCompanyUserAssignedIdentityProviders(A>.That.Matches(x => x.Count() == 3))) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteCompanyIdentityProvider(_companyId, identityProviderId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteIamIdentityProvider("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteIdentityProvider(identityProviderId)).MustHaveHappenedOnceExactly(); } - [Fact] - public async Task DeleteCompanyIdentityProviderAsync_WithValid_CallsExpected() + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task DeleteCompanyIdentityProviderAsync_WithManagedIdp_ExecutesExpected(bool multipleIdps) { // Arrange var identityProviderId = Guid.NewGuid(); + var role1 = Guid.NewGuid(); + var role2 = Guid.NewGuid(); + var company = _fixture.Build().With(x => x.CompanyStatusId, CompanyStatusId.ACTIVE).Create(); + var identity = _fixture.Build().With(x => x.UserStatusId, UserStatusId.ACTIVE).Create(); + var userRoleIds = _fixture.CreateMany(3); + var keycloakUserId = _fixture.Create(); + A.CallTo(() => _identity.CompanyId).Returns(company.Id); var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "other-alias" }.AsEnumerable()) })); + .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.MANAGED, Enumerable.Repeat(new ValueTuple>(company.Id, Enumerable.Empty()), 1), false, string.Empty)); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")) .Returns(false); - A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")) - .Returns(true); + A.CallTo(() => _provisioningManager.GetUserByUserName(identity.Id.ToString())).Returns((string?)keycloakUserId); + A.CallTo(() => _roleBaseMailService.GetRoleData(_options.Value.DeleteIdpRoles)).Returns(new List { role1, role2 }); + A.CallTo(() => _identityProviderRepository.GetManagedIdpLinkedData(identityProviderId, A>.That.Matches(x => x.Count() == 2 && x.Contains(role1) && x.Contains(role2)))).Returns( + new ValueTuple UserRoleIds)>>[] { + new (company.Id, CompanyStatusId.ACTIVE, multipleIdps, Enumerable.Repeat((identity.Id, true, new ValueTuple("test@example.org", "Test", "User"), true, userRoleIds), 1)) + }.ToAsyncEnumerable()); + A.CallTo(() => _companyRepository.AttachAndModifyCompany(company.Id, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action modify) => + { + initialize?.Invoke(company); + modify(company); + }); + A.CallTo(() => _userRepository.AttachAndModifyIdentities(A>>>._)) + .Invokes((IEnumerable<(Guid IdentityId, Action Modify)> identityData) => + { + var initial = identityData.Select(x => (Identity: identity, x.Modify)).ToList(); + initial.ForEach(x => x.Modify(x.Identity)); + }); // Act await sut.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); // Assert - A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")).MustHaveHappenedOnceExactly(); - A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")).MustHaveHappenedOnceExactly(); A.CallTo(() => _provisioningManager.DeleteSharedIdpRealmAsync("test")).MustNotHaveHappened(); A.CallTo(() => _provisioningManager.DeleteCentralIdentityProviderAsync("test")).MustHaveHappenedOnceExactly(); A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteCompanyIdentityProvider(company.Id, identityProviderId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteIamIdentityProvider("test")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.DeleteIdentityProvider(identityProviderId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _mailingService.SendMails("test@example.org", A>._, A>.That.Matches(x => x.Count() == 1 && x.Single() == "DeleteManagedIdp"))) + .MustHaveHappenedOnceExactly(); + company.CompanyStatusId.Should().Be(multipleIdps ? CompanyStatusId.ACTIVE : CompanyStatusId.INACTIVE); + if (multipleIdps) + { + identity.UserStatusId.Should().Be(UserStatusId.ACTIVE); + A.CallTo(() => _userRolesRepository.DeleteCompanyUserAssignedRoles(A>._)).MustNotHaveHappened(); + A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync(A._)).MustNotHaveHappened(); + } + else + { + identity.UserStatusId.Should().Be(UserStatusId.INACTIVE); + A.CallTo(() => _userRolesRepository.DeleteCompanyUserAssignedRoles(A>.That.Matches(x => x.Count() == userRoleIds.Count() && x.All(x => x.Item1 == identity.Id) && userRoleIds.All(r => x.Any(x => x.Item2 == r))))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync(keycloakUserId)).MustHaveHappenedOnceExactly(); + } } #endregion @@ -786,6 +893,8 @@ public async Task GetOwnCompanyIdentityProvidersAsync_WithValidId_ReturnsExpecte _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); var oidcGuid = Guid.NewGuid(); @@ -828,6 +937,8 @@ public async Task GetOwnCompanyIdentityProviderAsync_WithDifferentCompany_Throws _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) @@ -851,6 +962,8 @@ public async Task GetOwnCompanyIdentityProviderAsync_WithAliasNull_ThrowsNotFoun _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) @@ -874,6 +987,8 @@ public async Task GetOwnCompanyIdentityProviderAsync_WithOidcWithoutExistingKeyc _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) @@ -900,6 +1015,8 @@ public async Task GetOwnCompanyIdentityProviderAsync_WithValidOidc_CallsExpected _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) @@ -928,6 +1045,8 @@ public async Task GetOwnCompanyIdentityProviderAsync_WithSamlWithoutExistingKeyc _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) @@ -954,6 +1073,8 @@ public async Task GetOwnCompanyIdentityProviderAsync_WithValidSaml_CallsExpected _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) @@ -986,10 +1107,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithDifferentCompany_ _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?, bool, string))default); // Act async Task Act() => await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); @@ -1010,10 +1133,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithDifferentCompany_ _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((false, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((false, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); @@ -1034,10 +1159,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithNoOtherEnabledIdp _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) }, false, string.Empty)); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).Returns(false); // Act @@ -1060,10 +1187,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithNoOtherCompany_Ca _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-oidc").Create()); A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) @@ -1090,10 +1219,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidOidc_CallsEx _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) }, false, string.Empty)); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).Returns(true); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-oidc").Create()); @@ -1122,10 +1253,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidSaml_CallsEx _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) }, false, string.Empty)); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).Returns(true); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataSAMLAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-saml").Create()); @@ -1152,10 +1285,12 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidShared_Calls _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) }, false, string.Empty)); A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).Returns(true); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-oidc").Create()); @@ -1173,6 +1308,41 @@ public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidShared_Calls result.enabled.Should().BeTrue(); } + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_DeactivateManaged_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _errorMessageService, + _roleBaseMailService, + _mailingService, + _options, + _logger); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.MANAGED, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) }, true, string.Empty)); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).Returns(true); + A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("cl1")) + .Returns(_fixture.Build().With(x => x.Enabled, false).With(x => x.DisplayName, "dis-oidc").Create()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + // Act + var result = await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.SetCentralIdentityProviderStatusAsync("cl1", false)) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _roleBaseMailService.RoleBaseSendMailForIdp(A>._, A>._, A<(string ParameterName, string ParameterValue)>._, A>.That.Matches(x => x.Count() == 1 && x.Single() == "DeactivateManagedIdp"), identityProviderId)) + .MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(3); + result.displayName.Should().Be("dis-oidc"); + result.enabled.Should().BeFalse(); + } + #endregion #region UpdateOwnCompanyIdentityProviderAsync @@ -1193,10 +1363,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_WithInvalidDisplayName_T _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?, bool, string))default); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1219,10 +1391,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_WithNotExistingIdp_Throw _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?, bool, string))default); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1245,10 +1419,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_NotOwner_ThrowsForbidden _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((false, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((false, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1272,10 +1448,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_ForOidcWithOidcNull_Thro _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1300,10 +1478,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_ForOidcWithSamlNotNull_T _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1328,10 +1508,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_WithValidOidc_CallsExpec _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-oidc").Create()); A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) @@ -1362,10 +1544,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_ForSamlWithSamlNull_Thro _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1390,10 +1574,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_ForSamlWithOidcNotNull_T _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1418,10 +1604,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_WithValidSaml_CallsExpec _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataSAMLAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-saml").Create()); A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) @@ -1452,10 +1640,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_ForSharedWithOidcNotNull _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1480,10 +1670,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_ForSharedWithSamlNotNull _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); // Act async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); @@ -1508,10 +1700,12 @@ public async Task UpdateOwnCompanyIdentityProviderAsync_WithValidShared_CallsExp _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) - .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>())); + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>(), false, string.Empty)); A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("cl1")) .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-shared").Create()); A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) @@ -1546,6 +1740,8 @@ public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUs _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1573,6 +1769,8 @@ public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUs _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1602,6 +1800,8 @@ public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutAlias _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1629,6 +1829,8 @@ public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutSameC _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1657,6 +1859,8 @@ public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithKeycloak _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1689,6 +1893,8 @@ public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithValid_Ca _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1722,6 +1928,8 @@ public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_With _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1749,6 +1957,8 @@ public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_With _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1778,6 +1988,8 @@ public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_With _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1805,6 +2017,8 @@ public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_With _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1833,6 +2047,8 @@ public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_With _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1866,6 +2082,8 @@ public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserI _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1890,6 +2108,8 @@ public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserI _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1916,6 +2136,8 @@ public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutAlias_Th _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1940,6 +2162,8 @@ public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutSameComp _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1965,6 +2189,8 @@ public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutExisting _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -1997,6 +2223,8 @@ public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithValid_Calls _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -2029,6 +2257,8 @@ public async Task DeleteOwnCompanyUserIdentityProviderDataAsync_WithKeycloakErro _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -2058,6 +2288,8 @@ public async Task DeleteOwnCompanyUserIdentityProviderDataAsync_WithValid_CallsE _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -2089,6 +2321,8 @@ public async Task GetOwnCompanyUsersIdentityProviderDataAsync_WithoutIdentityPro _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, _identity.CompanyId)) @@ -2112,6 +2346,8 @@ public async Task GetOwnCompanyUsersIdentityProviderDataAsync_WithoutMatchingIdp _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasDataUntracked(_identity.CompanyId, A>._)) @@ -2139,6 +2375,8 @@ public async Task GetOwnIdentityProviderWithConnectedCompanies_WithDifferentComp _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, _companyId)) @@ -2162,6 +2400,8 @@ public async Task GetOwnIdentityProviderWithConnectedCompanies_WithAliasNull_Thr _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, _companyId)) @@ -2185,6 +2425,8 @@ public async Task GetOwnIdentityProviderWithConnectedCompanies_WithOidcWithoutEx _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, _companyId)) @@ -2212,6 +2454,8 @@ public async Task GetOwnIdentityProviderWithConnectedCompanies_WithValidOidc_Cal _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, _companyId)) @@ -2242,6 +2486,8 @@ public async Task GetOwnIdentityProviderWithConnectedCompanies_WithSamlWithoutEx _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, _companyId)) @@ -2270,6 +2516,8 @@ public async Task GetOwnIdentityProviderWithConnectedCompanies_WithValidSaml_Cal _provisioningManager, _identityService, _errorMessageService, + _roleBaseMailService, + _mailingService, _options, _logger); A.CallTo(() => _identityProviderRepository.GetOwnIdentityProviderWithConnectedCompanies(identityProviderId, _companyId)) diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index 7ee6ac3633..f4752831e8 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -461,16 +461,10 @@ public async Task DeclineRegistrationVerification_WithDecline_StateAndCommentSet { // Arrange const string comment = "application rejected because of reasons."; - var processSteps = new List(); var entry = new ApplicationChecklistEntry(IdWithBpn, ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION, checklistStatusId, DateTimeOffset.UtcNow); var company = new Company(CompanyId, null!, CompanyStatusId.PENDING, DateTimeOffset.UtcNow); var application = new CompanyApplication(ApplicationId, company.Id, CompanyApplicationStatusId.SUBMITTED, CompanyApplicationTypeId.INTERNAL, DateTimeOffset.UtcNow); SetupForDeclineRegistrationVerification(entry, application, company, checklistStatusId, idpTypeId); - A.CallTo(() => _processStepRepository.CreateProcessStepRange(A>._)) - .Invokes((IEnumerable<(ProcessStepTypeId ProcessStepTypeId, ProcessStepStatusId ProcessStepStatusId, Guid ProcessId)> processStepData) => - { - processSteps.AddRange(processStepData.Select(x => new ProcessStep(Guid.NewGuid(), x.ProcessStepTypeId, x.ProcessStepStatusId, x.ProcessId, DateTimeOffset.UtcNow))); - }); // Act await _logic.DeclineRegistrationVerification(IdWithBpn, comment, CancellationToken.None).ConfigureAwait(false); @@ -485,14 +479,14 @@ public async Task DeclineRegistrationVerification_WithDecline_StateAndCommentSet A._, A>.That.Matches(x => x.Single() == ProcessStepTypeId.VERIFY_REGISTRATION))) .MustHaveHappenedOnceExactly(); - processSteps.Should().ContainSingle().Which.Should().Match(x => - x.ProcessStepStatusId == ProcessStepStatusId.TODO && - x.ProcessStepTypeId == ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED); + A.CallTo(() => _processStepRepository.CreateProcessStep(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepStatusId.TODO, A._)) + .MustHaveHappenedOnceExactly(); if (idpTypeId == IdentityProviderTypeId.SHARED) { A.CallTo(() => _provisioningManager.DeleteSharedIdpRealmAsync(IamAliasId)) .MustHaveHappenedOnceExactly(); } + A.CallTo(() => _provisioningManager.DeleteCentralIdentityProviderAsync(IamAliasId)) .MustHaveHappenedOnceExactly(); A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync("user123")) @@ -505,7 +499,7 @@ public async Task DeclineRegistrationVerification_WithApplicationNotFound_Throws // Arrange var applicationId = Guid.NewGuid(); A.CallTo(() => _applicationRepository.GetCompanyIdNameForSubmittedApplication(applicationId)) - .Returns(default((Guid, string, Guid?, IEnumerable<(Guid, string, IdentityProviderTypeId)>, IEnumerable))); + .Returns(default((Guid, string, Guid?, IEnumerable<(Guid, string, IdentityProviderTypeId, IEnumerable)>, IEnumerable))); async Task Act() => await _logic.DeclineRegistrationVerification(applicationId, "test", CancellationToken.None).ConfigureAwait(false); // Act @@ -525,6 +519,9 @@ public async Task DeclineRegistrationVerification_WithMultipleIdps_CallsExpected var sharedIdpId = Guid.NewGuid(); var managedIdpId = Guid.NewGuid(); var ownIdpId = Guid.NewGuid(); + var user1 = Guid.NewGuid(); + var user2 = Guid.NewGuid(); + var user3 = Guid.NewGuid(); A.CallTo(() => _applicationRepository.GetCompanyIdNameForSubmittedApplication(applicationId)) .Returns(( @@ -533,11 +530,16 @@ public async Task DeclineRegistrationVerification_WithMultipleIdps_CallsExpected null, new[] { - (sharedIdpId, "idp1", IdentityProviderTypeId.SHARED), - (managedIdpId, "idp2", IdentityProviderTypeId.MANAGED), - (ownIdpId, "idp3", IdentityProviderTypeId.OWN), + (sharedIdpId, "idp1", IdentityProviderTypeId.SHARED, new[] { user1 }.AsEnumerable()), + (managedIdpId, "idp2", IdentityProviderTypeId.MANAGED, new[] { user2 }.AsEnumerable()), + (ownIdpId, "idp3", IdentityProviderTypeId.OWN, new[] { user3 }.AsEnumerable()), }, - Enumerable.Empty())); + new[] + { + user1, + user2, + user3 + })); // Act await _logic.DeclineRegistrationVerification(applicationId, "test", CancellationToken.None).ConfigureAwait(false); @@ -560,6 +562,10 @@ public async Task DeclineRegistrationVerification_WithMultipleIdps_CallsExpected A.CallTo(() => _identityProviderRepository.DeleteIdentityProvider(ownIdpId)).MustHaveHappenedOnceExactly(); A.CallTo(() => _provisioningManager.DeleteSharedIdpRealmAsync("idp3")).MustNotHaveHappened(); A.CallTo(() => _provisioningManager.DeleteCentralIdentityProviderAsync("idp3")).MustHaveHappenedOnceExactly(); + + A.CallTo(() => _userRepository.RemoveCompanyUserAssignedIdentityProviders(A>>.That.IsSameSequenceAs(new[] { new ValueTuple(user1, sharedIdpId) }))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _userRepository.RemoveCompanyUserAssignedIdentityProviders(A>>.That.IsSameSequenceAs(new[] { new ValueTuple(user2, managedIdpId) }))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _userRepository.RemoveCompanyUserAssignedIdentityProviders(A>>.That.IsSameSequenceAs(new[] { new ValueTuple(user3, ownIdpId) }))).MustHaveHappenedOnceExactly(); } #endregion @@ -911,7 +917,7 @@ private void SetupForDeclineRegistrationVerification(ApplicationChecklistEntry a }.ToImmutableDictionary(), Enumerable.Empty())); A.CallTo(() => _applicationRepository.GetCompanyIdNameForSubmittedApplication(IdWithBpn)) - .Returns((CompanyId, CompanyName, ExistingExternalId, Enumerable.Repeat((IdpId, IamAliasId, idpTypeId), 1), Enumerable.Repeat(UserId, 1))); + .Returns((CompanyId, CompanyName, ExistingExternalId, Enumerable.Repeat((IdpId, IamAliasId, idpTypeId, Enumerable.Repeat(UserId, 1)), 1), Enumerable.Repeat(UserId, 1))); A.CallTo(() => _provisioningManager.GetUserByUserName(UserId.ToString())) .Returns("user123"); diff --git a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json index 2803a51a66..1ac30245e6 100644 --- a/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json +++ b/tests/administration/Administration.Service.Tests/appsettings.IntegrationTests.json @@ -401,7 +401,19 @@ "HeaderProviderAlias": "test", "HeaderProviderUserId": "test", "HeaderProviderUserName": "test" - } + }, + "DeactivateIdpRoles": [ + { + "ClientId": "test", + "UserRoleNames": ["Company Admin"] + } + ], + "DeleteIdpRoles": [ + { + "ClientId": "test", + "UserRoleNames": ["Company Admin"] + } + ] }, "Document": { "FrameDocumentTypeIds": [ diff --git a/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs b/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs index 9a53836b82..686ced3d08 100644 --- a/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs +++ b/tests/mailing/Mailing.Service.Tests/RoleBaseMailServiceTests.cs @@ -29,12 +29,15 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Mailing.Service.Tests; public class RoleBaseMailServiceTests { private const string BasePortalUrl = "http//base-url.com"; + private readonly Guid _companyId = Guid.NewGuid(); + private readonly Guid _idpId = Guid.NewGuid(); + private readonly IFixture _fixture; private readonly IPortalRepositories _portalRepositories; private readonly IMailingService _mailingService; + private readonly IIdentityProviderRepository _identityProviderRepository; private readonly IUserRolesRepository _userRolesRepository; private readonly IUserRepository _userRepository; - private readonly Guid _companyId; private readonly IEnumerable _userRoleIds; private readonly RoleBaseMailService _sut; @@ -47,9 +50,9 @@ public RoleBaseMailServiceTests() _portalRepositories = A.Fake(); _mailingService = A.Fake(); + _identityProviderRepository = A.Fake(); _userRolesRepository = A.Fake(); _userRepository = A.Fake(); - _companyId = _fixture.Create(); _userRoleIds = _fixture.CreateMany(2); SetupRepositories(); @@ -57,10 +60,12 @@ public RoleBaseMailServiceTests() _sut = new RoleBaseMailService(_portalRepositories, _mailingService); } + #region RoleBaseSendMailForCompany + [Theory] [InlineData(true)] [InlineData(false)] - public async Task RoleBaseSendMail_WithUserNameParameter_ReturnsExpectedCalls(bool hasUserNameParameter) + public async Task RoleBaseSendMailForCompany_WithUserNameParameter_ReturnsExpectedCalls(bool hasUserNameParameter) { // Arrange var template = new[] { "test-request" }; @@ -89,7 +94,7 @@ public async Task RoleBaseSendMail_WithUserNameParameter_ReturnsExpectedCalls(bo .Returns(companyUserData.ToAsyncEnumerable()); // Act - await _sut.RoleBaseSendMail(receiverRoles, mailParams, userNameParam, template, _companyId); + await _sut.RoleBaseSendMailForCompany(receiverRoles, mailParams, userNameParam, template, _companyId); // Assert A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.Matches(x => x.Any(y => y.ClientId == "ClientId")))).MustHaveHappenedOnceExactly(); @@ -105,7 +110,7 @@ public async Task RoleBaseSendMail_WithUserNameParameter_ReturnsExpectedCalls(bo } [Fact] - public async Task RoleBaseSendMail_ThrowsConfigurationException() + public async Task RoleBaseSendMailForCompany_ThrowsConfigurationException() { // Arrange var template = new List { "test-request" }; @@ -125,7 +130,7 @@ public async Task RoleBaseSendMail_ThrowsConfigurationException() .Returns(roleData.ToAsyncEnumerable()); // Act - async Task Action() => await _sut.RoleBaseSendMail(receiverRoles, mailParams, userNameParam, template, _companyId); + async Task Action() => await _sut.RoleBaseSendMailForCompany(receiverRoles, mailParams, userNameParam, template, _companyId); // Assert var ex = await Assert.ThrowsAsync(Action); @@ -136,10 +141,92 @@ public async Task RoleBaseSendMail_ThrowsConfigurationException() A.CallTo(() => _mailingService.SendMails(A._, A>._, A>._)).MustNotHaveHappened(); } + #endregion + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task RoleBaseSendMailForIdp_WithUserNameParameter_ReturnsExpectedCalls(bool hasUserNameParameter) + { + // Arrange + var template = new[] { "test-request" }; + var idpAlias = _fixture.Create(); + var ownerCompanyName = _fixture.Create(); + var mailParams = new[] + { + ("idpAlias", idpAlias), + ("ownerCompanyName", ownerCompanyName) + }; + var userNameParam = hasUserNameParameter + ? ("username", "user") + : ((string, string)?)null; + var receiverRoles = new[] + { + new UserRoleConfig("ClientId", new[] { "IT Admin", "Company Admin" }) + }; + var companyUserData = new (string, string?, string?)[] + { + ("TestIt@bmw", "ItFirst", "ItLast"), + ("TestCompany@bmw", "CompanyFirst", "CompanyLast") + }; + + A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>._)) + .Returns(_userRoleIds.ToAsyncEnumerable()); + A.CallTo(() => _identityProviderRepository.GetCompanyUserEmailForIdpWithoutOwnerAndRoleId(A>._, _idpId)) + .Returns(companyUserData.ToAsyncEnumerable()); + + // Act + await _sut.RoleBaseSendMailForIdp(receiverRoles, mailParams, userNameParam, template, _idpId); + + // Assert + A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.Matches(x => x.Any(y => y.ClientId == "ClientId")))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.GetCompanyUserEmailForIdpWithoutOwnerAndRoleId(A>.That.IsSameSequenceAs(_userRoleIds), _idpId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _mailingService.SendMails( + "TestIt@bmw", + A>.That.Matches(x => x.Count() == (hasUserNameParameter ? 3 : 2) && x["idpAlias"] == idpAlias && x["ownerCompanyName"] == ownerCompanyName && (!hasUserNameParameter || x["username"] == "ItFirst ItLast")), + A>.That.IsSameSequenceAs(template))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _mailingService.SendMails( + "TestCompany@bmw", + A>.That.Matches(x => x.Count() == (hasUserNameParameter ? 3 : 2) && x["idpAlias"] == idpAlias && x["ownerCompanyName"] == ownerCompanyName && (!hasUserNameParameter || x["username"] == "CompanyFirst CompanyLast")), + A>.That.IsSameSequenceAs(template))).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task RoleBaseSendMailForIdp_ThrowsConfigurationException() + { + // Arrange + var template = new List { "test-request" }; + var mailParams = new[] + { + ("idpAlias", _fixture.Create()), + ("ownerCompanyName", "test") + }; + var userNameParam = ("username", "user"); + + var roleData = _fixture.CreateMany(1); + var receiverRoles = new[]{ + new UserRoleConfig("ClientId", new [] { "IT Admin", "Company Admin" }) + }; + + A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>._)) + .Returns(roleData.ToAsyncEnumerable()); + + // Act + async Task Action() => await _sut.RoleBaseSendMailForIdp(receiverRoles, mailParams, userNameParam, template, _idpId); + + // Assert + var ex = await Assert.ThrowsAsync(Action); + ex.Message.Should().Be($"invalid configuration, at least one of the configured roles does not exist in the database: {string.Join(", ", receiverRoles.Select(clientRoles => $"client: {clientRoles.ClientId}, roles: [{string.Join(", ", clientRoles.UserRoleNames)}]"))}"); + A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(receiverRoles))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _identityProviderRepository.GetCompanyUserEmailForIdpWithoutOwnerAndRoleId(A>.That.IsSameSequenceAs(roleData), _idpId)).MustNotHaveHappened(); + A.CallTo(() => _mailingService.SendMails(A._, A>._, A>._)).MustNotHaveHappened(); + } + #region Setup private void SetupRepositories() { + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_identityProviderRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_userRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_userRolesRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_mailingService); diff --git a/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs b/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs index 50e5a580f3..f4151298f5 100644 --- a/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs +++ b/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs @@ -885,7 +885,7 @@ public async Task ApproveOfferRequestAsync_ExecutesSuccessfully(bool isSingleIns A.CallTo(() => _offerSetupService.ActivateSingleInstanceAppAsync(offer.Id)) .MustNotHaveHappened(); } - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A.CallTo(() => _roleBaseMailService.RoleBaseSendMailForCompany( A>.That.IsSameSequenceAs(recipients), A>.That.IsSameSequenceAs(mailParameters), userNameParameter, @@ -1221,7 +1221,7 @@ public async Task DeclineOfferAsync_WithValidData_CallsExpected(OfferTypeId offe A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); A.CallTo(() => _notificationService.CreateNotifications(A>._, A._, A>._, A._, A._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _createNotificationsEnumerator.MoveNextAsync()).MustHaveHappened(2, Times.Exactly); - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A.CallTo(() => _roleBaseMailService.RoleBaseSendMailForCompany( A>.That.IsSameSequenceAs(recipients), A>.That.IsSameSequenceAs(mailParameters), userNameParameter, diff --git a/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs b/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs index f4fc499a10..37e256cb62 100644 --- a/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs +++ b/tests/marketplace/Offers.Library.Tests/Service/OfferSubscriptionServiceTests.cs @@ -166,7 +166,7 @@ public async Task AddOfferSubscription_WithExistingId_CreatesServiceSubscription A.CallTo(() => _offerSubscriptionsRepository.CheckPendingOrActiveSubscriptionExists(_existingOfferId, _companyId, offerTypeId)).MustHaveHappenedOnceExactly(); } A.CallTo(() => _processStepRepository.CreateProcessStepRange(A>.That.Matches(x => x.Count() == 1 && x.Single().ProcessStepTypeId == ProcessStepTypeId.TRIGGER_PROVIDER))).MustHaveHappenedOnceExactly(); - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A.CallTo(() => _roleBaseMailService.RoleBaseSendMailForCompany( A>.That.IsSameSequenceAs(subscriptionManagerRoles), A>.That.IsSameSequenceAs(mailParameters), userParameter, @@ -223,7 +223,7 @@ public async Task AddOfferSubscription_WithSalesManagerEqualsReceiver_CreatesSer // Assert companyAssignedApps.Should().HaveCount(1); - A.CallTo(() => _roleBaseMailService.RoleBaseSendMail( + A.CallTo(() => _roleBaseMailService.RoleBaseSendMailForCompany( A>.That.IsSameSequenceAs(subscriptionManagerRoles), A>.That.IsSameSequenceAs(mailParameters), userParameter, diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs index e576f6e30b..ad32873b87 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs @@ -118,13 +118,13 @@ public async Task GetOwnCompanyIdentityProviderAliasUntrackedAsync_WithValid_Ret #region GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync [Theory] - [InlineData("38f56465-ce26-4f25-9745-1791620dc198", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", true, "Idp-123", true, new[] { "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "0dcd8209-85e2-4073-b130-ac094fb47106" })] - [InlineData("38f56465-ce26-4f25-9745-1791620dc198", "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", true, "Idp-123", false, new[] { "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "0dcd8209-85e2-4073-b130-ac094fb47106" })] - [InlineData("38f56465-ce26-4f25-9745-1791620dc199", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", true, "Test-Alias", false, new[] { "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88" })] - [InlineData("38f56465-ce26-4f25-9745-1791620dc199", "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", true, "Test-Alias", true, new[] { "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88" })] - [InlineData("38f56465-ce26-4f25-9745-1791620dc200", "41fd2ab8-71cd-4546-9bef-a388d91b2542", true, "Test-Alias2", false, new[] { "41fd2ab8-71cd-4546-9bef-a388d91b2542", "41fd2ab8-7123-4546-9bef-a388d91b2999", "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "0dcd8209-85e2-4073-b130-ac094fb47106", "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88" })] - [InlineData("38f56465-ce26-4f25-9745-1791620dc200", "41fd2ab8-71cd-4546-9bef-a388d91b2542", false, "Test-Alias2", false, null)] - public async Task GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync_WithValidOwner_ReturnsExpected(Guid identityProviderId, Guid companyId, bool query, string alias, bool isOwner, IEnumerable? companyIds) + [InlineData("38f56465-ce26-4f25-9745-1791620dc198", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", true, "Idp-123", true, true, "Bayerische Motorenwerke AG", new[] { "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "0dcd8209-85e2-4073-b130-ac094fb47106" })] + [InlineData("38f56465-ce26-4f25-9745-1791620dc198", "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", true, "Idp-123", false, true, "Bayerische Motorenwerke AG", new[] { "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "0dcd8209-85e2-4073-b130-ac094fb47106" })] + [InlineData("38f56465-ce26-4f25-9745-1791620dc199", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", true, "Test-Alias", false, false, "CX-Test-Access", new[] { "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88" })] + [InlineData("38f56465-ce26-4f25-9745-1791620dc199", "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", true, "Test-Alias", true, false, "CX-Test-Access", new[] { "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88" })] + [InlineData("38f56465-ce26-4f25-9745-1791620dc200", "41fd2ab8-71cd-4546-9bef-a388d91b2542", true, "Test-Alias2", false, false, "Catena-X", new[] { "41fd2ab8-71cd-4546-9bef-a388d91b2542", "41fd2ab8-7123-4546-9bef-a388d91b2999", "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "0dcd8209-85e2-4073-b130-ac094fb47106", "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88" })] + [InlineData("38f56465-ce26-4f25-9745-1791620dc200", "41fd2ab8-71cd-4546-9bef-a388d91b2542", false, "Test-Alias2", false, false, "Catena-X", null)] + public async Task GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync_WithValidOwner_ReturnsExpected(Guid identityProviderId, Guid companyId, bool query, string alias, bool isOwner, bool companyUsersLinked, string ownerCompanyName, IEnumerable? companyIds) { var sut = await CreateSut().ConfigureAwait(false); @@ -133,6 +133,8 @@ public async Task GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync_WithVali // Assert result.Alias.Should().Be(alias); result.IsOwner.Should().Be(isOwner); + result.CompanyUsersLinked.Should().Be(companyUsersLinked); + result.IdpOwnerName.Should().Be(ownerCompanyName); if (query) { companyIds.Should().NotBeNull(); From 805a42262efbe1f92e62ea7c521374db84374114 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Mon, 22 Jan 2024 19:16:03 +0100 Subject: [PATCH 05/10] feat(osp): add decline endpoint for customer (#384) * add new endpoint to decline a company application which was created by an osp * feat(osp): add manual decline step * add extension method to skip steps except given types Refs: CPLP-3497 --------- Co-authored-by: Norbert Truchsess --- .../IdentityProviderBusinessLogic.cs | 2 +- .../BusinessLogic/NetworkBusinessLogic.cs | 6 +- .../RegistrationBusinessLogic.cs | 29 +- .../Repositories/IInvitationRepository.cs | 1 + .../Repositories/INetworkRepository.cs | 10 + .../Repositories/IUserRepository.cs | 3 +- .../Repositories/InvitationRepository.cs | 13 + .../Repositories/NetworkRepository.cs | 54 + .../Repositories/UserRepository.cs | 32 +- .../20240122180453_1.8.0-rc3.Designer.cs | 8867 +++++++++++++++++ .../Migrations/20240122180453_1.8.0-rc3.cs | 80 + .../PortalDbContextModelSnapshot.cs | 23 +- .../Enums/CompanyApplicationStatusId.cs | 6 +- .../Enums/ProcessStepStatusId.cs | 2 +- .../Enums/ProcessStepTypeId.cs | 3 + .../NetworkRegistrationExtensisons.cs | 1 + .../NetworkRegistrationProcessTypeExecutor.cs | 5 +- .../INetworkRegistrationHandler.cs | 1 + .../NetworkRegistrationHandler.cs | 45 + .../NetworkRegistrationProcessHelper.cs | 1 + .../ManualProcessStepDataExtensions.cs | 17 +- .../BusinessLogic/INetworkBusinessLogic.cs | 1 + .../BusinessLogic/NetworkBusinessLogic.cs | 57 +- .../Controllers/NetworkController.cs | 21 +- .../Model/CompanyRoleAgreementData.cs | 1 - .../Model/DeclineOspData.cs | 26 + .../Model/OspDeclineReason.cs | 28 + .../Registration.Service.csproj | 1 + .../IdentityProviderBusinessLogicTests.cs | 7 +- .../NetworkBusinessLogicTests.cs | 26 +- .../RegistrationBusinessLogicTest.cs | 6 +- .../NetworkRegistrationExtensisonsTests.cs | 1 + ...orkRegistrationProcessTypeExecutorTests.cs | 37 +- .../NetworkRegistrationHandlerTests.cs | 179 +- .../ManualProcessDataExtensionsTests.cs | 104 +- .../NetworkBusinessLogicTests.cs | 199 +- 36 files changed, 9815 insertions(+), 80 deletions(-) create mode 100644 src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.Designer.cs create mode 100644 src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.cs create mode 100644 src/registration/Registration.Service/Model/DeclineOspData.cs create mode 100644 src/registration/Registration.Service/Model/OspDeclineReason.cs diff --git a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs index 795b86798d..4c1d72a10a 100644 --- a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs @@ -411,7 +411,7 @@ private async Task DeleteManagedIdpLinks(Guid identityProviderId, string? alias, companyRepository.AttachAndModifyCompany(data.CompanyId, c => { c.CompanyStatusId = data.CompanyStatusId; }, c => { c.CompanyStatusId = CompanyStatusId.INACTIVE; }); - userRepository.AttachAndModifyIdentities(data.Identities.Select(x => new ValueTuple>(x.IdentityId, identity => { identity.UserStatusId = UserStatusId.INACTIVE; }))); + userRepository.AttachAndModifyIdentities(data.Identities.Select(x => new ValueTuple?, Action>(x.IdentityId, null, identity => { identity.UserStatusId = UserStatusId.INACTIVE; }))); userRolesRepository.DeleteCompanyUserAssignedRoles(data.Identities.SelectMany(i => i.UserRoleIds.Select(ur => new ValueTuple(i.IdentityId, ur)))); await DeleteKeycloakUsers(data.Identities.Select(i => i.IdentityId)); } diff --git a/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs index 241010065d..1f3bc23156 100644 --- a/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/NetworkBusinessLogic.cs @@ -76,7 +76,11 @@ public async Task HandlePartnerRegistration(PartnerRegistrationData data) }).Id; var processId = processStepRepository.CreateProcess(ProcessTypeId.PARTNER_REGISTRATION).Id; - processStepRepository.CreateProcessStep(ProcessStepTypeId.SYNCHRONIZE_USER, ProcessStepStatusId.TODO, processId); + processStepRepository.CreateProcessStepRange(new[] + { + (ProcessStepTypeId.SYNCHRONIZE_USER, ProcessStepStatusId.TODO, processId), + (ProcessStepTypeId.MANUAL_DECLINE_OSP, ProcessStepStatusId.TODO, processId) + }); networkRepository.CreateNetworkRegistration(data.ExternalId, companyId, processId, ownerCompanyId, applicationId); diff --git a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs index 9dd6e36b36..127a01af8d 100644 --- a/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/RegistrationBusinessLogic.cs @@ -432,7 +432,7 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com throw new ArgumentException($"CompanyApplication {applicationId} is not in status SUBMITTED", nameof(applicationId)); } - var (companyId, companyName, processId, idps, companyUserIds) = result; + var (companyId, companyName, networkRegistrationProcessId, idps, companyUserIds) = result; var context = await _checklistService .VerifyChecklistEntryAndProcessSteps( @@ -446,16 +446,6 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com _checklistService.SkipProcessSteps(context, new[] { ProcessStepTypeId.VERIFY_REGISTRATION }); - _checklistService.FinalizeChecklistEntryAndProcessSteps( - context, - null, - entry => - { - entry.ApplicationChecklistEntryStatusId = ApplicationChecklistEntryStatusId.FAILED; - entry.Comment = comment; - }, - null); - var identityProviderRepository = _portalRepositories.GetInstance(); var userRepository = _portalRepositories.GetInstance(); foreach (var (idpId, idpAlias, idpType, linkedUserIds) in idps) @@ -493,12 +483,19 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com await _provisioningManager.DeleteCentralRealmUserAsync(iamUserId).ConfigureAwait(false); } } + userRepository.AttachAndModifyIdentities(companyUserIds.Select(userId => new ValueTuple?, Action>(userId, null, identity => { identity.UserStatusId = UserStatusId.DELETED; }))); - userRepository.AttachAndModifyIdentities(companyUserIds.Select(userId => new ValueTuple>(userId, identity => { identity.UserStatusId = UserStatusId.DELETED; }))); - if (processId != null) - { - _portalRepositories.GetInstance().CreateProcessStep(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepStatusId.TODO, processId.Value); - } + _checklistService.FinalizeChecklistEntryAndProcessSteps( + context, + null, + entry => + { + entry.ApplicationChecklistEntryStatusId = ApplicationChecklistEntryStatusId.FAILED; + entry.Comment = comment; + }, + networkRegistrationProcessId == null + ? null + : new[] { ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED }); await _portalRepositories.SaveAsync().ConfigureAwait(false); await PostRegistrationCancelEmailAsync(applicationId, companyName, comment).ConfigureAwait(false); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IInvitationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IInvitationRepository.cs index e453fb1e5f..ac4592883c 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IInvitationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IInvitationRepository.cs @@ -26,4 +26,5 @@ public interface IInvitationRepository { public IAsyncEnumerable<(InvitationStatusId InvitationStatus, string? EmailId, IEnumerable Roles)> GetInvitedUserDetailsUntrackedAsync(Guid applicationId); Task GetInvitationStatusAsync(Guid companyUserId); + void AttachAndModifyInvitations(IEnumerable<(Guid InvitationId, Action? Initialize, Action Modify)> invitations); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/INetworkRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/INetworkRepository.cs index d2b3ce3841..15abf3656b 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/INetworkRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/INetworkRepository.cs @@ -32,4 +32,14 @@ public interface INetworkRepository Task<(bool Exists, IEnumerable<(Guid CompanyApplicationId, CompanyApplicationStatusId CompanyApplicationStatusId, string? CallbackUrl)> CompanyApplications, IEnumerable<(CompanyRoleId CompanyRoleId, IEnumerable AgreementIds)> CompanyRoleAgreementIds, Guid? ProcessId)> GetSubmitData(Guid companyId); Task<(OspDetails? OspDetails, string ExternalId, string? Bpn, Guid ApplicationId, IEnumerable Comments)> GetCallbackData(Guid networkRegistrationId, ProcessStepTypeId processStepTypeId); Task GetOspCompanyName(Guid networkRegistrationId); + Task<( + bool Exists, + bool IsValidTypeId, + bool IsValidStatusId, + bool IsValidCompany, + ( + (CompanyStatusId CompanyStatusId, IEnumerable<(Guid IdentityId, UserStatusId UserStatus)> Identities) CompanyData, + IEnumerable<(Guid InvitationId, InvitationStatusId StatusId)> InvitationData, + VerifyProcessData ProcessData + )? Data)> GetDeclineDataForApplicationId(Guid applicationId, CompanyApplicationTypeId validTypeId, IEnumerable validStatusIds, Guid companyId); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs index 15bd7abdb9..29190381e5 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IUserRepository.cs @@ -120,8 +120,9 @@ public interface IUserRepository Task GetCompanyBpnForIamUserAsync(Guid companyUserId); Identity AttachAndModifyIdentity(Guid identityId, Action? initialize, Action modify); + void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action? Initialize, Action Modify)> identities); CompanyUserAssignedIdentityProvider AddCompanyUserAssignedIdentityProvider(Guid companyUserId, Guid identityProviderId, string providerId, string userName); void RemoveCompanyUserAssignedIdentityProviders(IEnumerable<(Guid CompanyUserId, Guid IdentityProviderId)> companyUserIdentityProviderIds); IAsyncEnumerable GetUserAssignedIdentityProviderForNetworkRegistration(Guid networkRegistrationId); - void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action Modify)> identityData); + IAsyncEnumerable GetNextIdentitiesForNetworkRegistration(Guid networkRegistrationId, IEnumerable validUserStates); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs index 34e9622895..85cb7ecad7 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs @@ -48,4 +48,17 @@ public InvitationRepository(PortalDbContext dbContext) _dbContext.Invitations .Where(invitation => invitation.CompanyUserId == companyUserId) .SingleOrDefaultAsync(); + + public void AttachAndModifyInvitations(IEnumerable<(Guid InvitationId, Action? Initialize, Action Modify)> invitations) + { + var initial = invitations.Select(x => + { + var invitation = new Invitation(x.InvitationId, Guid.Empty, Guid.Empty, default, default); + x.Initialize?.Invoke(invitation); + return (Invitation: invitation, modify: x.Modify); + } + ).ToList(); + _dbContext.AttachRange(initial.Select(x => x.Invitation)); + initial.ForEach(x => x.modify(x.Invitation)); + } } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs index 1d184d02ee..26c426d8cd 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/NetworkRepository.cs @@ -111,4 +111,58 @@ public Task GetNetworkRegistrationDataForProcessIdAsync(Guid processId) => _context.NetworkRegistrations.Where(x => x.Id == networkRegistrationId) .Select(x => x.OnboardingServiceProvider!.Name) .SingleOrDefaultAsync(); + + public Task<( + bool Exists, + bool IsValidTypeId, + bool IsValidStatusId, + bool IsValidCompany, + ( + (CompanyStatusId CompanyStatusId, IEnumerable<(Guid IdentityId, UserStatusId UserStatus)> Identities) CompanyData, + IEnumerable<(Guid InvitationId, InvitationStatusId StatusId)> InvitationData, + VerifyProcessData ProcessData + )? Data)> GetDeclineDataForApplicationId(Guid applicationId, CompanyApplicationTypeId validTypeId, IEnumerable validStatusIds, Guid companyId) => + _context.NetworkRegistrations + .AsSplitQuery() + .Where(registration => registration.CompanyApplication!.Id == applicationId) + .Select(registration => new + { + IsValidType = validTypeId == registration.CompanyApplication!.CompanyApplicationTypeId, + IsValidStatus = validStatusIds.Contains(registration.CompanyApplication.ApplicationStatusId), + IsValidCompany = registration.CompanyId == companyId, + Invitations = registration.CompanyApplication.Invitations, + Company = registration.Company, + Process = registration.Process + }) + .Select(x => new ValueTuple< + bool, + bool, + bool, + bool, + ValueTuple< + ValueTuple>>, + IEnumerable>, + VerifyProcessData + >?>( + true, + x.IsValidType, + x.IsValidStatus, + x.IsValidCompany, + x.IsValidType && x.IsValidStatus && x.IsValidCompany + ? new ValueTuple< + ValueTuple>>, + IEnumerable>, + VerifyProcessData>( + new ValueTuple>>( + x.Company!.CompanyStatusId, + x.Company.Identities.Select(i => new ValueTuple(i.Id, i.UserStatusId))), + x.Invitations.Select(i => new ValueTuple( + i.Id, + i.InvitationStatusId)), + new VerifyProcessData( + x.Process, + x.Process!.ProcessSteps.Where(ps => ps.ProcessStepStatusId == ProcessStepStatusId.TODO))) + : null + )) + .SingleOrDefaultAsync(); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs index 8133ef8a8a..fb815f6983 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs @@ -426,6 +426,19 @@ public Identity AttachAndModifyIdentity(Guid identityId, Action? initi return updatedEntity; } + public void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action? Initialize, Action Modify)> identities) + { + var initial = identities.Select(x => + { + var identity = new Identity(x.IdentityId, default, Guid.Empty, default, default); + x.Initialize?.Invoke(identity); + return (Identity: identity, modify: x.Modify); + } + ).ToList(); + _dbContext.AttachRange(initial.Select(x => x.Identity)); + initial.ForEach(x => x.modify(x.Identity)); + } + public CompanyUserAssignedIdentityProvider AddCompanyUserAssignedIdentityProvider(Guid companyUserId, Guid identityProviderId, string providerId, string userName) => _dbContext.CompanyUserAssignedIdentityProviders.Add(new CompanyUserAssignedIdentityProvider(companyUserId, identityProviderId, providerId, userName)).Entity; @@ -449,15 +462,12 @@ public IAsyncEnumerable GetUserAssignedI )) .ToAsyncEnumerable(); - public void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action Modify)> identityData) - { - var initial = identityData.Select(x => - { - var identity = new Identity(x.IdentityId, default, Guid.Empty, default, default); - return (Identity: identity, x.Modify); - } - ).ToList(); - _dbContext.AttachRange(initial.Select(x => x.Identity)); - initial.ForEach(x => x.Modify(x.Identity)); - } + public IAsyncEnumerable GetNextIdentitiesForNetworkRegistration(Guid networkRegistrationId, IEnumerable validUserStates) => + _dbContext.CompanyUsers + .Where(cu => + validUserStates.Any(v => v == cu.Identity!.UserStatusId) && + cu.Identity!.Company!.NetworkRegistration!.Id == networkRegistrationId) + .Select(x => x.Id) + .Take(2) + .ToAsyncEnumerable(); } diff --git a/src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.Designer.cs b/src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.Designer.cs new file mode 100644 index 0000000000..19dc23580a --- /dev/null +++ b/src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.Designer.cs @@ -0,0 +1,8867 @@ +/******************************************************************************** + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities; + +#nullable disable + +namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.Migrations.Migrations +{ + [DbContext(typeof(PortalDbContext))] + [Migration("20240122180453_1.8.0-rc3")] + partial class _180rc3 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("portal") + .UseCollation("en_US.utf8") + .HasAnnotation("ProductVersion", "7.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditAppSubscriptionDetail20221118", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AppInstanceId") + .HasColumnType("uuid") + .HasColumnName("app_instance_id"); + + b.Property("AppSubscriptionUrl") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("app_subscription_url"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_app_subscription_detail20221118"); + + b.ToTable("audit_app_subscription_detail20221118", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditAppSubscriptionDetail20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AppInstanceId") + .HasColumnType("uuid") + .HasColumnName("app_instance_id"); + + b.Property("AppSubscriptionUrl") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("app_subscription_url"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_app_subscription_detail20231115"); + + b.ToTable("audit_app_subscription_detail20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyApplication20221005", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("ApplicationStatusId") + .HasColumnType("integer") + .HasColumnName("application_status_id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_application20221005"); + + b.ToTable("audit_company_application20221005", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyApplication20230214", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("ApplicationStatusId") + .HasColumnType("integer") + .HasColumnName("application_status_id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ChecklistProcessId") + .HasColumnType("uuid") + .HasColumnName("checklist_process_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_application20230214"); + + b.ToTable("audit_company_application20230214", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyApplication20230824", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("ApplicationStatusId") + .HasColumnType("integer") + .HasColumnName("application_status_id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ChecklistProcessId") + .HasColumnType("uuid") + .HasColumnName("checklist_process_id"); + + b.Property("CompanyApplicationTypeId") + .HasColumnType("integer") + .HasColumnName("company_application_type_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OnboardingServiceProviderId") + .HasColumnType("uuid") + .HasColumnName("onboarding_service_provider_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_application20230824"); + + b.ToTable("audit_company_application20230824", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyApplication20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("ApplicationStatusId") + .HasColumnType("integer") + .HasColumnName("application_status_id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ChecklistProcessId") + .HasColumnType("uuid") + .HasColumnName("checklist_process_id"); + + b.Property("CompanyApplicationTypeId") + .HasColumnType("integer") + .HasColumnName("company_application_type_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OnboardingServiceProviderId") + .HasColumnType("uuid") + .HasColumnName("onboarding_service_provider_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_application20231115"); + + b.ToTable("audit_company_application20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyAssignedRole2023316", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyRoleId") + .HasColumnType("integer") + .HasColumnName("company_role_id"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_assigned_role2023316"); + + b.ToTable("audit_company_assigned_role2023316", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanySsiDetail20230621", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanySsiDetailStatusId") + .HasColumnType("integer") + .HasColumnName("company_ssi_detail_status_id"); + + b.Property("CreatorUserId") + .HasColumnType("uuid") + .HasColumnName("creator_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("VerifiedCredentialExternalTypeUseCaseDetailId") + .HasColumnType("uuid") + .HasColumnName("verified_credential_external_type_use_case_detail_id"); + + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_ssi_detail20230621"); + + b.ToTable("audit_company_ssi_detail20230621", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanySsiDetail20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanySsiDetailStatusId") + .HasColumnType("integer") + .HasColumnName("company_ssi_detail_status_id"); + + b.Property("CreatorUserId") + .HasColumnType("uuid") + .HasColumnName("creator_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("VerifiedCredentialExternalTypeUseCaseDetailId") + .HasColumnType("uuid") + .HasColumnName("verified_credential_external_type_use_case_detail_id"); + + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_ssi_detail20231115"); + + b.ToTable("audit_company_ssi_detail20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyUser20221005", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyUserStatusId") + .HasColumnType("integer") + .HasColumnName("company_user_status_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Firstname") + .HasColumnType("text") + .HasColumnName("firstname"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("Lastlogin") + .HasColumnType("bytea") + .HasColumnName("lastlogin"); + + b.Property("Lastname") + .HasColumnType("text") + .HasColumnName("lastname"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_user20221005"); + + b.ToTable("audit_company_user20221005", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyUser20230522", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Firstname") + .HasColumnType("text") + .HasColumnName("firstname"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("Lastlogin") + .HasColumnType("bytea") + .HasColumnName("lastlogin"); + + b.Property("Lastname") + .HasColumnType("text") + .HasColumnName("lastname"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_user20230523"); + + b.ToTable("audit_company_user20230523", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditCompanyUserAssignedRole20221018", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("UserRoleId") + .HasColumnType("uuid") + .HasColumnName("user_role_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_company_user_assigned_role20221018"); + + b.ToTable("audit_company_user_assigned_role20221018", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditConnector20230405", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ConnectorUrl") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("connector_url"); + + b.Property("DapsRegistrationSuccessful") + .HasColumnType("boolean") + .HasColumnName("daps_registration_successful"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("HostId") + .HasColumnType("uuid") + .HasColumnName("host_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LocationId") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)") + .HasColumnName("location_id"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("ProviderId") + .HasColumnType("uuid") + .HasColumnName("provider_id"); + + b.Property("SelfDescriptionDocumentId") + .HasColumnType("uuid") + .HasColumnName("self_description_document_id"); + + b.Property("SelfDescriptionMessage") + .HasColumnType("text") + .HasColumnName("self_description_message"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id"); + + b.Property("TypeId") + .HasColumnType("integer") + .HasColumnName("type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_connector20230405"); + + b.ToTable("audit_connector20230405", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditConnector20230503", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyServiceAccountId") + .HasColumnType("uuid") + .HasColumnName("company_service_account_id"); + + b.Property("ConnectorUrl") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("connector_url"); + + b.Property("DapsRegistrationSuccessful") + .HasColumnType("boolean") + .HasColumnName("daps_registration_successful"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("HostId") + .HasColumnType("uuid") + .HasColumnName("host_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LocationId") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)") + .HasColumnName("location_id"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("ProviderId") + .HasColumnType("uuid") + .HasColumnName("provider_id"); + + b.Property("SelfDescriptionDocumentId") + .HasColumnType("uuid") + .HasColumnName("self_description_document_id"); + + b.Property("SelfDescriptionMessage") + .HasColumnType("text") + .HasColumnName("self_description_message"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id"); + + b.Property("TypeId") + .HasColumnType("integer") + .HasColumnName("type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_connector20230503"); + + b.ToTable("audit_connector20230503", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditConnector20230803", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyServiceAccountId") + .HasColumnType("uuid") + .HasColumnName("company_service_account_id"); + + b.Property("ConnectorUrl") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("connector_url"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("HostId") + .HasColumnType("uuid") + .HasColumnName("host_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LocationId") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)") + .HasColumnName("location_id"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("ProviderId") + .HasColumnType("uuid") + .HasColumnName("provider_id"); + + b.Property("SelfDescriptionDocumentId") + .HasColumnType("uuid") + .HasColumnName("self_description_document_id"); + + b.Property("SelfDescriptionMessage") + .HasColumnType("text") + .HasColumnName("self_description_message"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id"); + + b.Property("TypeId") + .HasColumnType("integer") + .HasColumnName("type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_connector20230803"); + + b.ToTable("audit_connector20230803", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditConnector20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyServiceAccountId") + .HasColumnType("uuid") + .HasColumnName("company_service_account_id"); + + b.Property("ConnectorUrl") + .HasColumnType("text") + .HasColumnName("connector_url"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("HostId") + .HasColumnType("uuid") + .HasColumnName("host_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LocationId") + .HasColumnType("text") + .HasColumnName("location_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("ProviderId") + .HasColumnType("uuid") + .HasColumnName("provider_id"); + + b.Property("SelfDescriptionDocumentId") + .HasColumnType("uuid") + .HasColumnName("self_description_document_id"); + + b.Property("SelfDescriptionMessage") + .HasColumnType("text") + .HasColumnName("self_description_message"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id"); + + b.Property("TypeId") + .HasColumnType("integer") + .HasColumnName("type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_connector20231115"); + + b.ToTable("audit_connector20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditConsent20230412", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Comment") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("comment"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("ConsentStatusId") + .HasColumnType("integer") + .HasColumnName("consent_status_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("Target") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("target"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_consent20230412"); + + b.ToTable("audit_consent20230412", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditConsent20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("ConsentStatusId") + .HasColumnType("integer") + .HasColumnName("consent_status_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("Target") + .HasColumnType("text") + .HasColumnName("target"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_consent20231115"); + + b.ToTable("audit_consent20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditDocument20231108", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentContent") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("document_content"); + + b.Property("DocumentHash") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("document_hash"); + + b.Property("DocumentName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("document_name"); + + b.Property("DocumentStatusId") + .HasColumnType("integer") + .HasColumnName("document_status_id"); + + b.Property("DocumentTypeId") + .HasColumnType("integer") + .HasColumnName("document_type_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("MediaTypeId") + .HasColumnType("integer") + .HasColumnName("media_type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_document20231108"); + + b.ToTable("audit_document20231108", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditDocument20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentContent") + .HasColumnType("bytea") + .HasColumnName("document_content"); + + b.Property("DocumentHash") + .HasColumnType("bytea") + .HasColumnName("document_hash"); + + b.Property("DocumentName") + .HasColumnType("text") + .HasColumnName("document_name"); + + b.Property("DocumentStatusId") + .HasColumnType("integer") + .HasColumnName("document_status_id"); + + b.Property("DocumentTypeId") + .HasColumnType("integer") + .HasColumnName("document_type_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("MediaTypeId") + .HasColumnType("integer") + .HasColumnName("media_type_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_document20231115"); + + b.ToTable("audit_document20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditIdentity20230526", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("IdentityTypeId") + .HasColumnType("integer") + .HasColumnName("identity_type_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("UserEntityId") + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("user_entity_id"); + + b.Property("UserStatusId") + .HasColumnType("integer") + .HasColumnName("user_status_id") + .HasAnnotation("Relational:JsonPropertyName", "user_status_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_identity20230526"); + + b.ToTable("audit_identity20230526", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditIdentity20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("IdentityTypeId") + .HasColumnType("integer") + .HasColumnName("identity_type_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("UserEntityId") + .HasColumnType("text") + .HasColumnName("user_entity_id"); + + b.Property("UserStatusId") + .HasColumnType("integer") + .HasColumnName("user_status_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_identity20231115"); + + b.ToTable("audit_identity20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditIdentityAssignedRole20230522", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("IdentityId") + .HasColumnType("uuid") + .HasColumnName("identity_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("UserRoleId") + .HasColumnType("uuid") + .HasColumnName("user_role_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_identity_assigned_role20230522"); + + b.ToTable("audit_identity_assigned_role20230522", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOffer20230119", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ContactEmail") + .HasColumnType("text") + .HasColumnName("contact_email"); + + b.Property("ContactNumber") + .HasColumnType("text") + .HasColumnName("contact_number"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DateReleased") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_released"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("MarketingUrl") + .HasColumnType("text") + .HasColumnName("marketing_url"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("OfferStatusId") + .HasColumnType("integer") + .HasColumnName("offer_status_id"); + + b.Property("OfferTypeId") + .HasColumnType("integer") + .HasColumnName("offer_type_id"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text") + .HasColumnName("provider"); + + b.Property("ProviderCompanyId") + .HasColumnType("uuid") + .HasColumnName("provider_company_id"); + + b.Property("SalesManagerId") + .HasColumnType("uuid") + .HasColumnName("sales_manager_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer20230119"); + + b.ToTable("audit_offer20230119", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOffer20230406", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ContactEmail") + .HasColumnType("text") + .HasColumnName("contact_email"); + + b.Property("ContactNumber") + .HasColumnType("text") + .HasColumnName("contact_number"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DateReleased") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_released"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LicenseTypeId") + .HasColumnType("integer") + .HasColumnName("license_type_id"); + + b.Property("MarketingUrl") + .HasColumnType("text") + .HasColumnName("marketing_url"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("OfferStatusId") + .HasColumnType("integer") + .HasColumnName("offer_status_id"); + + b.Property("OfferTypeId") + .HasColumnType("integer") + .HasColumnName("offer_type_id"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text") + .HasColumnName("provider"); + + b.Property("ProviderCompanyId") + .HasColumnType("uuid") + .HasColumnName("provider_company_id"); + + b.Property("SalesManagerId") + .HasColumnType("uuid") + .HasColumnName("sales_manager_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer20230406"); + + b.ToTable("audit_offer20230406", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOffer20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("ContactEmail") + .HasColumnType("text") + .HasColumnName("contact_email"); + + b.Property("ContactNumber") + .HasColumnType("text") + .HasColumnName("contact_number"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DateReleased") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_released"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LicenseTypeId") + .HasColumnType("integer") + .HasColumnName("license_type_id"); + + b.Property("MarketingUrl") + .HasColumnType("text") + .HasColumnName("marketing_url"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("OfferStatusId") + .HasColumnType("integer") + .HasColumnName("offer_status_id"); + + b.Property("OfferTypeId") + .HasColumnType("integer") + .HasColumnName("offer_type_id"); + + b.Property("Provider") + .HasColumnType("text") + .HasColumnName("provider"); + + b.Property("ProviderCompanyId") + .HasColumnType("uuid") + .HasColumnName("provider_company_id"); + + b.Property("SalesManagerId") + .HasColumnType("uuid") + .HasColumnName("sales_manager_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer20231115"); + + b.ToTable("audit_offer20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOfferSubscription20221005", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayName") + .HasColumnType("text") + .HasColumnName("display_name"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("OfferSubscriptionStatusId") + .HasColumnType("integer") + .HasColumnName("offer_subscription_status_id"); + + b.Property("RequesterId") + .HasColumnType("uuid") + .HasColumnName("requester_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer_subscription20221005"); + + b.ToTable("audit_offer_subscription20221005", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOfferSubscription20230317", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayName") + .HasColumnType("text") + .HasColumnName("display_name"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("OfferSubscriptionStatusId") + .HasColumnType("integer") + .HasColumnName("offer_subscription_status_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("RequesterId") + .HasColumnType("uuid") + .HasColumnName("requester_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer_subscription20230317"); + + b.ToTable("audit_offer_subscription20230317", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOfferSubscription20231013", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayName") + .HasColumnType("text") + .HasColumnName("display_name"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("OfferSubscriptionStatusId") + .HasColumnType("integer") + .HasColumnName("offer_subscription_status_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("RequesterId") + .HasColumnType("uuid") + .HasColumnName("requester_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer_subscription20231013"); + + b.ToTable("audit_offer_subscription20231013", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditOfferSubscription20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayName") + .HasColumnType("text") + .HasColumnName("display_name"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("OfferSubscriptionStatusId") + .HasColumnType("integer") + .HasColumnName("offer_subscription_status_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("RequesterId") + .HasColumnType("uuid") + .HasColumnName("requester_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_offer_subscription20231115"); + + b.ToTable("audit_offer_subscription20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditProviderCompanyDetail20230614", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("AutoSetupCallbackUrl") + .HasColumnType("text") + .HasColumnName("auto_setup_callback_url"); + + b.Property("AutoSetupUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("auto_setup_url"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_provider_company_detail20230614"); + + b.ToTable("audit_provider_company_detail20230614", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditProviderCompanyDetail20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("AutoSetupCallbackUrl") + .HasColumnType("text") + .HasColumnName("auto_setup_callback_url"); + + b.Property("AutoSetupUrl") + .HasColumnType("text") + .HasColumnName("auto_setup_url"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_provider_company_detail20231115"); + + b.ToTable("audit_provider_company_detail20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditUserRole20221017", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("UserRoleText") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_role"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_user_role20221017"); + + b.ToTable("audit_user_role20221017", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities.AuditUserRole20231115", b => + { + b.Property("AuditV1Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("audit_v1id"); + + b.Property("AuditV1DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("audit_v1date_last_changed"); + + b.Property("AuditV1LastEditorId") + .HasColumnType("uuid") + .HasColumnName("audit_v1last_editor_id"); + + b.Property("AuditV1OperationId") + .HasColumnType("integer") + .HasColumnName("audit_v1operation_id"); + + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("UserRoleText") + .HasColumnType("text") + .HasColumnName("user_role"); + + b.HasKey("AuditV1Id") + .HasName("pk_audit_user_role20231115"); + + b.ToTable("audit_user_role20231115", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("City") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("city"); + + b.Property("CountryAlpha2Code") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("country_alpha2code") + .HasAnnotation("Relational:JsonPropertyName", "country_alpha2code"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Region") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("region"); + + b.Property("Streetadditional") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("streetadditional"); + + b.Property("Streetname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("streetname"); + + b.Property("Streetnumber") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("streetnumber"); + + b.Property("Zipcode") + .HasMaxLength(12) + .HasColumnType("character varying(12)") + .HasColumnName("zipcode"); + + b.HasKey("Id") + .HasName("pk_addresses"); + + b.HasIndex("CountryAlpha2Code") + .HasDatabaseName("ix_addresses_country_alpha2code"); + + b.ToTable("addresses", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AgreementCategoryId") + .HasColumnType("integer") + .HasColumnName("agreement_category_id"); + + b.Property("AgreementLink") + .HasColumnType("text") + .HasColumnName("agreement_link"); + + b.Property("AgreementStatusId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(1) + .HasColumnName("agreement_status_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("IssuerCompanyId") + .HasColumnType("uuid") + .HasColumnName("issuer_company_id"); + + b.Property("Mandatory") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasColumnName("mandatory"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("UseCaseId") + .HasColumnType("uuid") + .HasColumnName("use_case_id"); + + b.HasKey("Id") + .HasName("pk_agreements"); + + b.HasIndex("AgreementCategoryId") + .HasDatabaseName("ix_agreements_agreement_category_id"); + + b.HasIndex("AgreementStatusId") + .HasDatabaseName("ix_agreements_agreement_status_id"); + + b.HasIndex("DocumentId") + .HasDatabaseName("ix_agreements_document_id"); + + b.HasIndex("IssuerCompanyId") + .HasDatabaseName("ix_agreements_issuer_company_id"); + + b.HasIndex("UseCaseId") + .HasDatabaseName("ix_agreements_use_case_id"); + + b.ToTable("agreements", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementAssignedCompanyRole", b => + { + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("CompanyRoleId") + .HasColumnType("integer") + .HasColumnName("company_role_id"); + + b.HasKey("AgreementId", "CompanyRoleId") + .HasName("pk_agreement_assigned_company_roles"); + + b.HasIndex("CompanyRoleId") + .HasDatabaseName("ix_agreement_assigned_company_roles_company_role_id"); + + b.ToTable("agreement_assigned_company_roles", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementAssignedOffer", b => + { + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.HasKey("AgreementId", "OfferId") + .HasName("pk_agreement_assigned_offers"); + + b.HasIndex("OfferId") + .HasDatabaseName("ix_agreement_assigned_offers_offer_id"); + + b.ToTable("agreement_assigned_offers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementAssignedOfferType", b => + { + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("OfferTypeId") + .HasColumnType("integer") + .HasColumnName("offer_type_id"); + + b.HasKey("AgreementId", "OfferTypeId") + .HasName("pk_agreement_assigned_offer_types"); + + b.HasIndex("OfferTypeId") + .HasDatabaseName("ix_agreement_assigned_offer_types_offer_type_id"); + + b.ToTable("agreement_assigned_offer_types", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementCategory", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_agreement_categories"); + + b.ToTable("agreement_categories", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "CX_FRAME_CONTRACT" + }, + new + { + Id = 2, + Label = "APP_CONTRACT" + }, + new + { + Id = 3, + Label = "DATA_CONTRACT" + }, + new + { + Id = 4, + Label = "SERVICE_CONTRACT" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_agreement_statuses"); + + b.ToTable("agreement_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "ACTIVE" + }, + new + { + Id = 2, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppAssignedUseCase", b => + { + b.Property("AppId") + .HasColumnType("uuid") + .HasColumnName("app_id"); + + b.Property("UseCaseId") + .HasColumnType("uuid") + .HasColumnName("use_case_id"); + + b.HasKey("AppId", "UseCaseId") + .HasName("pk_app_assigned_use_cases"); + + b.HasIndex("UseCaseId") + .HasDatabaseName("ix_app_assigned_use_cases_use_case_id"); + + b.ToTable("app_assigned_use_cases", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AppId") + .HasColumnType("uuid") + .HasColumnName("app_id"); + + b.Property("IamClientId") + .HasColumnType("uuid") + .HasColumnName("iam_client_id"); + + b.HasKey("Id") + .HasName("pk_app_instances"); + + b.HasIndex("AppId") + .HasDatabaseName("ix_app_instances_app_id"); + + b.HasIndex("IamClientId") + .HasDatabaseName("ix_app_instances_iam_client_id"); + + b.ToTable("app_instances", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstanceAssignedCompanyServiceAccount", b => + { + b.Property("AppInstanceId") + .HasColumnType("uuid") + .HasColumnName("app_instance_id"); + + b.Property("CompanyServiceAccountId") + .HasColumnType("uuid") + .HasColumnName("company_service_account_id"); + + b.HasKey("AppInstanceId", "CompanyServiceAccountId") + .HasName("pk_app_instance_assigned_service_accounts"); + + b.HasIndex("CompanyServiceAccountId") + .HasDatabaseName("ix_app_instance_assigned_service_accounts_company_service_acco"); + + b.ToTable("app_instance_assigned_service_accounts", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstanceSetup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AppId") + .HasColumnType("uuid") + .HasColumnName("app_id"); + + b.Property("InstanceUrl") + .HasColumnType("text") + .HasColumnName("instance_url"); + + b.Property("IsSingleInstance") + .HasColumnType("boolean") + .HasColumnName("is_single_instance"); + + b.HasKey("Id") + .HasName("pk_app_instance_setups"); + + b.HasIndex("AppId") + .IsUnique() + .HasDatabaseName("ix_app_instance_setups_app_id"); + + b.ToTable("app_instance_setups", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppLanguage", b => + { + b.Property("AppId") + .HasColumnType("uuid") + .HasColumnName("app_id"); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name"); + + b.HasKey("AppId", "LanguageShortName") + .HasName("pk_app_languages"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_app_languages_language_short_name"); + + b.ToTable("app_languages", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppSubscriptionDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AppInstanceId") + .HasColumnType("uuid") + .HasColumnName("app_instance_id"); + + b.Property("AppSubscriptionUrl") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("app_subscription_url"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.HasKey("Id") + .HasName("pk_app_subscription_details"); + + b.HasIndex("AppInstanceId") + .HasDatabaseName("ix_app_subscription_details_app_instance_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_app_subscription_details_last_editor_id"); + + b.HasIndex("OfferSubscriptionId") + .IsUnique() + .HasDatabaseName("ix_app_subscription_details_offer_subscription_id"); + + b.ToTable("app_subscription_details", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_app_subscription_detail20231115\" (\"id\", \"offer_subscription_id\", \"app_instance_id\", \"app_subscription_url\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"offer_subscription_id\", \r\n NEW.\"app_instance_id\", \r\n NEW.\"app_subscription_url\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL AFTER INSERT\r\nON \"portal\".\"app_subscription_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_APPSUBSCRIPTIONDETAIL\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_app_subscription_detail20231115\" (\"id\", \"offer_subscription_id\", \"app_instance_id\", \"app_subscription_url\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"offer_subscription_id\", \r\n NEW.\"app_instance_id\", \r\n NEW.\"app_subscription_url\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL AFTER UPDATE\r\nON \"portal\".\"app_subscription_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_APPSUBSCRIPTIONDETAIL\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntry", b => + { + b.Property("ApplicationId") + .HasColumnType("uuid") + .HasColumnName("application_id"); + + b.Property("ApplicationChecklistEntryTypeId") + .HasColumnType("integer") + .HasColumnName("application_checklist_entry_type_id"); + + b.Property("ApplicationChecklistEntryStatusId") + .HasColumnType("integer") + .HasColumnName("application_checklist_entry_status_id"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.HasKey("ApplicationId", "ApplicationChecklistEntryTypeId") + .HasName("pk_application_checklist"); + + b.HasIndex("ApplicationChecklistEntryStatusId") + .HasDatabaseName("ix_application_checklist_application_checklist_entry_status_id"); + + b.HasIndex("ApplicationChecklistEntryTypeId") + .HasDatabaseName("ix_application_checklist_application_checklist_entry_type_id"); + + b.ToTable("application_checklist", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntryStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_application_checklist_statuses"); + + b.ToTable("application_checklist_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "TO_DO" + }, + new + { + Id = 2, + Label = "IN_PROGRESS" + }, + new + { + Id = 3, + Label = "DONE" + }, + new + { + Id = 4, + Label = "FAILED" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntryType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_application_checklist_types"); + + b.ToTable("application_checklist_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "REGISTRATION_VERIFICATION" + }, + new + { + Id = 2, + Label = "BUSINESS_PARTNER_NUMBER" + }, + new + { + Id = 3, + Label = "IDENTITY_WALLET" + }, + new + { + Id = 4, + Label = "CLEARING_HOUSE" + }, + new + { + Id = 5, + Label = "SELF_DESCRIPTION_LP" + }, + new + { + Id = 6, + Label = "APPLICATION_ACTIVATION" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AuditOperation", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_audit_operation"); + + b.ToTable("audit_operation", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "INSERT" + }, + new + { + Id = 2, + Label = "UPDATE" + }, + new + { + Id = 3, + Label = "DELETE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.BpdmIdentifier", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_bpdm_identifiers"); + + b.ToTable("bpdm_identifiers", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "EU_VAT_ID_DE" + }, + new + { + Id = 2, + Label = "CH_UID" + }, + new + { + Id = 3, + Label = "EU_VAT_ID_FR" + }, + new + { + Id = 4, + Label = "FR_SIREN" + }, + new + { + Id = 5, + Label = "EU_VAT_ID_AT" + }, + new + { + Id = 6, + Label = "DE_BNUM" + }, + new + { + Id = 7, + Label = "CZ_ICO" + }, + new + { + Id = 8, + Label = "EU_VAT_ID_CZ" + }, + new + { + Id = 9, + Label = "EU_VAT_ID_PL" + }, + new + { + Id = 10, + Label = "EU_VAT_ID_BE" + }, + new + { + Id = 11, + Label = "EU_VAT_ID_CH" + }, + new + { + Id = 12, + Label = "EU_VAT_ID_DK" + }, + new + { + Id = 13, + Label = "EU_VAT_ID_ES" + }, + new + { + Id = 14, + Label = "EU_VAT_ID_GB" + }, + new + { + Id = 15, + Label = "EU_VAT_ID_NO" + }, + new + { + Id = 16, + Label = "BE_ENT_NO" + }, + new + { + Id = 17, + Label = "CVR_DK" + }, + new + { + Id = 18, + Label = "ID_CRN" + }, + new + { + Id = 19, + Label = "NO_ORGID" + }, + new + { + Id = 20, + Label = "LEI_ID" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AddressId") + .HasColumnType("uuid") + .HasColumnName("address_id"); + + b.Property("BusinessPartnerNumber") + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasColumnName("business_partner_number"); + + b.Property("CompanyStatusId") + .HasColumnType("integer") + .HasColumnName("company_status_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("SelfDescriptionDocumentId") + .HasColumnType("uuid") + .HasColumnName("self_description_document_id"); + + b.Property("Shortname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("shortname"); + + b.HasKey("Id") + .HasName("pk_companies"); + + b.HasIndex("AddressId") + .HasDatabaseName("ix_companies_address_id"); + + b.HasIndex("CompanyStatusId") + .HasDatabaseName("ix_companies_company_status_id"); + + b.HasIndex("SelfDescriptionDocumentId") + .HasDatabaseName("ix_companies_self_description_document_id"); + + b.ToTable("companies", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ApplicationStatusId") + .HasColumnType("integer") + .HasColumnName("application_status_id"); + + b.Property("ChecklistProcessId") + .HasColumnType("uuid") + .HasColumnName("checklist_process_id"); + + b.Property("CompanyApplicationTypeId") + .HasColumnType("integer") + .HasColumnName("company_application_type_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OnboardingServiceProviderId") + .HasColumnType("uuid") + .HasColumnName("onboarding_service_provider_id"); + + b.HasKey("Id") + .HasName("pk_company_applications"); + + b.HasIndex("ApplicationStatusId") + .HasDatabaseName("ix_company_applications_application_status_id"); + + b.HasIndex("ChecklistProcessId") + .IsUnique() + .HasDatabaseName("ix_company_applications_checklist_process_id"); + + b.HasIndex("CompanyApplicationTypeId") + .HasDatabaseName("ix_company_applications_company_application_type_id"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_company_applications_company_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_company_applications_last_editor_id"); + + b.HasIndex("OnboardingServiceProviderId") + .HasDatabaseName("ix_company_applications_onboarding_service_provider_id"); + + b.ToTable("company_applications", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_application20231115\" (\"id\", \"date_created\", \"date_last_changed\", \"application_status_id\", \"company_id\", \"checklist_process_id\", \"company_application_type_id\", \"onboarding_service_provider_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"application_status_id\", \r\n NEW.\"company_id\", \r\n NEW.\"checklist_process_id\", \r\n NEW.\"company_application_type_id\", \r\n NEW.\"onboarding_service_provider_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION AFTER INSERT\r\nON \"portal\".\"company_applications\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_application20231115\" (\"id\", \"date_created\", \"date_last_changed\", \"application_status_id\", \"company_id\", \"checklist_process_id\", \"company_application_type_id\", \"onboarding_service_provider_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"application_status_id\", \r\n NEW.\"company_id\", \r\n NEW.\"checklist_process_id\", \r\n NEW.\"company_application_type_id\", \r\n NEW.\"onboarding_service_provider_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION AFTER UPDATE\r\nON \"portal\".\"company_applications\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplicationStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_application_statuses"); + + b.ToTable("company_application_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "CREATED" + }, + new + { + Id = 2, + Label = "ADD_COMPANY_DATA" + }, + new + { + Id = 3, + Label = "INVITE_USER" + }, + new + { + Id = 4, + Label = "SELECT_COMPANY_ROLE" + }, + new + { + Id = 5, + Label = "UPLOAD_DOCUMENTS" + }, + new + { + Id = 6, + Label = "VERIFY" + }, + new + { + Id = 7, + Label = "SUBMITTED" + }, + new + { + Id = 8, + Label = "CONFIRMED" + }, + new + { + Id = 9, + Label = "DECLINED" + }, + new + { + Id = 10, + Label = "CANCELLED_BY_CUSTOMER" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplicationType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_application_types"); + + b.ToTable("company_application_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "INTERNAL" + }, + new + { + Id = 2, + Label = "EXTERNAL" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyAssignedRole", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyRoleId") + .HasColumnType("integer") + .HasColumnName("company_role_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("CompanyId", "CompanyRoleId") + .HasName("pk_company_assigned_roles"); + + b.HasIndex("CompanyRoleId") + .HasDatabaseName("ix_company_assigned_roles_company_role_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_company_assigned_roles_last_editor_id"); + + b.ToTable("company_assigned_roles", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_assigned_role2023316\" (\"company_id\", \"company_role_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"company_id\", \r\n NEW.\"company_role_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE AFTER INSERT\r\nON \"portal\".\"company_assigned_roles\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYASSIGNEDROLE\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_assigned_role2023316\" (\"company_id\", \"company_role_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"company_id\", \r\n NEW.\"company_role_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE AFTER UPDATE\r\nON \"portal\".\"company_assigned_roles\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYASSIGNEDROLE\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyAssignedUseCase", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("UseCaseId") + .HasColumnType("uuid") + .HasColumnName("use_case_id"); + + b.HasKey("CompanyId", "UseCaseId") + .HasName("pk_company_assigned_use_cases"); + + b.HasIndex("UseCaseId") + .HasDatabaseName("ix_company_assigned_use_cases_use_case_id"); + + b.ToTable("company_assigned_use_cases", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyIdentifier", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("UniqueIdentifierId") + .HasColumnType("integer") + .HasColumnName("unique_identifier_id"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("CompanyId", "UniqueIdentifierId") + .HasName("pk_company_identifiers"); + + b.HasIndex("UniqueIdentifierId") + .HasDatabaseName("ix_company_identifiers_unique_identifier_id"); + + b.ToTable("company_identifiers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyIdentityProvider", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("IdentityProviderId") + .HasColumnType("uuid") + .HasColumnName("identity_provider_id"); + + b.HasKey("CompanyId", "IdentityProviderId") + .HasName("pk_company_identity_providers"); + + b.HasIndex("IdentityProviderId") + .HasDatabaseName("ix_company_identity_providers_identity_provider_id"); + + b.ToTable("company_identity_providers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_roles"); + + b.ToTable("company_roles", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "ACTIVE_PARTICIPANT" + }, + new + { + Id = 2, + Label = "APP_PROVIDER" + }, + new + { + Id = 3, + Label = "SERVICE_PROVIDER" + }, + new + { + Id = 4, + Label = "OPERATOR" + }, + new + { + Id = 5, + Label = "ONBOARDING_SERVICE_PROVIDER" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleAssignedRoleCollection", b => + { + b.Property("CompanyRoleId") + .HasColumnType("integer") + .HasColumnName("company_role_id"); + + b.Property("UserRoleCollectionId") + .HasColumnType("uuid") + .HasColumnName("user_role_collection_id"); + + b.HasKey("CompanyRoleId") + .HasName("pk_company_role_assigned_role_collections"); + + b.HasIndex("UserRoleCollectionId") + .IsUnique() + .HasDatabaseName("ix_company_role_assigned_role_collections_user_role_collection"); + + b.ToTable("company_role_assigned_role_collections", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleDescription", b => + { + b.Property("CompanyRoleId") + .HasColumnType("integer") + .HasColumnName("company_role_id"); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description"); + + b.HasKey("CompanyRoleId", "LanguageShortName") + .HasName("pk_company_role_descriptions"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_company_role_descriptions_language_short_name"); + + b.ToTable("company_role_descriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleRegistrationData", b => + { + b.Property("CompanyRoleId") + .HasColumnType("integer") + .HasColumnName("company_role_id"); + + b.Property("IsRegistrationRole") + .HasColumnType("boolean") + .HasColumnName("is_registration_role"); + + b.HasKey("CompanyRoleId") + .HasName("pk_company_role_registration_data"); + + b.ToTable("company_role_registration_data", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ClientClientId") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("client_client_id"); + + b.Property("CompanyServiceAccountTypeId") + .HasColumnType("integer") + .HasColumnName("company_service_account_type_id"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.HasKey("Id") + .HasName("pk_company_service_accounts"); + + b.HasIndex("ClientClientId") + .IsUnique() + .HasDatabaseName("ix_company_service_accounts_client_client_id"); + + b.HasIndex("CompanyServiceAccountTypeId") + .HasDatabaseName("ix_company_service_accounts_company_service_account_type_id"); + + b.HasIndex("OfferSubscriptionId") + .HasDatabaseName("ix_company_service_accounts_offer_subscription_id"); + + b.ToTable("company_service_accounts", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccountType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_service_account_types"); + + b.ToTable("company_service_account_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "MANAGED" + }, + new + { + Id = 2, + Label = "OWN" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanySsiDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanySsiDetailStatusId") + .HasColumnType("integer") + .HasColumnName("company_ssi_detail_status_id"); + + b.Property("CreatorUserId") + .HasColumnType("uuid") + .HasColumnName("creator_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("VerifiedCredentialExternalTypeUseCaseDetailId") + .HasColumnType("uuid") + .HasColumnName("verified_credential_external_type_use_case_detail_id"); + + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.HasKey("Id") + .HasName("pk_company_ssi_details"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_company_ssi_details_company_id"); + + b.HasIndex("CompanySsiDetailStatusId") + .HasDatabaseName("ix_company_ssi_details_company_ssi_detail_status_id"); + + b.HasIndex("CreatorUserId") + .HasDatabaseName("ix_company_ssi_details_creator_user_id"); + + b.HasIndex("DocumentId") + .IsUnique() + .HasDatabaseName("ix_company_ssi_details_document_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_company_ssi_details_last_editor_id"); + + b.HasIndex("VerifiedCredentialExternalTypeUseCaseDetailId") + .HasDatabaseName("ix_company_ssi_details_verified_credential_external_type_use_c"); + + b.HasIndex("VerifiedCredentialTypeId") + .HasDatabaseName("ix_company_ssi_details_verified_credential_type_id"); + + b.ToTable("company_ssi_details", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_ssi_detail20231115\" (\"id\", \"company_id\", \"verified_credential_type_id\", \"company_ssi_detail_status_id\", \"document_id\", \"date_created\", \"creator_user_id\", \"expiry_date\", \"verified_credential_external_type_use_case_detail_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"company_id\", \r\n NEW.\"verified_credential_type_id\", \r\n NEW.\"company_ssi_detail_status_id\", \r\n NEW.\"document_id\", \r\n NEW.\"date_created\", \r\n NEW.\"creator_user_id\", \r\n NEW.\"expiry_date\", \r\n NEW.\"verified_credential_external_type_use_case_detail_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL AFTER INSERT\r\nON \"portal\".\"company_ssi_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYSSIDETAIL\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_ssi_detail20231115\" (\"id\", \"company_id\", \"verified_credential_type_id\", \"company_ssi_detail_status_id\", \"document_id\", \"date_created\", \"creator_user_id\", \"expiry_date\", \"verified_credential_external_type_use_case_detail_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"company_id\", \r\n NEW.\"verified_credential_type_id\", \r\n NEW.\"company_ssi_detail_status_id\", \r\n NEW.\"document_id\", \r\n NEW.\"date_created\", \r\n NEW.\"creator_user_id\", \r\n NEW.\"expiry_date\", \r\n NEW.\"verified_credential_external_type_use_case_detail_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL AFTER UPDATE\r\nON \"portal\".\"company_ssi_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYSSIDETAIL\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanySsiDetailStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_ssi_detail_statuses"); + + b.ToTable("company_ssi_detail_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "PENDING" + }, + new + { + Id = 2, + Label = "ACTIVE" + }, + new + { + Id = 3, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_company_statuses"); + + b.ToTable("company_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "PENDING" + }, + new + { + Id = 2, + Label = "ACTIVE" + }, + new + { + Id = 3, + Label = "REJECTED" + }, + new + { + Id = 4, + Label = "INACTIVE" + }, + new + { + Id = 5, + Label = "DELETED" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Email") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("email"); + + b.Property("Firstname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("firstname"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("Lastlogin") + .HasColumnType("bytea") + .HasColumnName("lastlogin"); + + b.Property("Lastname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("lastname"); + + b.HasKey("Id") + .HasName("pk_company_users"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_company_users_last_editor_id"); + + b.ToTable("company_users", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_COMPANYUSER"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_COMPANYUSER"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_COMPANYUSER", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYUSER\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_COMPANYUSER$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_user20230523\" (\"id\", \"email\", \"firstname\", \"lastlogin\", \"lastname\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"email\", \r\n NEW.\"firstname\", \r\n NEW.\"lastlogin\", \r\n NEW.\"lastname\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_COMPANYUSER$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_COMPANYUSER AFTER INSERT\r\nON \"portal\".\"company_users\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYUSER\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_COMPANYUSER", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYUSER\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_COMPANYUSER$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_company_user20230523\" (\"id\", \"email\", \"firstname\", \"lastlogin\", \"lastname\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"email\", \r\n NEW.\"firstname\", \r\n NEW.\"lastlogin\", \r\n NEW.\"lastname\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_COMPANYUSER$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_COMPANYUSER AFTER UPDATE\r\nON \"portal\".\"company_users\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYUSER\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUserAssignedAppFavourite", b => + { + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("AppId") + .HasColumnType("uuid") + .HasColumnName("app_id"); + + b.HasKey("CompanyUserId", "AppId") + .HasName("pk_company_user_assigned_app_favourites"); + + b.HasIndex("AppId") + .HasDatabaseName("ix_company_user_assigned_app_favourites_app_id"); + + b.ToTable("company_user_assigned_app_favourites", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUserAssignedBusinessPartner", b => + { + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("BusinessPartnerNumber") + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasColumnName("business_partner_number"); + + b.HasKey("CompanyUserId", "BusinessPartnerNumber") + .HasName("pk_company_user_assigned_business_partners"); + + b.ToTable("company_user_assigned_business_partners", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUserAssignedIdentityProvider", b => + { + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("IdentityProviderId") + .HasColumnType("uuid") + .HasColumnName("identity_provider_id"); + + b.Property("ProviderId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("provider_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("CompanyUserId", "IdentityProviderId") + .HasName("pk_company_user_assigned_identity_providers"); + + b.HasIndex("IdentityProviderId") + .HasDatabaseName("ix_company_user_assigned_identity_providers_identity_provider_"); + + b.ToTable("company_user_assigned_identity_providers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Connector", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CompanyServiceAccountId") + .HasColumnType("uuid") + .HasColumnName("company_service_account_id"); + + b.Property("ConnectorUrl") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("connector_url"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("HostId") + .HasColumnType("uuid") + .HasColumnName("host_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LocationId") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("location_id"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("ProviderId") + .HasColumnType("uuid") + .HasColumnName("provider_id"); + + b.Property("SelfDescriptionDocumentId") + .HasColumnType("uuid") + .HasColumnName("self_description_document_id"); + + b.Property("SelfDescriptionMessage") + .HasColumnType("text") + .HasColumnName("self_description_message"); + + b.Property("StatusId") + .HasColumnType("integer") + .HasColumnName("status_id"); + + b.Property("TypeId") + .HasColumnType("integer") + .HasColumnName("type_id"); + + b.HasKey("Id") + .HasName("pk_connectors"); + + b.HasIndex("CompanyServiceAccountId") + .IsUnique() + .HasDatabaseName("ix_connectors_company_service_account_id"); + + b.HasIndex("HostId") + .HasDatabaseName("ix_connectors_host_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_connectors_last_editor_id"); + + b.HasIndex("LocationId") + .HasDatabaseName("ix_connectors_location_id"); + + b.HasIndex("ProviderId") + .HasDatabaseName("ix_connectors_provider_id"); + + b.HasIndex("SelfDescriptionDocumentId") + .IsUnique() + .HasDatabaseName("ix_connectors_self_description_document_id"); + + b.HasIndex("StatusId") + .HasDatabaseName("ix_connectors_status_id"); + + b.HasIndex("TypeId") + .HasDatabaseName("ix_connectors_type_id"); + + b.ToTable("connectors", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_CONNECTOR"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_CONNECTOR"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_CONNECTOR", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_CONNECTOR\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_CONNECTOR$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_connector20231115\" (\"id\", \"name\", \"connector_url\", \"type_id\", \"status_id\", \"provider_id\", \"host_id\", \"self_description_document_id\", \"location_id\", \"self_description_message\", \"date_last_changed\", \"company_service_account_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"name\", \r\n NEW.\"connector_url\", \r\n NEW.\"type_id\", \r\n NEW.\"status_id\", \r\n NEW.\"provider_id\", \r\n NEW.\"host_id\", \r\n NEW.\"self_description_document_id\", \r\n NEW.\"location_id\", \r\n NEW.\"self_description_message\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"company_service_account_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_CONNECTOR$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_CONNECTOR AFTER INSERT\r\nON \"portal\".\"connectors\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_CONNECTOR\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_CONNECTOR", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_CONNECTOR\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_CONNECTOR$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_connector20231115\" (\"id\", \"name\", \"connector_url\", \"type_id\", \"status_id\", \"provider_id\", \"host_id\", \"self_description_document_id\", \"location_id\", \"self_description_message\", \"date_last_changed\", \"company_service_account_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"name\", \r\n NEW.\"connector_url\", \r\n NEW.\"type_id\", \r\n NEW.\"status_id\", \r\n NEW.\"provider_id\", \r\n NEW.\"host_id\", \r\n NEW.\"self_description_document_id\", \r\n NEW.\"location_id\", \r\n NEW.\"self_description_message\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"company_service_account_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_CONNECTOR$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_CONNECTOR AFTER UPDATE\r\nON \"portal\".\"connectors\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_CONNECTOR\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorAssignedOfferSubscription", b => + { + b.Property("ConnectorId") + .HasColumnType("uuid") + .HasColumnName("connector_id"); + + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.HasKey("ConnectorId", "OfferSubscriptionId") + .HasName("pk_connector_assigned_offer_subscriptions"); + + b.HasIndex("OfferSubscriptionId") + .HasDatabaseName("ix_connector_assigned_offer_subscriptions_offer_subscription_id"); + + b.ToTable("connector_assigned_offer_subscriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_connector_statuses"); + + b.ToTable("connector_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "PENDING" + }, + new + { + Id = 2, + Label = "ACTIVE" + }, + new + { + Id = 3, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_connector_types"); + + b.ToTable("connector_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "COMPANY_CONNECTOR" + }, + new + { + Id = 2, + Label = "CONNECTOR_AS_A_SERVICE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Consent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("Comment") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("comment"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("ConsentStatusId") + .HasColumnType("integer") + .HasColumnName("consent_status_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("Target") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("target"); + + b.HasKey("Id") + .HasName("pk_consents"); + + b.HasIndex("AgreementId") + .HasDatabaseName("ix_consents_agreement_id"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_consents_company_id"); + + b.HasIndex("CompanyUserId") + .HasDatabaseName("ix_consents_company_user_id"); + + b.HasIndex("ConsentStatusId") + .HasDatabaseName("ix_consents_consent_status_id"); + + b.HasIndex("DocumentId") + .HasDatabaseName("ix_consents_document_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_consents_last_editor_id"); + + b.ToTable("consents", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_CONSENT"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_CONSENT"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_CONSENT", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_CONSENT\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_CONSENT$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_consent20231115\" (\"id\", \"date_created\", \"comment\", \"consent_status_id\", \"target\", \"agreement_id\", \"company_id\", \"document_id\", \"company_user_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"comment\", \r\n NEW.\"consent_status_id\", \r\n NEW.\"target\", \r\n NEW.\"agreement_id\", \r\n NEW.\"company_id\", \r\n NEW.\"document_id\", \r\n NEW.\"company_user_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_CONSENT$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_CONSENT AFTER INSERT\r\nON \"portal\".\"consents\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_CONSENT\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_CONSENT", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_CONSENT\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_CONSENT$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_consent20231115\" (\"id\", \"date_created\", \"comment\", \"consent_status_id\", \"target\", \"agreement_id\", \"company_id\", \"document_id\", \"company_user_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"comment\", \r\n NEW.\"consent_status_id\", \r\n NEW.\"target\", \r\n NEW.\"agreement_id\", \r\n NEW.\"company_id\", \r\n NEW.\"document_id\", \r\n NEW.\"company_user_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_CONSENT$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_CONSENT AFTER UPDATE\r\nON \"portal\".\"consents\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_CONSENT\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentAssignedOffer", b => + { + b.Property("ConsentId") + .HasColumnType("uuid") + .HasColumnName("consent_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.HasKey("ConsentId", "OfferId") + .HasName("pk_consent_assigned_offers"); + + b.HasIndex("OfferId") + .HasDatabaseName("ix_consent_assigned_offers_offer_id"); + + b.ToTable("consent_assigned_offers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentAssignedOfferSubscription", b => + { + b.Property("ConsentId") + .HasColumnType("uuid") + .HasColumnName("consent_id"); + + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.HasKey("ConsentId", "OfferSubscriptionId") + .HasName("pk_consent_assigned_offer_subscriptions"); + + b.HasIndex("OfferSubscriptionId") + .HasDatabaseName("ix_consent_assigned_offer_subscriptions_offer_subscription_id"); + + b.ToTable("consent_assigned_offer_subscriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_consent_statuses"); + + b.ToTable("consent_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "ACTIVE" + }, + new + { + Id = 2, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Country", b => + { + b.Property("Alpha2Code") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("alpha2code") + .IsFixedLength() + .HasAnnotation("Relational:JsonPropertyName", "alpha2code"); + + b.Property("Alpha3Code") + .HasMaxLength(3) + .HasColumnType("character(3)") + .HasColumnName("alpha3code") + .IsFixedLength() + .HasAnnotation("Relational:JsonPropertyName", "alpha3code"); + + b.HasKey("Alpha2Code") + .HasName("pk_countries"); + + b.ToTable("countries", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CountryAssignedIdentifier", b => + { + b.Property("CountryAlpha2Code") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("country_alpha2code") + .HasAnnotation("Relational:JsonPropertyName", "country_alpha2code"); + + b.Property("UniqueIdentifierId") + .HasColumnType("integer") + .HasColumnName("unique_identifier_id"); + + b.Property("BpdmIdentifierId") + .HasColumnType("integer") + .HasColumnName("bpdm_identifier_id"); + + b.HasKey("CountryAlpha2Code", "UniqueIdentifierId") + .HasName("pk_country_assigned_identifiers"); + + b.HasIndex("BpdmIdentifierId") + .HasDatabaseName("ix_country_assigned_identifiers_bpdm_identifier_id"); + + b.HasIndex("UniqueIdentifierId") + .HasDatabaseName("ix_country_assigned_identifiers_unique_identifier_id"); + + b.ToTable("country_assigned_identifiers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CountryLongName", b => + { + b.Property("Alpha2Code") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("alpha2code") + .HasAnnotation("Relational:JsonPropertyName", "alpha2code"); + + b.Property("ShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("short_name"); + + b.Property("LongName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("long_name"); + + b.HasKey("Alpha2Code", "ShortName") + .HasName("pk_country_long_names"); + + b.HasIndex("ShortName") + .HasDatabaseName("ix_country_long_names_short_name"); + + b.ToTable("country_long_names", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DocumentContent") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("document_content"); + + b.Property("DocumentHash") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("document_hash"); + + b.Property("DocumentName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("document_name"); + + b.Property("DocumentStatusId") + .HasColumnType("integer") + .HasColumnName("document_status_id"); + + b.Property("DocumentTypeId") + .HasColumnType("integer") + .HasColumnName("document_type_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("MediaTypeId") + .HasColumnType("integer") + .HasColumnName("media_type_id"); + + b.HasKey("Id") + .HasName("pk_documents"); + + b.HasIndex("CompanyUserId") + .HasDatabaseName("ix_documents_company_user_id"); + + b.HasIndex("DocumentStatusId") + .HasDatabaseName("ix_documents_document_status_id"); + + b.HasIndex("DocumentTypeId") + .HasDatabaseName("ix_documents_document_type_id"); + + b.HasIndex("MediaTypeId") + .HasDatabaseName("ix_documents_media_type_id"); + + b.ToTable("documents", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_DOCUMENT"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_DOCUMENT"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_DOCUMENT", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_DOCUMENT\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_DOCUMENT$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_document20231115\" (\"id\", \"date_created\", \"document_hash\", \"document_content\", \"document_name\", \"media_type_id\", \"document_type_id\", \"document_status_id\", \"company_user_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"document_hash\", \r\n NEW.\"document_content\", \r\n NEW.\"document_name\", \r\n NEW.\"media_type_id\", \r\n NEW.\"document_type_id\", \r\n NEW.\"document_status_id\", \r\n NEW.\"company_user_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_DOCUMENT$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_DOCUMENT AFTER INSERT\r\nON \"portal\".\"documents\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_DOCUMENT\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_DOCUMENT", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_DOCUMENT\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_DOCUMENT$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_document20231115\" (\"id\", \"date_created\", \"document_hash\", \"document_content\", \"document_name\", \"media_type_id\", \"document_type_id\", \"document_status_id\", \"company_user_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"document_hash\", \r\n NEW.\"document_content\", \r\n NEW.\"document_name\", \r\n NEW.\"media_type_id\", \r\n NEW.\"document_type_id\", \r\n NEW.\"document_status_id\", \r\n NEW.\"company_user_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_DOCUMENT$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_DOCUMENT AFTER UPDATE\r\nON \"portal\".\"documents\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_DOCUMENT\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.DocumentStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_document_status"); + + b.ToTable("document_status", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "PENDING" + }, + new + { + Id = 2, + Label = "LOCKED" + }, + new + { + Id = 3, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.DocumentType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_document_types"); + + b.ToTable("document_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "CX_FRAME_CONTRACT" + }, + new + { + Id = 2, + Label = "COMMERCIAL_REGISTER_EXTRACT" + }, + new + { + Id = 3, + Label = "APP_CONTRACT" + }, + new + { + Id = 4, + Label = "CONFORMITY_APPROVAL_REGISTRATION" + }, + new + { + Id = 5, + Label = "ADDITIONAL_DETAILS" + }, + new + { + Id = 6, + Label = "APP_LEADIMAGE" + }, + new + { + Id = 7, + Label = "APP_IMAGE" + }, + new + { + Id = 8, + Label = "SELF_DESCRIPTION" + }, + new + { + Id = 9, + Label = "APP_TECHNICAL_INFORMATION" + }, + new + { + Id = 10, + Label = "CONFORMITY_APPROVAL_CONNECTOR" + }, + new + { + Id = 11, + Label = "CONFORMITY_APPROVAL_BUSINESS_APPS" + }, + new + { + Id = 12, + Label = "CONFORMITY_APPROVAL_SERVICES" + }, + new + { + Id = 13, + Label = "SERVICE_LEADIMAGE" + }, + new + { + Id = 14, + Label = "PRESENTATION" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IamClient", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ClientClientId") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("client_client_id"); + + b.HasKey("Id") + .HasName("pk_iam_clients"); + + b.HasIndex("ClientClientId") + .IsUnique() + .HasDatabaseName("ix_iam_clients_client_client_id"); + + b.ToTable("iam_clients", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IamIdentityProvider", b => + { + b.Property("IamIdpAlias") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("iam_idp_alias"); + + b.Property("IdentityProviderId") + .HasColumnType("uuid") + .HasColumnName("identity_provider_id"); + + b.HasKey("IamIdpAlias") + .HasName("pk_iam_identity_providers"); + + b.HasIndex("IdentityProviderId") + .IsUnique() + .HasDatabaseName("ix_iam_identity_providers_identity_provider_id"); + + b.ToTable("iam_identity_providers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("IdentityTypeId") + .HasColumnType("integer") + .HasColumnName("identity_type_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("UserEntityId") + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("user_entity_id"); + + b.Property("UserStatusId") + .HasColumnType("integer") + .HasColumnName("user_status_id") + .HasAnnotation("Relational:JsonPropertyName", "user_status_id"); + + b.HasKey("Id") + .HasName("pk_identities"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_identities_company_id"); + + b.HasIndex("IdentityTypeId") + .HasDatabaseName("ix_identities_identity_type_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_identities_last_editor_id"); + + b.HasIndex("UserEntityId") + .IsUnique() + .HasDatabaseName("ix_identities_user_entity_id"); + + b.HasIndex("UserStatusId") + .HasDatabaseName("ix_identities_user_status_id"); + + b.ToTable("identities", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_IDENTITY"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_IDENTITY"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_IDENTITY", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_IDENTITY\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_IDENTITY$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_identity20231115\" (\"id\", \"date_created\", \"company_id\", \"user_status_id\", \"user_entity_id\", \"identity_type_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"company_id\", \r\n NEW.\"user_status_id\", \r\n NEW.\"user_entity_id\", \r\n NEW.\"identity_type_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_IDENTITY$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_IDENTITY AFTER INSERT\r\nON \"portal\".\"identities\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_IDENTITY\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_IDENTITY", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_IDENTITY\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_IDENTITY$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_identity20231115\" (\"id\", \"date_created\", \"company_id\", \"user_status_id\", \"user_entity_id\", \"identity_type_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"company_id\", \r\n NEW.\"user_status_id\", \r\n NEW.\"user_entity_id\", \r\n NEW.\"identity_type_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_IDENTITY$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_IDENTITY AFTER UPDATE\r\nON \"portal\".\"identities\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_IDENTITY\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityAssignedRole", b => + { + b.Property("IdentityId") + .HasColumnType("uuid") + .HasColumnName("identity_id"); + + b.Property("UserRoleId") + .HasColumnType("uuid") + .HasColumnName("user_role_id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("IdentityId", "UserRoleId") + .HasName("pk_identity_assigned_roles"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_identity_assigned_roles_last_editor_id"); + + b.HasIndex("UserRoleId") + .HasDatabaseName("ix_identity_assigned_roles_user_role_id"); + + b.ToTable("identity_assigned_roles", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_identity_assigned_role20230522\" (\"identity_id\", \"user_role_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"identity_id\", \r\n NEW.\"user_role_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE AFTER INSERT\r\nON \"portal\".\"identity_assigned_roles\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_IDENTITYASSIGNEDROLE\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_identity_assigned_role20230522\" (\"identity_id\", \"user_role_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"identity_id\", \r\n NEW.\"user_role_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE AFTER UPDATE\r\nON \"portal\".\"identity_assigned_roles\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_IDENTITYASSIGNEDROLE\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProvider", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("IdentityProviderCategoryId") + .HasColumnType("integer") + .HasColumnName("identity_provider_category_id"); + + b.Property("IdentityProviderTypeId") + .HasColumnType("integer") + .HasColumnName("identity_provider_type_id"); + + b.Property("OwnerId") + .HasColumnType("uuid") + .HasColumnName("owner_id"); + + b.HasKey("Id") + .HasName("pk_identity_providers"); + + b.HasIndex("IdentityProviderCategoryId") + .HasDatabaseName("ix_identity_providers_identity_provider_category_id"); + + b.HasIndex("IdentityProviderTypeId") + .HasDatabaseName("ix_identity_providers_identity_provider_type_id"); + + b.HasIndex("OwnerId") + .HasDatabaseName("ix_identity_providers_owner_id"); + + b.ToTable("identity_providers", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProviderCategory", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_identity_provider_categories"); + + b.ToTable("identity_provider_categories", "portal"); + + b.HasData( + new + { + Id = 2, + Label = "KEYCLOAK_OIDC" + }, + new + { + Id = 3, + Label = "KEYCLOAK_SAML" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProviderType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_identity_provider_types"); + + b.ToTable("identity_provider_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "OWN" + }, + new + { + Id = 2, + Label = "MANAGED" + }, + new + { + Id = 3, + Label = "SHARED" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_identity_type"); + + b.ToTable("identity_type", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "COMPANY_USER" + }, + new + { + Id = 2, + Label = "COMPANY_SERVICE_ACCOUNT" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityUserStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_identity_user_statuses"); + + b.ToTable("identity_user_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "ACTIVE" + }, + new + { + Id = 2, + Label = "INACTIVE" + }, + new + { + Id = 3, + Label = "DELETED" + }, + new + { + Id = 4, + Label = "PENDING" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Invitation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CompanyApplicationId") + .HasColumnType("uuid") + .HasColumnName("company_application_id"); + + b.Property("CompanyUserId") + .HasColumnType("uuid") + .HasColumnName("company_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("InvitationStatusId") + .HasColumnType("integer") + .HasColumnName("invitation_status_id"); + + b.HasKey("Id") + .HasName("pk_invitations"); + + b.HasIndex("CompanyApplicationId") + .HasDatabaseName("ix_invitations_company_application_id"); + + b.HasIndex("CompanyUserId") + .HasDatabaseName("ix_invitations_company_user_id"); + + b.HasIndex("InvitationStatusId") + .HasDatabaseName("ix_invitations_invitation_status_id"); + + b.ToTable("invitations", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.InvitationStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_invitation_statuses"); + + b.ToTable("invitation_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "CREATED" + }, + new + { + Id = 2, + Label = "PENDING" + }, + new + { + Id = 3, + Label = "ACCEPTED" + }, + new + { + Id = 4, + Label = "DECLINED" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", b => + { + b.Property("ShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("short_name") + .IsFixedLength(); + + b.HasKey("ShortName") + .HasName("pk_languages"); + + b.ToTable("languages", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.LanguageLongName", b => + { + b.Property("ShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("short_name") + .IsFixedLength(); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name") + .IsFixedLength(); + + b.Property("LongName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("long_name"); + + b.HasKey("ShortName", "LanguageShortName") + .HasName("pk_language_long_names"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_language_long_names_language_short_name"); + + b.ToTable("language_long_names", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.LicenseType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_license_types"); + + b.ToTable("license_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "COTS" + }, + new + { + Id = 2, + Label = "FOSS" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.MediaType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_media_types"); + + b.ToTable("media_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "JPEG" + }, + new + { + Id = 2, + Label = "GIF" + }, + new + { + Id = 3, + Label = "PNG" + }, + new + { + Id = 4, + Label = "SVG" + }, + new + { + Id = 5, + Label = "TIFF" + }, + new + { + Id = 6, + Label = "PDF" + }, + new + { + Id = 7, + Label = "JSON" + }, + new + { + Id = 8, + Label = "PEM" + }, + new + { + Id = 9, + Label = "CA_CERT" + }, + new + { + Id = 10, + Label = "PKX_CER" + }, + new + { + Id = 11, + Label = "OCTET" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NetworkRegistration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ApplicationId") + .HasColumnType("uuid") + .HasColumnName("application_id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("external_id"); + + b.Property("OnboardingServiceProviderId") + .HasColumnType("uuid") + .HasColumnName("onboarding_service_provider_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.HasKey("Id") + .HasName("pk_network_registrations"); + + b.HasIndex("ApplicationId") + .IsUnique() + .HasDatabaseName("ix_network_registrations_application_id"); + + b.HasIndex("CompanyId") + .IsUnique() + .HasDatabaseName("ix_network_registrations_company_id"); + + b.HasIndex("OnboardingServiceProviderId") + .HasDatabaseName("ix_network_registrations_onboarding_service_provider_id"); + + b.HasIndex("ProcessId") + .IsUnique() + .HasDatabaseName("ix_network_registrations_process_id"); + + b.HasIndex("ExternalId", "OnboardingServiceProviderId") + .IsUnique() + .HasDatabaseName("ix_network_registrations_external_id_onboarding_service_provid"); + + b.ToTable("network_registrations", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Content") + .HasColumnType("text") + .HasColumnName("content"); + + b.Property("CreatorUserId") + .HasColumnType("uuid") + .HasColumnName("creator_user_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("Done") + .HasColumnType("boolean") + .HasColumnName("done"); + + b.Property("DueDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("due_date"); + + b.Property("IsRead") + .HasColumnType("boolean") + .HasColumnName("is_read"); + + b.Property("NotificationTypeId") + .HasColumnType("integer") + .HasColumnName("notification_type_id"); + + b.Property("ReceiverUserId") + .HasColumnType("uuid") + .HasColumnName("receiver_user_id"); + + b.HasKey("Id") + .HasName("pk_notifications"); + + b.HasIndex("CreatorUserId") + .HasDatabaseName("ix_notifications_creator_user_id"); + + b.HasIndex("NotificationTypeId") + .HasDatabaseName("ix_notifications_notification_type_id"); + + b.HasIndex("ReceiverUserId") + .HasDatabaseName("ix_notifications_receiver_user_id"); + + b.ToTable("notifications", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationTopic", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_notification_topic"); + + b.ToTable("notification_topic", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "INFO" + }, + new + { + Id = 2, + Label = "ACTION" + }, + new + { + Id = 3, + Label = "OFFER" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_notification_type"); + + b.ToTable("notification_type", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "INFO" + }, + new + { + Id = 2, + Label = "ACTION" + }, + new + { + Id = 3, + Label = "WELCOME" + }, + new + { + Id = 4, + Label = "WELCOME_USE_CASES" + }, + new + { + Id = 5, + Label = "WELCOME_SERVICE_PROVIDER" + }, + new + { + Id = 6, + Label = "WELCOME_CONNECTOR_REGISTRATION" + }, + new + { + Id = 7, + Label = "WELCOME_APP_MARKETPLACE" + }, + new + { + Id = 8, + Label = "APP_SUBSCRIPTION_REQUEST" + }, + new + { + Id = 9, + Label = "APP_SUBSCRIPTION_ACTIVATION" + }, + new + { + Id = 10, + Label = "CONNECTOR_REGISTERED" + }, + new + { + Id = 11, + Label = "APP_RELEASE_REQUEST" + }, + new + { + Id = 12, + Label = "TECHNICAL_USER_CREATION" + }, + new + { + Id = 13, + Label = "SERVICE_REQUEST" + }, + new + { + Id = 14, + Label = "SERVICE_ACTIVATION" + }, + new + { + Id = 15, + Label = "APP_ROLE_ADDED" + }, + new + { + Id = 16, + Label = "APP_RELEASE_APPROVAL" + }, + new + { + Id = 17, + Label = "SERVICE_RELEASE_REQUEST" + }, + new + { + Id = 18, + Label = "SERVICE_RELEASE_APPROVAL" + }, + new + { + Id = 19, + Label = "APP_RELEASE_REJECTION" + }, + new + { + Id = 20, + Label = "SERVICE_RELEASE_REJECTION" + }, + new + { + Id = 21, + Label = "ROLE_UPDATE_CORE_OFFER" + }, + new + { + Id = 22, + Label = "ROLE_UPDATE_APP_OFFER" + }, + new + { + Id = 23, + Label = "SUBSCRIPTION_URL_UPDATE" + }, + new + { + Id = 24, + Label = "CREDENTIAL_APPROVAL" + }, + new + { + Id = 25, + Label = "CREDENTIAL_REJECTED" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationTypeAssignedTopic", b => + { + b.Property("NotificationTypeId") + .HasColumnType("integer") + .HasColumnName("notification_type_id"); + + b.Property("NotificationTopicId") + .HasColumnType("integer") + .HasColumnName("notification_topic_id"); + + b.HasKey("NotificationTypeId", "NotificationTopicId") + .HasName("pk_notification_type_assigned_topics"); + + b.HasIndex("NotificationTopicId") + .HasDatabaseName("ix_notification_type_assigned_topics_notification_topic_id"); + + b.HasIndex("NotificationTypeId") + .IsUnique() + .HasDatabaseName("ix_notification_type_assigned_topics_notification_type_id"); + + b.ToTable("notification_type_assigned_topics", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ContactEmail") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("contact_email"); + + b.Property("ContactNumber") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("contact_number"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("DateReleased") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_released"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("LicenseTypeId") + .HasColumnType("integer") + .HasColumnName("license_type_id"); + + b.Property("MarketingUrl") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("marketing_url"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("OfferStatusId") + .HasColumnType("integer") + .HasColumnName("offer_status_id"); + + b.Property("OfferTypeId") + .HasColumnType("integer") + .HasColumnName("offer_type_id"); + + b.Property("Provider") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("provider"); + + b.Property("ProviderCompanyId") + .HasColumnType("uuid") + .HasColumnName("provider_company_id"); + + b.Property("SalesManagerId") + .HasColumnType("uuid") + .HasColumnName("sales_manager_id"); + + b.HasKey("Id") + .HasName("pk_offers"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_offers_last_editor_id"); + + b.HasIndex("LicenseTypeId") + .HasDatabaseName("ix_offers_license_type_id"); + + b.HasIndex("OfferStatusId") + .HasDatabaseName("ix_offers_offer_status_id"); + + b.HasIndex("OfferTypeId") + .HasDatabaseName("ix_offers_offer_type_id"); + + b.HasIndex("ProviderCompanyId") + .HasDatabaseName("ix_offers_provider_company_id"); + + b.HasIndex("SalesManagerId") + .HasDatabaseName("ix_offers_sales_manager_id"); + + b.ToTable("offers", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_OFFER"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_OFFER"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_OFFER", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_OFFER\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_OFFER$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_offer20231115\" (\"id\", \"name\", \"date_created\", \"date_released\", \"marketing_url\", \"contact_email\", \"contact_number\", \"provider\", \"offer_type_id\", \"sales_manager_id\", \"provider_company_id\", \"offer_status_id\", \"license_type_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"name\", \r\n NEW.\"date_created\", \r\n NEW.\"date_released\", \r\n NEW.\"marketing_url\", \r\n NEW.\"contact_email\", \r\n NEW.\"contact_number\", \r\n NEW.\"provider\", \r\n NEW.\"offer_type_id\", \r\n NEW.\"sales_manager_id\", \r\n NEW.\"provider_company_id\", \r\n NEW.\"offer_status_id\", \r\n NEW.\"license_type_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_OFFER$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_OFFER AFTER INSERT\r\nON \"portal\".\"offers\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_OFFER\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_OFFER", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_OFFER\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_OFFER$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_offer20231115\" (\"id\", \"name\", \"date_created\", \"date_released\", \"marketing_url\", \"contact_email\", \"contact_number\", \"provider\", \"offer_type_id\", \"sales_manager_id\", \"provider_company_id\", \"offer_status_id\", \"license_type_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"name\", \r\n NEW.\"date_created\", \r\n NEW.\"date_released\", \r\n NEW.\"marketing_url\", \r\n NEW.\"contact_email\", \r\n NEW.\"contact_number\", \r\n NEW.\"provider\", \r\n NEW.\"offer_type_id\", \r\n NEW.\"sales_manager_id\", \r\n NEW.\"provider_company_id\", \r\n NEW.\"offer_status_id\", \r\n NEW.\"license_type_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_OFFER$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_OFFER AFTER UPDATE\r\nON \"portal\".\"offers\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_OFFER\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferAssignedDocument", b => + { + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasColumnName("document_id"); + + b.HasKey("OfferId", "DocumentId") + .HasName("pk_offer_assigned_documents"); + + b.HasIndex("DocumentId") + .HasDatabaseName("ix_offer_assigned_documents_document_id"); + + b.ToTable("offer_assigned_documents", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferAssignedLicense", b => + { + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("OfferLicenseId") + .HasColumnType("uuid") + .HasColumnName("offer_license_id"); + + b.HasKey("OfferId", "OfferLicenseId") + .HasName("pk_offer_assigned_licenses"); + + b.HasIndex("OfferLicenseId") + .HasDatabaseName("ix_offer_assigned_licenses_offer_license_id"); + + b.ToTable("offer_assigned_licenses", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferAssignedPrivacyPolicy", b => + { + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("PrivacyPolicyId") + .HasColumnType("integer") + .HasColumnName("privacy_policy_id"); + + b.HasKey("OfferId", "PrivacyPolicyId") + .HasName("pk_offer_assigned_privacy_policies"); + + b.HasIndex("PrivacyPolicyId") + .HasDatabaseName("ix_offer_assigned_privacy_policies_privacy_policy_id"); + + b.ToTable("offer_assigned_privacy_policies", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferDescription", b => + { + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name"); + + b.Property("DescriptionLong") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("description_long"); + + b.Property("DescriptionShort") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description_short"); + + b.HasKey("OfferId", "LanguageShortName") + .HasName("pk_offer_descriptions"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_offer_descriptions_language_short_name"); + + b.ToTable("offer_descriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferLicense", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Licensetext") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("licensetext"); + + b.HasKey("Id") + .HasName("pk_offer_licenses"); + + b.ToTable("offer_licenses", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_offer_statuses"); + + b.ToTable("offer_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "CREATED" + }, + new + { + Id = 2, + Label = "IN_REVIEW" + }, + new + { + Id = 3, + Label = "ACTIVE" + }, + new + { + Id = 4, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("Description") + .HasMaxLength(4096) + .HasColumnType("character varying(4096)") + .HasColumnName("description"); + + b.Property("DisplayName") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("display_name"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("OfferSubscriptionStatusId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(1) + .HasColumnName("offer_subscription_status_id"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("RequesterId") + .HasColumnType("uuid") + .HasColumnName("requester_id"); + + b.HasKey("Id") + .HasName("pk_offer_subscriptions"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_offer_subscriptions_company_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_offer_subscriptions_last_editor_id"); + + b.HasIndex("OfferId") + .HasDatabaseName("ix_offer_subscriptions_offer_id"); + + b.HasIndex("OfferSubscriptionStatusId") + .HasDatabaseName("ix_offer_subscriptions_offer_subscription_status_id"); + + b.HasIndex("ProcessId") + .IsUnique() + .HasDatabaseName("ix_offer_subscriptions_process_id"); + + b.HasIndex("RequesterId") + .HasDatabaseName("ix_offer_subscriptions_requester_id"); + + b.ToTable("offer_subscriptions", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_offer_subscription20231115\" (\"id\", \"company_id\", \"offer_id\", \"offer_subscription_status_id\", \"display_name\", \"description\", \"requester_id\", \"last_editor_id\", \"process_id\", \"date_created\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"company_id\", \r\n NEW.\"offer_id\", \r\n NEW.\"offer_subscription_status_id\", \r\n NEW.\"display_name\", \r\n NEW.\"description\", \r\n NEW.\"requester_id\", \r\n NEW.\"last_editor_id\", \r\n NEW.\"process_id\", \r\n NEW.\"date_created\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION AFTER INSERT\r\nON \"portal\".\"offer_subscriptions\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_OFFERSUBSCRIPTION\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_offer_subscription20231115\" (\"id\", \"company_id\", \"offer_id\", \"offer_subscription_status_id\", \"display_name\", \"description\", \"requester_id\", \"last_editor_id\", \"process_id\", \"date_created\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"company_id\", \r\n NEW.\"offer_id\", \r\n NEW.\"offer_subscription_status_id\", \r\n NEW.\"display_name\", \r\n NEW.\"description\", \r\n NEW.\"requester_id\", \r\n NEW.\"last_editor_id\", \r\n NEW.\"process_id\", \r\n NEW.\"date_created\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION AFTER UPDATE\r\nON \"portal\".\"offer_subscriptions\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_OFFERSUBSCRIPTION\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscriptionProcessData", b => + { + b.Property("OfferSubscriptionId") + .HasColumnType("uuid") + .HasColumnName("offer_subscription_id"); + + b.Property("OfferUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("offer_url"); + + b.HasKey("OfferSubscriptionId") + .HasName("pk_offer_subscriptions_process_datas"); + + b.ToTable("offer_subscriptions_process_datas", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscriptionStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_offer_subscription_statuses"); + + b.ToTable("offer_subscription_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "PENDING" + }, + new + { + Id = 2, + Label = "ACTIVE" + }, + new + { + Id = 3, + Label = "INACTIVE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferTag", b => + { + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("tag_name") + .HasAnnotation("Relational:JsonPropertyName", "tag_name"); + + b.HasKey("OfferId", "Name") + .HasName("pk_offer_tags"); + + b.ToTable("offer_tags", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_offer_types"); + + b.ToTable("offer_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "APP" + }, + new + { + Id = 2, + Label = "CORE_COMPONENT" + }, + new + { + Id = 3, + Label = "SERVICE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OnboardingServiceProviderDetail", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("AuthUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("auth_url"); + + b.Property("CallbackUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("callback_url"); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("client_id"); + + b.Property("ClientSecret") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("client_secret"); + + b.HasKey("CompanyId") + .HasName("pk_onboarding_service_provider_details"); + + b.ToTable("onboarding_service_provider_details", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.PrivacyPolicy", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_privacy_policies"); + + b.ToTable("privacy_policies", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "COMPANY_DATA" + }, + new + { + Id = 2, + Label = "USER_DATA" + }, + new + { + Id = 3, + Label = "LOCATION" + }, + new + { + Id = 4, + Label = "BROWSER_HISTORY" + }, + new + { + Id = 5, + Label = "NONE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LockExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("lock_expiry_date"); + + b.Property("ProcessTypeId") + .HasColumnType("integer") + .HasColumnName("process_type_id"); + + b.Property("Version") + .IsConcurrencyToken() + .HasColumnType("uuid") + .HasColumnName("version"); + + b.HasKey("Id") + .HasName("pk_processes"); + + b.HasIndex("ProcessTypeId") + .HasDatabaseName("ix_processes_process_type_id"); + + b.ToTable("processes", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStep", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("Message") + .HasColumnType("text") + .HasColumnName("message"); + + b.Property("ProcessId") + .HasColumnType("uuid") + .HasColumnName("process_id"); + + b.Property("ProcessStepStatusId") + .HasColumnType("integer") + .HasColumnName("process_step_status_id"); + + b.Property("ProcessStepTypeId") + .HasColumnType("integer") + .HasColumnName("process_step_type_id"); + + b.HasKey("Id") + .HasName("pk_process_steps"); + + b.HasIndex("ProcessId") + .HasDatabaseName("ix_process_steps_process_id"); + + b.HasIndex("ProcessStepStatusId") + .HasDatabaseName("ix_process_steps_process_step_status_id"); + + b.HasIndex("ProcessStepTypeId") + .HasDatabaseName("ix_process_steps_process_step_type_id"); + + b.ToTable("process_steps", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStepStatus", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_process_step_statuses"); + + b.ToTable("process_step_statuses", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "TODO" + }, + new + { + Id = 2, + Label = "DONE" + }, + new + { + Id = 3, + Label = "SKIPPED" + }, + new + { + Id = 4, + Label = "FAILED" + }, + new + { + Id = 5, + Label = "DUPLICATE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStepType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_process_step_types"); + + b.ToTable("process_step_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "VERIFY_REGISTRATION" + }, + new + { + Id = 2, + Label = "CREATE_BUSINESS_PARTNER_NUMBER_PUSH" + }, + new + { + Id = 3, + Label = "CREATE_BUSINESS_PARTNER_NUMBER_PULL" + }, + new + { + Id = 4, + Label = "CREATE_BUSINESS_PARTNER_NUMBER_MANUAL" + }, + new + { + Id = 5, + Label = "CREATE_IDENTITY_WALLET" + }, + new + { + Id = 6, + Label = "RETRIGGER_IDENTITY_WALLET" + }, + new + { + Id = 7, + Label = "START_CLEARING_HOUSE" + }, + new + { + Id = 8, + Label = "RETRIGGER_CLEARING_HOUSE" + }, + new + { + Id = 9, + Label = "END_CLEARING_HOUSE" + }, + new + { + Id = 10, + Label = "START_SELF_DESCRIPTION_LP" + }, + new + { + Id = 11, + Label = "RETRIGGER_SELF_DESCRIPTION_LP" + }, + new + { + Id = 12, + Label = "ACTIVATE_APPLICATION" + }, + new + { + Id = 13, + Label = "RETRIGGER_BUSINESS_PARTNER_NUMBER_PUSH" + }, + new + { + Id = 14, + Label = "RETRIGGER_BUSINESS_PARTNER_NUMBER_PULL" + }, + new + { + Id = 15, + Label = "OVERRIDE_BUSINESS_PARTNER_NUMBER" + }, + new + { + Id = 16, + Label = "TRIGGER_OVERRIDE_CLEARING_HOUSE" + }, + new + { + Id = 17, + Label = "START_OVERRIDE_CLEARING_HOUSE" + }, + new + { + Id = 18, + Label = "FINISH_SELF_DESCRIPTION_LP" + }, + new + { + Id = 19, + Label = "DECLINE_APPLICATION" + }, + new + { + Id = 100, + Label = "TRIGGER_PROVIDER" + }, + new + { + Id = 101, + Label = "START_AUTOSETUP" + }, + new + { + Id = 102, + Label = "OFFERSUBSCRIPTION_CLIENT_CREATION" + }, + new + { + Id = 103, + Label = "SINGLE_INSTANCE_SUBSCRIPTION_DETAILS_CREATION" + }, + new + { + Id = 104, + Label = "OFFERSUBSCRIPTION_TECHNICALUSER_CREATION" + }, + new + { + Id = 105, + Label = "ACTIVATE_SUBSCRIPTION" + }, + new + { + Id = 106, + Label = "TRIGGER_PROVIDER_CALLBACK" + }, + new + { + Id = 107, + Label = "RETRIGGER_PROVIDER" + }, + new + { + Id = 108, + Label = "RETRIGGER_OFFERSUBSCRIPTION_CLIENT_CREATION" + }, + new + { + Id = 109, + Label = "RETRIGGER_OFFERSUBSCRIPTION_TECHNICALUSER_CREATION" + }, + new + { + Id = 110, + Label = "RETRIGGER_PROVIDER_CALLBACK" + }, + new + { + Id = 111, + Label = "TRIGGER_ACTIVATE_SUBSCRIPTION" + }, + new + { + Id = 200, + Label = "SYNCHRONIZE_USER" + }, + new + { + Id = 201, + Label = "RETRIGGER_SYNCHRONIZE_USER" + }, + new + { + Id = 202, + Label = "TRIGGER_CALLBACK_OSP_SUBMITTED" + }, + new + { + Id = 203, + Label = "TRIGGER_CALLBACK_OSP_APPROVED" + }, + new + { + Id = 204, + Label = "TRIGGER_CALLBACK_OSP_DECLINED" + }, + new + { + Id = 205, + Label = "RETRIGGER_CALLBACK_OSP_SUBMITTED" + }, + new + { + Id = 206, + Label = "RETRIGGER_CALLBACK_OSP_APPROVED" + }, + new + { + Id = 207, + Label = "RETRIGGER_CALLBACK_OSP_DECLINED" + }, + new + { + Id = 208, + Label = "MANUAL_DECLINE_OSP" + }, + new + { + Id = 209, + Label = "REMOVE_KEYCLOAK_USERS" + }, + new + { + Id = 210, + Label = "RETRIGGER_REMOVE_KEYCLOAK_USERS" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_process_types"); + + b.ToTable("process_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "APPLICATION_CHECKLIST" + }, + new + { + Id = 3, + Label = "OFFER_SUBSCRIPTION" + }, + new + { + Id = 4, + Label = "PARTNER_REGISTRATION" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProviderCompanyDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AutoSetupCallbackUrl") + .HasColumnType("text") + .HasColumnName("auto_setup_callback_url"); + + b.Property("AutoSetupUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("auto_setup_url"); + + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateLastChanged") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_changed"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.HasKey("Id") + .HasName("pk_provider_company_details"); + + b.HasIndex("CompanyId") + .IsUnique() + .HasDatabaseName("ix_provider_company_details_company_id"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_provider_company_details_last_editor_id"); + + b.ToTable("provider_company_details", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_provider_company_detail20231115\" (\"id\", \"date_created\", \"auto_setup_url\", \"auto_setup_callback_url\", \"company_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"auto_setup_url\", \r\n NEW.\"auto_setup_callback_url\", \r\n NEW.\"company_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL AFTER INSERT\r\nON \"portal\".\"provider_company_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_PROVIDERCOMPANYDETAIL\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_provider_company_detail20231115\" (\"id\", \"date_created\", \"auto_setup_url\", \"auto_setup_callback_url\", \"company_id\", \"date_last_changed\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"date_created\", \r\n NEW.\"auto_setup_url\", \r\n NEW.\"auto_setup_callback_url\", \r\n NEW.\"company_id\", \r\n NEW.\"date_last_changed\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL AFTER UPDATE\r\nON \"portal\".\"provider_company_details\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_PROVIDERCOMPANYDETAIL\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ServiceDetail", b => + { + b.Property("ServiceId") + .HasColumnType("uuid") + .HasColumnName("service_id"); + + b.Property("ServiceTypeId") + .HasColumnType("integer") + .HasColumnName("service_type_id"); + + b.HasKey("ServiceId", "ServiceTypeId") + .HasName("pk_service_details"); + + b.HasIndex("ServiceTypeId") + .HasDatabaseName("ix_service_details_service_type_id"); + + b.ToTable("service_details", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ServiceType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_service_types"); + + b.ToTable("service_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "DATASPACE_SERVICE" + }, + new + { + Id = 2, + Label = "CONSULTANCY_SERVICE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.TechnicalUserProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.HasKey("Id") + .HasName("pk_technical_user_profiles"); + + b.HasIndex("OfferId") + .HasDatabaseName("ix_technical_user_profiles_offer_id"); + + b.ToTable("technical_user_profiles", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.TechnicalUserProfileAssignedUserRole", b => + { + b.Property("TechnicalUserProfileId") + .HasColumnType("uuid") + .HasColumnName("technical_user_profile_id"); + + b.Property("UserRoleId") + .HasColumnType("uuid") + .HasColumnName("user_role_id"); + + b.HasKey("TechnicalUserProfileId", "UserRoleId") + .HasName("pk_technical_user_profile_assigned_user_roles"); + + b.HasIndex("UserRoleId") + .HasDatabaseName("ix_technical_user_profile_assigned_user_roles_user_role_id"); + + b.ToTable("technical_user_profile_assigned_user_roles", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UniqueIdentifier", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_unique_identifiers"); + + b.ToTable("unique_identifiers", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "COMMERCIAL_REG_NUMBER" + }, + new + { + Id = 2, + Label = "VAT_ID" + }, + new + { + Id = 3, + Label = "LEI_CODE" + }, + new + { + Id = 4, + Label = "VIES" + }, + new + { + Id = 5, + Label = "EORI" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("Shortname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("shortname"); + + b.HasKey("Id") + .HasName("pk_use_cases"); + + b.ToTable("use_cases", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCaseDescription", b => + { + b.Property("UseCaseId") + .HasColumnType("uuid") + .HasColumnName("use_case_id"); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasColumnName("description"); + + b.HasKey("UseCaseId", "LanguageShortName") + .HasName("pk_use_case_descriptions"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_use_case_descriptions_language_short_name"); + + b.ToTable("use_case_descriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("LastEditorId") + .HasColumnType("uuid") + .HasColumnName("last_editor_id"); + + b.Property("OfferId") + .HasColumnType("uuid") + .HasColumnName("offer_id"); + + b.Property("UserRoleText") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("user_role") + .HasAnnotation("Relational:JsonPropertyName", "user_role"); + + b.HasKey("Id") + .HasName("pk_user_roles"); + + b.HasIndex("LastEditorId") + .HasDatabaseName("ix_user_roles_last_editor_id"); + + b.HasIndex("OfferId") + .HasDatabaseName("ix_user_roles_offer_id"); + + b.ToTable("user_roles", "portal", t => + { + t.HasTrigger("LC_TRIGGER_AFTER_INSERT_USERROLE"); + + t.HasTrigger("LC_TRIGGER_AFTER_UPDATE_USERROLE"); + }); + + b + .HasAnnotation("LC_TRIGGER_AFTER_INSERT_USERROLE", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_USERROLE\"() RETURNS trigger as $LC_TRIGGER_AFTER_INSERT_USERROLE$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_user_role20231115\" (\"id\", \"user_role\", \"offer_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"user_role\", \r\n NEW.\"offer_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 1, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_INSERT_USERROLE$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_INSERT_USERROLE AFTER INSERT\r\nON \"portal\".\"user_roles\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_INSERT_USERROLE\"();") + .HasAnnotation("LC_TRIGGER_AFTER_UPDATE_USERROLE", "CREATE FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_USERROLE\"() RETURNS trigger as $LC_TRIGGER_AFTER_UPDATE_USERROLE$\r\nBEGIN\r\n INSERT INTO \"portal\".\"audit_user_role20231115\" (\"id\", \"user_role\", \"offer_id\", \"last_editor_id\", \"audit_v1id\", \"audit_v1operation_id\", \"audit_v1date_last_changed\", \"audit_v1last_editor_id\") SELECT NEW.\"id\", \r\n NEW.\"user_role\", \r\n NEW.\"offer_id\", \r\n NEW.\"last_editor_id\", \r\n gen_random_uuid(), \r\n 2, \r\n CURRENT_TIMESTAMP, \r\n NEW.\"last_editor_id\";\r\nRETURN NEW;\r\nEND;\r\n$LC_TRIGGER_AFTER_UPDATE_USERROLE$ LANGUAGE plpgsql;\r\nCREATE TRIGGER LC_TRIGGER_AFTER_UPDATE_USERROLE AFTER UPDATE\r\nON \"portal\".\"user_roles\"\r\nFOR EACH ROW EXECUTE PROCEDURE \"portal\".\"LC_TRIGGER_AFTER_UPDATE_USERROLE\"();"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleAssignedCollection", b => + { + b.Property("UserRoleId") + .HasColumnType("uuid") + .HasColumnName("user_role_id"); + + b.Property("UserRoleCollectionId") + .HasColumnType("uuid") + .HasColumnName("user_role_collection_id"); + + b.HasKey("UserRoleId", "UserRoleCollectionId") + .HasName("pk_user_role_assigned_collections"); + + b.HasIndex("UserRoleCollectionId") + .HasDatabaseName("ix_user_role_assigned_collections_user_role_collection_id"); + + b.ToTable("user_role_assigned_collections", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_user_role_collections"); + + b.ToTable("user_role_collections", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollectionDescription", b => + { + b.Property("UserRoleCollectionId") + .HasColumnType("uuid") + .HasColumnName("user_role_collection_id"); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description"); + + b.HasKey("UserRoleCollectionId", "LanguageShortName") + .HasName("pk_user_role_collection_descriptions"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_user_role_collection_descriptions_language_short_name"); + + b.ToTable("user_role_collection_descriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleDescription", b => + { + b.Property("UserRoleId") + .HasColumnType("uuid") + .HasColumnName("user_role_id"); + + b.Property("LanguageShortName") + .HasMaxLength(2) + .HasColumnType("character(2)") + .HasColumnName("language_short_name"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description"); + + b.HasKey("UserRoleId", "LanguageShortName") + .HasName("pk_user_role_descriptions"); + + b.HasIndex("LanguageShortName") + .HasDatabaseName("ix_user_role_descriptions_language_short_name"); + + b.ToTable("user_role_descriptions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasColumnType("text") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_verified_credential_external_types"); + + b.ToTable("verified_credential_external_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "TRACEABILITY_CREDENTIAL" + }, + new + { + Id = 2, + Label = "PCF_CREDENTIAL" + }, + new + { + Id = 3, + Label = "BEHAVIOR_TWIN_CREDENTIAL" + }, + new + { + Id = 4, + Label = "VEHICLE_DISMANTLE" + }, + new + { + Id = 5, + Label = "SUSTAINABILITY_CREDENTIAL" + }, + new + { + Id = 6, + Label = "Quality_Credential" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalTypeUseCaseDetailVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Expiry") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry"); + + b.Property("Template") + .HasColumnType("text") + .HasColumnName("template"); + + b.Property("ValidFrom") + .HasColumnType("timestamp with time zone") + .HasColumnName("valid_from"); + + b.Property("VerifiedCredentialExternalTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_external_type_id"); + + b.Property("Version") + .IsRequired() + .HasColumnType("text") + .HasColumnName("version"); + + b.HasKey("Id") + .HasName("pk_verified_credential_external_type_use_case_detail_versions"); + + b.HasIndex("VerifiedCredentialExternalTypeId", "Version") + .IsUnique() + .HasDatabaseName("ix_verified_credential_external_type_use_case_detail_versions_"); + + b.ToTable("verified_credential_external_type_use_case_detail_versions", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialType", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_verified_credential_types"); + + b.ToTable("verified_credential_types", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "TRACEABILITY_FRAMEWORK" + }, + new + { + Id = 2, + Label = "PCF_FRAMEWORK" + }, + new + { + Id = 3, + Label = "BEHAVIOR_TWIN_FRAMEWORK" + }, + new + { + Id = 4, + Label = "DISMANTLER_CERTIFICATE" + }, + new + { + Id = 5, + Label = "SUSTAINABILITY_FRAMEWORK" + }, + new + { + Id = 6, + Label = "FRAMEWORK_AGREEMENT_QUALITY" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedExternalType", b => + { + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.Property("VerifiedCredentialExternalTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_external_type_id"); + + b.HasKey("VerifiedCredentialTypeId", "VerifiedCredentialExternalTypeId") + .HasName("pk_verified_credential_type_assigned_external_types"); + + b.HasIndex("VerifiedCredentialExternalTypeId") + .HasDatabaseName("ix_verified_credential_type_assigned_external_types_verified_c"); + + b.HasIndex("VerifiedCredentialTypeId") + .IsUnique() + .HasDatabaseName("ix_verified_credential_type_assigned_external_types_verified_c1"); + + b.ToTable("verified_credential_type_assigned_external_types", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedKind", b => + { + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.Property("VerifiedCredentialTypeKindId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_kind_id"); + + b.HasKey("VerifiedCredentialTypeId", "VerifiedCredentialTypeKindId") + .HasName("pk_verified_credential_type_assigned_kinds"); + + b.HasIndex("VerifiedCredentialTypeId") + .HasDatabaseName("ix_verified_credential_type_assigned_kinds_verified_credential"); + + b.HasIndex("VerifiedCredentialTypeKindId") + .HasDatabaseName("ix_verified_credential_type_assigned_kinds_verified_credential1"); + + b.ToTable("verified_credential_type_assigned_kinds", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedUseCase", b => + { + b.Property("VerifiedCredentialTypeId") + .HasColumnType("integer") + .HasColumnName("verified_credential_type_id"); + + b.Property("UseCaseId") + .HasColumnType("uuid") + .HasColumnName("use_case_id"); + + b.HasKey("VerifiedCredentialTypeId", "UseCaseId") + .HasName("pk_verified_credential_type_assigned_use_cases"); + + b.HasIndex("UseCaseId") + .IsUnique() + .HasDatabaseName("ix_verified_credential_type_assigned_use_cases_use_case_id"); + + b.HasIndex("VerifiedCredentialTypeId") + .IsUnique() + .HasDatabaseName("ix_verified_credential_type_assigned_use_cases_verified_creden"); + + b.ToTable("verified_credential_type_assigned_use_cases", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeKind", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Label") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("label"); + + b.HasKey("Id") + .HasName("pk_verified_credential_type_kinds"); + + b.ToTable("verified_credential_type_kinds", "portal"); + + b.HasData( + new + { + Id = 1, + Label = "USE_CASE" + }, + new + { + Id = 2, + Label = "CERTIFICATE" + }); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.AgreementView", b => + { + b.Property("AgreementCompanyRole") + .IsRequired() + .HasColumnType("text") + .HasColumnName("agreement_company_role"); + + b.Property("AgreementId") + .HasColumnType("uuid") + .HasColumnName("agreement_id"); + + b.Property("AgreementName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("agreement_name"); + + b.Property("AgreementStatus") + .IsRequired() + .HasColumnType("text") + .HasColumnName("agreement_status"); + + b.Property("Mandatory") + .HasColumnType("boolean") + .HasColumnName("mandatory"); + + b.ToTable((string)null); + + b.ToView("agreement_view", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompaniesLinkedServiceAccount", b => + { + b.Property("ServiceAccountId") + .HasColumnType("uuid") + .HasColumnName("service_account_id"); + + b.Property("Owners") + .HasColumnType("uuid") + .HasColumnName("owners"); + + b.Property("Provider") + .HasColumnType("uuid") + .HasColumnName("provider"); + + b.HasKey("ServiceAccountId"); + + b.ToTable((string)null); + + b.ToView("company_linked_service_accounts", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompanyConnectorView", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("company_name"); + + b.Property("ConnectorStatus") + .IsRequired() + .HasColumnType("text") + .HasColumnName("connector_status"); + + b.Property("ConnectorUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("connector_url"); + + b.ToTable((string)null); + + b.ToView("company_connector_view", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompanyIdpView", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("company_name"); + + b.Property("IdpAlias") + .IsRequired() + .HasColumnType("text") + .HasColumnName("idp_alias"); + + b.ToTable((string)null); + + b.ToView("company_idp_view", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompanyRoleCollectionRolesView", b => + { + b.Property("ClientName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("client_name"); + + b.Property("CollectionName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("collection_name"); + + b.Property("UserRole") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_role"); + + b.ToTable((string)null); + + b.ToView("companyrole_collectionroles_view", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompanyUsersView", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("company_name"); + + b.Property("FirstName") + .HasColumnType("text") + .HasColumnName("first_name"); + + b.Property("LastName") + .HasColumnType("text") + .HasColumnName("last_name"); + + b.Property("UserEmail") + .HasColumnType("text") + .HasColumnName("user_email"); + + b.Property("UserStatus") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_status"); + + b.ToTable((string)null); + + b.ToView("company_users_view", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.OfferSubscriptionView", b => + { + b.Property("AppInstance") + .HasColumnType("uuid") + .HasColumnName("app_instance"); + + b.Property("Connector") + .HasColumnType("uuid") + .HasColumnName("connector"); + + b.Property("OfferTypeId") + .HasColumnType("integer") + .HasColumnName("offer_type_id"); + + b.Property("SubscriptionId") + .HasColumnType("uuid") + .HasColumnName("subscription_id"); + + b.Property("TechnicalUser") + .HasColumnType("uuid") + .HasColumnName("technical_user"); + + b.ToTable((string)null); + + b.ToView("offer_subscription_view", "portal"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Address", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Country", "Country") + .WithMany("Addresses") + .HasForeignKey("CountryAlpha2Code") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_addresses_countries_country_temp_id"); + + b.Navigation("Country"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementCategory", "AgreementCategory") + .WithMany("Agreements") + .HasForeignKey("AgreementCategoryId") + .IsRequired() + .HasConstraintName("fk_agreements_agreement_categories_agreement_category_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementStatus", null) + .WithMany("Agreements") + .HasForeignKey("AgreementStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_agreements_agreement_statuses_agreement_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", "Document") + .WithMany("Agreements") + .HasForeignKey("DocumentId") + .HasConstraintName("fk_agreements_documents_document_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "IssuerCompany") + .WithMany("Agreements") + .HasForeignKey("IssuerCompanyId") + .IsRequired() + .HasConstraintName("fk_agreements_companies_issuer_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", "UseCase") + .WithMany("Agreements") + .HasForeignKey("UseCaseId") + .HasConstraintName("fk_agreements_use_cases_use_case_id"); + + b.Navigation("AgreementCategory"); + + b.Navigation("Document"); + + b.Navigation("IssuerCompany"); + + b.Navigation("UseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementAssignedCompanyRole", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", "Agreement") + .WithMany("AgreementAssignedCompanyRoles") + .HasForeignKey("AgreementId") + .IsRequired() + .HasConstraintName("fk_agreement_assigned_company_roles_agreements_agreement_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", "CompanyRole") + .WithMany("AgreementAssignedCompanyRoles") + .HasForeignKey("CompanyRoleId") + .IsRequired() + .HasConstraintName("fk_agreement_assigned_company_roles_company_roles_company_role"); + + b.Navigation("Agreement"); + + b.Navigation("CompanyRole"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementAssignedOffer", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", "Agreement") + .WithMany("AgreementAssignedOffers") + .HasForeignKey("AgreementId") + .IsRequired() + .HasConstraintName("fk_agreement_assigned_offers_agreements_agreement_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("AgreementAssignedOffers") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_agreement_assigned_offers_offers_offer_id"); + + b.Navigation("Agreement"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementAssignedOfferType", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", "Agreement") + .WithMany("AgreementAssignedOfferTypes") + .HasForeignKey("AgreementId") + .IsRequired() + .HasConstraintName("fk_agreement_assigned_offer_types_agreements_agreement_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferType", "OfferType") + .WithMany("AgreementAssignedOfferTypes") + .HasForeignKey("OfferTypeId") + .IsRequired() + .HasConstraintName("fk_agreement_assigned_offer_types_offer_types_offer_type_id"); + + b.Navigation("Agreement"); + + b.Navigation("OfferType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppAssignedUseCase", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "App") + .WithMany() + .HasForeignKey("AppId") + .IsRequired() + .HasConstraintName("fk_app_assigned_use_cases_offers_app_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", "UseCase") + .WithMany() + .HasForeignKey("UseCaseId") + .IsRequired() + .HasConstraintName("fk_app_assigned_use_cases_use_cases_use_case_id"); + + b.Navigation("App"); + + b.Navigation("UseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstance", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "App") + .WithMany("AppInstances") + .HasForeignKey("AppId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired() + .HasConstraintName("fk_app_instances_offers_app_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IamClient", "IamClient") + .WithMany("AppInstances") + .HasForeignKey("IamClientId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired() + .HasConstraintName("fk_app_instances_iam_clients_iam_client_id"); + + b.Navigation("App"); + + b.Navigation("IamClient"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstanceAssignedCompanyServiceAccount", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstance", "AppInstance") + .WithMany("ServiceAccounts") + .HasForeignKey("AppInstanceId") + .IsRequired() + .HasConstraintName("fk_app_instance_assigned_service_accounts_app_instances_app_in"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", "CompanyServiceAccount") + .WithMany("AppInstances") + .HasForeignKey("CompanyServiceAccountId") + .IsRequired() + .HasConstraintName("fk_app_instance_assigned_service_accounts_company_service_acco"); + + b.Navigation("AppInstance"); + + b.Navigation("CompanyServiceAccount"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstanceSetup", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "App") + .WithOne("AppInstanceSetup") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstanceSetup", "AppId") + .IsRequired() + .HasConstraintName("fk_app_instance_setups_offers_app_id"); + + b.Navigation("App"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppLanguage", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "App") + .WithMany() + .HasForeignKey("AppId") + .IsRequired() + .HasConstraintName("fk_app_languages_offers_app_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany() + .HasForeignKey("LanguageShortName") + .IsRequired() + .HasConstraintName("fk_app_languages_languages_language_temp_id"); + + b.Navigation("App"); + + b.Navigation("Language"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppSubscriptionDetail", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstance", "AppInstance") + .WithMany("AppSubscriptionDetails") + .HasForeignKey("AppInstanceId") + .HasConstraintName("fk_app_subscription_details_app_instances_app_instance_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_app_subscription_details_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", "OfferSubscription") + .WithOne("AppSubscriptionDetail") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppSubscriptionDetail", "OfferSubscriptionId") + .IsRequired() + .HasConstraintName("fk_app_subscription_details_offer_subscriptions_offer_subscrip"); + + b.Navigation("AppInstance"); + + b.Navigation("LastEditor"); + + b.Navigation("OfferSubscription"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntry", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntryStatus", "ApplicationChecklistEntryStatus") + .WithMany("ApplicationChecklistEntries") + .HasForeignKey("ApplicationChecklistEntryStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_application_checklist_application_checklist_statuses_applic"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntryType", "ApplicationChecklistEntryType") + .WithMany("ApplicationChecklistEntries") + .HasForeignKey("ApplicationChecklistEntryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_application_checklist_application_checklist_types_applicati"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", "Application") + .WithMany("ApplicationChecklistEntries") + .HasForeignKey("ApplicationId") + .IsRequired() + .HasConstraintName("fk_application_checklist_company_applications_application_id"); + + b.Navigation("Application"); + + b.Navigation("ApplicationChecklistEntryStatus"); + + b.Navigation("ApplicationChecklistEntryType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Address", "Address") + .WithMany("Companies") + .HasForeignKey("AddressId") + .HasConstraintName("fk_companies_addresses_address_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyStatus", "CompanyStatus") + .WithMany("Companies") + .HasForeignKey("CompanyStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_companies_company_statuses_company_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", "SelfDescriptionDocument") + .WithMany("Companies") + .HasForeignKey("SelfDescriptionDocumentId") + .HasConstraintName("fk_companies_documents_self_description_document_id"); + + b.Navigation("Address"); + + b.Navigation("CompanyStatus"); + + b.Navigation("SelfDescriptionDocument"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplicationStatus", "ApplicationStatus") + .WithMany("CompanyApplications") + .HasForeignKey("ApplicationStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_applications_company_application_statuses_applicati"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", "ChecklistProcess") + .WithOne("CompanyApplication") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", "ChecklistProcessId") + .HasConstraintName("fk_company_applications_processes_checklist_process_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplicationType", "CompanyApplicationType") + .WithMany("CompanyApplications") + .HasForeignKey("CompanyApplicationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_applications_company_application_types_company_appl"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("CompanyApplications") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_company_applications_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_company_applications_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "OnboardingServiceProvider") + .WithMany("ProvidedApplications") + .HasForeignKey("OnboardingServiceProviderId") + .HasConstraintName("fk_company_applications_companies_onboarding_service_provider_"); + + b.Navigation("ApplicationStatus"); + + b.Navigation("ChecklistProcess"); + + b.Navigation("Company"); + + b.Navigation("CompanyApplicationType"); + + b.Navigation("LastEditor"); + + b.Navigation("OnboardingServiceProvider"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyAssignedRole", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("CompanyAssignedRoles") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_company_assigned_roles_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", "CompanyRole") + .WithMany("CompanyAssignedRoles") + .HasForeignKey("CompanyRoleId") + .IsRequired() + .HasConstraintName("fk_company_assigned_roles_company_roles_company_role_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_company_assigned_roles_identities_last_editor_id"); + + b.Navigation("Company"); + + b.Navigation("CompanyRole"); + + b.Navigation("LastEditor"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyAssignedUseCase", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("CompanyAssignedUseCase") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_company_assigned_use_cases_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", "UseCase") + .WithMany("CompanyAssignedUseCase") + .HasForeignKey("UseCaseId") + .IsRequired() + .HasConstraintName("fk_company_assigned_use_cases_use_cases_use_case_id"); + + b.Navigation("Company"); + + b.Navigation("UseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyIdentifier", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("CompanyIdentifiers") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_company_identifiers_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UniqueIdentifier", "UniqueIdentifier") + .WithMany("CompanyIdentifiers") + .HasForeignKey("UniqueIdentifierId") + .IsRequired() + .HasConstraintName("fk_company_identifiers_unique_identifiers_unique_identifier_id"); + + b.Navigation("Company"); + + b.Navigation("UniqueIdentifier"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyIdentityProvider", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_company_identity_providers_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProvider", "IdentityProvider") + .WithMany("CompanyIdentityProviders") + .HasForeignKey("IdentityProviderId") + .IsRequired() + .HasConstraintName("fk_company_identity_providers_identity_providers_identity_prov"); + + b.Navigation("Company"); + + b.Navigation("IdentityProvider"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleAssignedRoleCollection", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", "CompanyRole") + .WithOne("CompanyRoleAssignedRoleCollection") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleAssignedRoleCollection", "CompanyRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_role_assigned_role_collections_company_roles_compan"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollection", "UserRoleCollection") + .WithOne("CompanyRoleAssignedRoleCollection") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleAssignedRoleCollection", "UserRoleCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_role_assigned_role_collections_user_role_collection"); + + b.Navigation("CompanyRole"); + + b.Navigation("UserRoleCollection"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleDescription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", "CompanyRole") + .WithMany("CompanyRoleDescriptions") + .HasForeignKey("CompanyRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_role_descriptions_company_roles_company_role_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany("CompanyRoleDescriptions") + .HasForeignKey("LanguageShortName") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_role_descriptions_languages_language_temp_id1"); + + b.Navigation("CompanyRole"); + + b.Navigation("Language"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleRegistrationData", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", "CompanyRole") + .WithOne("CompanyRoleRegistrationData") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRoleRegistrationData", "CompanyRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_role_registration_data_company_roles_company_role_id"); + + b.Navigation("CompanyRole"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccountType", "CompanyServiceAccountType") + .WithMany("CompanyServiceAccounts") + .HasForeignKey("CompanyServiceAccountTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_service_accounts_company_service_account_types_comp"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "Identity") + .WithOne("CompanyServiceAccount") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_service_accounts_identities_identity_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", "OfferSubscription") + .WithMany("CompanyServiceAccounts") + .HasForeignKey("OfferSubscriptionId") + .HasConstraintName("fk_company_service_accounts_offer_subscriptions_offer_subscrip"); + + b.Navigation("CompanyServiceAccountType"); + + b.Navigation("Identity"); + + b.Navigation("OfferSubscription"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanySsiDetail", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("CompanySsiDetails") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanySsiDetailStatus", "CompanySsiDetailStatus") + .WithMany("CompanySsiDetails") + .HasForeignKey("CompanySsiDetailStatusId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_company_ssi_detail_statuses_company_ssi"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CreatorUser") + .WithMany("CompanySsiDetails") + .HasForeignKey("CreatorUserId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_company_users_creator_user_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", "Document") + .WithOne("CompanySsiDetail") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanySsiDetail", "DocumentId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_documents_document_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_company_ssi_details_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalTypeUseCaseDetailVersion", "VerifiedCredentialExternalTypeUseCaseDetailVersion") + .WithMany("CompanySsiDetails") + .HasForeignKey("VerifiedCredentialExternalTypeUseCaseDetailId") + .HasConstraintName("fk_company_ssi_details_verified_credential_external_type_use_c"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithMany("CompanySsiDetails") + .HasForeignKey("VerifiedCredentialTypeId") + .IsRequired() + .HasConstraintName("fk_company_ssi_details_verified_credential_types_verified_cred"); + + b.Navigation("Company"); + + b.Navigation("CompanySsiDetailStatus"); + + b.Navigation("CreatorUser"); + + b.Navigation("Document"); + + b.Navigation("LastEditor"); + + b.Navigation("VerifiedCredentialExternalTypeUseCaseDetailVersion"); + + b.Navigation("VerifiedCredentialType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "Identity") + .WithOne("CompanyUser") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_users_identities_identity_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_company_users_identities_last_editor_id"); + + b.Navigation("Identity"); + + b.Navigation("LastEditor"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUserAssignedAppFavourite", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "App") + .WithMany() + .HasForeignKey("AppId") + .IsRequired() + .HasConstraintName("fk_company_user_assigned_app_favourites_offers_app_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CompanyUser") + .WithMany() + .HasForeignKey("CompanyUserId") + .IsRequired() + .HasConstraintName("fk_company_user_assigned_app_favourites_company_users_company_"); + + b.Navigation("App"); + + b.Navigation("CompanyUser"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUserAssignedBusinessPartner", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CompanyUser") + .WithMany("CompanyUserAssignedBusinessPartners") + .HasForeignKey("CompanyUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_user_assigned_business_partners_company_users_compa"); + + b.Navigation("CompanyUser"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUserAssignedIdentityProvider", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CompanyUser") + .WithMany("CompanyUserAssignedIdentityProviders") + .HasForeignKey("CompanyUserId") + .IsRequired() + .HasConstraintName("fk_company_user_assigned_identity_providers_company_users_comp"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProvider", "IdentityProvider") + .WithMany("CompanyUserAssignedIdentityProviders") + .HasForeignKey("IdentityProviderId") + .IsRequired() + .HasConstraintName("fk_company_user_assigned_identity_providers_identity_providers"); + + b.Navigation("CompanyUser"); + + b.Navigation("IdentityProvider"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Connector", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", "CompanyServiceAccount") + .WithOne("Connector") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Connector", "CompanyServiceAccountId") + .HasConstraintName("fk_connectors_company_service_accounts_company_service_account"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Host") + .WithMany("HostedConnectors") + .HasForeignKey("HostId") + .HasConstraintName("fk_connectors_companies_host_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_connectors_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Country", "Location") + .WithMany("Connectors") + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_connectors_countries_location_temp_id1"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Provider") + .WithMany("ProvidedConnectors") + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_connectors_companies_provider_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", "SelfDescriptionDocument") + .WithOne("Connector") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Connector", "SelfDescriptionDocumentId") + .HasConstraintName("fk_connectors_documents_self_description_document_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorStatus", "Status") + .WithMany("Connectors") + .HasForeignKey("StatusId") + .IsRequired() + .HasConstraintName("fk_connectors_connector_statuses_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorType", "Type") + .WithMany("Connectors") + .HasForeignKey("TypeId") + .IsRequired() + .HasConstraintName("fk_connectors_connector_types_type_id"); + + b.Navigation("CompanyServiceAccount"); + + b.Navigation("Host"); + + b.Navigation("LastEditor"); + + b.Navigation("Location"); + + b.Navigation("Provider"); + + b.Navigation("SelfDescriptionDocument"); + + b.Navigation("Status"); + + b.Navigation("Type"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorAssignedOfferSubscription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Connector", "Connector") + .WithMany("ConnectorAssignedOfferSubscriptions") + .HasForeignKey("ConnectorId") + .IsRequired() + .HasConstraintName("fk_connector_assigned_offer_subscriptions_connectors_connector"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", "OfferSubscription") + .WithMany("ConnectorAssignedOfferSubscriptions") + .HasForeignKey("OfferSubscriptionId") + .IsRequired() + .HasConstraintName("fk_connector_assigned_offer_subscriptions_offer_subscriptions_"); + + b.Navigation("Connector"); + + b.Navigation("OfferSubscription"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Consent", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", "Agreement") + .WithMany("Consents") + .HasForeignKey("AgreementId") + .IsRequired() + .HasConstraintName("fk_consents_agreements_agreement_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("Consents") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_consents_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CompanyUser") + .WithMany("Consents") + .HasForeignKey("CompanyUserId") + .IsRequired() + .HasConstraintName("fk_consents_company_users_company_user_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentStatus", "ConsentStatus") + .WithMany("Consents") + .HasForeignKey("ConsentStatusId") + .IsRequired() + .HasConstraintName("fk_consents_consent_statuses_consent_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", "Document") + .WithMany("Consents") + .HasForeignKey("DocumentId") + .HasConstraintName("fk_consents_documents_document_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_consents_identities_last_editor_id"); + + b.Navigation("Agreement"); + + b.Navigation("Company"); + + b.Navigation("CompanyUser"); + + b.Navigation("ConsentStatus"); + + b.Navigation("Document"); + + b.Navigation("LastEditor"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentAssignedOffer", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Consent", "Consent") + .WithMany("ConsentAssignedOffers") + .HasForeignKey("ConsentId") + .IsRequired() + .HasConstraintName("fk_consent_assigned_offers_consents_consent_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("ConsentAssignedOffers") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_consent_assigned_offers_offers_offer_id"); + + b.Navigation("Consent"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentAssignedOfferSubscription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Consent", "Consent") + .WithMany("ConsentAssignedOfferSubscriptions") + .HasForeignKey("ConsentId") + .IsRequired() + .HasConstraintName("fk_consent_assigned_offer_subscriptions_consents_consent_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", "OfferSubscription") + .WithMany("ConsentAssignedOfferSubscriptions") + .HasForeignKey("OfferSubscriptionId") + .IsRequired() + .HasConstraintName("fk_consent_assigned_offer_subscriptions_offer_subscriptions_of"); + + b.Navigation("Consent"); + + b.Navigation("OfferSubscription"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CountryAssignedIdentifier", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.BpdmIdentifier", "BpdmIdentifier") + .WithMany("CountryAssignedIdentifiers") + .HasForeignKey("BpdmIdentifierId") + .HasConstraintName("fk_country_assigned_identifiers_bpdm_identifiers_bpdm_identifi"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Country", "Country") + .WithMany("CountryAssignedIdentifiers") + .HasForeignKey("CountryAlpha2Code") + .IsRequired() + .HasConstraintName("fk_country_assigned_identifiers_countries_country_alpha2code"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UniqueIdentifier", "UniqueIdentifier") + .WithMany("CountryAssignedIdentifiers") + .HasForeignKey("UniqueIdentifierId") + .IsRequired() + .HasConstraintName("fk_country_assigned_identifiers_unique_identifiers_unique_iden"); + + b.Navigation("BpdmIdentifier"); + + b.Navigation("Country"); + + b.Navigation("UniqueIdentifier"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CountryLongName", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Country", "Country") + .WithMany("CountryLongNames") + .HasForeignKey("Alpha2Code") + .IsRequired() + .HasConstraintName("fk_country_long_names_countries_country_alpha2code"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany("CountryLongNames") + .HasForeignKey("ShortName") + .IsRequired() + .HasConstraintName("fk_country_long_names_languages_language_temp_id2"); + + b.Navigation("Country"); + + b.Navigation("Language"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CompanyUser") + .WithMany("Documents") + .HasForeignKey("CompanyUserId") + .HasConstraintName("fk_documents_company_users_company_user_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.DocumentStatus", "DocumentStatus") + .WithMany("Documents") + .HasForeignKey("DocumentStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_documents_document_status_document_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.DocumentType", "DocumentType") + .WithMany("Documents") + .HasForeignKey("DocumentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_documents_document_types_document_type_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.MediaType", "MediaType") + .WithMany("Documents") + .HasForeignKey("MediaTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_documents_media_types_media_type_id"); + + b.Navigation("CompanyUser"); + + b.Navigation("DocumentStatus"); + + b.Navigation("DocumentType"); + + b.Navigation("MediaType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IamIdentityProvider", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProvider", "IdentityProvider") + .WithOne("IamIdentityProvider") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IamIdentityProvider", "IdentityProviderId") + .IsRequired() + .HasConstraintName("fk_iam_identity_providers_identity_providers_identity_provider"); + + b.Navigation("IdentityProvider"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("Identities") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_identities_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityType", "IdentityType") + .WithMany("Identities") + .HasForeignKey("IdentityTypeId") + .IsRequired() + .HasConstraintName("fk_identities_identity_type_identity_type_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_identities_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityUserStatus", "IdentityStatus") + .WithMany("Identities") + .HasForeignKey("UserStatusId") + .IsRequired() + .HasConstraintName("fk_identities_identity_user_statuses_identity_status_id"); + + b.Navigation("Company"); + + b.Navigation("IdentityStatus"); + + b.Navigation("IdentityType"); + + b.Navigation("LastEditor"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityAssignedRole", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "Identity") + .WithMany("IdentityAssignedRoles") + .HasForeignKey("IdentityId") + .IsRequired() + .HasConstraintName("fk_identity_assigned_roles_identities_identity_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_identity_assigned_roles_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", "UserRole") + .WithMany("IdentityAssignedRoles") + .HasForeignKey("UserRoleId") + .IsRequired() + .HasConstraintName("fk_identity_assigned_roles_user_roles_user_role_id"); + + b.Navigation("Identity"); + + b.Navigation("LastEditor"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProvider", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProviderCategory", "IdentityProviderCategory") + .WithMany("IdentityProviders") + .HasForeignKey("IdentityProviderCategoryId") + .IsRequired() + .HasConstraintName("fk_identity_providers_identity_provider_categories_identity_pr"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProviderType", "IdentityProviderType") + .WithMany("IdentityProviders") + .HasForeignKey("IdentityProviderTypeId") + .IsRequired() + .HasConstraintName("fk_identity_providers_identity_provider_types_identity_provide"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Owner") + .WithMany("OwnedIdentityProviders") + .HasForeignKey("OwnerId") + .IsRequired() + .HasConstraintName("fk_identity_providers_companies_owner_id"); + + b.Navigation("IdentityProviderCategory"); + + b.Navigation("IdentityProviderType"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Invitation", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", "CompanyApplication") + .WithMany("Invitations") + .HasForeignKey("CompanyApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_invitations_company_applications_company_application_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "CompanyUser") + .WithMany("Invitations") + .HasForeignKey("CompanyUserId") + .IsRequired() + .HasConstraintName("fk_invitations_company_users_company_user_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.InvitationStatus", "InvitationStatus") + .WithMany("Invitations") + .HasForeignKey("InvitationStatusId") + .IsRequired() + .HasConstraintName("fk_invitations_invitation_statuses_invitation_status_id"); + + b.Navigation("CompanyApplication"); + + b.Navigation("CompanyUser"); + + b.Navigation("InvitationStatus"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.LanguageLongName", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "LongNameLanguage") + .WithMany("LanguageLongNameLanguages") + .HasForeignKey("LanguageShortName") + .IsRequired() + .HasConstraintName("fk_language_long_names_languages_long_name_language_short_name"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany("LanguageLongNames") + .HasForeignKey("ShortName") + .IsRequired() + .HasConstraintName("fk_language_long_names_languages_language_short_name"); + + b.Navigation("Language"); + + b.Navigation("LongNameLanguage"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NetworkRegistration", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", "CompanyApplication") + .WithOne("NetworkRegistration") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NetworkRegistration", "ApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_network_registrations_company_applications_application_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithOne("NetworkRegistration") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NetworkRegistration", "CompanyId") + .IsRequired() + .HasConstraintName("fk_network_registrations_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "OnboardingServiceProvider") + .WithMany("OnboardedNetworkRegistrations") + .HasForeignKey("OnboardingServiceProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_network_registrations_companies_onboarding_service_provider"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", "Process") + .WithOne("NetworkRegistration") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NetworkRegistration", "ProcessId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_network_registrations_processes_process_id"); + + b.Navigation("Company"); + + b.Navigation("CompanyApplication"); + + b.Navigation("OnboardingServiceProvider"); + + b.Navigation("Process"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Notification", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "Creator") + .WithMany("CreatedNotifications") + .HasForeignKey("CreatorUserId") + .HasConstraintName("fk_notifications_identities_creator_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationType", "NotificationType") + .WithMany("Notifications") + .HasForeignKey("NotificationTypeId") + .IsRequired() + .HasConstraintName("fk_notifications_notification_type_notification_type_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "Receiver") + .WithMany("Notifications") + .HasForeignKey("ReceiverUserId") + .IsRequired() + .HasConstraintName("fk_notifications_company_users_receiver_id"); + + b.Navigation("Creator"); + + b.Navigation("NotificationType"); + + b.Navigation("Receiver"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationTypeAssignedTopic", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationTopic", "NotificationTopic") + .WithMany("NotificationTypeAssignedTopics") + .HasForeignKey("NotificationTopicId") + .IsRequired() + .HasConstraintName("fk_notification_type_assigned_topics_notification_topic_notifi"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationType", "NotificationType") + .WithOne("NotificationTypeAssignedTopic") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationTypeAssignedTopic", "NotificationTypeId") + .IsRequired() + .HasConstraintName("fk_notification_type_assigned_topics_notification_type_notific"); + + b.Navigation("NotificationTopic"); + + b.Navigation("NotificationType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_offers_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.LicenseType", "LicenseType") + .WithMany("Offers") + .HasForeignKey("LicenseTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_offers_license_types_license_type_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferStatus", "OfferStatus") + .WithMany("Offers") + .HasForeignKey("OfferStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_offers_offer_statuses_offer_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferType", "OfferType") + .WithMany("Offers") + .HasForeignKey("OfferTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_offers_offer_types_offer_type_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "ProviderCompany") + .WithMany("ProvidedOffers") + .HasForeignKey("ProviderCompanyId") + .HasConstraintName("fk_offers_companies_provider_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "SalesManager") + .WithMany("SalesManagerOfOffers") + .HasForeignKey("SalesManagerId") + .HasConstraintName("fk_offers_company_users_sales_manager_id"); + + b.Navigation("LastEditor"); + + b.Navigation("LicenseType"); + + b.Navigation("OfferStatus"); + + b.Navigation("OfferType"); + + b.Navigation("ProviderCompany"); + + b.Navigation("SalesManager"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferAssignedDocument", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .IsRequired() + .HasConstraintName("fk_offer_assigned_documents_documents_document_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany() + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_offer_assigned_documents_offers_offer_id"); + + b.Navigation("Document"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferAssignedLicense", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany() + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_offer_assigned_licenses_offers_offer_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferLicense", "OfferLicense") + .WithMany() + .HasForeignKey("OfferLicenseId") + .IsRequired() + .HasConstraintName("fk_offer_assigned_licenses_offer_licenses_offer_license_id"); + + b.Navigation("Offer"); + + b.Navigation("OfferLicense"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferAssignedPrivacyPolicy", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("OfferAssignedPrivacyPolicies") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_offer_assigned_privacy_policies_offers_offer_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.PrivacyPolicy", "PrivacyPolicy") + .WithMany("OfferAssignedPrivacyPolicies") + .HasForeignKey("PrivacyPolicyId") + .IsRequired() + .HasConstraintName("fk_offer_assigned_privacy_policies_privacy_policies_privacy_po"); + + b.Navigation("Offer"); + + b.Navigation("PrivacyPolicy"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferDescription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany("AppDescriptions") + .HasForeignKey("LanguageShortName") + .IsRequired() + .HasConstraintName("fk_offer_descriptions_languages_language_short_name"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("OfferDescriptions") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_offer_descriptions_offers_offer_id"); + + b.Navigation("Language"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithMany("OfferSubscriptions") + .HasForeignKey("CompanyId") + .IsRequired() + .HasConstraintName("fk_offer_subscriptions_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_offer_subscriptions_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("OfferSubscriptions") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_offer_subscriptions_offers_offer_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscriptionStatus", "OfferSubscriptionStatus") + .WithMany("OfferSubscriptions") + .HasForeignKey("OfferSubscriptionStatusId") + .IsRequired() + .HasConstraintName("fk_offer_subscriptions_offer_subscription_statuses_offer_subsc"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", "Process") + .WithOne("OfferSubscription") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", "ProcessId") + .HasConstraintName("fk_offer_subscriptions_processes_process_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", "Requester") + .WithMany("RequestedSubscriptions") + .HasForeignKey("RequesterId") + .IsRequired() + .HasConstraintName("fk_offer_subscriptions_company_users_requester_id"); + + b.Navigation("Company"); + + b.Navigation("LastEditor"); + + b.Navigation("Offer"); + + b.Navigation("OfferSubscriptionStatus"); + + b.Navigation("Process"); + + b.Navigation("Requester"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscriptionProcessData", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", "OfferSubscription") + .WithOne("OfferSubscriptionProcessData") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscriptionProcessData", "OfferSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_offer_subscriptions_process_datas_offer_subscriptions_offer"); + + b.Navigation("OfferSubscription"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferTag", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("Tags") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_offer_tags_offers_offer_id"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OnboardingServiceProviderDetail", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithOne("OnboardingServiceProviderDetail") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OnboardingServiceProviderDetail", "CompanyId") + .IsRequired() + .HasConstraintName("fk_onboarding_service_provider_details_companies_company_id"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessType", "ProcessType") + .WithMany("Processes") + .HasForeignKey("ProcessTypeId") + .IsRequired() + .HasConstraintName("fk_processes_process_types_process_type_id"); + + b.Navigation("ProcessType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStep", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", "Process") + .WithMany("ProcessSteps") + .HasForeignKey("ProcessId") + .IsRequired() + .HasConstraintName("fk_process_steps_processes_process_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStepStatus", "ProcessStepStatus") + .WithMany("ProcessSteps") + .HasForeignKey("ProcessStepStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_process_steps_process_step_statuses_process_step_status_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStepType", "ProcessStepType") + .WithMany("ProcessSteps") + .HasForeignKey("ProcessStepTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_process_steps_process_step_types_process_step_type_id"); + + b.Navigation("Process"); + + b.Navigation("ProcessStepStatus"); + + b.Navigation("ProcessStepType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProviderCompanyDetail", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", "Company") + .WithOne("ProviderCompanyDetail") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProviderCompanyDetail", "CompanyId") + .IsRequired() + .HasConstraintName("fk_provider_company_details_companies_company_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_provider_company_details_identities_last_editor_id"); + + b.Navigation("Company"); + + b.Navigation("LastEditor"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ServiceDetail", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Service") + .WithMany("ServiceDetails") + .HasForeignKey("ServiceId") + .IsRequired() + .HasConstraintName("fk_service_details_offers_service_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ServiceType", "ServiceType") + .WithMany("ServiceDetails") + .HasForeignKey("ServiceTypeId") + .IsRequired() + .HasConstraintName("fk_service_details_service_types_service_type_id"); + + b.Navigation("Service"); + + b.Navigation("ServiceType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.TechnicalUserProfile", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("TechnicalUserProfiles") + .HasForeignKey("OfferId") + .IsRequired() + .HasConstraintName("fk_technical_user_profiles_offers_offer_id"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.TechnicalUserProfileAssignedUserRole", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.TechnicalUserProfile", "TechnicalUserProfile") + .WithMany("TechnicalUserProfileAssignedUserRoles") + .HasForeignKey("TechnicalUserProfileId") + .IsRequired() + .HasConstraintName("fk_technical_user_profile_assigned_user_roles_technical_user_p"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", "UserRole") + .WithMany("TechnicalUserProfileAssignedUserRole") + .HasForeignKey("UserRoleId") + .IsRequired() + .HasConstraintName("fk_technical_user_profile_assigned_user_roles_user_roles_user_r"); + + b.Navigation("TechnicalUserProfile"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCaseDescription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany("UseCases") + .HasForeignKey("LanguageShortName") + .IsRequired() + .HasConstraintName("fk_use_case_descriptions_languages_language_short_name"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", "UseCase") + .WithMany("UseCaseDescriptions") + .HasForeignKey("UseCaseId") + .IsRequired() + .HasConstraintName("fk_use_case_descriptions_use_cases_use_case_id"); + + b.Navigation("Language"); + + b.Navigation("UseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", "LastEditor") + .WithMany() + .HasForeignKey("LastEditorId") + .HasConstraintName("fk_user_roles_identities_last_editor_id"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", "Offer") + .WithMany("UserRoles") + .HasForeignKey("OfferId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_roles_offers_offer_id"); + + b.Navigation("LastEditor"); + + b.Navigation("Offer"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleAssignedCollection", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollection", "UserRoleCollection") + .WithMany() + .HasForeignKey("UserRoleCollectionId") + .IsRequired() + .HasConstraintName("fk_user_role_assigned_collections_user_role_collections_user_r"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", "UserRole") + .WithMany() + .HasForeignKey("UserRoleId") + .IsRequired() + .HasConstraintName("fk_user_role_assigned_collections_user_roles_user_role_id"); + + b.Navigation("UserRole"); + + b.Navigation("UserRoleCollection"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollectionDescription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany() + .HasForeignKey("LanguageShortName") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_role_collection_descriptions_languages_language_short_"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollection", "UserRoleCollection") + .WithMany("UserRoleCollectionDescriptions") + .HasForeignKey("UserRoleCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_role_collection_descriptions_user_role_collections_use"); + + b.Navigation("Language"); + + b.Navigation("UserRoleCollection"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleDescription", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", "Language") + .WithMany("UserRoleDescriptions") + .HasForeignKey("LanguageShortName") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_role_descriptions_languages_language_short_name"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", "UserRole") + .WithMany("UserRoleDescriptions") + .HasForeignKey("UserRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_role_descriptions_user_roles_user_role_id"); + + b.Navigation("Language"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalTypeUseCaseDetailVersion", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalType", "VerifiedCredentialExternalType") + .WithMany("VerifiedCredentialExternalTypeUseCaseDetailVersions") + .HasForeignKey("VerifiedCredentialExternalTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_external_type_use_case_detail_versions_"); + + b.Navigation("VerifiedCredentialExternalType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedExternalType", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalType", "VerifiedCredentialExternalType") + .WithMany("VerifiedCredentialTypeAssignedExternalTypes") + .HasForeignKey("VerifiedCredentialExternalTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_external_types_verified_c"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithOne("VerifiedCredentialTypeAssignedExternalType") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedExternalType", "VerifiedCredentialTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_external_types_verified_c1"); + + b.Navigation("VerifiedCredentialExternalType"); + + b.Navigation("VerifiedCredentialType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedKind", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithOne("VerifiedCredentialTypeAssignedKind") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedKind", "VerifiedCredentialTypeId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_kinds_verified_credential"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeKind", "VerifiedCredentialTypeKind") + .WithMany("VerifiedCredentialTypeAssignedKinds") + .HasForeignKey("VerifiedCredentialTypeKindId") + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_kinds_verified_credential1"); + + b.Navigation("VerifiedCredentialType"); + + b.Navigation("VerifiedCredentialTypeKind"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedUseCase", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", "UseCase") + .WithOne("VerifiedCredentialAssignedUseCase") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedUseCase", "UseCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_use_cases_use_cases_use_c"); + + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialType", "VerifiedCredentialType") + .WithOne("VerifiedCredentialTypeAssignedUseCase") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeAssignedUseCase", "VerifiedCredentialTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_verified_credential_type_assigned_use_cases_verified_creden"); + + b.Navigation("UseCase"); + + b.Navigation("VerifiedCredentialType"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompaniesLinkedServiceAccount", b => + { + b.HasOne("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", "CompanyServiceAccount") + .WithOne("CompaniesLinkedServiceAccount") + .HasForeignKey("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Views.CompaniesLinkedServiceAccount", "ServiceAccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_company_linked_service_accounts_company_service_accounts_co"); + + b.Navigation("CompanyServiceAccount"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Address", b => + { + b.Navigation("Companies"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Agreement", b => + { + b.Navigation("AgreementAssignedCompanyRoles"); + + b.Navigation("AgreementAssignedOfferTypes"); + + b.Navigation("AgreementAssignedOffers"); + + b.Navigation("Consents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementCategory", b => + { + b.Navigation("Agreements"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AgreementStatus", b => + { + b.Navigation("Agreements"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.AppInstance", b => + { + b.Navigation("AppSubscriptionDetails"); + + b.Navigation("ServiceAccounts"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntryStatus", b => + { + b.Navigation("ApplicationChecklistEntries"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ApplicationChecklistEntryType", b => + { + b.Navigation("ApplicationChecklistEntries"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.BpdmIdentifier", b => + { + b.Navigation("CountryAssignedIdentifiers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Company", b => + { + b.Navigation("Agreements"); + + b.Navigation("CompanyApplications"); + + b.Navigation("CompanyAssignedRoles"); + + b.Navigation("CompanyAssignedUseCase"); + + b.Navigation("CompanyIdentifiers"); + + b.Navigation("CompanySsiDetails"); + + b.Navigation("Consents"); + + b.Navigation("HostedConnectors"); + + b.Navigation("Identities"); + + b.Navigation("NetworkRegistration"); + + b.Navigation("OfferSubscriptions"); + + b.Navigation("OnboardedNetworkRegistrations"); + + b.Navigation("OnboardingServiceProviderDetail"); + + b.Navigation("OwnedIdentityProviders"); + + b.Navigation("ProvidedApplications"); + + b.Navigation("ProvidedConnectors"); + + b.Navigation("ProvidedOffers"); + + b.Navigation("ProviderCompanyDetail"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplication", b => + { + b.Navigation("ApplicationChecklistEntries"); + + b.Navigation("Invitations"); + + b.Navigation("NetworkRegistration"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplicationStatus", b => + { + b.Navigation("CompanyApplications"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyApplicationType", b => + { + b.Navigation("CompanyApplications"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyRole", b => + { + b.Navigation("AgreementAssignedCompanyRoles"); + + b.Navigation("CompanyAssignedRoles"); + + b.Navigation("CompanyRoleAssignedRoleCollection"); + + b.Navigation("CompanyRoleDescriptions"); + + b.Navigation("CompanyRoleRegistrationData"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccount", b => + { + b.Navigation("AppInstances"); + + b.Navigation("CompaniesLinkedServiceAccount"); + + b.Navigation("Connector"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyServiceAccountType", b => + { + b.Navigation("CompanyServiceAccounts"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanySsiDetailStatus", b => + { + b.Navigation("CompanySsiDetails"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyStatus", b => + { + b.Navigation("Companies"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.CompanyUser", b => + { + b.Navigation("CompanySsiDetails"); + + b.Navigation("CompanyUserAssignedBusinessPartners"); + + b.Navigation("CompanyUserAssignedIdentityProviders"); + + b.Navigation("Consents"); + + b.Navigation("Documents"); + + b.Navigation("Invitations"); + + b.Navigation("Notifications"); + + b.Navigation("RequestedSubscriptions"); + + b.Navigation("SalesManagerOfOffers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Connector", b => + { + b.Navigation("ConnectorAssignedOfferSubscriptions"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorStatus", b => + { + b.Navigation("Connectors"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConnectorType", b => + { + b.Navigation("Connectors"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Consent", b => + { + b.Navigation("ConsentAssignedOfferSubscriptions"); + + b.Navigation("ConsentAssignedOffers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ConsentStatus", b => + { + b.Navigation("Consents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Country", b => + { + b.Navigation("Addresses"); + + b.Navigation("Connectors"); + + b.Navigation("CountryAssignedIdentifiers"); + + b.Navigation("CountryLongNames"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Document", b => + { + b.Navigation("Agreements"); + + b.Navigation("Companies"); + + b.Navigation("CompanySsiDetail"); + + b.Navigation("Connector"); + + b.Navigation("Consents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.DocumentStatus", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.DocumentType", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IamClient", b => + { + b.Navigation("AppInstances"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Identity", b => + { + b.Navigation("CompanyServiceAccount"); + + b.Navigation("CompanyUser"); + + b.Navigation("CreatedNotifications"); + + b.Navigation("IdentityAssignedRoles"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProvider", b => + { + b.Navigation("CompanyIdentityProviders"); + + b.Navigation("CompanyUserAssignedIdentityProviders"); + + b.Navigation("IamIdentityProvider"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProviderCategory", b => + { + b.Navigation("IdentityProviders"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityProviderType", b => + { + b.Navigation("IdentityProviders"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityType", b => + { + b.Navigation("Identities"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.IdentityUserStatus", b => + { + b.Navigation("Identities"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.InvitationStatus", b => + { + b.Navigation("Invitations"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Language", b => + { + b.Navigation("AppDescriptions"); + + b.Navigation("CompanyRoleDescriptions"); + + b.Navigation("CountryLongNames"); + + b.Navigation("LanguageLongNameLanguages"); + + b.Navigation("LanguageLongNames"); + + b.Navigation("UseCases"); + + b.Navigation("UserRoleDescriptions"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.LicenseType", b => + { + b.Navigation("Offers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.MediaType", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationTopic", b => + { + b.Navigation("NotificationTypeAssignedTopics"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.NotificationType", b => + { + b.Navigation("NotificationTypeAssignedTopic"); + + b.Navigation("Notifications"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Offer", b => + { + b.Navigation("AgreementAssignedOffers"); + + b.Navigation("AppInstanceSetup"); + + b.Navigation("AppInstances"); + + b.Navigation("ConsentAssignedOffers"); + + b.Navigation("OfferAssignedPrivacyPolicies"); + + b.Navigation("OfferDescriptions"); + + b.Navigation("OfferSubscriptions"); + + b.Navigation("ServiceDetails"); + + b.Navigation("Tags"); + + b.Navigation("TechnicalUserProfiles"); + + b.Navigation("UserRoles"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferStatus", b => + { + b.Navigation("Offers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscription", b => + { + b.Navigation("AppSubscriptionDetail"); + + b.Navigation("CompanyServiceAccounts"); + + b.Navigation("ConnectorAssignedOfferSubscriptions"); + + b.Navigation("ConsentAssignedOfferSubscriptions"); + + b.Navigation("OfferSubscriptionProcessData"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferSubscriptionStatus", b => + { + b.Navigation("OfferSubscriptions"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OfferType", b => + { + b.Navigation("AgreementAssignedOfferTypes"); + + b.Navigation("Offers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.PrivacyPolicy", b => + { + b.Navigation("OfferAssignedPrivacyPolicies"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.Process", b => + { + b.Navigation("CompanyApplication"); + + b.Navigation("NetworkRegistration"); + + b.Navigation("OfferSubscription"); + + b.Navigation("ProcessSteps"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStepStatus", b => + { + b.Navigation("ProcessSteps"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessStepType", b => + { + b.Navigation("ProcessSteps"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ProcessType", b => + { + b.Navigation("Processes"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.ServiceType", b => + { + b.Navigation("ServiceDetails"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.TechnicalUserProfile", b => + { + b.Navigation("TechnicalUserProfileAssignedUserRoles"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UniqueIdentifier", b => + { + b.Navigation("CompanyIdentifiers"); + + b.Navigation("CountryAssignedIdentifiers"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UseCase", b => + { + b.Navigation("Agreements"); + + b.Navigation("CompanyAssignedUseCase"); + + b.Navigation("UseCaseDescriptions"); + + b.Navigation("VerifiedCredentialAssignedUseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRole", b => + { + b.Navigation("IdentityAssignedRoles"); + + b.Navigation("TechnicalUserProfileAssignedUserRole"); + + b.Navigation("UserRoleDescriptions"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.UserRoleCollection", b => + { + b.Navigation("CompanyRoleAssignedRoleCollection"); + + b.Navigation("UserRoleCollectionDescriptions"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalType", b => + { + b.Navigation("VerifiedCredentialExternalTypeUseCaseDetailVersions"); + + b.Navigation("VerifiedCredentialTypeAssignedExternalTypes"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialExternalTypeUseCaseDetailVersion", b => + { + b.Navigation("CompanySsiDetails"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialType", b => + { + b.Navigation("CompanySsiDetails"); + + b.Navigation("VerifiedCredentialTypeAssignedExternalType"); + + b.Navigation("VerifiedCredentialTypeAssignedKind"); + + b.Navigation("VerifiedCredentialTypeAssignedUseCase"); + }); + + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.VerifiedCredentialTypeKind", b => + { + b.Navigation("VerifiedCredentialTypeAssignedKinds"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.cs b/src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.cs new file mode 100644 index 0000000000..d6954338be --- /dev/null +++ b/src/portalbackend/PortalBackend.Migrations/Migrations/20240122180453_1.8.0-rc3.cs @@ -0,0 +1,80 @@ +/******************************************************************************** + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.Migrations.Migrations +{ + /// + public partial class _180rc3 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + schema: "portal", + table: "company_application_statuses", + columns: new[] { "id", "label" }, + values: new object[] { 10, "CANCELLED_BY_CUSTOMER" }); + + migrationBuilder.InsertData( + schema: "portal", + table: "process_step_types", + columns: new[] { "id", "label" }, + values: new object[,] + { + { 208, "MANUAL_DECLINE_OSP" }, + { 209, "REMOVE_KEYCLOAK_USERS" }, + { 210, "RETRIGGER_REMOVE_KEYCLOAK_USERS" } + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + schema: "portal", + table: "company_application_statuses", + keyColumn: "id", + keyValue: 10); + + migrationBuilder.DeleteData( + schema: "portal", + table: "process_step_types", + keyColumn: "id", + keyValue: 208); + + migrationBuilder.DeleteData( + schema: "portal", + table: "process_step_types", + keyColumn: "id", + keyValue: 209); + + migrationBuilder.DeleteData( + schema: "portal", + table: "process_step_types", + keyColumn: "id", + keyValue: 210); + } + } +} diff --git a/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs b/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs index f2eb537a3b..dba85e96b0 100644 --- a/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs +++ b/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs @@ -18,11 +18,8 @@ ********************************************************************************/ // -using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities; #nullable disable @@ -3040,6 +3037,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 9, Label = "DECLINED" + }, + new + { + Id = 10, + Label = "CANCELLED_BY_CUSTOMER" }); }); @@ -5949,6 +5951,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 207, Label = "RETRIGGER_CALLBACK_OSP_DECLINED" + }, + new + { + Id = 208, + Label = "MANUAL_DECLINE_OSP" + }, + new + { + Id = 209, + Label = "REMOVE_KEYCLOAK_USERS" + }, + new + { + Id = 210, + Label = "RETRIGGER_REMOVE_KEYCLOAK_USERS" }); }); diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationStatusId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationStatusId.cs index 09425460b1..c7c7140cf6 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationStatusId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationStatusId.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 @@ -20,7 +19,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; -public enum CompanyApplicationStatusId : int +public enum CompanyApplicationStatusId { CREATED = 1, ADD_COMPANY_DATA = 2, @@ -30,5 +29,6 @@ public enum CompanyApplicationStatusId : int VERIFY = 6, SUBMITTED = 7, CONFIRMED = 8, - DECLINED = 9 + DECLINED = 9, + CANCELLED_BY_CUSTOMER = 10 } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepStatusId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepStatusId.cs index 9cd78374a5..0e679b87db 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepStatusId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepStatusId.cs @@ -26,5 +26,5 @@ public enum ProcessStepStatusId DONE = 2, SKIPPED = 3, FAILED = 4, - DUPLICATE = 5, + DUPLICATE = 5 } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs index 1a302b5461..d472098b34 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs @@ -65,4 +65,7 @@ public enum ProcessStepTypeId RETRIGGER_CALLBACK_OSP_SUBMITTED = 205, RETRIGGER_CALLBACK_OSP_APPROVED = 206, RETRIGGER_CALLBACK_OSP_DECLINED = 207, + MANUAL_DECLINE_OSP = 208, + REMOVE_KEYCLOAK_USERS = 209, + RETRIGGER_REMOVE_KEYCLOAK_USERS = 210 } diff --git a/src/processes/NetworkRegistration.Executor/NetworkRegistrationExtensisons.cs b/src/processes/NetworkRegistration.Executor/NetworkRegistrationExtensisons.cs index 8d2830b554..20c2b7ccf4 100644 --- a/src/processes/NetworkRegistration.Executor/NetworkRegistrationExtensisons.cs +++ b/src/processes/NetworkRegistration.Executor/NetworkRegistrationExtensisons.cs @@ -31,6 +31,7 @@ public static class NetworkRegistrationExtensisons ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED => new[] { ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_SUBMITTED }, ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED => new[] { ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_DECLINED }, ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED => new[] { ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_APPROVED }, + ProcessStepTypeId.REMOVE_KEYCLOAK_USERS => new[] { ProcessStepTypeId.RETRIGGER_REMOVE_KEYCLOAK_USERS }, _ => null }; } diff --git a/src/processes/NetworkRegistration.Executor/NetworkRegistrationProcessTypeExecutor.cs b/src/processes/NetworkRegistration.Executor/NetworkRegistrationProcessTypeExecutor.cs index d17aa97c52..fe4639f840 100644 --- a/src/processes/NetworkRegistration.Executor/NetworkRegistrationProcessTypeExecutor.cs +++ b/src/processes/NetworkRegistration.Executor/NetworkRegistrationProcessTypeExecutor.cs @@ -39,7 +39,8 @@ public class NetworkRegistrationProcessTypeExecutor : IProcessTypeExecutor ProcessStepTypeId.SYNCHRONIZE_USER, ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED, ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, - ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED); + ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED, + ProcessStepTypeId.REMOVE_KEYCLOAK_USERS); private Guid _networkRegistrationId; @@ -94,6 +95,8 @@ public NetworkRegistrationProcessTypeExecutor( .ConfigureAwait(false), ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED => await _onboardingServiceProviderBusinessLogic.TriggerProviderCallback(_networkRegistrationId, ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, cancellationToken) .ConfigureAwait(false), + ProcessStepTypeId.REMOVE_KEYCLOAK_USERS => await _networkRegistrationHandler.RemoveKeycloakUser(_networkRegistrationId) + .ConfigureAwait(false), _ => (null, ProcessStepStatusId.TODO, false, null) }; } diff --git a/src/processes/NetworkRegistration.Library/INetworkRegistrationHandler.cs b/src/processes/NetworkRegistration.Library/INetworkRegistrationHandler.cs index f562464594..6faae66624 100644 --- a/src/processes/NetworkRegistration.Library/INetworkRegistrationHandler.cs +++ b/src/processes/NetworkRegistration.Library/INetworkRegistrationHandler.cs @@ -24,4 +24,5 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Processes.NetworkRegistration.Libr public interface INetworkRegistrationHandler { Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> SynchronizeUser(Guid networkRegistrationId); + Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> RemoveKeycloakUser(Guid networkRegistrationId); } diff --git a/src/processes/NetworkRegistration.Library/NetworkRegistrationHandler.cs b/src/processes/NetworkRegistration.Library/NetworkRegistrationHandler.cs index a5d53a14e5..b9e7284f16 100644 --- a/src/processes/NetworkRegistration.Library/NetworkRegistrationHandler.cs +++ b/src/processes/NetworkRegistration.Library/NetworkRegistrationHandler.cs @@ -19,6 +19,7 @@ using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; +using Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling; 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; @@ -169,4 +170,48 @@ private async Task SendMails(IAsyncEnumerable companyUserWi await _mailingService.SendMails(receiver, mailParameters, MailTemplates).ConfigureAwait(false); } } + + public async Task<(IEnumerable? nextStepTypeIds, ProcessStepStatusId stepStatusId, bool modified, string? processMessage)> RemoveKeycloakUser(Guid networkRegistrationId) + { + var userRepository = _portalRepositories.GetInstance(); + var companyUserIds = userRepository.GetNextIdentitiesForNetworkRegistration(networkRegistrationId, new[] + { + UserStatusId.ACTIVE, + UserStatusId.PENDING + }); + await using var enumerator = companyUserIds.GetAsyncEnumerator(); + if (!await enumerator.MoveNextAsync().ConfigureAwait(false)) + { + return (null, ProcessStepStatusId.DONE, false, "no users found to remove from keycloak"); + } + + var companyUserId = enumerator.Current; + string? iamUserId; + IEnumerable? nextStepTypeIds; + try + { + iamUserId = await _provisioningManager.GetUserByUserName(companyUserId.ToString()) + .ConfigureAwait(false); + if (iamUserId == null) + { + throw new KeycloakEntityNotFoundException($"no user found for user {companyUserId}"); + } + } + catch (KeycloakEntityNotFoundException) // we will ignore a not found exception and proceed with the next identity + { + _portalRepositories.GetInstance().AttachAndModifyIdentity(companyUserId, null, x => { x.UserStatusId = UserStatusId.INACTIVE; }); + nextStepTypeIds = await enumerator.MoveNextAsync().ConfigureAwait(false) + ? Enumerable.Repeat(ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, 1) // in case there are further company users eligible for remove reschedule the same stepTypeId + : null; + return (nextStepTypeIds, ProcessStepStatusId.DONE, true, $"no user found for company user id {companyUserId}"); + } + + await _provisioningManager.DeleteCentralRealmUserAsync(iamUserId).ConfigureAwait(false); + _portalRepositories.GetInstance().AttachAndModifyIdentity(companyUserId, null, x => { x.UserStatusId = UserStatusId.INACTIVE; }); + + nextStepTypeIds = await enumerator.MoveNextAsync().ConfigureAwait(false) + ? Enumerable.Repeat(ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, 1) // in case there are further company users eligible for remove reschedule the same stepTypeId + : null; + return (nextStepTypeIds, ProcessStepStatusId.DONE, true, $"deleted user {iamUserId} for company user {companyUserId}"); + } } diff --git a/src/processes/NetworkRegistration.Library/NetworkRegistrationProcessHelper.cs b/src/processes/NetworkRegistration.Library/NetworkRegistrationProcessHelper.cs index 081a87ed57..18f7c7d465 100644 --- a/src/processes/NetworkRegistration.Library/NetworkRegistrationProcessHelper.cs +++ b/src/processes/NetworkRegistration.Library/NetworkRegistrationProcessHelper.cs @@ -43,6 +43,7 @@ public async Task TriggerProcessStep(string externalId, ProcessStepTypeId stepTo ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_APPROVED => ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_DECLINED => ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_SUBMITTED => ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED, + ProcessStepTypeId.RETRIGGER_REMOVE_KEYCLOAK_USERS => ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, _ => throw new ConflictException($"Step {stepToTrigger} is not retriggerable") }; diff --git a/src/processes/Processes.Library/ManualProcessStepDataExtensions.cs b/src/processes/Processes.Library/ManualProcessStepDataExtensions.cs index 7575c2b351..c711973eef 100644 --- a/src/processes/Processes.Library/ManualProcessStepDataExtensions.cs +++ b/src/processes/Processes.Library/ManualProcessStepDataExtensions.cs @@ -1,6 +1,5 @@ /******************************************************************************** - * Copyright (c) 2021, 2023 Microsoft and BMW Group AG - * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -61,7 +60,7 @@ public static ManualProcessStepData CreateManualProcessData( throw new UnexpectedConditionException($"processSteps should never have any other status than TODO here"); } - if (!processData.ProcessSteps.Any(step => step.ProcessStepTypeId == processStepTypeId)) + if (processData.ProcessSteps.All(step => step.ProcessStepTypeId != processStepTypeId)) { throw new ConflictException($"{getProcessEntityName()}, process step {processStepTypeId} is not eligible to run"); } @@ -87,8 +86,18 @@ public static void SkipProcessSteps(this ManualProcessStepData context, IEnumera context.PortalRepositories.GetInstance() .AttachAndModifyProcessSteps( context.ProcessSteps + .Where(step => step.ProcessStepTypeId != context.ProcessStepTypeId) .GroupBy(step => step.ProcessStepTypeId) - .IntersectBy(processStepTypeIds, step => step.Key) + .IntersectBy(processStepTypeIds, group => group.Key) + .SelectMany(group => ModifyStepStatusRange(group, ProcessStepStatusId.SKIPPED))); + + public static void SkipProcessStepsExcept(this ManualProcessStepData context, IEnumerable processStepTypeIds) => + context.PortalRepositories.GetInstance() + .AttachAndModifyProcessSteps( + context.ProcessSteps + .Where(step => step.ProcessStepTypeId != context.ProcessStepTypeId) + .GroupBy(step => step.ProcessStepTypeId) + .ExceptBy(processStepTypeIds, group => group.Key) .SelectMany(group => ModifyStepStatusRange(group, ProcessStepStatusId.SKIPPED))); public static void ScheduleProcessSteps(this ManualProcessStepData context, IEnumerable processStepTypeIds) => diff --git a/src/registration/Registration.Service/BusinessLogic/INetworkBusinessLogic.cs b/src/registration/Registration.Service/BusinessLogic/INetworkBusinessLogic.cs index e2ccf31488..367b635265 100644 --- a/src/registration/Registration.Service/BusinessLogic/INetworkBusinessLogic.cs +++ b/src/registration/Registration.Service/BusinessLogic/INetworkBusinessLogic.cs @@ -24,4 +24,5 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Registration.Service.BusinessLogic public interface INetworkBusinessLogic { Task Submit(PartnerSubmitData submitData); + Task DeclineOsp(Guid applicationId, DeclineOspData declineData); } diff --git a/src/registration/Registration.Service/BusinessLogic/NetworkBusinessLogic.cs b/src/registration/Registration.Service/BusinessLogic/NetworkBusinessLogic.cs index fcf62407f4..84674fa5e4 100644 --- a/src/registration/Registration.Service/BusinessLogic/NetworkBusinessLogic.cs +++ b/src/registration/Registration.Service/BusinessLogic/NetworkBusinessLogic.cs @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -21,9 +21,11 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess; 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.Processes.ApplicationChecklist.Library; +using Org.Eclipse.TractusX.Portal.Backend.Processes.Library; using Org.Eclipse.TractusX.Portal.Backend.Registration.Service.Model; using System.Collections.Immutable; @@ -108,4 +110,57 @@ public async Task Submit(PartnerSubmitData submitData) await _portalRepositories.SaveAsync().ConfigureAwait(false); } + + public async Task DeclineOsp(Guid applicationId, DeclineOspData declineData) + { + var companyId = _identityData.CompanyId; + var validStatus = new[] + { + CompanyApplicationStatusId.CREATED, CompanyApplicationStatusId.ADD_COMPANY_DATA, + CompanyApplicationStatusId.INVITE_USER, CompanyApplicationStatusId.SELECT_COMPANY_ROLE, + CompanyApplicationStatusId.UPLOAD_DOCUMENTS, CompanyApplicationStatusId.VERIFY + }; + var networkRepository = _portalRepositories.GetInstance(); + var data = await networkRepository.GetDeclineDataForApplicationId(applicationId, CompanyApplicationTypeId.EXTERNAL, validStatus, companyId).ConfigureAwait(false); + if (!data.Exists) + { + throw new NotFoundException($"CompanyApplication {applicationId} does not exist"); + } + + if (!data.IsValidCompany) + { + throw new ForbiddenException($"User is not allowed to decline application {applicationId}"); + } + + if (!data.IsValidTypeId) + { + throw new ConflictException("Only external registrations can be declined"); + } + + if (!data.IsValidStatusId) + { + throw new ConflictException($"The status of the application {applicationId} must be one of the following: {string.Join(",", validStatus.Select(x => x.ToString()))}"); + } + + var (companyData, invitationData, processData) = data.Data!.Value; + var context = processData.CreateManualProcessData(ProcessStepTypeId.MANUAL_DECLINE_OSP, _portalRepositories, () => $"applicationId {applicationId}"); + + _portalRepositories.GetInstance().AttachAndModifyCompanyApplication(applicationId, ca => { ca.ApplicationStatusId = CompanyApplicationStatusId.CANCELLED_BY_CUSTOMER; }); + _portalRepositories.GetInstance().AttachAndModifyCompany( + companyId, + c => { c.CompanyStatusId = companyData.CompanyStatusId; }, + c => { c.CompanyStatusId = CompanyStatusId.REJECTED; }); + + _portalRepositories.GetInstance().AttachAndModifyInvitations(invitationData.Select( + x => + new ValueTuple?, Action>( + x.InvitationId, + i => { i.InvitationStatusId = x.StatusId; }, + i => { i.InvitationStatusId = InvitationStatusId.DECLINED; }))); + + context.SkipProcessStepsExcept(Enumerable.Repeat(ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, 1)); + context.FinalizeProcessStep(); + + await _portalRepositories.SaveAsync().ConfigureAwait(false); + } } diff --git a/src/registration/Registration.Service/Controllers/NetworkController.cs b/src/registration/Registration.Service/Controllers/NetworkController.cs index d21e30ee33..832cf81c75 100644 --- a/src/registration/Registration.Service/Controllers/NetworkController.cs +++ b/src/registration/Registration.Service/Controllers/NetworkController.cs @@ -49,7 +49,7 @@ public NetworkController(INetworkBusinessLogic logic) /// /// The agreements for the companyRoles /// NoContent - /// Example: POST: api/administration/registration/network/partnerRegistration/submit + /// Example: POST: api/registration/network/partnerRegistration/submit /// Empty response on success. /// No registration found for the externalId. [HttpPost] @@ -64,4 +64,23 @@ public async Task Submit([FromBody] PartnerSubmitData data) await _logic.Submit(data).ConfigureAwait(false); return NoContent(); } + + /// + /// Declines the osp registration + /// + /// Id of the company application + /// Data with the information to decline + /// Example: POST: api/registration/network/{externalId}/decline + /// Empty response on success. + /// No registration found for the externalId. + [HttpPost] + [Authorize(Policy = PolicyTypes.ValidCompany)] + [Authorize(Roles = "decline_partner_registration")] + [Route("decline")] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task DeclineOsp([FromRoute] Guid applicationId, [FromBody] DeclineOspData declineData) + { + await _logic.DeclineOsp(applicationId, declineData).ConfigureAwait(false); + return this.Ok(); + } } diff --git a/src/registration/Registration.Service/Model/CompanyRoleAgreementData.cs b/src/registration/Registration.Service/Model/CompanyRoleAgreementData.cs index 7f4d579e0c..72c046393a 100644 --- a/src/registration/Registration.Service/Model/CompanyRoleAgreementData.cs +++ b/src/registration/Registration.Service/Model/CompanyRoleAgreementData.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 diff --git a/src/registration/Registration.Service/Model/DeclineOspData.cs b/src/registration/Registration.Service/Model/DeclineOspData.cs new file mode 100644 index 0000000000..33bc585228 --- /dev/null +++ b/src/registration/Registration.Service/Model/DeclineOspData.cs @@ -0,0 +1,26 @@ +/******************************************************************************** + * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +namespace Org.Eclipse.TractusX.Portal.Backend.Registration.Service.Model; + +public record DeclineOspData +( + OspDeclineReason DeclineReason, + string? Message +); diff --git a/src/registration/Registration.Service/Model/OspDeclineReason.cs b/src/registration/Registration.Service/Model/OspDeclineReason.cs new file mode 100644 index 0000000000..a54a040eed --- /dev/null +++ b/src/registration/Registration.Service/Model/OspDeclineReason.cs @@ -0,0 +1,28 @@ +/******************************************************************************** + * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +namespace Org.Eclipse.TractusX.Portal.Backend.Registration.Service.Model; + +public enum OspDeclineReason +{ + REGISTRATION_NOT_REQUESTED = 1, + OPINION_CHANGED = 2, + INACCAPTABLE_DATASPACE_RULES = 3, + OTHERS = 4 +} diff --git a/src/registration/Registration.Service/Registration.Service.csproj b/src/registration/Registration.Service/Registration.Service.csproj index 76b15830b1..6e6007e441 100644 --- a/src/registration/Registration.Service/Registration.Service.csproj +++ b/src/registration/Registration.Service/Registration.Service.csproj @@ -49,6 +49,7 @@ + diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs index c88c27ccfb..d8bb343ecc 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs @@ -846,10 +846,11 @@ public async Task DeleteCompanyIdentityProviderAsync_WithManagedIdp_ExecutesExpe initialize?.Invoke(company); modify(company); }); - A.CallTo(() => _userRepository.AttachAndModifyIdentities(A>>>._)) - .Invokes((IEnumerable<(Guid IdentityId, Action Modify)> identityData) => + A.CallTo(() => _userRepository.AttachAndModifyIdentities(A?, Action>>>._)) + .Invokes((IEnumerable<(Guid IdentityId, Action? Initialize, Action Modify)> identityData) => { - var initial = identityData.Select(x => (Identity: identity, x.Modify)).ToList(); + var initial = identityData.Select(x => (Identity: identity, x.Initialize, x.Modify)).ToList(); + initial.ForEach(x => x.Initialize?.Invoke(x.Identity)); initial.ForEach(x => x.Modify(x.Identity)); }); diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs index 6efddffcf0..a3cf3ce331 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs @@ -484,10 +484,10 @@ public async Task HandlePartnerRegistration_WithIdpNotSetAndOnlyOneIdp_CallsExpe processes.Add(process); return process; }); - A.CallTo(() => _processStepRepository.CreateProcessStep(A._, A._, A._)) - .Invokes((ProcessStepTypeId processStepTypeId, ProcessStepStatusId processStepStatusId, Guid processId) => + A.CallTo(() => _processStepRepository.CreateProcessStepRange(A>._)) + .Invokes((IEnumerable<(ProcessStepTypeId ProcessStepTypeId, ProcessStepStatusId ProcessStepStatusId, Guid ProcessId)> foo) => { - processSteps.Add(new ProcessStep(Guid.NewGuid(), processStepTypeId, processStepStatusId, processId, DateTimeOffset.UtcNow)); + processSteps.AddRange(foo.Select(x => new ProcessStep(Guid.NewGuid(), x.ProcessStepTypeId, x.ProcessStepStatusId, x.ProcessId, DateTimeOffset.UtcNow))); }); A.CallTo(() => _applicationRepository.CreateCompanyApplication(A._, A._, A._, A>._)) .ReturnsLazily((Guid companyId, CompanyApplicationStatusId companyApplicationStatusId, CompanyApplicationTypeId applicationTypeId, Action? setOptionalFields) => @@ -523,10 +523,9 @@ public async Task HandlePartnerRegistration_WithIdpNotSetAndOnlyOneIdp_CallsExpe processes.Should().ContainSingle() .Which.Should().Match( x => x.ProcessTypeId == ProcessTypeId.PARTNER_REGISTRATION); - processSteps.Should().ContainSingle() - .Which.Should().Match(x => - x.ProcessStepStatusId == ProcessStepStatusId.TODO && - x.ProcessStepTypeId == ProcessStepTypeId.SYNCHRONIZE_USER); + processSteps.Should().HaveCount(2).And.Satisfy( + x => x.ProcessStepStatusId == ProcessStepStatusId.TODO && x.ProcessStepTypeId == ProcessStepTypeId.SYNCHRONIZE_USER, + x => x.ProcessStepStatusId == ProcessStepStatusId.TODO && x.ProcessStepTypeId == ProcessStepTypeId.MANUAL_DECLINE_OSP); companyApplications.Should().ContainSingle() .Which.Should().Match(x => x.CompanyId == newCompanyId && @@ -617,10 +616,10 @@ public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string? processes.Add(process); return process; }); - A.CallTo(() => _processStepRepository.CreateProcessStep(A._, A._, A._)) - .Invokes((ProcessStepTypeId processStepTypeId, ProcessStepStatusId processStepStatusId, Guid processId) => + A.CallTo(() => _processStepRepository.CreateProcessStepRange(A>>._)) + .Invokes((IEnumerable<(ProcessStepTypeId ProcessStepTypeId, ProcessStepStatusId ProcessStepStatusId, Guid ProcessId)> processStepTypeStatus) => { - processSteps.Add(new ProcessStep(Guid.NewGuid(), processStepTypeId, processStepStatusId, processId, DateTimeOffset.UtcNow)); + processSteps.AddRange(processStepTypeStatus.Select(x => new ProcessStep(Guid.NewGuid(), x.ProcessStepTypeId, x.ProcessStepStatusId, x.ProcessId, DateTimeOffset.UtcNow)).ToList()); }); A.CallTo(() => _applicationRepository.CreateCompanyApplication(A._, A._, A._, A>._)) .ReturnsLazily((Guid companyId, CompanyApplicationStatusId companyApplicationStatusId, CompanyApplicationTypeId applicationTypeId, Action? setOptionalFields) => @@ -656,10 +655,9 @@ public async Task HandlePartnerRegistration_WithValidData_CallsExpected(string? processes.Should().ContainSingle() .Which.Should().Match(x => x.ProcessTypeId == ProcessTypeId.PARTNER_REGISTRATION); - processSteps.Should().ContainSingle() - .Which.Should().Match(x => - x.ProcessStepStatusId == ProcessStepStatusId.TODO && - x.ProcessStepTypeId == ProcessStepTypeId.SYNCHRONIZE_USER); + processSteps.Should().HaveCount(2).And.Satisfy( + x => x.ProcessStepStatusId == ProcessStepStatusId.TODO && x.ProcessStepTypeId == ProcessStepTypeId.SYNCHRONIZE_USER, + x => x.ProcessStepStatusId == ProcessStepStatusId.TODO && x.ProcessStepTypeId == ProcessStepTypeId.MANUAL_DECLINE_OSP); companyApplications.Should().ContainSingle() .Which.Should().Match(x => x.CompanyId == newCompanyId && diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index f4752831e8..9ded8fa30d 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -479,7 +479,11 @@ public async Task DeclineRegistrationVerification_WithDecline_StateAndCommentSet A._, A>.That.Matches(x => x.Single() == ProcessStepTypeId.VERIFY_REGISTRATION))) .MustHaveHappenedOnceExactly(); - A.CallTo(() => _processStepRepository.CreateProcessStep(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepStatusId.TODO, A._)) + A.CallTo(() => _checklistService.FinalizeChecklistEntryAndProcessSteps( + A._, + A>._, + A>._, + A?>.That.Matches(x => x != null && x.Count() == 1 && x.Single() == ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED))) .MustHaveHappenedOnceExactly(); if (idpTypeId == IdentityProviderTypeId.SHARED) { diff --git a/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationExtensisonsTests.cs b/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationExtensisonsTests.cs index 58c731259d..e563fa9caf 100644 --- a/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationExtensisonsTests.cs +++ b/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationExtensisonsTests.cs @@ -26,6 +26,7 @@ public class NetworkRegistrationExtensisonsTests { [Theory] [InlineData(ProcessStepTypeId.SYNCHRONIZE_USER, ProcessStepTypeId.RETRIGGER_SYNCHRONIZE_USER)] + [InlineData(ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, ProcessStepTypeId.RETRIGGER_REMOVE_KEYCLOAK_USERS)] [InlineData(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_SUBMITTED)] [InlineData(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_DECLINED)] [InlineData(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_APPROVED)] diff --git a/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationProcessTypeExecutorTests.cs b/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationProcessTypeExecutorTests.cs index 9b9fa5af7c..fc5ecb1636 100644 --- a/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationProcessTypeExecutorTests.cs +++ b/tests/processes/NetworkRegistration.Executor.Tests/NetworkRegistrationProcessTypeExecutorTests.cs @@ -99,6 +99,7 @@ public void IsExecutableStepTypeId_WithValid_ReturnsExpected() [InlineData(ProcessStepTypeId.RETRIGGER_PROVIDER_CALLBACK)] [InlineData(ProcessStepTypeId.TRIGGER_ACTIVATE_SUBSCRIPTION)] [InlineData(ProcessStepTypeId.RETRIGGER_SYNCHRONIZE_USER)] + [InlineData(ProcessStepTypeId.RETRIGGER_REMOVE_KEYCLOAK_USERS)] public void IsExecutableStepTypeId_WithInvalid_ReturnsExpected(ProcessStepTypeId processStepTypeId) { // Assert @@ -109,11 +110,12 @@ public void IsExecutableStepTypeId_WithInvalid_ReturnsExpected(ProcessStepTypeId public void GetExecutableStepTypeIds_ReturnsExpected() { // Assert - _sut.GetExecutableStepTypeIds().Should().HaveCount(4).And.Satisfy( + _sut.GetExecutableStepTypeIds().Should().HaveCount(5).And.Satisfy( x => x == ProcessStepTypeId.SYNCHRONIZE_USER, x => x == ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED, x => x == ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, - x => x == ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED); + x => x == ProcessStepTypeId.TRIGGER_CALLBACK_OSP_APPROVED, + x => x == ProcessStepTypeId.REMOVE_KEYCLOAK_USERS); } [Fact] @@ -206,6 +208,37 @@ public async Task ExecuteProcessStep_WithValidData_CallsExpected() result.SkipStepTypeIds.Should().BeNull(); } + [Fact] + public async Task ExecuteProcessStep_WithRemoveKeycloakUser_CallsExpected() + { + // Arrange InitializeProcess + var validProcessId = Guid.NewGuid(); + var networkRegistrationId = Guid.NewGuid(); + A.CallTo(() => _networkRepository.GetNetworkRegistrationDataForProcessIdAsync(validProcessId)) + .Returns(networkRegistrationId); + + // Act InitializeProcess + var initializeResult = await _sut.InitializeProcess(validProcessId, Enumerable.Empty()).ConfigureAwait(false); + + // Assert InitializeProcess + initializeResult.Modified.Should().BeFalse(); + initializeResult.ScheduleStepTypeIds.Should().BeNull(); + + // Arrange + A.CallTo(() => _networkRegistrationHandler.RemoveKeycloakUser(networkRegistrationId)) + .Returns(new ValueTuple?, ProcessStepStatusId, bool, string?>(null, ProcessStepStatusId.DONE, false, null)); + + // Act + var result = await _sut.ExecuteProcessStep(ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, Enumerable.Empty(), CancellationToken.None).ConfigureAwait(false); + + // Assert + result.Modified.Should().BeFalse(); + result.ScheduleStepTypeIds.Should().BeNull(); + result.ProcessStepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.ProcessMessage.Should().BeNull(); + result.SkipStepTypeIds.Should().BeNull(); + } + [Theory] [InlineData(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED)] [InlineData(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED)] diff --git a/tests/processes/NetworkRegistration.Library.Tests/NetworkRegistrationHandlerTests.cs b/tests/processes/NetworkRegistration.Library.Tests/NetworkRegistrationHandlerTests.cs index 395536c633..f9e6652e9f 100644 --- a/tests/processes/NetworkRegistration.Library.Tests/NetworkRegistrationHandlerTests.cs +++ b/tests/processes/NetworkRegistration.Library.Tests/NetworkRegistrationHandlerTests.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration; +using Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling; 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; @@ -39,9 +40,11 @@ public class NetworkRegistrationHandlerTests private static readonly Guid NetworkRegistrationId = Guid.NewGuid(); private static readonly Guid UserRoleIds = Guid.NewGuid(); + private readonly IFixture _fixture; + private readonly IUserProvisioningService _userProvisioningService; - private readonly IProvisioningManager _provisioningManger; + private readonly IProvisioningManager _provisioningManager; private readonly IUserRepository _userRepository; private readonly INetworkRepository _networkRepository; @@ -50,12 +53,17 @@ public class NetworkRegistrationHandlerTests public NetworkRegistrationHandlerTests() { + _fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + _fixture.Behaviors.OfType().ToList() + .ForEach(b => _fixture.Behaviors.Remove(b)); + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + var portalRepositories = A.Fake(); _userRepository = A.Fake(); _networkRepository = A.Fake(); _userProvisioningService = A.Fake(); - _provisioningManger = A.Fake(); + _provisioningManager = A.Fake(); _mailingService = A.Fake(); var settings = new NetworkRegistrationProcessSettings @@ -68,9 +76,11 @@ public NetworkRegistrationHandlerTests() A.CallTo(() => portalRepositories.GetInstance()).Returns(_userRepository); A.CallTo(() => portalRepositories.GetInstance()).Returns(_networkRepository); - _sut = new NetworkRegistrationHandler(portalRepositories, _userProvisioningService, _provisioningManger, _mailingService, options); + _sut = new NetworkRegistrationHandler(portalRepositories, _userProvisioningService, _provisioningManager, _mailingService, options); } + #region SynchronizeUser + [Fact] public async Task SynchronizeUser_WithoutOspName_ThrowsUnexpectedConditionException() { @@ -164,8 +174,8 @@ public async Task SynchronizeUser_WithDisplayNameNull_ThrowsConflictException() }.ToAsyncEnumerable()); A.CallTo(() => _userProvisioningService.GetRoleDatas(A>._)) .Returns(Enumerable.Repeat(new UserRoleData(UserRoleIds, "cl1", "Company Admin"), 1).ToAsyncEnumerable()); - A.CallTo(() => _provisioningManger.GetUserByUserName(user1.CompanyUserId.ToString())).Returns(user1Id); - A.CallTo(() => _provisioningManger.GetUserByUserName(user2.CompanyUserId.ToString())).Returns((string?)null); + A.CallTo(() => _provisioningManager.GetUserByUserName(user1.CompanyUserId.ToString())).Returns(user1Id); + A.CallTo(() => _provisioningManager.GetUserByUserName(user2.CompanyUserId.ToString())).Returns((string?)null); // Act async Task Act() => await _sut.SynchronizeUser(NetworkRegistrationId).ConfigureAwait(false); @@ -201,12 +211,12 @@ public async Task SynchronizeUser_WithValidData_ReturnsExpected() }.ToAsyncEnumerable()); A.CallTo(() => _userProvisioningService.GetRoleDatas(A>._)) .Returns(Enumerable.Repeat(new UserRoleData(UserRoleIds, "cl1", "Company Admin"), 1).ToAsyncEnumerable()); - A.CallTo(() => _provisioningManger.GetUserByUserName(user1.CompanyUserId.ToString())).Returns(user1Id); - A.CallTo(() => _provisioningManger.GetUserByUserName(user2.CompanyUserId.ToString())).Returns((string?)null); - A.CallTo(() => _provisioningManger.GetUserByUserName(user3.CompanyUserId.ToString())).Returns((string?)null); - A.CallTo(() => _provisioningManger.GetIdentityProviderDisplayName("idp1")) + A.CallTo(() => _provisioningManager.GetUserByUserName(user1.CompanyUserId.ToString())).Returns(user1Id); + A.CallTo(() => _provisioningManager.GetUserByUserName(user2.CompanyUserId.ToString())).Returns((string?)null); + A.CallTo(() => _provisioningManager.GetUserByUserName(user3.CompanyUserId.ToString())).Returns((string?)null); + A.CallTo(() => _provisioningManager.GetIdentityProviderDisplayName("idp1")) .Returns("DisplayName for Idp1"); - A.CallTo(() => _provisioningManger.GetIdentityProviderDisplayName("idp2")) + A.CallTo(() => _provisioningManager.GetIdentityProviderDisplayName("idp2")) .Returns("DisplayName for Idp2"); // Act @@ -233,4 +243,153 @@ public async Task SynchronizeUser_WithValidData_ReturnsExpected() result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); result.nextStepTypeIds.Should().BeNull(); } + + #endregion + + #region Remove Keycloak User + + [Fact] + public async Task RemoveKeycloakUser_WithNotFoundException_ReturnsExpected() + { + // Arrange + var networkRegistrationId = Guid.NewGuid(); + var iamUserId = _fixture.Create(); + var identity = new Identity(Guid.NewGuid(), DateTimeOffset.UtcNow, Guid.NewGuid(), UserStatusId.ACTIVE, IdentityTypeId.COMPANY_USER); + A.CallTo(() => _userRepository.GetNextIdentitiesForNetworkRegistration(networkRegistrationId, A>.That.Matches(x => x.Count() == 2 && x.Contains(UserStatusId.ACTIVE) && x.Contains(UserStatusId.PENDING)))) + .Returns(new[] + { + identity.Id, + }.ToAsyncEnumerable()); + A.CallTo(() => _provisioningManager.GetUserByUserName(A._)) + .Throws(new KeycloakEntityNotFoundException($"user {identity.Id} not found")); + A.CallTo(() => _userRepository.AttachAndModifyIdentity(A._, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action setOptionalFields) => + { + initialize?.Invoke(identity); + setOptionalFields.Invoke(identity); + }); + + // Act + var result = await _sut.RemoveKeycloakUser(networkRegistrationId).ConfigureAwait(false); + + // Assert + result.modified.Should().BeTrue(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.processMessage.Should().Be($"no user found for company user id {identity.Id}"); + result.nextStepTypeIds.Should().BeNull(); + identity.UserStatusId.Should().Be(UserStatusId.INACTIVE); + + A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync(iamUserId)) + .MustNotHaveHappened(); + } + + [Fact] + public async Task RemoveKeycloakUser_WithIamUserIdNull_ReturnsExpected() + { + // Arrange + var networkRegistrationId = Guid.NewGuid(); + var iamUserId = _fixture.Create(); + var identity = new Identity(Guid.NewGuid(), DateTimeOffset.UtcNow, Guid.NewGuid(), UserStatusId.ACTIVE, IdentityTypeId.COMPANY_USER); + A.CallTo(() => _userRepository.GetNextIdentitiesForNetworkRegistration(networkRegistrationId, A>.That.Matches(x => x.Count() == 2 && x.Contains(UserStatusId.ACTIVE) && x.Contains(UserStatusId.PENDING)))) + .Returns(new[] + { + identity.Id, + }.ToAsyncEnumerable()); + A.CallTo(() => _provisioningManager.GetUserByUserName(A._)) + .Returns((string?)null); + A.CallTo(() => _userRepository.AttachAndModifyIdentity(A._, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action setOptionalFields) => + { + initialize?.Invoke(identity); + setOptionalFields.Invoke(identity); + }); + + // Act + var result = await _sut.RemoveKeycloakUser(networkRegistrationId).ConfigureAwait(false); + + // Assert + result.modified.Should().BeTrue(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.processMessage.Should().Be($"no user found for company user id {identity.Id}"); + result.nextStepTypeIds.Should().BeNull(); + identity.UserStatusId.Should().Be(UserStatusId.INACTIVE); + + A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync(iamUserId)) + .MustNotHaveHappened(); + } + + [Fact] + public async Task RemoveKeycloakUser_WithValidData_ReturnsExpected() + { + // Arrange + var networkRegistrationId = Guid.NewGuid(); + var iamUserId = _fixture.Create(); + var identity = new Identity(Guid.NewGuid(), DateTimeOffset.UtcNow, Guid.NewGuid(), UserStatusId.ACTIVE, IdentityTypeId.COMPANY_USER); + A.CallTo(() => _userRepository.GetNextIdentitiesForNetworkRegistration(networkRegistrationId, A>.That.Matches(x => x.Count() == 2 && x.Contains(UserStatusId.ACTIVE) && x.Contains(UserStatusId.PENDING)))) + .Returns(new[] + { + identity.Id, + }.ToAsyncEnumerable()); + A.CallTo(() => _provisioningManager.GetUserByUserName(A._)) + .Returns(iamUserId); + A.CallTo(() => _userRepository.AttachAndModifyIdentity(A._, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action setOptionalFields) => + { + initialize?.Invoke(identity); + setOptionalFields.Invoke(identity); + }); + + // Act + var result = await _sut.RemoveKeycloakUser(networkRegistrationId).ConfigureAwait(false); + + // Assert + result.modified.Should().BeTrue(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.processMessage.Should().Be($"deleted user {iamUserId} for company user {identity.Id}"); + result.nextStepTypeIds.Should().BeNull(); + identity.UserStatusId.Should().Be(UserStatusId.INACTIVE); + + A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync(iamUserId)) + .MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task RemoveKeycloakUser_WithMultipleIdentityIds_ReturnsExpected() + { + // Arrange + var networkRegistrationId = Guid.NewGuid(); + var iamUserId = _fixture.Create(); + var identity = new Identity(Guid.NewGuid(), DateTimeOffset.UtcNow, Guid.NewGuid(), UserStatusId.ACTIVE, IdentityTypeId.COMPANY_USER); + var otherIdentity = new Identity(Guid.NewGuid(), DateTimeOffset.UtcNow, Guid.NewGuid(), UserStatusId.ACTIVE, IdentityTypeId.COMPANY_USER); + A.CallTo(() => _userRepository.GetNextIdentitiesForNetworkRegistration(networkRegistrationId, A>.That.Matches(x => x.Count() == 2 && x.Contains(UserStatusId.ACTIVE) && x.Contains(UserStatusId.PENDING)))) + .Returns(new[] + { + identity.Id, + otherIdentity.Id + }.ToAsyncEnumerable()); + A.CallTo(() => _provisioningManager.GetUserByUserName(A._)) + .Returns(iamUserId); + A.CallTo(() => _userRepository.AttachAndModifyIdentity(A._, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action setOptionalFields) => + { + initialize?.Invoke(identity); + setOptionalFields.Invoke(identity); + }); + + // Act + var result = await _sut.RemoveKeycloakUser(networkRegistrationId).ConfigureAwait(false); + + // Assert + result.modified.Should().BeTrue(); + result.stepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.processMessage.Should().Be($"deleted user {iamUserId} for company user {identity.Id}"); + result.nextStepTypeIds.Should().ContainSingle().And.Satisfy( + x => x == ProcessStepTypeId.REMOVE_KEYCLOAK_USERS); + identity.UserStatusId.Should().Be(UserStatusId.INACTIVE); + + A.CallTo(() => _provisioningManager.DeleteCentralRealmUserAsync(iamUserId)) + .MustHaveHappenedOnceExactly(); + } + + #endregion } diff --git a/tests/processes/Processes.Library.Tests/ManualProcessDataExtensionsTests.cs b/tests/processes/Processes.Library.Tests/ManualProcessDataExtensionsTests.cs index 60236fdb14..20bbcef940 100644 --- a/tests/processes/Processes.Library.Tests/ManualProcessDataExtensionsTests.cs +++ b/tests/processes/Processes.Library.Tests/ManualProcessDataExtensionsTests.cs @@ -1,6 +1,5 @@ /******************************************************************************** - * Copyright (c) 2021, 2023 BMW Group AG - * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -248,7 +247,7 @@ public void SkipProcessSteps_ReturnsExpected() { // Arrange var process = _fixture.Create(); - var stepTypeIds = _fixture.CreateMany(3).ToImmutableArray(); + var stepTypeIds = _fixture.CreateMany(4).ToImmutableArray(); var before = DateTimeOffset.UtcNow.AddDays(-1); var processSteps0 = new ProcessStep[] { @@ -268,18 +267,27 @@ public void SkipProcessSteps_ReturnsExpected() new(Guid.NewGuid(), stepTypeIds[2], ProcessStepStatusId.TODO, process.Id, before), new(Guid.NewGuid(), stepTypeIds[2], ProcessStepStatusId.TODO, process.Id, before) }; + var processSteps3 = new ProcessStep[] + { + new(Guid.NewGuid(), stepTypeIds[3], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[3], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[3], ProcessStepStatusId.TODO, process.Id, before) + }; var processSteps = new[] { processSteps0[0], processSteps1[0], processSteps2[0], + processSteps3[0], processSteps0[1], processSteps1[1], processSteps2[1], + processSteps3[1], processSteps0[2], processSteps1[2], processSteps2[2], + processSteps3[2], }; var modifiedProcessSteps = new List(); @@ -297,13 +305,14 @@ public void SkipProcessSteps_ReturnsExpected() }); var sut = _fixture.Build() + .With(x => x.ProcessStepTypeId, stepTypeIds[3]) .With(x => x.Process, process) .With(x => x.PortalRepositories, _portalRepositories) .With(x => x.ProcessSteps, processSteps) .Create(); // Act - sut.SkipProcessSteps(new ProcessStepTypeId[] { stepTypeIds[1], stepTypeIds[2] }); + sut.SkipProcessSteps(new ProcessStepTypeId[] { stepTypeIds[1], stepTypeIds[2], stepTypeIds[3] }); // Assert A.CallTo(() => _processStepRepository.AttachAndModifyProcessSteps(A?, Action)>>._)) @@ -321,6 +330,93 @@ public void SkipProcessSteps_ReturnsExpected() #endregion + #region SkipProcessStepsExcept + + [Fact] + public void SkipProcessStepsExcept_ReturnsExpected() + { + // Arrange + var process = _fixture.Create(); + var stepTypeIds = _fixture.CreateMany(4).ToImmutableArray(); + var before = DateTimeOffset.UtcNow.AddDays(-1); + var processSteps0 = new ProcessStep[] + { + new(Guid.NewGuid(), stepTypeIds[0], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[0], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[0], ProcessStepStatusId.TODO, process.Id, before) + }; + var processSteps1 = new ProcessStep[] + { + new(Guid.NewGuid(), stepTypeIds[1], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[1], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[1], ProcessStepStatusId.TODO, process.Id, before) + }; + var processSteps2 = new ProcessStep[] + { + new(Guid.NewGuid(), stepTypeIds[2], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[2], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[2], ProcessStepStatusId.TODO, process.Id, before) + }; + var processSteps3 = new ProcessStep[] + { + new(Guid.NewGuid(), stepTypeIds[3], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[3], ProcessStepStatusId.TODO, process.Id, before), + new(Guid.NewGuid(), stepTypeIds[3], ProcessStepStatusId.TODO, process.Id, before) + }; + + var processSteps = new[] + { + processSteps0[0], + processSteps1[0], + processSteps2[0], + processSteps3[0], + processSteps0[1], + processSteps1[1], + processSteps2[1], + processSteps3[1], + processSteps0[2], + processSteps1[2], + processSteps2[2], + processSteps3[2], + }; + + var modifiedProcessSteps = new List(); + + A.CallTo(() => _processStepRepository.AttachAndModifyProcessSteps(A?, Action)>>._)) + .Invokes((IEnumerable<(Guid ProcessStepId, Action? Initialize, Action Modify)> processStepIdInitializeModify) => + { + foreach (var (stepId, initialize, modify) in processStepIdInitializeModify) + { + var step = new ProcessStep(stepId, default, default, Guid.Empty, default); + initialize?.Invoke(step); + modify(step); + modifiedProcessSteps.Add(step); + } + }); + + var sut = _fixture.Build() + .With(x => x.ProcessStepTypeId, stepTypeIds[3]) + .With(x => x.Process, process) + .With(x => x.PortalRepositories, _portalRepositories) + .With(x => x.ProcessSteps, processSteps) + .Create(); + + // Act + sut.SkipProcessStepsExcept(new ProcessStepTypeId[] { stepTypeIds[1], stepTypeIds[2] }); + + // Assert + A.CallTo(() => _processStepRepository.AttachAndModifyProcessSteps(A?, Action)>>._)) + .MustHaveHappenedOnceExactly(); + + modifiedProcessSteps.Should().HaveCount(3).And.Satisfy( + x => processSteps0.Any(step => step.Id == x.Id) && x.ProcessStepStatusId == ProcessStepStatusId.SKIPPED && x.DateLastChanged != before, + x => processSteps0.Any(step => step.Id == x.Id) && x.ProcessStepStatusId == ProcessStepStatusId.DUPLICATE && x.DateLastChanged != before, + x => processSteps0.Any(step => step.Id == x.Id) && x.ProcessStepStatusId == ProcessStepStatusId.DUPLICATE && x.DateLastChanged != before + ); + } + + #endregion + #region ScheduleProcessSteps [Fact] diff --git a/tests/registration/Registration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs b/tests/registration/Registration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs index a4c4b97359..c9d70b1f6f 100644 --- a/tests/registration/Registration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs +++ b/tests/registration/Registration.Service.Tests/BusinessLogic/NetworkBusinessLogicTests.cs @@ -46,6 +46,7 @@ public class NetworkBusinessLogicTests private static readonly Guid NoIdpCompanyId = Guid.NewGuid(); private static readonly Guid IdpId = Guid.NewGuid(); private static readonly Guid NoAliasIdpCompanyId = Guid.NewGuid(); + private static readonly Guid IdentityCompanyId = Guid.NewGuid(); private readonly IFixture _fixture; @@ -62,6 +63,7 @@ public class NetworkBusinessLogicTests private readonly ICountryRepository _countryRepository; private readonly NetworkBusinessLogic _sut; private readonly IConsentRepository _consentRepository; + private readonly IInvitationRepository _invitationRepository; public NetworkBusinessLogicTests() { @@ -81,12 +83,13 @@ public NetworkBusinessLogicTests() _identityProviderRepository = A.Fake(); _countryRepository = A.Fake(); _consentRepository = A.Fake(); + _invitationRepository = A.Fake(); var identityService = A.Fake(); _identity = A.Fake(); A.CallTo(() => _identity.IdentityId).Returns(Guid.NewGuid()); A.CallTo(() => _identity.IdentityTypeId).Returns(IdentityTypeId.COMPANY_USER); - A.CallTo(() => _identity.CompanyId).Returns(Guid.NewGuid()); + A.CallTo(() => _identity.CompanyId).Returns(IdentityCompanyId); A.CallTo(() => identityService.IdentityData).Returns(_identity); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_companyRepository); @@ -96,6 +99,7 @@ public NetworkBusinessLogicTests() A.CallTo(() => _portalRepositories.GetInstance()).Returns(_networkRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_identityProviderRepository); A.CallTo(() => _portalRepositories.GetInstance()).Returns(_countryRepository); + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_invitationRepository); _sut = new NetworkBusinessLogic(_portalRepositories, identityService, _checklistService); @@ -339,6 +343,199 @@ public async Task Submit_WithValidData_CallsExpected() #endregion + #region DeclineOsp + + [Fact] + public async Task DeclineOsp_WithoutExisting_ThrowsNotFoundException() + { + // Arrange + var notExistingId = Guid.NewGuid(); + var data = _fixture.Create(); + A.CallTo(() => _networkRepository.GetDeclineDataForApplicationId(notExistingId, CompanyApplicationTypeId.EXTERNAL, A>._, IdentityCompanyId)) + .Returns(new ValueTuple), + IEnumerable<(Guid, InvitationStatusId)>, + VerifyProcessData + )>()); + + // Act + async Task Act() => await _sut.DeclineOsp(notExistingId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"CompanyApplication {notExistingId} does not exist"); + } + + [Fact] + public async Task DeclineOsp_WithWrongCompany_ThrowsForbiddenException() + { + // Arrange + var applcationId = Guid.NewGuid(); + var data = _fixture.Create(); + A.CallTo(() => _networkRepository.GetDeclineDataForApplicationId(applcationId, CompanyApplicationTypeId.EXTERNAL, A>._, IdentityCompanyId)) + .Returns(new ValueTuple), + IEnumerable<(Guid, InvitationStatusId)>, + VerifyProcessData + )>( + true, + true, + true, + false, + default)); + + // Act + async Task Act() => await _sut.DeclineOsp(applcationId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"User is not allowed to decline application {applcationId}"); + } + + [Fact] + public async Task DeclineOsp_WithInternalApplication_ThrowsConflictException() + { + // Arrange + var applicationId = Guid.NewGuid(); + var data = _fixture.Create(); + A.CallTo(() => _networkRepository.GetDeclineDataForApplicationId(applicationId, CompanyApplicationTypeId.EXTERNAL, A>._, IdentityCompanyId)) + .Returns(new ValueTuple), + IEnumerable<(Guid, InvitationStatusId)>, + VerifyProcessData + )>( + true, + false, + true, + true, + default + )); + + // Act + async Task Act() => await _sut.DeclineOsp(applicationId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("Only external registrations can be declined"); + } + + [Fact] + public async Task DeclineOsp_WithInvalidApplicationState_ThrowsConflictException() + { + // Arrange + var applicationId = Guid.NewGuid(); + var data = _fixture.Create(); + A.CallTo(() => _networkRepository.GetDeclineDataForApplicationId(applicationId, CompanyApplicationTypeId.EXTERNAL, A>._, IdentityCompanyId)) + .Returns(new ValueTuple), + IEnumerable<(Guid, InvitationStatusId)>, + VerifyProcessData + )>( + true, + true, + false, + true, + default)); + + // Act + async Task Act() => await _sut.DeclineOsp(applicationId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"The status of the application {applicationId} must be one of the following: CREATED,ADD_COMPANY_DATA,INVITE_USER,SELECT_COMPANY_ROLE,UPLOAD_DOCUMENTS,VERIFY"); + } + + [Fact] + public async Task DeclineOsp_WithValid_ExecutesExpected() + { + // Arrange + var application = _fixture.Build().With(x => x.ApplicationStatusId, CompanyApplicationStatusId.CREATED).Create(); + var company = new Company(IdentityCompanyId, "company", CompanyStatusId.ACTIVE, DateTimeOffset.UtcNow); + var invitation = _fixture.Build().With(x => x.InvitationStatusId, InvitationStatusId.PENDING).Create(); + var identityId = Guid.NewGuid(); + var currentVersion = Guid.NewGuid(); + var process = _fixture.Build() + .With(x => x.LockExpiryDate, (DateTimeOffset?)null) + .With(x => x.Version, currentVersion).Create(); + var currentProcessStep = new ProcessStep(Guid.NewGuid(), ProcessStepTypeId.MANUAL_DECLINE_OSP, ProcessStepStatusId.TODO, process.Id, DateTimeOffset.UtcNow); + var removeUsersProcessStep = new ProcessStep(Guid.NewGuid(), ProcessStepTypeId.REMOVE_KEYCLOAK_USERS, ProcessStepStatusId.TODO, process.Id, DateTimeOffset.UtcNow); + var otherProcessStep = new ProcessStep(Guid.NewGuid(), ProcessStepTypeId.SYNCHRONIZE_USER, ProcessStepStatusId.TODO, process.Id, DateTimeOffset.UtcNow); + var existingProcessSteps = new[] { currentProcessStep, removeUsersProcessStep, otherProcessStep }; + var data = _fixture.Create(); + A.CallTo(() => _networkRepository.GetDeclineDataForApplicationId(application.Id, CompanyApplicationTypeId.EXTERNAL, A>._, IdentityCompanyId)) + .Returns(new ValueTuple), + IEnumerable<(Guid, InvitationStatusId)>, + VerifyProcessData + )>(true, + true, + true, + true, + new ValueTuple>, IEnumerable<(Guid, InvitationStatusId)>, VerifyProcessData>( + new(company.CompanyStatusId, Enumerable.Repeat(new ValueTuple(identityId, UserStatusId.ACTIVE), 1)), + Enumerable.Repeat(new ValueTuple(invitation.Id, invitation.InvitationStatusId), 1), + new VerifyProcessData(process, existingProcessSteps) + ) + )); + A.CallTo(() => _applicationRepository.AttachAndModifyCompanyApplication(application.Id, A>._)) + .Invokes((Guid _, Action modify) => + { + modify.Invoke(application); + }); + A.CallTo(() => _companyRepository.AttachAndModifyCompany(company.Id, A>._, A>._)) + .Invokes((Guid _, Action? initialize, Action modify) => + { + initialize?.Invoke(company); + modify.Invoke(company); + }); + A.CallTo(() => _invitationRepository.AttachAndModifyInvitations(A?, Action>>>._)) + .Invokes((IEnumerable<(Guid InvitationId, Action? Initialize, Action Modify)> invitationData) => + { + var initial = invitationData.Select(x => + { + x.Initialize?.Invoke(invitation); + return (Invitation: invitation, modify: x.Modify); + } + ).ToList(); + initial.ForEach(x => x.modify(x.Invitation)); + }); + A.CallTo(() => _processStepRepository.AttachAndModifyProcessSteps(A?, Action>>>._)) + .Invokes((IEnumerable<(Guid ProcessStepId, Action? Initialize, Action Modify)> processSteps) => + { + var initial = processSteps.Select(x => + { + var existing = existingProcessSteps.Single(s => s.Id == x.ProcessStepId); + x.Initialize?.Invoke(existing); + return (ProcessStep: existing, modify: x.Modify); + } + ).ToList(); + initial.ForEach(x => x.modify(x.ProcessStep)); + }); + + // Act + await _sut.DeclineOsp(application.Id, data).ConfigureAwait(false); + + // Assert + A.CallTo(() => _processStepRepository.CreateProcessStepRange(A>._)) + .MustNotHaveHappened(); + A.CallTo(() => _portalRepositories.SaveAsync()) + .MustHaveHappenedOnceExactly(); + application.ApplicationStatusId.Should().Be(CompanyApplicationStatusId.CANCELLED_BY_CUSTOMER); + invitation.InvitationStatusId.Should().Be(InvitationStatusId.DECLINED); + company.CompanyStatusId.Should().Be(CompanyStatusId.REJECTED); + currentProcessStep.ProcessStepStatusId.Should().Be(ProcessStepStatusId.DONE); + removeUsersProcessStep.ProcessStepStatusId.Should().Be(ProcessStepStatusId.TODO); + otherProcessStep.ProcessStepStatusId.Should().Be(ProcessStepStatusId.SKIPPED); + process.Version.Should().NotBe(currentVersion); + } + + #endregion + #region Setup private void SetupRepos() From cac93f1c4260071a3875aed6f437d5fe08826f1d Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Tue, 23 Jan 2024 09:10:46 +0100 Subject: [PATCH 06/10] fix(sa): adjust filter for inactive service accounts (#426) adjust endpoint GET: api/administration/serviceaccount/owncompany/serviceaccounts to filter for active service accounts by default Refs: TEST-1799 --- .../BusinessLogic/IServiceAccountBusinessLogic.cs | 2 +- .../BusinessLogic/ServiceAccountBusinessLogic.cs | 4 ++-- .../Controllers/ServiceAccountController.cs | 6 +++--- .../BusinessLogic/ServiceAccountBusinessLogicTests.cs | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs index 059369322d..59b4afed54 100644 --- a/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/IServiceAccountBusinessLogic.cs @@ -32,6 +32,6 @@ public interface IServiceAccountBusinessLogic Task GetOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId); Task UpdateOwnCompanyServiceAccountDetailsAsync(Guid serviceAccountId, ServiceAccountEditableDetails serviceAccountDetails); Task ResetOwnCompanyServiceAccountSecretAsync(Guid serviceAccountId); - Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, string? clientId, bool? isOwner, bool isUserStatusActive); + Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, string? clientId, bool? isOwner, bool filterForInactive); IAsyncEnumerable GetServiceAccountRolesAsync(string? languageShortName); } diff --git a/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs index dda25ca46b..6a108f51ea 100644 --- a/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/ServiceAccountBusinessLogic.cs @@ -265,12 +265,12 @@ public async Task UpdateOwnCompanyServiceAccountDetailsAs result.OfferSubscriptionId); } - public Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, string? clientId, bool? isOwner, bool isUserStatusActive) => + public Task> GetOwnCompanyServiceAccountsDataAsync(int page, int size, string? clientId, bool? isOwner, bool filterForInactive) => Pagination.CreateResponseAsync( page, size, 15, - _portalRepositories.GetInstance().GetOwnCompanyServiceAccountsUntracked(_identityData.CompanyId, clientId, isOwner, isUserStatusActive ? UserStatusId.ACTIVE : UserStatusId.INACTIVE)); + _portalRepositories.GetInstance().GetOwnCompanyServiceAccountsUntracked(_identityData.CompanyId, clientId, isOwner, filterForInactive ? UserStatusId.INACTIVE : UserStatusId.ACTIVE)); public IAsyncEnumerable GetServiceAccountRolesAsync(string? languageShortName) => _portalRepositories.GetInstance().GetServiceAccountRolesAsync(_identityData.CompanyId, _settings.ClientId, languageShortName ?? Constants.DefaultLanguage); diff --git a/src/administration/Administration.Service/Controllers/ServiceAccountController.cs b/src/administration/Administration.Service/Controllers/ServiceAccountController.cs index f9474cafbf..968ff63355 100644 --- a/src/administration/Administration.Service/Controllers/ServiceAccountController.cs +++ b/src/administration/Administration.Service/Controllers/ServiceAccountController.cs @@ -162,7 +162,7 @@ public Task ResetServiceAccountCredentials([FromRoute] Gu /// number of service account data /// isOwner either true or false /// clientId is string clientclientid - /// isUserStatusActive is True or False + /// isUserStatusActive is True or False /// Returns the specific number of service account data for the given page. /// Example: GET: api/administration/serviceaccount/owncompany/serviceaccounts /// Returns the specific number of service account data for the given page. @@ -171,8 +171,8 @@ public Task ResetServiceAccountCredentials([FromRoute] Gu [Authorize(Policy = PolicyTypes.ValidCompany)] [Route("owncompany/serviceaccounts")] [ProducesResponseType(typeof(Pagination.Response), StatusCodes.Status200OK)] - public Task> GetServiceAccountsData([FromQuery] int page, [FromQuery] int size, [FromQuery] bool? isOwner, [FromQuery] string? clientId, [FromQuery] bool isUserStatusActive) => - _logic.GetOwnCompanyServiceAccountsDataAsync(page, size, clientId, isOwner, isUserStatusActive); + public Task> GetServiceAccountsData([FromQuery] int page, [FromQuery] int size, [FromQuery] bool? isOwner, [FromQuery] string? clientId, [FromQuery] bool filterForInactive) => + _logic.GetOwnCompanyServiceAccountsDataAsync(page, size, clientId, isOwner, filterForInactive); /// /// Get all service account roles diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs index bf59035c0e..e8be2613f1 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/ServiceAccountBusinessLogicTests.cs @@ -390,9 +390,9 @@ public async Task UpdateOwnCompanyServiceAccountDetailsAsync_WithInactiveService #region GetOwnCompanyServiceAccountsDataAsync [Theory] - [InlineData(UserStatusId.ACTIVE, true)] - [InlineData(UserStatusId.INACTIVE, false)] - public async Task GetOwnCompanyServiceAccountsDataAsync_GetsExpectedData(UserStatusId userStatusId, bool isUserStatusActive) + [InlineData(UserStatusId.ACTIVE, false)] + [InlineData(UserStatusId.INACTIVE, true)] + public async Task GetOwnCompanyServiceAccountsDataAsync_GetsExpectedData(UserStatusId userStatusId, bool isUserInactive) { // Arrange var data = _fixture.CreateMany(15); @@ -403,7 +403,7 @@ public async Task GetOwnCompanyServiceAccountsDataAsync_GetsExpectedData(UserSta var sut = new ServiceAccountBusinessLogic(_provisioningManager, _portalRepositories, _options, null!, _identityService); // Act - var result = await sut.GetOwnCompanyServiceAccountsDataAsync(1, 10, null, null, isUserStatusActive).ConfigureAwait(false); + var result = await sut.GetOwnCompanyServiceAccountsDataAsync(1, 10, null, null, isUserInactive).ConfigureAwait(false); // Assert result.Should().NotBeNull(); From 6b8d15f6e0da216b28764d20340acd0011e2c0a0 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Tue, 23 Jan 2024 09:13:05 +0100 Subject: [PATCH 07/10] fix(custodian): save error message when remote call is failing (#428) Refs: CPLP-3730 --- .../ClearinghouseService.cs | 5 +++- .../ClearinghouseServiceTests.cs | 24 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/externalsystems/Clearinghouse.Library/ClearinghouseService.cs b/src/externalsystems/Clearinghouse.Library/ClearinghouseService.cs index 03a50438c5..830de1e220 100644 --- a/src/externalsystems/Clearinghouse.Library/ClearinghouseService.cs +++ b/src/externalsystems/Clearinghouse.Library/ClearinghouseService.cs @@ -42,7 +42,10 @@ public async Task TriggerCompanyDataPost(ClearinghouseTransferData data, Cancell { var httpClient = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(false); + async ValueTask<(bool, string?)> CreateErrorMessage(HttpResponseMessage errorResponse) => + (false, (await errorResponse.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false))); + await httpClient.PostAsJsonAsync("/api/v1/validation", data, cancellationToken) - .CatchingIntoServiceExceptionFor("clearinghouse-post", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE).ConfigureAwait(false); + .CatchingIntoServiceExceptionFor("clearinghouse-post", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, CreateErrorMessage).ConfigureAwait(false); } } diff --git a/tests/externalsystems/Clearinghouse.Library.Tests/ClearinghouseServiceTests.cs b/tests/externalsystems/Clearinghouse.Library.Tests/ClearinghouseServiceTests.cs index 94ae0bf510..abf57226de 100644 --- a/tests/externalsystems/Clearinghouse.Library.Tests/ClearinghouseServiceTests.cs +++ b/tests/externalsystems/Clearinghouse.Library.Tests/ClearinghouseServiceTests.cs @@ -100,7 +100,7 @@ public async Task TriggerCompanyDataPost_WithInvalidData_ThrowsServiceException( // Assert var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Contain("call to external system clearinghouse-post failed with statuscode"); + ex.Message.Should().Be("call to external system clearinghouse-post failed with statuscode 400"); ex.StatusCode.Should().Be(HttpStatusCode.BadRequest); } @@ -122,9 +122,29 @@ public async Task TriggerCompanyDataPost_WitException_ThrowsServiceException() // Assert var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Contain("call to external system clearinghouse-post failed"); + ex.Message.Should().Be("call to external system clearinghouse-post failed"); ex.InnerException.Should().Be(error); } + [Fact] + public async Task TriggerCompanyDataPost_WitErrorContent_LogsContent() + { + // Arrange + var data = _fixture.Create(); + var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.BadRequest, new StringContent("{ \"message\": \"Framework test!\" }")); + var httpClient = new HttpClient(httpMessageHandlerMock) + { + BaseAddress = new Uri("https://base.address.com") + }; + A.CallTo(() => _tokenService.GetAuthorizedClient(_options.Value, A._)).Returns(httpClient); + + // Act + async Task Act() => await _sut.TriggerCompanyDataPost(data, CancellationToken.None).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("call to external system clearinghouse-post failed with statuscode 400 - Message: { \"message\": \"Framework test!\" }"); + } + #endregion } From 71921034fc07fe7073df92d1ca0f31bee868851f Mon Sep 17 00:00:00 2001 From: Evelyn Gurschler Date: Tue, 23 Jan 2024 10:06:38 +0100 Subject: [PATCH 08/10] build(release): add additional image tag of type semver (#422) --- .github/workflows/release.yml | 9 +++++++++ .github/workflows/release_iam-seeding.yml | 1 + .github/workflows/release_release_candidate.yml | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a33fef96a3..c854a2c8d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -128,6 +129,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -184,6 +186,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -240,6 +243,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -296,6 +300,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -352,6 +357,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -408,6 +414,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -464,6 +471,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -520,6 +528,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} diff --git a/.github/workflows/release_iam-seeding.yml b/.github/workflows/release_iam-seeding.yml index 8ffd4099c4..6a27b26b9d 100644 --- a/.github/workflows/release_iam-seeding.yml +++ b/.github/workflows/release_iam-seeding.yml @@ -62,6 +62,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} diff --git a/.github/workflows/release_release_candidate.yml b/.github/workflows/release_release_candidate.yml index 5f0adf7a90..8889651488 100644 --- a/.github/workflows/release_release_candidate.yml +++ b/.github/workflows/release_release_candidate.yml @@ -71,6 +71,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -127,6 +128,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -183,6 +185,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -239,6 +242,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -295,6 +299,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -351,6 +356,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -407,6 +413,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -463,6 +470,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} @@ -519,6 +527,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ github.ref_name }} + type=semver,pattern=v{{version}} type=semver,pattern=v{{major}} type=semver,pattern=v{{major}}.{{minor}} From 2d1b20cbe8b4c5fcb611823d09bfa50579bfb378 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Tue, 23 Jan 2024 14:24:11 +0100 Subject: [PATCH 09/10] chore: update external package (#432) * fix security vulnerability ----------------- Refs: CPLP-3653 Reviewed-By: Evelyn Gurschler --- src/maintenance/Maintenance.App/Maintenance.App.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maintenance/Maintenance.App/Maintenance.App.csproj b/src/maintenance/Maintenance.App/Maintenance.App.csproj index 4159b5a60d..a537e09369 100644 --- a/src/maintenance/Maintenance.App/Maintenance.App.csproj +++ b/src/maintenance/Maintenance.App/Maintenance.App.csproj @@ -43,7 +43,7 @@ - + From 5ace3c6655dd30f13c2b4b08c72d883d5e2311cf Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Tue, 23 Jan 2024 15:45:23 +0100 Subject: [PATCH 10/10] chore: update changelog for v.1.8.0-RC3 (#433) * changelog v.1.8.0 RC3 * bump version for v1.8.0-RC3 --------- Co-authored-by: jjeroch <94133633+jjeroch@users.noreply.github.com> Reviewed-By: Evelyn Gurschler --- CHANGELOG.md | 24 ++++++++++++++++++++++++ src/Directory.Build.props | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0f07b15f8..543288e1aa 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. +## 1.8.0-RC3 + +### Change +- External Interface Details + - BPDM interface refactored - bpdm push process was updated to support the new interface spec of the bpdm gate service + - Clearinghouse interface updated - possible generated clearinghouse service error content is getting saved inside the application comment level +- Email Template "cx_admin_invitation" enhanced by adding the section and link of the decline url (portal-frontend implementation) + +### Feature +- Onboarding Service Provider Function + - enabled deactivation of managed idps (administration service) via the existing idp status update endpoint + - enabled deletion of managed idps (administration service) via the existing idp delete endpoint + - added new endpoint to enable customer to decline their own company application which was created by an osp + +### Technical Support +- Release workflow updated by adding additional image tag of type semver +- Upgraded external packages with security vulnerabilities + +### Bugfix +- Endpoint authorization on valid companyId added for + - POST: /api/apps/appreleaseprocess/consent/{appId}/agreementConsents + - POST: /api/services/servicerelease/consent/{serviceId}/agreementConsents +- Adjusted endpoint GET: api/administration/serviceaccount/owncompany/serviceaccounts to filter for active service accounts by default if no parameter is submitted + ## 1.8.0-RC2 ### Bugfix diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 0274e58d38..1a3e96b3ff 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -20,6 +20,6 @@ 1.8.0 - RC2 + RC3