From 10ad44fd5f99837d90dd2dd5385075180e80a77d Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Thu, 7 Sep 2023 22:56:13 +0200 Subject: [PATCH] feat(n2n): add database structure for n2n (#243) add new database structure for network to network add seeding for n2n adjust POST: api/administration/identityprovider/owncompany/identityproviders add onboardingServiceProviderId to companyApplication adjust existing idp endpoints for n2n (#410) add owner validation to PUT /api/administration/identityprovider/owncompany/identityproviders/{identityProviderId} enhance GET api/administration/identityprovider/owncompany/identityproviders with identityProviderTypeId add managed validation to DELETE /api/administration/identityprovider/owncompany/identityproviders/{identityProviderId} add unit tests for identityProvider --------- Refs: CPLP-3145, CPLP-3149, CPLP-3150, CPLP-3151, CPLP-3152, CPLP-3153, CPLP-3154, CPLP-3200 Co-authored-by: Norbert Truchsess Reviewed-By: Norbert Truchsess --- .../IIdentityProviderBusinessLogic.cs | 13 +- .../IdentityProviderBusinessLogic.cs | 261 +- .../BusinessLogic/InvitationBusinessLogic.cs | 6 +- .../Controllers/IdentityProviderController.cs | 21 +- .../Models/IdentityProviderDetails.cs | 2 +- .../Repositories/ApplicationRepository.cs | 5 +- .../Repositories/CompanyRepository.cs | 10 + .../Repositories/IApplicationRepository.cs | 2 +- .../Repositories/ICompanyRepository.cs | 2 + .../IIdentityProviderRepository.cs | 17 +- .../IdentityProviderRepository.cs | 85 +- .../Repositories/UserRepository.cs | 8 +- ...6061622_CPLP-3165-AddN2NModels.Designer.cs | 7549 +++++++++++++++++ .../20230906061622_CPLP-3165-AddN2NModels.cs | 338 + .../PortalDbContextModelSnapshot.cs | 239 +- .../PortalBackend.Migrations.csproj | 2 - .../agreement_assigned_company_roles.json | 4 + .../Seeder/Data/agreements.json | 11 + .../Data/company_applications.consortia.json | 10 + .../Data/company_role_descriptions.json | 10 + .../Data/company_role_registration_data.json | 4 + .../Seeder/Data/documents.json | 11 + .../Data/identity_providers.consortia.json | 36 +- .../Seeder/Data/identity_providers.json | 6 +- .../Data/user_role_assigned_collections.json | 12 + .../user_role_collection_descriptions.json | 10 + .../Seeder/Data/user_role_collections.json | 4 + .../AuditCompanyApplication20230824.cs | 63 + .../Entities/Company.cs | 6 +- .../Entities/CompanyApplication.cs | 11 +- .../Entities/CompanyApplicationType.cs | 62 + .../Entities/IdentityProvider.cs | 9 +- .../Entities/IdentityProviderType.cs | 62 + .../OnboardingServiceProviderDetail.cs | 42 + .../Enums/CompanyApplicationTypeId.cs | 27 + .../Enums/CompanyRoleId.cs | 1 + .../Enums/IdentityProviderCategoryId.cs | 1 - .../Enums/IdentityProviderTypeId.cs | 28 + .../PortalDbContext.cs | 62 +- .../Service/UserProvisioningService.cs | 2 +- .../RegistrationBusinessLogic.cs | 2 +- .../Registration.Service/Program.cs | 3 +- .../IdentityProviderBusinessLogicTests.cs | 1772 +++- .../InvitationBusinessLogicTests.cs | 19 +- .../RegistrationBusinessLogicTest.cs | 2 +- .../IdentityProviderControllerTests.cs | 69 + .../AgreementRepositoryTests.cs | 2 +- .../CompanyRepositoryTests.cs | 6 +- .../IdentityProviderRepositoryTests.cs | 199 + .../PortalBackend.DBAccess.Tests.csproj | 11 +- .../PortalDbContextTests.cs | 14 +- .../Data/company_applications.test.json | 3 + .../Data/company_identity_providers.test.json | 38 + .../Data/iam_identity_providers.test.json | 18 + .../Seeder/Data/identity_providers.test.json | 30 + ...rovisioningServiceAuxiliaryMethodsTests.cs | 14 +- .../RegistrationBusinessLogicTest.cs | 4 +- 57 files changed, 10922 insertions(+), 338 deletions(-) create mode 100644 src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.Designer.cs create mode 100644 src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.cs create mode 100644 src/portalbackend/PortalBackend.PortalEntities/AuditEntities/AuditCompanyApplication20230824.cs create mode 100644 src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplicationType.cs create mode 100644 src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProviderType.cs create mode 100644 src/portalbackend/PortalBackend.PortalEntities/Entities/OnboardingServiceProviderDetail.cs create mode 100644 src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationTypeId.cs create mode 100644 src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderTypeId.cs create mode 100644 tests/administration/Administration.Service.Tests/Controllers/IdentityProviderControllerTests.cs create mode 100644 tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs create mode 100644 tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_identity_providers.test.json create mode 100644 tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/iam_identity_providers.test.json create mode 100644 tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_providers.test.json diff --git a/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs index 1778037751..07fa0078d3 100644 --- a/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/IIdentityProviderBusinessLogic.cs @@ -19,6 +19,7 @@ ********************************************************************************/ using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Enums; using System.Text; @@ -26,12 +27,12 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog public interface IIdentityProviderBusinessLogic { - IAsyncEnumerable GetOwnCompanyIdentityProvidersAsync(Guid companyId); - ValueTask CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol protocol, string? displayName, Guid companyId); - ValueTask GetOwnCompanyIdentityProviderAsync(Guid identityProviderId, Guid companyId); - ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled, Guid companyId); - ValueTask UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details, Guid companyId); - ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId, Guid companyId); + IAsyncEnumerable GetOwnCompanyIdentityProvidersAsync(); + ValueTask CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol protocol, IdentityProviderTypeId typeId, string? displayName); + ValueTask GetOwnCompanyIdentityProviderAsync(Guid identityProviderId); + ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled); + ValueTask UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details); + ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId); IAsyncEnumerable GetOwnCompanyUsersIdentityProviderDataAsync(IEnumerable identityProviderIds, Guid companyId, bool unlinkedUsersOnly); (Stream FileStream, string ContentType, string FileName, Encoding Encoding) GetOwnCompanyUsersIdentityProviderLinkDataStream(IEnumerable identityProviderIds, Guid companyId, bool unlinkedUsersOnly); ValueTask UploadOwnCompanyUsersIdentityProviderLinkDataAsync(IFormFile document, Guid companyId, CancellationToken cancellationToken); diff --git a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs index 744cef0301..bbed09b939 100644 --- a/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/IdentityProviderBusinessLogic.cs @@ -27,6 +27,7 @@ using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities; using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library; using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Enums; using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models; @@ -40,26 +41,28 @@ public class IdentityProviderBusinessLogic : IIdentityProviderBusinessLogic { private readonly IPortalRepositories _portalRepositories; private readonly IProvisioningManager _provisioningManager; + private readonly IIdentityService _identityService; private readonly IdentityProviderSettings _settings; private static readonly Regex _displayNameValidationExpression = new Regex(@"^[a-zA-Z0-9\!\?\@\&\#\'\x22\(\)_\-\=\/\*\.\,\;\: ]+$", RegexOptions.None, TimeSpan.FromSeconds(1)); - public IdentityProviderBusinessLogic(IPortalRepositories portalRepositories, IProvisioningManager provisioningManager, IOptions options) + public IdentityProviderBusinessLogic(IPortalRepositories portalRepositories, IProvisioningManager provisioningManager, IIdentityService identityService, IOptions options) { _portalRepositories = portalRepositories; _provisioningManager = provisioningManager; + _identityService = identityService; _settings = options.Value; } - public async IAsyncEnumerable GetOwnCompanyIdentityProvidersAsync(Guid companyId) + public async IAsyncEnumerable GetOwnCompanyIdentityProvidersAsync() { + var companyId = _identityService.IdentityData.CompanyId; await foreach (var identityProviderData in _portalRepositories.GetInstance().GetCompanyIdentityProviderCategoryDataUntracked(companyId).ConfigureAwait(false)) { switch (identityProviderData.CategoryId) { - case IdentityProviderCategoryId.KEYCLOAK_SHARED: case IdentityProviderCategoryId.KEYCLOAK_OIDC: - yield return await GetIdentityProviderDetailsOidc(identityProviderData.IdentityProviderId, identityProviderData.Alias, identityProviderData.CategoryId).ConfigureAwait(false); + yield return await GetIdentityProviderDetailsOidc(identityProviderData.IdentityProviderId, identityProviderData.Alias, identityProviderData.CategoryId, identityProviderData.TypeId).ConfigureAwait(false); break; case IdentityProviderCategoryId.KEYCLOAK_SAML: var identityProviderDataSAML = await _provisioningManager.GetCentralIdentityProviderDataSAMLAsync(identityProviderData.Alias).ConfigureAwait(false); @@ -67,6 +70,7 @@ public async IAsyncEnumerable GetOwnCompanyIdentityProv identityProviderData.IdentityProviderId, identityProviderData.Alias, identityProviderData.CategoryId, + identityProviderData.TypeId, identityProviderDataSAML.DisplayName, identityProviderDataSAML.RedirectUrl, identityProviderDataSAML.Enabled, @@ -81,31 +85,25 @@ await _provisioningManager.GetIdentityProviderMappers(identityProviderData.Alias } } - public ValueTask CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol protocol, string? displayName, Guid companyId) + public ValueTask CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol protocol, IdentityProviderTypeId typeId, string? displayName) { - IdentityProviderCategoryId identityProviderCategory; - switch (protocol) + var identityProviderCategory = protocol switch { - case IamIdentityProviderProtocol.SAML: - identityProviderCategory = IdentityProviderCategoryId.KEYCLOAK_SAML; - break; - case IamIdentityProviderProtocol.OIDC: - identityProviderCategory = IdentityProviderCategoryId.KEYCLOAK_OIDC; - break; - default: - throw new ControllerArgumentException($"unexcepted value of protocol: '{protocol.ToString()}'", nameof(protocol)); - } + IamIdentityProviderProtocol.SAML => IdentityProviderCategoryId.KEYCLOAK_SAML, + IamIdentityProviderProtocol.OIDC => IdentityProviderCategoryId.KEYCLOAK_OIDC, + _ => throw new ControllerArgumentException($"unexcepted value of protocol: '{protocol}'", nameof(protocol)) + }; if (displayName != null) { ValidateDisplayName(displayName); } - return CreateOwnCompanyIdentityProviderInternalAsync(identityProviderCategory, protocol, displayName, companyId); + return CreateOwnCompanyIdentityProviderInternalAsync(identityProviderCategory, protocol, typeId, displayName); } private static void ValidateDisplayName(string displayName) { - if (displayName.Length < 2 || displayName.Length > 30) + if (displayName.Length is < 2 or > 30) { throw new ControllerArgumentException("displayName length must be 2-30 characters"); } @@ -115,139 +113,171 @@ private static void ValidateDisplayName(string displayName) } } - private async ValueTask CreateOwnCompanyIdentityProviderInternalAsync(IdentityProviderCategoryId identityProviderCategory, IamIdentityProviderProtocol protocol, string? displayName, Guid companyId) + private async ValueTask CreateOwnCompanyIdentityProviderInternalAsync(IdentityProviderCategoryId identityProviderCategory, IamIdentityProviderProtocol protocol, IdentityProviderTypeId typeId, string? displayName) { + var companyId = _identityService.IdentityData.CompanyId; var identityProviderRepository = _portalRepositories.GetInstance(); - - var result = await _portalRepositories.GetInstance().GetCompanyNameUntrackedAsync(companyId).ConfigureAwait(false); + var requiredCompanyRoles = typeId switch + { + IdentityProviderTypeId.OWN => Enumerable.Empty(), + IdentityProviderTypeId.MANAGED => new[] { CompanyRoleId.OPERATOR, CompanyRoleId.ONBOARDING_SERVICE_PROVIDER }, + _ => throw new ControllerArgumentException($"creation of identityProviderType {typeId} is not supported") + }; + var result = await _portalRepositories.GetInstance().CheckCompanyAndCompanyRolesAsync(companyId, requiredCompanyRoles).ConfigureAwait(false); if (!result.IsValidCompany) { throw new ControllerArgumentException($"company {companyId} does not exist", nameof(companyId)); } + if (!result.IsAllowed) + { + throw new ForbiddenException($"Not allowed to create an identityProvider of type {typeId}"); + } + var alias = await _provisioningManager.CreateOwnIdpAsync(displayName ?? result.CompanyName, result.CompanyName, protocol).ConfigureAwait(false); - var identityProvider = identityProviderRepository.CreateIdentityProvider(identityProviderCategory); - identityProvider.CompanyIdentityProviders.Add(identityProviderRepository.CreateCompanyIdentityProvider(companyId, identityProvider.Id)); - identityProviderRepository.CreateIamIdentityProvider(identityProvider, alias); + var identityProviderId = identityProviderRepository.CreateIdentityProvider(identityProviderCategory, typeId, idp => + { + if (typeId == IdentityProviderTypeId.MANAGED) + { + idp.OwnerId = companyId; + } + }).Id; + if (typeId == IdentityProviderTypeId.OWN) + { + identityProviderRepository.CreateCompanyIdentityProvider(companyId, identityProviderId); + } + identityProviderRepository.CreateIamIdentityProvider(identityProviderId, alias); await _portalRepositories.SaveAsync().ConfigureAwait(false); - switch (protocol) + return protocol switch { - case IamIdentityProviderProtocol.OIDC: - return await GetIdentityProviderDetailsOidc(identityProvider.Id, alias, IdentityProviderCategoryId.KEYCLOAK_OIDC).ConfigureAwait(false); - case IamIdentityProviderProtocol.SAML: - return await GetIdentityProviderDetailsSaml(identityProvider.Id, alias).ConfigureAwait(false); - default: - throw new UnexpectedConditionException($"unexpected value of protocol: '{protocol.ToString()}'"); - } + IamIdentityProviderProtocol.OIDC => await GetIdentityProviderDetailsOidc(identityProviderId, alias, IdentityProviderCategoryId.KEYCLOAK_OIDC, typeId).ConfigureAwait(false), + IamIdentityProviderProtocol.SAML => await GetIdentityProviderDetailsSaml(identityProviderId, alias, typeId).ConfigureAwait(false), + _ => throw new UnexpectedConditionException($"unexpected value of protocol: '{protocol.ToString()}'") + }; } - public async ValueTask GetOwnCompanyIdentityProviderAsync(Guid identityProviderId, Guid companyId) + public async ValueTask GetOwnCompanyIdentityProviderAsync(Guid identityProviderId) { - var (alias, category) = await ValidateGetOwnCompanyIdentityProviderArguments(identityProviderId, companyId).ConfigureAwait(false); + var companyId = _identityService.IdentityData.CompanyId; + var (alias, category, typeId) = await ValidateGetOwnCompanyIdentityProviderArguments(identityProviderId, companyId).ConfigureAwait(false); - switch (category) + return category switch { - case IdentityProviderCategoryId.KEYCLOAK_SHARED: - case IdentityProviderCategoryId.KEYCLOAK_OIDC: - return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category).ConfigureAwait(false); - case IdentityProviderCategoryId.KEYCLOAK_SAML: - return await GetIdentityProviderDetailsSaml(identityProviderId, alias).ConfigureAwait(false); - default: - throw new ControllerArgumentException($"unexpected value for category '{category.ToString()}' of identityProvider '{identityProviderId}'"); - } + IdentityProviderCategoryId.KEYCLOAK_OIDC => await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false), + IdentityProviderCategoryId.KEYCLOAK_SAML => await GetIdentityProviderDetailsSaml(identityProviderId, alias, typeId).ConfigureAwait(false), + _ => throw new ControllerArgumentException($"unexpected value for category '{category}' of identityProvider '{identityProviderId}'") + }; } - private async ValueTask<(string Alias, IdentityProviderCategoryId Category)> ValidateGetOwnCompanyIdentityProviderArguments(Guid identityProviderId, Guid companyId) + private async ValueTask<(string Alias, IdentityProviderCategoryId Category, IdentityProviderTypeId TypeId)> ValidateGetOwnCompanyIdentityProviderArguments(Guid identityProviderId, Guid companyId) { - var (alias, category, isOwnCompany) = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false); - if (!isOwnCompany) + var (alias, category, isOwnOrOwnerCompany, typeId) = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false); + if (!isOwnOrOwnerCompany) { throw new ConflictException($"identityProvider {identityProviderId} is not associated with company {companyId}"); } + if (alias == null) { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - return new ValueTuple(alias, category); + + if (category == IdentityProviderCategoryId.KEYCLOAK_SAML && typeId is IdentityProviderTypeId.SHARED) + { + throw new ConflictException("Shared Idps must not use SAML"); + } + + return new ValueTuple(alias, category, typeId); } - public async ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled, Guid companyId) + public async ValueTask SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled) { - var (category, alias) = await ValidateSetOwnCompanyIdentityProviderStatusArguments(identityProviderId, enabled, companyId).ConfigureAwait(false); + var companyId = _identityService.IdentityData.CompanyId; + var (category, alias, typeId) = await ValidateSetOwnCompanyIdentityProviderStatusArguments(identityProviderId, enabled, companyId).ConfigureAwait(false); switch (category) { + case IdentityProviderCategoryId.KEYCLOAK_OIDC when typeId is IdentityProviderTypeId.SHARED: + await _provisioningManager.SetSharedIdentityProviderStatusAsync(alias, enabled).ConfigureAwait(false); + return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false); case IdentityProviderCategoryId.KEYCLOAK_OIDC: await _provisioningManager.SetCentralIdentityProviderStatusAsync(alias, enabled).ConfigureAwait(false); - return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category).ConfigureAwait(false); + return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false); case IdentityProviderCategoryId.KEYCLOAK_SAML: await _provisioningManager.SetCentralIdentityProviderStatusAsync(alias, enabled).ConfigureAwait(false); - return await GetIdentityProviderDetailsSaml(identityProviderId, alias).ConfigureAwait(false); - case IdentityProviderCategoryId.KEYCLOAK_SHARED: - await _provisioningManager.SetSharedIdentityProviderStatusAsync(alias, enabled).ConfigureAwait(false); - return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category).ConfigureAwait(false); + return await GetIdentityProviderDetailsSaml(identityProviderId, alias, typeId).ConfigureAwait(false); default: - throw new ControllerArgumentException($"unexpected value for category '{category.ToString()}' of identityProvider '{identityProviderId}'"); + throw new ControllerArgumentException($"unexpected value for category '{category}' of identityProvider '{identityProviderId}'"); } } - private async ValueTask<(IdentityProviderCategoryId Category, string Alias)> ValidateSetOwnCompanyIdentityProviderStatusArguments(Guid identityProviderId, bool enabled, Guid companyId) + private async ValueTask<(IdentityProviderCategoryId Category, string Alias, IdentityProviderTypeId TypeId)> ValidateSetOwnCompanyIdentityProviderStatusArguments(Guid identityProviderId, bool enabled, Guid companyId) { - var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false); + var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false); if (result == default) { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - if (!result.IsSameCompany) + var (isOwnOrOwner, alias, identityProviderCategory, identityProviderTypeId, companyIdAliase) = result; + if (!isOwnOrOwner) { throw new ConflictException($"identityProvider {identityProviderId} is not associated with company {companyId}"); } - if (!enabled) + if (alias == null) + { + throw new ConflictException($"identityprovider {identityProviderId} does not have an iamIdentityProvider.alias"); + } + if (!enabled && + !await ValidateOtherActiveIdentityProvider( + alias, + companyIdAliase ?? throw new UnexpectedConditionException("CompanyIdAliase should never be null here")).ConfigureAwait(false)) { - await ValidateOtherActiveIdentityProvider( - result.Alias, - result.Aliase, - () => throw new ControllerArgumentException($"cannot disable indentityProvider {identityProviderId} as no other active identityProvider exists for this company") - ).ConfigureAwait(false); + throw new ControllerArgumentException($"cannot disable indentityProvider {identityProviderId} as no other active identityProvider exists for this company"); } - return new ValueTuple(result.IdentityProviderCategory, result.Alias); + return new ValueTuple(identityProviderCategory, alias, identityProviderTypeId); } - public async ValueTask UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details, Guid companyId) + public async ValueTask UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details) { - var (category, alias) = await ValidateUpdateOwnCompanyIdentityProviderArguments(identityProviderId, details, companyId).ConfigureAwait(false); + var (category, alias, typeId) = await ValidateUpdateOwnCompanyIdentityProviderArguments(identityProviderId, details).ConfigureAwait(false); switch (category) { + case IdentityProviderCategoryId.KEYCLOAK_OIDC when typeId is IdentityProviderTypeId.SHARED: + await UpdateIdentityProviderShared(alias, details).ConfigureAwait(false); + return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false); case IdentityProviderCategoryId.KEYCLOAK_OIDC: await UpdateIdentityProviderOidc(alias, details).ConfigureAwait(false); - return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category).ConfigureAwait(false); + return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category, typeId).ConfigureAwait(false); case IdentityProviderCategoryId.KEYCLOAK_SAML: await UpdateIdentityProviderSaml(alias, details).ConfigureAwait(false); - return await GetIdentityProviderDetailsSaml(identityProviderId, alias).ConfigureAwait(false); - case IdentityProviderCategoryId.KEYCLOAK_SHARED: - await UpdateIdentityProviderShared(alias, details).ConfigureAwait(false); - return await GetIdentityProviderDetailsOidc(identityProviderId, alias, category).ConfigureAwait(false); + return await GetIdentityProviderDetailsSaml(identityProviderId, alias, typeId).ConfigureAwait(false); default: throw new ControllerArgumentException($"unexpected value for category '{category.ToString()}' of identityProvider '{identityProviderId}'"); } } - private async ValueTask<(IdentityProviderCategoryId Category, string Alias)> ValidateUpdateOwnCompanyIdentityProviderArguments(Guid identityProviderId, IdentityProviderEditableDetails details, Guid companyId) + private async ValueTask<(IdentityProviderCategoryId Category, string Alias, IdentityProviderTypeId TypeId)> ValidateUpdateOwnCompanyIdentityProviderArguments(Guid identityProviderId, IdentityProviderEditableDetails details) { + var companyId = _identityService.IdentityData.CompanyId; ValidateDisplayName(details.displayName); - var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false); + var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, false).ConfigureAwait(false); if (result == default) { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - if (!result.IsSameCompany) + var (isOwnOrOwner, alias, identityProviderCategory, identityProviderTypeId, _) = result; + if (!isOwnOrOwner) { - throw new ForbiddenException($"identityProvider {identityProviderId} is not associated with company {companyId}"); + throw new ForbiddenException($"User not allowed to run the change for identity provider {identityProviderId}"); } - return new ValueTuple(result.IdentityProviderCategory, result.Alias); + if (alias == null) + { + throw new ConflictException($"identityprovider {identityProviderId} does not have an iamIdentityProvider.alias"); + } + return new ValueTuple(identityProviderCategory, alias, identityProviderTypeId); } private async ValueTask UpdateIdentityProviderOidc(string alias, IdentityProviderEditableDetails details) @@ -304,72 +334,78 @@ private async ValueTask UpdateIdentityProviderShared(string alias, IdentityProvi await _provisioningManager.UpdateSharedIdentityProviderAsync(alias, details.displayName).ConfigureAwait(false); } - private async ValueTask ValidateOtherActiveIdentityProvider(string alias, IEnumerable aliase, Action noSuccessAction) + private async ValueTask ValidateOtherActiveIdentityProvider(string? alias, IEnumerable<(Guid CompanyId, IEnumerable Aliase)> companyIdAliase) { - if (!await aliase - .Where(_alias => _alias != alias) - .ToAsyncEnumerable() - .AnyAwaitAsync(alias => _provisioningManager.IsCentralIdentityProviderEnabled(alias))) - { - noSuccessAction(); - } + var aliasStatus = (await Task.WhenAll(companyIdAliase.SelectMany(x => x.Aliase).Where(x => x != alias).Distinct().Select(async alias => (Alias: alias, Enabled: await _provisioningManager.IsCentralIdentityProviderEnabled(alias).ConfigureAwait(false)))).ConfigureAwait(false)).ToDictionary(x => x.Alias, x => x.Enabled); + return companyIdAliase.All(x => + x.Aliase.Where(a => a != alias).Any(a => aliasStatus[a])); } - public async ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId, Guid companyId) + public async ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId) { - var (companyCount, alias, category) = await ValidateDeleteOwnCompanyIdentityProviderArguments(identityProviderId, companyId).ConfigureAwait(false); + var companyId = _identityService.IdentityData.CompanyId; + var (alias, typeId) = await ValidateDeleteOwnCompanyIdentityProviderArguments(identityProviderId, companyId).ConfigureAwait(false); _portalRepositories.Remove(new CompanyIdentityProvider(companyId, identityProviderId)); - if (companyCount == 1) + + if (alias != null) { - if (alias != null) + _portalRepositories.Remove(new IamIdentityProvider(alias, Guid.Empty)); + if (typeId == IdentityProviderTypeId.SHARED) { - _portalRepositories.Remove(new IamIdentityProvider(alias, Guid.Empty)); - if (category == IdentityProviderCategoryId.KEYCLOAK_SHARED) - { - await _provisioningManager.DeleteSharedIdpRealmAsync(alias).ConfigureAwait(false); - } - await _provisioningManager.DeleteCentralIdentityProviderAsync(alias).ConfigureAwait(false); + await _provisioningManager.DeleteSharedIdpRealmAsync(alias).ConfigureAwait(false); } - _portalRepositories.Remove(_portalRepositories.Attach(new IdentityProvider(identityProviderId, default, default))); + await _provisioningManager.DeleteCentralIdentityProviderAsync(alias).ConfigureAwait(false); } + _portalRepositories.Remove(_portalRepositories.Attach(new IdentityProvider(identityProviderId, default, default, default))); + await _portalRepositories.SaveAsync().ConfigureAwait(false); } - private async ValueTask<(int CompanyCount, string Alias, IdentityProviderCategoryId Category)> ValidateDeleteOwnCompanyIdentityProviderArguments(Guid identityProviderId, Guid companyId) + private async ValueTask<(string? Alias, IdentityProviderTypeId TypeId)> ValidateDeleteOwnCompanyIdentityProviderArguments(Guid identityProviderId, Guid companyId) { - var result = await _portalRepositories.GetInstance().GetCompanyIdentityProviderDeletionDataUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false); + var result = await _portalRepositories.GetInstance().GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, true).ConfigureAwait(false); if (result == default) { throw new NotFoundException($"identityProvider {identityProviderId} does not exist"); } - var (isValidCompanyId, companyCount, alias, category, aliase) = result; - if (!isValidCompanyId) + var (isOwnOrOwner, alias, _, typeId, aliase) = result; + if (!isOwnOrOwner) { throw new ConflictException($"identityProvider {identityProviderId} is not associated with company {companyId}"); } - if (await _provisioningManager.IsCentralIdentityProviderEnabled(alias).ConfigureAwait(false)) + if (typeId == IdentityProviderTypeId.MANAGED) { - throw new ControllerArgumentException($"cannot delete identityProvider {identityProviderId} as it is enabled"); + throw new ConflictException($"IdentityProviders of type {typeId} can not be deleted"); } - await ValidateOtherActiveIdentityProvider( - alias, - aliase, - () => throw new ControllerArgumentException($"cannot delete indentityProvider {identityProviderId} as no other active identityProvider exists for this company") - ).ConfigureAwait(false); + if (alias != null) + { + if (await _provisioningManager.IsCentralIdentityProviderEnabled(alias).ConfigureAwait(false)) + { + throw new ControllerArgumentException($"cannot delete identityProvider {identityProviderId} as it is enabled"); + } + + 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"); + } + } - return new ValueTuple(companyCount, alias, category); + return (alias, typeId); } - private async ValueTask GetIdentityProviderDetailsOidc(Guid identityProviderId, string alias, IdentityProviderCategoryId categoryId) + private async ValueTask GetIdentityProviderDetailsOidc(Guid identityProviderId, string alias, IdentityProviderCategoryId categoryId, IdentityProviderTypeId typeId) { var identityProviderDataOIDC = await _provisioningManager.GetCentralIdentityProviderDataOIDCAsync(alias).ConfigureAwait(false); return new IdentityProviderDetails( identityProviderId, alias, categoryId, + typeId, identityProviderDataOIDC.DisplayName, identityProviderDataOIDC.RedirectUrl, identityProviderDataOIDC.Enabled, @@ -385,13 +421,14 @@ await _provisioningManager.GetIdentityProviderMappers(alias).ToListAsync().Confi }; } - private async ValueTask GetIdentityProviderDetailsSaml(Guid identityProviderId, string alias) + private async ValueTask GetIdentityProviderDetailsSaml(Guid identityProviderId, string alias, IdentityProviderTypeId typeId) { var identityProviderDataSAML = await _provisioningManager.GetCentralIdentityProviderDataSAMLAsync(alias).ConfigureAwait(false); return new IdentityProviderDetails( identityProviderId, alias, IdentityProviderCategoryId.KEYCLOAK_SAML, + typeId, identityProviderDataSAML.DisplayName, identityProviderDataSAML.RedirectUrl, identityProviderDataSAML.Enabled, @@ -596,8 +633,8 @@ private async ValueTask UploadOwnCompanyUsersIdenti private async ValueTask<(string? SharedIdpAlias, IEnumerable ValidAliase)> GetCompanyAliasDataAsync(Guid companyId) { - var identityProviderCategoryData = (await _portalRepositories.GetInstance().GetCompanyIdentityProviderCategoryDataUntracked(companyId).ToListAsync().ConfigureAwait(false)); - var sharedIdpAlias = identityProviderCategoryData.Where(data => data.CategoryId == IdentityProviderCategoryId.KEYCLOAK_SHARED).Select(data => data.Alias).SingleOrDefault(); + var identityProviderCategoryData = await _portalRepositories.GetInstance().GetCompanyIdentityProviderCategoryDataUntracked(companyId).ToListAsync().ConfigureAwait(false); + var sharedIdpAlias = identityProviderCategoryData.Where(data => data.TypeId == IdentityProviderTypeId.SHARED).Select(data => data.Alias).SingleOrDefault(); var validAliase = identityProviderCategoryData.Select(data => data.Alias).ToList(); return (sharedIdpAlias, validAliase); } diff --git a/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs index af699f7a74..8cbb198368 100644 --- a/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/InvitationBusinessLogic.cs @@ -83,12 +83,12 @@ private async Task ExecuteInvitationInternalAsync(CompanyInvitationData invitati var company = _portalRepositories.GetInstance().CreateCompany(invitationData.organisationName); var identityProviderRepository = _portalRepositories.GetInstance(); - var identityProvider = identityProviderRepository.CreateIdentityProvider(IdentityProviderCategoryId.KEYCLOAK_SHARED); + var identityProvider = identityProviderRepository.CreateIdentityProvider(IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, null); identityProvider.Companies.Add(company); - identityProviderRepository.CreateIamIdentityProvider(identityProvider, idpName); + identityProviderRepository.CreateIamIdentityProvider(identityProvider.Id, idpName); var applicationRepository = _portalRepositories.GetInstance(); - var application = applicationRepository.CreateCompanyApplication(company.Id, CompanyApplicationStatusId.CREATED); + var application = applicationRepository.CreateCompanyApplication(company.Id, CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.INTERNAL); await _portalRepositories.SaveAsync().ConfigureAwait(false); diff --git a/src/administration/Administration.Service/Controllers/IdentityProviderController.cs b/src/administration/Administration.Service/Controllers/IdentityProviderController.cs index a7c6a3e72f..87c86ad45d 100644 --- a/src/administration/Administration.Service/Controllers/IdentityProviderController.cs +++ b/src/administration/Administration.Service/Controllers/IdentityProviderController.cs @@ -25,6 +25,7 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling.Library; using Org.Eclipse.TractusX.Portal.Backend.Framework.Models; using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Authentication; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Enums; namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Controllers; @@ -63,7 +64,7 @@ public IdentityProviderController(IIdentityProviderBusinessLogic identityProvide [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)] public ValueTask> GetOwnCompanyIdentityProviderDetails() => - this.WithCompanyId(companyId => _businessLogic.GetOwnCompanyIdentityProvidersAsync(companyId).ToListAsync()); + _businessLogic.GetOwnCompanyIdentityProvidersAsync().ToListAsync(); /// /// Create an identity provider @@ -84,9 +85,9 @@ public ValueTask> GetOwnCompanyIdentityProviderDet [ProducesResponseType(typeof(IdentityProviderDetails), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)] - public async ValueTask> CreateOwnCompanyIdentityProvider([FromQuery] IamIdentityProviderProtocol protocol, [FromQuery] string? displayName = null) + public async ValueTask> CreateOwnCompanyIdentityProvider([FromQuery] IamIdentityProviderProtocol protocol, [FromQuery] IdentityProviderTypeId typeId, [FromQuery] string? displayName = null) { - var details = await this.WithCompanyId(companyId => _businessLogic.CreateOwnCompanyIdentityProviderAsync(protocol, displayName, companyId)).ConfigureAwait(false); + var details = await _businessLogic.CreateOwnCompanyIdentityProviderAsync(protocol, typeId, displayName).ConfigureAwait(false); return (ActionResult)CreatedAtRoute(nameof(GetOwnCompanyIdentityProvider), new { identityProviderId = details.identityProviderId }, details); } @@ -111,7 +112,7 @@ public async ValueTask> CreateOwnCompanyId [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)] public ValueTask GetOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId) => - this.WithCompanyId(companyId => _businessLogic.GetOwnCompanyIdentityProviderAsync(identityProviderId, companyId)); + _businessLogic.GetOwnCompanyIdentityProviderAsync(identityProviderId); /// /// Sets the status of the given Identity Provider @@ -139,7 +140,7 @@ public ValueTask GetOwnCompanyIdentityProvider([FromRou [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)] public ValueTask SetOwnCompanyIdentityProviderStatus([FromRoute] Guid identityProviderId, [FromQuery] bool enabled) => - this.WithCompanyId(companyId => _businessLogic.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, enabled, companyId)); + _businessLogic.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, enabled); /// /// Updates the details of the identity provider @@ -167,7 +168,7 @@ public ValueTask SetOwnCompanyIdentityProviderStatus([F [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)] public ValueTask UpdateOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId, [FromBody] IdentityProviderEditableDetails details) => - this.WithCompanyId(companyId => _businessLogic.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, details, companyId)); + _businessLogic.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, details); /// /// Deletes the identity provider with the given id @@ -187,16 +188,16 @@ public ValueTask UpdateOwnCompanyIdentityProvider([From [Authorize(Roles = "delete_idp")] [Authorize(Policy = PolicyTypes.ValidCompany)] [Route("owncompany/identityproviders/{identityProviderId}")] - [ProducesResponseType(typeof(NoContentResult), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status403Forbidden)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)] - public async Task DeleteOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId) + public async Task DeleteOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId) { - await this.WithCompanyId(companyId => _businessLogic.DeleteCompanyIdentityProviderAsync(identityProviderId, companyId)).ConfigureAwait(false); - return (ActionResult)NoContent(); + await _businessLogic.DeleteCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); + return NoContent(); } /// diff --git a/src/administration/Administration.Service/Models/IdentityProviderDetails.cs b/src/administration/Administration.Service/Models/IdentityProviderDetails.cs index 01a3d6b117..b6c30a2307 100644 --- a/src/administration/Administration.Service/Models/IdentityProviderDetails.cs +++ b/src/administration/Administration.Service/Models/IdentityProviderDetails.cs @@ -25,7 +25,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models; -public record IdentityProviderDetails(Guid identityProviderId, string alias, IdentityProviderCategoryId identityProviderCategoryId, string displayName, string redirectUrl, bool enabled, IEnumerable mappers) +public record IdentityProviderDetails(Guid identityProviderId, string alias, IdentityProviderCategoryId identityProviderCategoryId, IdentityProviderTypeId IdentityProviderTypeId, string displayName, string redirectUrl, bool enabled, IEnumerable mappers) { [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public IdentityProviderDetailsOidc? oidc { get; init; } = null; diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs index 8189d89dc3..75e9d2b8cc 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ApplicationRepository.cs @@ -36,17 +36,18 @@ public ApplicationRepository(PortalDbContext portalDbContext) _dbContext = portalDbContext; } - public CompanyApplication CreateCompanyApplication(Guid companyId, CompanyApplicationStatusId companyApplicationStatusId) => + public CompanyApplication CreateCompanyApplication(Guid companyId, CompanyApplicationStatusId companyApplicationStatusId, CompanyApplicationTypeId applicationTypeId) => _dbContext.CompanyApplications.Add( new CompanyApplication( Guid.NewGuid(), companyId, companyApplicationStatusId, + applicationTypeId, DateTimeOffset.UtcNow)).Entity; public void AttachAndModifyCompanyApplication(Guid companyApplicationId, Action setOptionalParameters) { - var companyApplication = _dbContext.Attach(new CompanyApplication(companyApplicationId, Guid.Empty, default, default)).Entity; + var companyApplication = _dbContext.Attach(new CompanyApplication(companyApplicationId, Guid.Empty, default, default, default)).Entity; setOptionalParameters.Invoke(companyApplication); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs index 57d834cf9d..132263396a 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs @@ -308,4 +308,14 @@ public IAsyncEnumerable GetOperatorBpns() => x.Name, x.BusinessPartnerNumber!)) .AsAsyncEnumerable(); + + public Task<(bool IsValidCompany, string CompanyName, bool IsAllowed)> CheckCompanyAndCompanyRolesAsync(Guid companyId, IEnumerable companyRoles) => + _context.Companies + .Where(x => x.Id == companyId) + .Select(x => new ValueTuple( + true, + x.Name, + !companyRoles.Any() || x.CompanyAssignedRoles.Any(role => companyRoles.Contains(role.CompanyRoleId)) + )) + .SingleOrDefaultAsync(); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs index 073293ac6e..08fedb456f 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IApplicationRepository.cs @@ -26,7 +26,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositorie public interface IApplicationRepository { - CompanyApplication CreateCompanyApplication(Guid companyId, CompanyApplicationStatusId companyApplicationStatusId); + CompanyApplication CreateCompanyApplication(Guid companyId, CompanyApplicationStatusId companyApplicationStatusId, CompanyApplicationTypeId applicationTypeId); void AttachAndModifyCompanyApplication(Guid companyApplicationId, Action setOptionalParameters); Invitation CreateInvitation(Guid applicationId, Guid companyUserId); void DeleteInvitations(IEnumerable invitationIds); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs index 0ed13f60d3..eedadc606e 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs @@ -164,4 +164,6 @@ public interface ICompanyRepository /// /// Async enumerable of bpns IAsyncEnumerable GetOperatorBpns(); + + Task<(bool IsValidCompany, string CompanyName, bool IsAllowed)> CheckCompanyAndCompanyRolesAsync(Guid companyId, IEnumerable companyRoles); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs index 64e6828c95..4337e29528 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IIdentityProviderRepository.cs @@ -28,22 +28,19 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositorie /// public interface IIdentityProviderRepository { - IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory); - IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityProvider, string idpAlias); + IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory, IdentityProviderTypeId identityProviderTypeId, Action? setOptionalFields); + IamIdentityProvider CreateIamIdentityProvider(Guid identityProviderId, string idpAlias); CompanyIdentityProvider CreateCompanyIdentityProvider(Guid companyId, Guid identityProviderId); Task GetSharedIdentityProviderIamAliasDataUntrackedAsync(Guid companyId); Task GetIdpCategoryIdByUserIdAsync(Guid companyUserId, Guid userCompanyId); - Task<(string Alias, IdentityProviderCategoryId IamIdentityProviderCategory, bool IsOwnCompany)> GetOwnCompanyIdentityProviderAliasUntrackedAsync(Guid identityProviderId, Guid companyId); - Task<(bool IsSameCompany, string Alias, IdentityProviderCategoryId IdentityProviderCategory, IEnumerable Aliase)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId); - Task<(bool IsValidCompanyId, int LinkedCompaniesCount, string Alias, IdentityProviderCategoryId IdentityProviderCategory, IEnumerable Aliase)> GetCompanyIdentityProviderDeletionDataUntrackedAsync(Guid identityProviderId, Guid companyId); - IAsyncEnumerable<(Guid IdentityProviderId, IdentityProviderCategoryId CategoryId, string Alias)> GetCompanyIdentityProviderCategoryDataUntracked(Guid companyId); + Task<(string? Alias, IdentityProviderCategoryId IamIdentityProviderCategory, bool IsOwnOrOwnerCompany, IdentityProviderTypeId TypeId)> GetOwnCompanyIdentityProviderAliasUntrackedAsync(Guid identityProviderId, Guid companyId); + Task<(bool IsOwnOrOwner, string? Alias, IdentityProviderCategoryId IdentityProviderCategory, IdentityProviderTypeId IdentityProviderTypeId, IEnumerable<(Guid CompanyId, IEnumerable Aliase)>? CompanyIdAliase)> 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<(string? UserEntityId, string? Alias, bool IsSameCompany)> GetIamUserIsOwnCompanyIdentityProviderAliasAsync(Guid companyUserId, Guid identityProviderId, Guid companyId); - Task<((Guid CompanyId, string? CompanyName, string? BusinessPartnerNumber) Company, - (Guid CompanyUserId, string? FirstName, string? LastName, string? Email) CompanyUser, - IEnumerable IdpAliase)> - GetCompanyNameIdpAliaseUntrackedAsync(Guid companyUserId, Guid? applicationId, IdentityProviderCategoryId identityProviderCategoryId); + Task<((Guid CompanyId, string? CompanyName, string? BusinessPartnerNumber) Company, (Guid CompanyUserId, string? FirstName, string? LastName, string? Email) CompanyUser, IEnumerable IdpAliase)> + GetCompanyNameIdpAliaseUntrackedAsync(Guid companyUserId, Guid? applicationId, IdentityProviderCategoryId identityProviderCategoryId, IdentityProviderTypeId identityProviderTypeId); Task<((Guid CompanyId, string? CompanyName, string? BusinessPartnerNumber) Company, (Guid CompanyUserId, string? FirstName, string? LastName, string? Email) CompanyUser, diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs index 1946bd2b9e..50f09db884 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IdentityProviderRepository.cs @@ -41,12 +41,17 @@ public IdentityProviderRepository(PortalDbContext portalDbContext) } /// - public IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory) => - _context.IdentityProviders - .Add(new IdentityProvider( + public IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory, IdentityProviderTypeId identityProviderTypeId, Action? setOptionalFields) + { + var idp = new IdentityProvider( Guid.NewGuid(), identityProviderCategory, - DateTimeOffset.UtcNow)).Entity; + identityProviderTypeId, + DateTimeOffset.UtcNow); + setOptionalFields?.Invoke(idp); + return _context.IdentityProviders + .Add(idp).Entity; + } public CompanyIdentityProvider CreateCompanyIdentityProvider(Guid companyId, Guid identityProviderId) => _context.CompanyIdentityProviders @@ -56,17 +61,17 @@ public CompanyIdentityProvider CreateCompanyIdentityProvider(Guid companyId, Gui )).Entity; /// - public IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityProvider, string idpAlias) => + public IamIdentityProvider CreateIamIdentityProvider(Guid identityProviderId, string idpAlias) => _context.IamIdentityProviders.Add( new IamIdentityProvider( idpAlias, - identityProvider.Id)).Entity; + identityProviderId)).Entity; public Task GetSharedIdentityProviderIamAliasDataUntrackedAsync(Guid companyId) => _context.IdentityProviders .AsNoTracking() .Where(identityProvider => - identityProvider.IdentityProviderCategoryId == IdentityProviderCategoryId.KEYCLOAK_SHARED && + identityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED && identityProvider.Companies.Any(company => company.Id == companyId)) .Select(identityProvider => identityProvider.IamIdentityProvider!.IamIdpAlias) .SingleOrDefaultAsync(); @@ -79,64 +84,46 @@ public IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityPr { TargetIamUserId = companyUser.Identity!.UserEntityId, IdpName = companyUser.Identity!.Company!.IdentityProviders - .Where(identityProvider => identityProvider.IdentityProviderCategoryId == IdentityProviderCategoryId.KEYCLOAK_SHARED) + .Where(identityProvider => identityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED) .Select(identityProvider => identityProvider.IamIdentityProvider!.IamIdpAlias) .SingleOrDefault() }).SingleOrDefaultAsync(); - public Task<(string Alias, IdentityProviderCategoryId IamIdentityProviderCategory, bool IsOwnCompany)> GetOwnCompanyIdentityProviderAliasUntrackedAsync(Guid identityProviderId, Guid companyId) => + public Task<(string? Alias, IdentityProviderCategoryId IamIdentityProviderCategory, bool IsOwnOrOwnerCompany, IdentityProviderTypeId TypeId)> GetOwnCompanyIdentityProviderAliasUntrackedAsync(Guid identityProviderId, Guid companyId) => _context.IdentityProviders .Where(identityProvider => identityProvider.Id == identityProviderId) .Select(identityProvider => - new ValueTuple( + new ValueTuple( identityProvider.IamIdentityProvider!.IamIdpAlias, identityProvider.IdentityProviderCategoryId, - identityProvider.Companies.Any(company => company.Id == companyId))) - .SingleOrDefaultAsync(); - - public Task<(bool IsSameCompany, string Alias, IdentityProviderCategoryId IdentityProviderCategory, IEnumerable Aliase)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId) => - _context.IdentityProviders - .Where(identityProvider => identityProvider.Id == identityProviderId) - .Select(identityProvider => new - { - IdentityProvider = identityProvider, - Company = identityProvider.Companies.SingleOrDefault(company => company.Id == companyId) - }) - .Select(item => - new ValueTuple>( - item.Company != null, - item.IdentityProvider.IamIdentityProvider!.IamIdpAlias, - item.IdentityProvider.IdentityProviderCategoryId, - item.Company!.IdentityProviders.Select(identityProvider => identityProvider.IamIdentityProvider!.IamIdpAlias) - )) + identityProvider.OwnerId == companyId || identityProvider.Companies.Any(company => company.Id == companyId), + identityProvider.IdentityProviderTypeId)) .SingleOrDefaultAsync(); - public Task<(bool IsValidCompanyId, int LinkedCompaniesCount, string Alias, IdentityProviderCategoryId IdentityProviderCategory, IEnumerable Aliase)> GetCompanyIdentityProviderDeletionDataUntrackedAsync(Guid identityProviderId, Guid companyId) => + public Task<(bool IsOwnOrOwner, string? Alias, IdentityProviderCategoryId IdentityProviderCategory, IdentityProviderTypeId IdentityProviderTypeId, IEnumerable<(Guid CompanyId, IEnumerable Aliase)>? CompanyIdAliase)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId, bool queryAliase) => _context.IdentityProviders .Where(identityProvider => identityProvider.Id == identityProviderId) - .Select(identityProvider => new - { - IdentityProvider = identityProvider, - Company = identityProvider.Companies.SingleOrDefault(company => company.Id == companyId) - }) - .Select(item => - new ValueTuple>( - item.Company != null, - item.IdentityProvider.Companies.Count, - item.IdentityProvider.IamIdentityProvider!.IamIdpAlias, - item.IdentityProvider.IdentityProviderCategoryId, - item.Company!.IdentityProviders.Select(identityProvider => identityProvider.IamIdentityProvider!.IamIdpAlias) + .Select(identityProvider => + new ValueTuple)>?>( + identityProvider.Owner == null && identityProvider.Companies.Any(c => c.Id == companyId) && identityProvider.Companies.Count == 1 || 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 )) .SingleOrDefaultAsync(); - public IAsyncEnumerable<(Guid IdentityProviderId, IdentityProviderCategoryId CategoryId, string Alias)> GetCompanyIdentityProviderCategoryDataUntracked(Guid companyId) => + public IAsyncEnumerable<(Guid IdentityProviderId, IdentityProviderCategoryId CategoryId, string Alias, IdentityProviderTypeId TypeId)> GetCompanyIdentityProviderCategoryDataUntracked(Guid companyId) => _context.IdentityProviders .AsNoTracking() - .Where(identityProvider => identityProvider.Companies.Any(company => company.Id == companyId)) - .Select(identityProvider => new ValueTuple( + .Where(identityProvider => identityProvider.OwnerId == companyId || identityProvider.Companies.Any(company => company.Id == companyId) && identityProvider.OwnerId == null) + .Select(identityProvider => new ValueTuple( identityProvider.Id, identityProvider.IdentityProviderCategoryId, - identityProvider.IamIdentityProvider!.IamIdpAlias + identityProvider.IamIdentityProvider!.IamIdpAlias, + identityProvider.IdentityProviderTypeId )) .ToAsyncEnumerable(); @@ -168,7 +155,7 @@ public IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityPr public Task<((Guid CompanyId, string? CompanyName, string? BusinessPartnerNumber) Company, (Guid CompanyUserId, string? FirstName, string? LastName, string? Email) CompanyUser, IEnumerable IdpAliase)> - GetCompanyNameIdpAliaseUntrackedAsync(Guid companyUserId, Guid? applicationId, IdentityProviderCategoryId identityProviderCategoryId) => + GetCompanyNameIdpAliaseUntrackedAsync(Guid companyUserId, Guid? applicationId, IdentityProviderCategoryId identityProviderCategoryId, IdentityProviderTypeId identityProviderTypeId) => _context.CompanyUsers .AsNoTracking() .Where(companyUser => companyUser.Id == companyUserId && @@ -184,7 +171,9 @@ public IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityPr companyUser.Lastname, companyUser.Email), companyUser.Identity!.Company!.IdentityProviders - .Where(identityProvider => identityProvider.IdentityProviderCategoryId == identityProviderCategoryId) + .Where(identityProvider => + identityProvider.IdentityProviderCategoryId == identityProviderCategoryId && + identityProvider.IdentityProviderTypeId == identityProviderTypeId) .Select(identityProvider => identityProvider.IamIdentityProvider!.IamIdpAlias))) .SingleOrDefaultAsync(); @@ -213,6 +202,6 @@ public IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityPr s.CompanyUser.Email), new ValueTuple( s.IdentityProvider!.IamIdentityProvider!.IamIdpAlias, - s.IdentityProvider.IdentityProviderCategoryId == IdentityProviderCategoryId.KEYCLOAK_SHARED))) + s.IdentityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED))) .SingleOrDefaultAsync(); } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs index 83a3133138..1b1f174315 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/UserRepository.cs @@ -210,9 +210,7 @@ public Task IsOwnCompanyUserWithEmailExisting(string email, Guid companyId .AsSplitQuery() .Where(companyUser => companyUser.Id == companyUserId && companyUser.Identity!.Company!.IdentityProviders - .Any(identityProvider => - identityProvider.IdentityProviderCategoryId == - IdentityProviderCategoryId.KEYCLOAK_SHARED)) + .Any(identityProvider => identityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED)) .Select(companyUser => new CompanyUserWithIdpBusinessPartnerData( new CompanyUserInformation( companyUser.Id, @@ -224,7 +222,7 @@ public Task IsOwnCompanyUserWithEmailExisting(string email, Guid companyId companyUser.Identity.UserStatusId, companyUser.Identity.UserEntityId), companyUser.Identity!.Company!.IdentityProviders.Where(identityProvider => - identityProvider.IdentityProviderCategoryId == IdentityProviderCategoryId.KEYCLOAK_SHARED) + identityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED) .Select(identityProvider => identityProvider.IamIdentityProvider!.IamIdpAlias) .SingleOrDefault()!, companyUser.CompanyUserAssignedBusinessPartners.Select(assignedPartner => @@ -370,7 +368,7 @@ public IAsyncEnumerable GetServiceProviderCompanyUserWithRoleIdAsync(Guid _dbContext.CompanyUsers.AsNoTracking().AsSplitQuery() .Where(companyUser => companyUser.Id == companyUserId) .Select(companyUser => new ValueTuple( - companyUser.Identity!.Company!.IdentityProviders.SingleOrDefault(identityProvider => identityProvider.IdentityProviderCategoryId == IdentityProviderCategoryId.KEYCLOAK_SHARED)!.IamIdentityProvider!.IamIdpAlias, + companyUser.Identity!.Company!.IdentityProviders.SingleOrDefault(identityProvider => identityProvider.IdentityProviderTypeId == IdentityProviderTypeId.SHARED)!.IamIdentityProvider!.IamIdpAlias, new CompanyUserAccountData( companyUser.Id, companyUser.Identity!.UserEntityId, diff --git a/src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.Designer.cs b/src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.Designer.cs new file mode 100644 index 0000000000..b2bcd74649 --- /dev/null +++ b/src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.Designer.cs @@ -0,0 +1,7549 @@ +/******************************************************************************** + * 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 + * 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("20230906061622_CPLP-3165-AddN2NModels")] + partial class CPLP3165AddN2NModels + { + /// + 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.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.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.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.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.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.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.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.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.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("AgreementType") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agreement_type"); + + 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("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("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.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_detail20221118\" (\"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_detail20221118\" (\"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.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.Entities.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.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_application20230824\" (\"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_application20230824\" (\"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" + }); + }); + + 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("ClientId") + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("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_detail20230621\" (\"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_detail20230621\" (\"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.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_connector20230803\" (\"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_connector20230803\" (\"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_consent20230412\" (\"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_consent20230412\" (\"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.Property("CountryNameDe") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("country_name_de"); + + b.Property("CountryNameEn") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("country_name_en"); + + 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.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("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("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"); + }); + + 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_identity20230526\" (\"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_identity20230526\" (\"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" + }); + }); + + 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.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_offer20230406\" (\"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_offer20230406\" (\"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("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_subscription20230317\" (\"id\", \"company_id\", \"offer_id\", \"offer_subscription_status_id\", \"display_name\", \"description\", \"requester_id\", \"last_editor_id\", \"process_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.\"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 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_subscription20230317\" (\"id\", \"company_id\", \"offer_id\", \"offer_subscription_status_id\", \"display_name\", \"description\", \"requester_id\", \"last_editor_id\", \"process_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.\"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 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("CallbackUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("callback_url"); + + 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" + }); + }); + + 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" + }); + }); + + 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_detail20230614\" (\"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_detail20230614\" (\"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_role20221017\" (\"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_role20221017\" (\"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" + }); + }); + + 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") + .IsRequired() + .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" + }); + }); + + 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.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.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.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.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.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") + .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.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.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("OfferSubscriptions"); + + 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"); + }); + + 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("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"); + }); + + 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("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("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("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/20230906061622_CPLP-3165-AddN2NModels.cs b/src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.cs new file mode 100644 index 0000000000..0cc687654a --- /dev/null +++ b/src/portalbackend/PortalBackend.Migrations/Migrations/20230906061622_CPLP-3165-AddN2NModels.cs @@ -0,0 +1,338 @@ +/******************************************************************************** + * 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 + * 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 CPLP3165AddN2NModels : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("DROP FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION\"() CASCADE;"); + migrationBuilder.Sql("DROP FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION\"() CASCADE;"); + + migrationBuilder.AddColumn( + name: "identity_provider_type_id", + schema: "portal", + table: "identity_providers", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "owner_id", + schema: "portal", + table: "identity_providers", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "company_application_type_id", + schema: "portal", + table: "company_applications", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "onboarding_service_provider_id", + schema: "portal", + table: "company_applications", + type: "uuid", + nullable: true); + + migrationBuilder.CreateTable( + name: "audit_company_application20230824", + schema: "portal", + columns: table => new + { + audit_v1id = table.Column(type: "uuid", nullable: false), + id = table.Column(type: "uuid", nullable: false), + date_created = table.Column(type: "timestamp with time zone", nullable: false), + application_status_id = table.Column(type: "integer", nullable: false), + company_id = table.Column(type: "uuid", nullable: false), + checklist_process_id = table.Column(type: "uuid", nullable: true), + date_last_changed = table.Column(type: "timestamp with time zone", nullable: true), + company_application_type_id = table.Column(type: "integer", nullable: false), + onboarding_service_provider_id = table.Column(type: "uuid", nullable: true), + last_editor_id = table.Column(type: "uuid", nullable: true), + audit_v1last_editor_id = table.Column(type: "uuid", nullable: true), + audit_v1operation_id = table.Column(type: "integer", nullable: false), + audit_v1date_last_changed = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_audit_company_application20230824", x => x.audit_v1id); + }); + + migrationBuilder.CreateTable( + name: "company_application_types", + schema: "portal", + columns: table => new + { + id = table.Column(type: "integer", nullable: false), + label = table.Column(type: "character varying(255)", maxLength: 255, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_company_application_types", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "identity_provider_types", + schema: "portal", + columns: table => new + { + id = table.Column(type: "integer", nullable: false), + label = table.Column(type: "character varying(255)", maxLength: 255, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_identity_provider_types", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "onboarding_service_provider_details", + schema: "portal", + columns: table => new + { + company_id = table.Column(type: "uuid", nullable: false), + callback_url = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_onboarding_service_provider_details", x => x.company_id); + table.ForeignKey( + name: "fk_onboarding_service_provider_details_companies_company_id", + column: x => x.company_id, + principalSchema: "portal", + principalTable: "companies", + principalColumn: "id"); + }); + + migrationBuilder.InsertData( + schema: "portal", + table: "company_application_types", + columns: new[] { "id", "label" }, + values: new object[,] + { + { 1, "INTERNAL" }, + { 2, "EXTERNAL" } + }); + + migrationBuilder.InsertData( + schema: "portal", + table: "company_roles", + columns: new[] { "id", "label" }, + values: new object[] { 5, "ONBOARDING_SERVICE_PROVIDER" }); + + migrationBuilder.InsertData( + schema: "portal", + table: "identity_provider_types", + columns: new[] { "id", "label" }, + values: new object[,] + { + { 1, "OWN" }, + { 2, "MANAGED" }, + { 3, "SHARED" } + }); + + migrationBuilder.Sql("UPDATE portal.identity_providers set identity_provider_type_id = 3 where identity_provider_category_id = 1;"); + migrationBuilder.Sql("UPDATE portal.identity_providers set identity_provider_category_id = 2 where identity_provider_category_id = 1;"); + + migrationBuilder.DeleteData( + schema: "portal", + table: "identity_provider_categories", + keyColumn: "id", + keyValue: 1); + + migrationBuilder.CreateIndex( + name: "ix_identity_providers_identity_provider_type_id", + schema: "portal", + table: "identity_providers", + column: "identity_provider_type_id"); + + migrationBuilder.CreateIndex( + name: "ix_identity_providers_owner_id", + schema: "portal", + table: "identity_providers", + column: "owner_id"); + + migrationBuilder.CreateIndex( + name: "ix_company_applications_company_application_type_id", + schema: "portal", + table: "company_applications", + column: "company_application_type_id"); + + migrationBuilder.CreateIndex( + name: "ix_company_applications_onboarding_service_provider_id", + schema: "portal", + table: "company_applications", + column: "onboarding_service_provider_id"); + + migrationBuilder.AddForeignKey( + name: "fk_company_applications_companies_onboarding_service_provider_", + schema: "portal", + table: "company_applications", + column: "onboarding_service_provider_id", + principalSchema: "portal", + principalTable: "companies", + principalColumn: "id"); + + migrationBuilder.AddForeignKey( + name: "fk_company_applications_company_application_types_company_appl", + schema: "portal", + table: "company_applications", + column: "company_application_type_id", + principalSchema: "portal", + principalTable: "company_application_types", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_identity_providers_companies_owner_id", + schema: "portal", + table: "identity_providers", + column: "owner_id", + principalSchema: "portal", + principalTable: "companies", + principalColumn: "id"); + + migrationBuilder.AddForeignKey( + name: "fk_identity_providers_identity_provider_types_identity_provide", + schema: "portal", + table: "identity_providers", + column: "identity_provider_type_id", + principalSchema: "portal", + principalTable: "identity_provider_types", + principalColumn: "id"); + + migrationBuilder.Sql("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_application20230824\" (\"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\"();"); + migrationBuilder.Sql("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_application20230824\" (\"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\"();"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("DROP FUNCTION \"portal\".\"LC_TRIGGER_AFTER_INSERT_COMPANYAPPLICATION\"() CASCADE;"); + migrationBuilder.Sql("DROP FUNCTION \"portal\".\"LC_TRIGGER_AFTER_UPDATE_COMPANYAPPLICATION\"() CASCADE;"); + + migrationBuilder.InsertData( + schema: "portal", + table: "identity_provider_categories", + columns: new[] { "id", "label" }, + values: new object[] { 1, "KEYCLOAK_SHARED" }); + + migrationBuilder.Sql("UPDATE portal.identity_providers set identity_provider_category_id = 1 where identity_provider_type_id = 3;"); + + migrationBuilder.DropForeignKey( + name: "fk_company_applications_companies_onboarding_service_provider_", + schema: "portal", + table: "company_applications"); + + migrationBuilder.DropForeignKey( + name: "fk_company_applications_company_application_types_company_appl", + schema: "portal", + table: "company_applications"); + + migrationBuilder.DropForeignKey( + name: "fk_identity_providers_companies_owner_id", + schema: "portal", + table: "identity_providers"); + + migrationBuilder.DropForeignKey( + name: "fk_identity_providers_identity_provider_types_identity_provide", + schema: "portal", + table: "identity_providers"); + + migrationBuilder.DropTable( + name: "audit_company_application20230824", + schema: "portal"); + + migrationBuilder.DropTable( + name: "company_application_types", + schema: "portal"); + + migrationBuilder.DropTable( + name: "identity_provider_types", + schema: "portal"); + + migrationBuilder.DropTable( + name: "onboarding_service_provider_details", + schema: "portal"); + + migrationBuilder.DropIndex( + name: "ix_identity_providers_identity_provider_type_id", + schema: "portal", + table: "identity_providers"); + + migrationBuilder.DropIndex( + name: "ix_identity_providers_owner_id", + schema: "portal", + table: "identity_providers"); + + migrationBuilder.DropIndex( + name: "ix_company_applications_company_application_type_id", + schema: "portal", + table: "company_applications"); + + migrationBuilder.DropIndex( + name: "ix_company_applications_onboarding_service_provider_id", + schema: "portal", + table: "company_applications"); + + migrationBuilder.DeleteData( + schema: "portal", + table: "company_roles", + keyColumn: "id", + keyValue: 5); + + migrationBuilder.DropColumn( + name: "identity_provider_type_id", + schema: "portal", + table: "identity_providers"); + + migrationBuilder.DropColumn( + name: "owner_id", + schema: "portal", + table: "identity_providers"); + + migrationBuilder.DropColumn( + name: "company_application_type_id", + schema: "portal", + table: "company_applications"); + + migrationBuilder.DropColumn( + name: "onboarding_service_provider_id", + schema: "portal", + table: "company_applications"); + + migrationBuilder.Sql("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_application20230214\" (\"id\", \"date_created\", \"date_last_changed\", \"application_status_id\", \"company_id\", \"checklist_process_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.\"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\"();"); + migrationBuilder.Sql("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_application20230214\" (\"id\", \"date_created\", \"date_last_changed\", \"application_status_id\", \"company_id\", \"checklist_process_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.\"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\"();"); + } + } +} diff --git a/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs b/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs index c8ca31063f..fb16f9753f 100644 --- a/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs +++ b/src/portalbackend/PortalBackend.Migrations/Migrations/PortalDbContextModelSnapshot.cs @@ -189,6 +189,67 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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.AuditCompanyAssignedRole2023316", b => { b.Property("AuditV1Id") @@ -1991,6 +2052,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("uuid") .HasColumnName("checklist_process_id"); + b.Property("CompanyApplicationTypeId") + .HasColumnType("integer") + .HasColumnName("company_application_type_id"); + b.Property("CompanyId") .HasColumnType("uuid") .HasColumnName("company_id"); @@ -2007,6 +2072,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("uuid") .HasColumnName("last_editor_id"); + b.Property("OnboardingServiceProviderId") + .HasColumnType("uuid") + .HasColumnName("onboarding_service_provider_id"); + b.HasKey("Id") .HasName("pk_company_applications"); @@ -2017,12 +2086,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) .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"); @@ -2031,8 +2106,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) }); 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_application20230214\" (\"id\", \"date_created\", \"date_last_changed\", \"application_status_id\", \"company_id\", \"checklist_process_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.\"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_application20230214\" (\"id\", \"date_created\", \"date_last_changed\", \"application_status_id\", \"company_id\", \"checklist_process_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.\"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\"();"); + .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_application20230824\" (\"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_application20230824\" (\"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 => @@ -2100,6 +2175,36 @@ protected override void BuildModel(ModelBuilder modelBuilder) }); }); + 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") @@ -2234,6 +2339,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 4, Label = "OPERATOR" + }, + new + { + Id = 5, + Label = "ONBOARDING_SERVICE_PROVIDER" }); }); @@ -3373,12 +3483,26 @@ protected override void BuildModel(ModelBuilder modelBuilder) .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"); }); @@ -3399,21 +3523,51 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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 = "KEYCLOAK_SHARED" + Label = "OWN" }, new { Id = 2, - Label = "KEYCLOAK_OIDC" + Label = "MANAGED" }, new { Id = 3, - Label = "KEYCLOAK_SAML" + Label = "SHARED" }); }); @@ -4396,6 +4550,23 @@ protected override void BuildModel(ModelBuilder modelBuilder) }); }); + modelBuilder.Entity("Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities.OnboardingServiceProviderDetail", b => + { + b.Property("CompanyId") + .HasColumnType("uuid") + .HasColumnName("company_id"); + + b.Property("CallbackUrl") + .IsRequired() + .HasColumnType("text") + .HasColumnName("callback_url"); + + 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") @@ -5690,6 +5861,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) .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") @@ -5701,13 +5879,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) .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 => @@ -6295,7 +6482,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) .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") + .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 => @@ -6589,6 +6791,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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") @@ -6942,6 +7155,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("OfferSubscriptions"); + b.Navigation("OnboardingServiceProviderDetail"); + + b.Navigation("OwnedIdentityProviders"); + + b.Navigation("ProvidedApplications"); + b.Navigation("ProvidedConnectors"); b.Navigation("ProvidedOffers"); @@ -6961,6 +7180,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); @@ -7104,6 +7328,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); diff --git a/src/portalbackend/PortalBackend.Migrations/PortalBackend.Migrations.csproj b/src/portalbackend/PortalBackend.Migrations/PortalBackend.Migrations.csproj index 2d2bad4618..ee13eef87d 100644 --- a/src/portalbackend/PortalBackend.Migrations/PortalBackend.Migrations.csproj +++ b/src/portalbackend/PortalBackend.Migrations/PortalBackend.Migrations.csproj @@ -59,8 +59,6 @@ - - diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreement_assigned_company_roles.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreement_assigned_company_roles.json index 362123d104..8e7de64a54 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreement_assigned_company_roles.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreement_assigned_company_roles.json @@ -18,5 +18,9 @@ { "agreement_id": "aa0a0000-7fbc-1f2f-817f-bce0502c1090", "company_role_id": 1 + }, + { + "agreement_id": "311aac58-932b-4622-be8b-34337e48d70d", + "company_role_id": 5 } ] diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreements.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreements.json index 4944c3250c..53a1266481 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreements.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/agreements.json @@ -108,5 +108,16 @@ "issuer_company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87", "use_case_id": "1aacde78-35ec-4df3-ba1e-f988cddcbbd9", "document_id": null + }, + { + "id": "311aac58-932b-4622-be8b-34337e48d70d", + "agreement_category_id": 4, + "date_created": "2022-09-18 00:00:00.000000 +00:00", + "date_last_changed": "2022-09-18 00:00:00.000000 +00:00", + "agreement_type": null, + "name": "Terms & Conditions - Onboarding Service Provider", + "issuer_company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87", + "use_case_id": "1aacde78-35ec-4df3-ba1e-f988cddcbbd9", + "document_id": "1cc048fc-34d7-43ec-a205-bcbea6cbe01f" } ] diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_applications.consortia.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_applications.consortia.json index 154a14c5b7..5be49b82ee 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_applications.consortia.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_applications.consortia.json @@ -6,6 +6,7 @@ "application_status_id": 8, "company_id": "ac861325-bc54-4583-bcdc-9e9f2a38ff84", "checklist_process_id": "dd371565-9489-4907-a2e4-b8cbfe7a8cd2", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -15,6 +16,7 @@ "application_status_id": 8, "company_id": "0dcd8209-85e2-4073-b130-ac094fb47106", "checklist_process_id": "c97b0676-5b07-42fa-92ef-3743e1ac2ade", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -24,6 +26,7 @@ "application_status_id": 8, "company_id": "9d049598-0dac-4d26-8a21-8f5b64c799cf", "checklist_process_id": "a61f51b2-4400-4066-b421-b3992e37586e", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -33,6 +36,7 @@ "application_status_id": 8, "company_id": "cac8fa6a-9db7-4bad-9cbd-56298b74bac2", "checklist_process_id": "34215ee3-f99f-45e7-8c4e-747a089cf0b1", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -42,6 +46,7 @@ "application_status_id": 7, "company_id": "d14eba77-0b18-4e41-9d84-49ef875c0763", "checklist_process_id": "1f9a3232-9772-4ecb-8f50-c16e97772dfe", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -50,6 +55,7 @@ "date_last_changed": "2022-03-24 18:01:33.431000 +00:00", "application_status_id": 9, "company_id": "bdac6865-2a8d-4bfd-9373-9dfce8190895", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -58,6 +64,7 @@ "date_last_changed": "2022-03-24 18:01:33.439000 +00:00", "application_status_id": 3, "company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -66,6 +73,7 @@ "date_last_changed": "2022-03-24 18:01:33.439000 +00:00", "application_status_id": 1, "company_id": "220330ac-170d-4e22-8d72-9467ed042149", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -74,6 +82,7 @@ "date_last_changed": "2022-05-05 18:01:33.439000 +00:00", "application_status_id": 1, "company_id": "bdac6865-2a8d-4bfd-9373-9dfce8190895", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -82,6 +91,7 @@ "date_last_changed": "2022-05-05 18:01:33.439000 +00:00", "application_status_id": 1, "company_id": "41fd2ab8-71cd-4546-9bef-a388d91b2542", + "company_application_type_id": 1, "last_editor_id": null } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_descriptions.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_descriptions.json index 347c18f07f..a6a013e70e 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_descriptions.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_descriptions.json @@ -38,5 +38,15 @@ "company_role_id": 4, "language_short_name": "en", "description": "Operator" + }, + { + "company_role_id": 5, + "language_short_name": "de", + "description": "Der Onboarding-Dienstleister ist eine Catena-X zertifizierte Rolle, die es dem Unternehmen ermöglicht, als Onboarding-Anbieter innerhalb des Netzwerks zu fungieren." + }, + { + "company_role_id": 5, + "language_short_name": "en", + "description": "The Onboarding service provider is a Catena-X certified role which enables the company to act as onboarding provider inside the network." } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_registration_data.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_registration_data.json index 9dd012fbcc..e12a217ec3 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_registration_data.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/company_role_registration_data.json @@ -14,5 +14,9 @@ { "company_role_id": 4, "is_registration_role": false + }, + { + "company_role_id": 5, + "is_registration_role": true } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json index e9311b1adf..7940cb8cb5 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/documents.json @@ -86,5 +86,16 @@ "document_hash": "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", "document_content": "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MDAwMDAwMDkzMyAwMDAwMCBuIAowMDAwMDExNzI2IDAwMDAwIG4gCjAwMDAwMTQ1NTggMDAwMDAgbiAKMDAwMDAxNTA2NiAwMDAwMCBuIAowMDAwMDE0NzcwIDAwMDAwIG4gCjAwMDAwMTUzMDIgMDAwMDAgbiAKMDAwMDAyMjcyMyAwMDAwMCBuIAowMDAwMDIyMzQ0IDAwMDAwIG4gCjAwMDAwMjI5NTkgMDAwMDAgbiAKMDAwMDAzMzI4NSAwMDAwMCBuIAowMDAwMDMyOTc4IDAwMDAwIG4gCjAwMDAwMzM1MjEgMDAwMDAgbiAKMDAwMDA0MDk5MiAwMDAwMCBuIAowMDAwMDQwNjM3IDAwMDAwIG4gCjAwMDAwNDEyMjggMDAwMDAgbiAKMDAwMDA0OTg5MyAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDMwIC9Sb290IDE2IDAgUiAvSW5mbyAyOSAwIFIgL0lEIFsgPDQzZjZkMjJmYzFiM2NiZjk1MDhjNTliMWE0NjViYTdjPgo8NDNmNmQyMmZjMWIzY2JmOTUwOGM1OWIxYTQ2NWJhN2M+IF0gPj4Kc3RhcnR4cmVmCjUwMTEwCiUlRU9GCg==", "document_status_id": 2 + }, + { + "id": "1cc048fc-34d7-43ec-a205-bcbea6cbe01f", + "date_created": "2023-01-04T19:29:08.602237+00:00", + "document_name": "Terms & Conditions - Onboarding Service Provider.pdf", + "media_type_id": 6, + "document_type_id": 1, + "company_user_id": "ac1cf001-7fbc-1f2f-817f-bce058020006", + "document_hash": "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", + "document_content": "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MDAwMDAwMDkzMyAwMDAwMCBuIAowMDAwMDExNzI2IDAwMDAwIG4gCjAwMDAwMTQ1NTggMDAwMDAgbiAKMDAwMDAxNTA2NiAwMDAwMCBuIAowMDAwMDE0NzcwIDAwMDAwIG4gCjAwMDAwMTUzMDIgMDAwMDAgbiAKMDAwMDAyMjcyMyAwMDAwMCBuIAowMDAwMDIyMzQ0IDAwMDAwIG4gCjAwMDAwMjI5NTkgMDAwMDAgbiAKMDAwMDAzMzI4NSAwMDAwMCBuIAowMDAwMDMyOTc4IDAwMDAwIG4gCjAwMDAwMzM1MjEgMDAwMDAgbiAKMDAwMDA0MDk5MiAwMDAwMCBuIAowMDAwMDQwNjM3IDAwMDAwIG4gCjAwMDAwNDEyMjggMDAwMDAgbiAKMDAwMDA0OTg5MyAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDMwIC9Sb290IDE2IDAgUiAvSW5mbyAyOSAwIFIgL0lEIFsgPDQzZjZkMjJmYzFiM2NiZjk1MDhjNTliMWE0NjViYTdjPgo8NDNmNmQyMmZjMWIzY2JmOTUwOGM1OWIxYTQ2NWJhN2M+IF0gPj4Kc3RhcnR4cmVmCjUwMTEwCiUlRU9GCg==", + "document_status_id": 2 } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.consortia.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.consortia.json index b20eb69269..3627dab8c7 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.consortia.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.consortia.json @@ -2,46 +2,64 @@ { "id": "ac1cf001-7fbc-1f2f-817f-bce0571b0004", "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 2 + "identity_provider_category_id": 2, + "identity_provider_type_id": 2, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce057230006", "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce057230007", "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce057230008", "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce0575a0012", "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce057770016", "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce057770017", "date_created": "2022-11-01 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "ac1cf001-7fbc-1f2f-817f-bce057770018", "date_created": "2022-11-01 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" }, { "id": "e7317720-051d-4f4c-9140-ac23c6330351", "date_created": "2022-11-01 00:00:00.000000 +00:00", - "identity_provider_category_id": 2 + "identity_provider_category_id": 2, + "identity_provider_type_id": 2, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87" } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.json index 12d5aa8281..21eae5648e 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/identity_providers.json @@ -1,7 +1,9 @@ [ { "id": "ac1cf001-7fbc-1f2f-817f-bce057770015", - "date_created": "2022-05-05 00:00:00.000000 +00:00", - "identity_provider_category_id": 1 + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87", + "date_created": "2022-05-05 00:00:00.000000 +00:00" } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json index 35d677fbfa..5c001f9060 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_assigned_collections.json @@ -134,5 +134,17 @@ { "user_role_id": "607818be-4978-41f4-bf63-fa8d2de51157", "user_role_collection_id": "ec428950-8b64-4646-b336-28af869b5d73" + }, + { + "user_role_id": "58f897ec-0aad-4588-8ffa-5f45d6638632", + "user_role_collection_id": "916b09e7-7841-4e57-bdca-e0d3bd329c27" + }, + { + "user_role_id": "607818be-4978-41f4-bf63-fa8d2de51154", + "user_role_collection_id": "916b09e7-7841-4e57-bdca-e0d3bd329c27" + }, + { + "user_role_id": "58f897ec-0aad-4588-8ffa-5f45d6638633", + "user_role_collection_id": "916b09e7-7841-4e57-bdca-e0d3bd329c27" } ] diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collection_descriptions.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collection_descriptions.json index a0b41a38f8..16fd1eea07 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collection_descriptions.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collection_descriptions.json @@ -38,5 +38,15 @@ "user_role_collection_id": "ec428950-8b64-4646-b336-28af869b5d73", "language_short_name": "en", "description": "App Provider" + }, + { + "user_role_collection_id": "916b09e7-7841-4e57-bdca-e0d3bd329c27", + "language_short_name": "de", + "description": "Onboarding Service Provider" + }, + { + "user_role_collection_id": "916b09e7-7841-4e57-bdca-e0d3bd329c27", + "language_short_name": "en", + "description": "Onboarding Service Provider" } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collections.json b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collections.json index 58ffef3e5d..8f672519b9 100644 --- a/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collections.json +++ b/src/portalbackend/PortalBackend.Migrations/Seeder/Data/user_role_collections.json @@ -14,5 +14,9 @@ { "id": "ec428950-8b64-4646-b336-28af869b5d73", "name": "App Provider" + }, + { + "id": "916b09e7-7841-4e57-bdca-e0d3bd329c27", + "name": "Onboarding Service Provider" } ] \ No newline at end of file diff --git a/src/portalbackend/PortalBackend.PortalEntities/AuditEntities/AuditCompanyApplication20230824.cs b/src/portalbackend/PortalBackend.PortalEntities/AuditEntities/AuditCompanyApplication20230824.cs new file mode 100644 index 0000000000..eb3ec0d195 --- /dev/null +++ b/src/portalbackend/PortalBackend.PortalEntities/AuditEntities/AuditCompanyApplication20230824.cs @@ -0,0 +1,63 @@ +/******************************************************************************** + * 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 + * 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 Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Auditing; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using System.ComponentModel.DataAnnotations; + +namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.AuditEntities; + +/// +/// Audit entity for only needed for configuration purposes +/// +public class AuditCompanyApplication20230824 : IAuditEntityV1 +{ + /// + [Key] + public Guid AuditV1Id { get; set; } + + public Guid Id { get; set; } + + public DateTimeOffset DateCreated { get; set; } + + public CompanyApplicationStatusId ApplicationStatusId { get; set; } + + public Guid CompanyId { get; set; } + + public Guid? ChecklistProcessId { get; set; } + + public DateTimeOffset? DateLastChanged { get; set; } + + public CompanyApplicationTypeId CompanyApplicationTypeId { get; set; } + + public Guid? OnboardingServiceProviderId { get; set; } + + public Guid? LastEditorId { get; set; } + + /// + public Guid? AuditV1LastEditorId { get; set; } + + /// + public AuditOperationId AuditV1OperationId { get; set; } + + /// + public DateTimeOffset AuditV1DateLastChanged { get; set; } +} diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/Company.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/Company.cs index b4129eede7..5b38781485 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Entities/Company.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/Company.cs @@ -43,6 +43,8 @@ private Company() CompanyIdentifiers = new HashSet(); CompanyAssignedUseCase = new HashSet(); CompanySsiDetails = new HashSet(); + OwnedIdentityProviders = new HashSet(); + ProvidedApplications = new HashSet(); } public Company(Guid id, string name, CompanyStatusId companyStatusId, DateTimeOffset dateCreated) : this() @@ -74,7 +76,7 @@ public Company(Guid id, string name, CompanyStatusId companyStatusId, DateTimeOf // Navigation properties public virtual Address? Address { get; set; } - + public virtual OnboardingServiceProviderDetail? OnboardingServiceProviderDetail { get; set; } public virtual ProviderCompanyDetail? ProviderCompanyDetail { get; private set; } public virtual ICollection Agreements { get; private set; } public virtual ICollection BoughtOffers { get; private set; } @@ -92,4 +94,6 @@ public Company(Guid id, string name, CompanyStatusId companyStatusId, DateTimeOf public virtual ICollection CompanyIdentifiers { get; private set; } public virtual ICollection CompanyAssignedUseCase { get; private set; } public virtual ICollection CompanySsiDetails { get; private set; } + public virtual ICollection OwnedIdentityProviders { get; private set; } + public virtual ICollection ProvidedApplications { get; private set; } } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplication.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplication.cs index bce4656391..018b9bd6c8 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplication.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplication.cs @@ -25,7 +25,7 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; -[AuditEntityV1(typeof(AuditCompanyApplication20230214))] +[AuditEntityV1(typeof(AuditCompanyApplication20230824))] public class CompanyApplication : IAuditableV1, IBaseEntity { protected CompanyApplication() @@ -34,11 +34,12 @@ protected CompanyApplication() ApplicationChecklistEntries = new HashSet(); } - public CompanyApplication(Guid id, Guid companyId, CompanyApplicationStatusId applicationStatusId, DateTimeOffset dateCreated) : this() + public CompanyApplication(Guid id, Guid companyId, CompanyApplicationStatusId applicationStatusId, CompanyApplicationTypeId companyApplicationTypeId, DateTimeOffset dateCreated) : this() { Id = id; CompanyId = companyId; ApplicationStatusId = applicationStatusId; + CompanyApplicationTypeId = companyApplicationTypeId; DateCreated = dateCreated; } @@ -53,6 +54,10 @@ public CompanyApplication(Guid id, Guid companyId, CompanyApplicationStatusId ap public Guid CompanyId { get; private set; } public Guid? ChecklistProcessId { get; set; } + public CompanyApplicationTypeId CompanyApplicationTypeId { get; private set; } + + public Guid? OnboardingServiceProviderId { get; private set; } + [LastEditorV1] public Guid? LastEditorId { get; private set; } @@ -60,6 +65,8 @@ public CompanyApplication(Guid id, Guid companyId, CompanyApplicationStatusId ap public virtual CompanyApplicationStatus? ApplicationStatus { get; set; } public virtual Company? Company { get; set; } public virtual Process? ChecklistProcess { get; set; } + public virtual CompanyApplicationType? CompanyApplicationType { get; set; } + public virtual Company? OnboardingServiceProvider { get; set; } public virtual ICollection Invitations { get; private set; } public virtual ICollection ApplicationChecklistEntries { get; private set; } public virtual Identity? LastEditor { get; private set; } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplicationType.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplicationType.cs new file mode 100644 index 0000000000..14ce3e107d --- /dev/null +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyApplicationType.cs @@ -0,0 +1,62 @@ +/******************************************************************************** + * 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 + * 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 Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using System.ComponentModel.DataAnnotations; + +namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; + +/// +/// Type of a companyApplication +/// +public class CompanyApplicationType +{ + /// + /// Internal constructor, only for EF + /// + private CompanyApplicationType() + { + Label = null!; + CompanyApplications = new HashSet(); + } + + /// + /// Creates a new instance of and initializes the id and label + /// + /// The CompanyApplicationTypeId + public CompanyApplicationType(CompanyApplicationTypeId companyApplicationTypeId) : this() + { + Id = companyApplicationTypeId; + Label = companyApplicationTypeId.ToString(); + } + + /// + /// Id of the type + /// + public CompanyApplicationTypeId Id { get; private set; } + + /// + /// The type as string + /// + [MaxLength(255)] + public string Label { get; private set; } + + public virtual ICollection CompanyApplications { get; private set; } +} diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProvider.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProvider.cs index 799fece5f4..cea54c10ac 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProvider.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProvider.cs @@ -31,10 +31,11 @@ private IdentityProvider() CompanyIdentityProviders = new HashSet(); } - public IdentityProvider(Guid id, IdentityProviderCategoryId identityProviderCategoryId, DateTimeOffset dateCreated) : this() + public IdentityProvider(Guid id, IdentityProviderCategoryId identityProviderCategoryId, IdentityProviderTypeId identityProviderTypeId, DateTimeOffset dateCreated) : this() { Id = id; IdentityProviderCategoryId = identityProviderCategoryId; + IdentityProviderTypeId = identityProviderTypeId; DateCreated = dateCreated; } @@ -44,9 +45,15 @@ public IdentityProvider(Guid id, IdentityProviderCategoryId identityProviderCate public IdentityProviderCategoryId IdentityProviderCategoryId { get; private set; } + public IdentityProviderTypeId IdentityProviderTypeId { get; private set; } + + public Guid? OwnerId { get; set; } + // Navigation properties public virtual IdentityProviderCategory? IdentityProviderCategory { get; private set; } public virtual IamIdentityProvider? IamIdentityProvider { get; set; } + public virtual IdentityProviderType? IdentityProviderType { get; set; } + public virtual Company? Owner { get; set; } public virtual ICollection Companies { get; private set; } public virtual ICollection CompanyIdentityProviders { get; private set; } } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProviderType.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProviderType.cs new file mode 100644 index 0000000000..b3a2674445 --- /dev/null +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityProviderType.cs @@ -0,0 +1,62 @@ +/******************************************************************************** + * 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 + * 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 Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using System.ComponentModel.DataAnnotations; + +namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; + +/// +/// Type of a identity type +/// +public class IdentityProviderType +{ + /// + /// Internal constructor, only for EF + /// + private IdentityProviderType() + { + Label = null!; + IdentityProviders = new HashSet(); + } + + /// + /// Creates a new instance of and initializes the id and label + /// + /// The IdentityProviderTypeId + public IdentityProviderType(IdentityProviderTypeId identityProviderTypeId) : this() + { + Id = identityProviderTypeId; + Label = identityProviderTypeId.ToString(); + } + + /// + /// Id of the type + /// + public IdentityProviderTypeId Id { get; private set; } + + /// + /// The type as string + /// + [MaxLength(255)] + public string Label { get; private set; } + + public virtual ICollection IdentityProviders { get; private set; } +} diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/OnboardingServiceProviderDetail.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/OnboardingServiceProviderDetail.cs new file mode 100644 index 0000000000..cc73efcaa0 --- /dev/null +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/OnboardingServiceProviderDetail.cs @@ -0,0 +1,42 @@ +/******************************************************************************** + * 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 + * 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.PortalBackend.PortalEntities.Entities; + +public class OnboardingServiceProviderDetail +{ + public OnboardingServiceProviderDetail() + { + CallbackUrl = null!; + } + + public OnboardingServiceProviderDetail(Guid companyId, string callbackUrl) + : this() + { + CompanyId = companyId; + CallbackUrl = callbackUrl; + } + + public Guid CompanyId { get; set; } + + public string CallbackUrl { get; set; } + + public virtual Company? Company { get; private set; } +} diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationTypeId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationTypeId.cs new file mode 100644 index 0000000000..1959d6059a --- /dev/null +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyApplicationTypeId.cs @@ -0,0 +1,27 @@ +/******************************************************************************** + * 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 + * 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.PortalBackend.PortalEntities.Enums; + +public enum CompanyApplicationTypeId +{ + INTERNAL = 1, + EXTERNAL = 2 +} diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyRoleId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyRoleId.cs index adb5ebc800..cd71e297b4 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyRoleId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyRoleId.cs @@ -26,4 +26,5 @@ public enum CompanyRoleId : int APP_PROVIDER = 2, SERVICE_PROVIDER = 3, OPERATOR = 4, + ONBOARDING_SERVICE_PROVIDER = 5 } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderCategoryId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderCategoryId.cs index 27f2008103..1859f78435 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderCategoryId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderCategoryId.cs @@ -22,7 +22,6 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums public enum IdentityProviderCategoryId : int { - KEYCLOAK_SHARED = 1, KEYCLOAK_OIDC = 2, KEYCLOAK_SAML = 3 } diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderTypeId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderTypeId.cs new file mode 100644 index 0000000000..fd537dbfd8 --- /dev/null +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/IdentityProviderTypeId.cs @@ -0,0 +1,28 @@ +/******************************************************************************** + * 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 + * 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.PortalBackend.PortalEntities.Enums; + +public enum IdentityProviderTypeId +{ + OWN = 1, + MANAGED = 2, + SHARED = 3 +} diff --git a/src/portalbackend/PortalBackend.PortalEntities/PortalDbContext.cs b/src/portalbackend/PortalBackend.PortalEntities/PortalDbContext.cs index 5d5866723f..2d64a1285c 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/PortalDbContext.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/PortalDbContext.cs @@ -74,6 +74,7 @@ public PortalDbContext(DbContextOptions options, IAuditHandler public virtual DbSet AuditOfferSubscription20230317 { get; set; } = default!; public virtual DbSet AuditCompanyApplication20221005 { get; set; } = default!; public virtual DbSet AuditCompanyApplication20230214 { get; set; } = default!; + public virtual DbSet AuditCompanyApplication20230824 { get; set; } = default!; public virtual DbSet AuditCompanySsiDetail20230621 { get; set; } = default!; public virtual DbSet AuditCompanyUser20221005 { get; set; } = default!; public virtual DbSet AuditCompanyUser20230523 { get; set; } = default!; @@ -91,6 +92,7 @@ public PortalDbContext(DbContextOptions options, IAuditHandler public virtual DbSet Companies { get; set; } = default!; public virtual DbSet CompanyApplications { get; set; } = default!; public virtual DbSet CompanyApplicationStatuses { get; set; } = default!; + public virtual DbSet CompanyApplicationTypes { get; set; } = default!; public virtual DbSet CompanyAssignedRoles { get; set; } = default!; public virtual DbSet CompanyAssignedUseCases { get; set; } = default!; public virtual DbSet CompanyIdentifiers { get; set; } = default!; @@ -124,6 +126,7 @@ public PortalDbContext(DbContextOptions options, IAuditHandler public virtual DbSet Identities { get; set; } = default!; public virtual DbSet IdentityAssignedRoles { get; set; } = default!; public virtual DbSet IdentityProviders { get; set; } = default!; + public virtual DbSet IdentityProviderTypes { get; set; } = default!; public virtual DbSet IdentityProviderCategories { get; set; } = default!; public virtual DbSet IdentityUserStatuses { get; set; } = default!; public virtual DbSet Invitations { get; set; } = default!; @@ -146,6 +149,7 @@ public PortalDbContext(DbContextOptions options, IAuditHandler public virtual DbSet OfferSubscriptions { get; set; } = default!; public virtual DbSet OfferSubscriptionStatuses { get; set; } = default!; public virtual DbSet OfferSubscriptionsProcessDatas { get; set; } = default!; + public virtual DbSet OnboardingServiceProviderDetails { get; set; } = default!; public virtual DbSet Processes { get; set; } = default!; public virtual DbSet ProcessSteps { get; set; } = default!; public virtual DbSet ProcessStepStatuses { get; set; } = default!; @@ -558,11 +562,21 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasOne(d => d.Company) - .WithMany(p => p!.CompanyApplications) + .WithMany(p => p.CompanyApplications) .HasForeignKey(d => d.CompanyId) .OnDelete(DeleteBehavior.ClientSetNull); - entity.HasAuditV1Triggers(); + entity.HasOne(d => d.Company) + .WithMany(p => p.CompanyApplications) + .HasForeignKey(d => d.CompanyId) + .OnDelete(DeleteBehavior.ClientSetNull); + + entity.HasOne(x => x.OnboardingServiceProvider) + .WithMany(x => x.ProvidedApplications) + .HasForeignKey(x => x.OnboardingServiceProviderId) + .OnDelete(DeleteBehavior.ClientSetNull); + + entity.HasAuditV1Triggers(); }); modelBuilder.Entity() @@ -572,6 +586,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .Select(e => new CompanyApplicationStatus(e)) ); + modelBuilder.Entity() + .HasData( + Enum.GetValues(typeof(CompanyApplicationTypeId)) + .Cast() + .Select(e => new CompanyApplicationType(e)) + ); + modelBuilder.Entity(entity => { entity.HasKey(x => new { x.ApplicationId, ChecklistEntryTypeId = x.ApplicationChecklistEntryTypeId }); @@ -891,12 +912,31 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasForeignKey(d => d.IdentityProviderId) .OnDelete(DeleteBehavior.ClientSetNull); - modelBuilder.Entity() - .HasOne(d => d.IdentityProviderCategory) - .WithMany(p => p!.IdentityProviders) - .HasForeignKey(d => d.IdentityProviderCategoryId) + modelBuilder.Entity(entity => + { + entity.HasOne(x => x.IdentityProviderCategory) + .WithMany(x => x.IdentityProviders) + .HasForeignKey(x => x.IdentityProviderCategoryId) + .OnDelete(DeleteBehavior.ClientSetNull); + + entity.HasOne(x => x.IdentityProviderType) + .WithMany(x => x.IdentityProviders) + .HasForeignKey(x => x.IdentityProviderTypeId) .OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(x => x.Owner) + .WithMany(x => x.OwnedIdentityProviders) + .HasForeignKey(x => x.OwnerId) + .OnDelete(DeleteBehavior.ClientSetNull); + }); + + modelBuilder.Entity() + .HasData( + Enum.GetValues(typeof(IdentityProviderTypeId)) + .Cast() + .Select(e => new IdentityProviderType(e)) + ); + modelBuilder.Entity() .HasData( Enum.GetValues(typeof(IdentityProviderCategoryId)) @@ -1343,6 +1383,16 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .WithOne(x => x.CompanyServiceAccount) .HasForeignKey(x => x.ServiceAccountId); }); + + modelBuilder.Entity(entity => + { + entity.HasKey(x => x.CompanyId); + + entity.HasOne(x => x.Company) + .WithOne(x => x.OnboardingServiceProviderDetail) + .HasForeignKey(x => x.CompanyId) + .OnDelete(DeleteBehavior.ClientSetNull); + }); } /// diff --git a/src/provisioning/Provisioning.Library/Service/UserProvisioningService.cs b/src/provisioning/Provisioning.Library/Service/UserProvisioningService.cs index cc16e1967e..398aacf3d5 100644 --- a/src/provisioning/Provisioning.Library/Service/UserProvisioningService.cs +++ b/src/provisioning/Provisioning.Library/Service/UserProvisioningService.cs @@ -197,7 +197,7 @@ private Task CreateSharedIdpUserOrReturnUserId(UserCreationRoleDataIdpIn public async Task<(CompanyNameIdpAliasData IdpAliasData, string NameCreatedBy)> GetCompanyNameSharedIdpAliasData(Guid companyUserId, Guid? applicationId = null) { - var result = await _portalRepositories.GetInstance().GetCompanyNameIdpAliaseUntrackedAsync(companyUserId, applicationId, IdentityProviderCategoryId.KEYCLOAK_SHARED).ConfigureAwait(false); + var result = await _portalRepositories.GetInstance().GetCompanyNameIdpAliaseUntrackedAsync(companyUserId, applicationId, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED).ConfigureAwait(false); if (result == default) { throw applicationId == null diff --git a/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs index 6112275bbb..ae7b1bd1a4 100644 --- a/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs +++ b/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs @@ -93,7 +93,7 @@ private async Task GetCompanyBpdmDetailDataByBusinessPart throw new ConflictException("Bpdm did return incorrect bpn legal-entity-data"); } - var country = legalEntity.LegalEntityAddress.PhysicalPostalAddress?.Country?.TechnicalKey ?? + var country = legalEntity.LegalEntityAddress?.PhysicalPostalAddress?.Country?.TechnicalKey ?? throw new ConflictException("Legal-entity-data did not contain a valid country identifier"); var bpdmIdentifiers = ParseBpdmIdentifierDtos(legalEntity.Identifiers).ToList(); diff --git a/src/registration/Registration.Service/Program.cs b/src/registration/Registration.Service/Program.cs index cc30b69f5f..23fae3c6c8 100644 --- a/src/registration/Registration.Service/Program.cs +++ b/src/registration/Registration.Service/Program.cs @@ -19,6 +19,7 @@ ********************************************************************************/ using Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library.DependencyInjection; +using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.Framework.Web; using Org.Eclipse.TractusX.Portal.Backend.Mailing.SendMail; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess; @@ -43,5 +44,5 @@ .ConfigureRegistrationSettings(builder.Configuration.GetSection("Registration")); builder.Services.AddApplicationChecklistCreation(); - builder.Services.AddBpnAccess(builder.Configuration.GetValue("BPN_Address")); + builder.Services.AddBpnAccess(builder.Configuration.GetValue("BPN_Address") ?? throw new ConfigurationException("BPN_Address is not configured")); }); diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs index 61868a475c..82aebb5cca 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/IdentityProviderBusinessLogicTests.cs @@ -20,37 +20,44 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; +using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic; +using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; using Org.Eclipse.TractusX.Portal.Backend.Framework.IO; +using Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling; 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.Provisioning.Library; +using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Enums; using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models; using System.Text; -namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic.Tests; +namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Tests.BusinessLogic; public class IdentityProviderBusinessLogicTests { private readonly IFixture _fixture; private readonly IProvisioningManager _provisioningManager; + private readonly ICompanyRepository _companyRepository; private readonly IPortalRepositories _portalRepositories; private readonly IIdentityProviderRepository _identityProviderRepository; private readonly IUserRepository _userRepository; private readonly IOptions _options; private readonly IdentityProviderCsvSettings _csvSettings; + private readonly IIdentityService _identityService; private readonly IFormFile _document; private readonly Encoding _encoding; private readonly Guid _companyId; - private readonly Guid _companyUserId; + private readonly Guid _invalidCompanyId; private readonly IdentityData _identity; private readonly Guid _sharedIdentityProviderId; private readonly string _sharedIdpAlias; private readonly Guid _otherIdentityProviderId; private readonly string _otherIdpAlias; + private readonly Guid _identityProviderId; public IdentityProviderBusinessLogicTests() { @@ -61,19 +68,24 @@ public IdentityProviderBusinessLogicTests() _provisioningManager = A.Fake(); _portalRepositories = A.Fake(); + _companyRepository = A.Fake(); _identityProviderRepository = A.Fake(); _userRepository = A.Fake(); + _identityService = A.Fake(); _options = A.Fake>(); _document = A.Fake(); _companyId = _fixture.Create(); - _companyUserId = _fixture.Create(); + _invalidCompanyId = _fixture.Create(); + _identityProviderId = _fixture.Create(); _sharedIdentityProviderId = _fixture.Create(); _sharedIdpAlias = _fixture.Create(); _otherIdentityProviderId = _fixture.Create(); _otherIdpAlias = _fixture.Create(); _encoding = _fixture.Create(); - _identity = new(Guid.NewGuid().ToString(), _companyUserId, IdentityTypeId.COMPANY_USER, _companyId); + _identity = new(Guid.NewGuid().ToString(), Guid.NewGuid(), IdentityTypeId.COMPANY_USER, _companyId); + + A.CallTo(() => _identityService.IdentityData).Returns(_identity); _csvSettings = new IdentityProviderCsvSettings { @@ -88,8 +100,11 @@ public IdentityProviderBusinessLogicTests() HeaderEmail = "Email", HeaderProviderAlias = "ProviderAlias", HeaderProviderUserId = "ProviderUserId", - HeaderProviderUserName = "ProviderUserName" + HeaderProviderUserName = "ProviderUserName", }; + + A.CallTo(() => _portalRepositories.GetInstance()) + .Returns(_identityProviderRepository); } #region UploadOwnCompanyUsersIdentityProviderLinkDataAsync @@ -97,7 +112,7 @@ public IdentityProviderBusinessLogicTests() [Fact] public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncAllUnchangedSuccess() { - var numUsers = 5; + const int numUsers = 5; var users = _fixture.CreateMany(numUsers).ToList(); @@ -108,6 +123,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncAllUncha var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, + _identityService, _options); var result = await sut.UploadOwnCompanyUsersIdentityProviderLinkDataAsync(_document, _identity.CompanyId, CancellationToken.None).ConfigureAwait(false); @@ -129,7 +145,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncAllUncha [Fact] public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncWrongContentTypeThrows() { - var numUsers = 1; + const int numUsers = 1; var users = _fixture.CreateMany(numUsers).ToList(); @@ -142,6 +158,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncWrongCon var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, + _identityService, _options); async Task Act() => await sut.UploadOwnCompanyUsersIdentityProviderLinkDataAsync(_document, _identity.CompanyId, CancellationToken.None).ConfigureAwait(false); @@ -153,22 +170,12 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncWrongCon [Fact] public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncEmailChangedSuccess() { - var numUsers = 5; + const int numUsers = 5; var changedEmail = _fixture.Create(); var unchanged = _fixture.Create(); - var changed = new TestUserData( - unchanged.CompanyUserId, - unchanged.UserEntityId, - unchanged.FirstName, - unchanged.LastName, - changedEmail, - unchanged.SharedIdpUserId, - unchanged.SharedIdpUserName, - unchanged.OtherIdpUserId, - unchanged.OtherIdpUserName - ); + var changed = unchanged with { Email = changedEmail }; var users = new[] { _fixture.Create(), @@ -199,6 +206,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncEmailCha var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, + _identityService, _options); var result = await sut.UploadOwnCompanyUsersIdentityProviderLinkDataAsync(_document, _identity.CompanyId, CancellationToken.None).ConfigureAwait(false); @@ -223,20 +231,10 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncEmailCha [Fact] public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncSharedIdpLinkChangedError() { - var numUsers = 5; + const int numUsers = 5; var unchanged = _fixture.Create(); - var changed = new TestUserData( - unchanged.CompanyUserId, - unchanged.UserEntityId, - unchanged.FirstName, - unchanged.LastName, - unchanged.Email, - unchanged.SharedIdpUserId, - _fixture.Create(), - unchanged.OtherIdpUserId, - unchanged.OtherIdpUserName - ); + var changed = unchanged with { SharedIdpUserName = _fixture.Create() }; var users = new[] { _fixture.Create(), @@ -253,6 +251,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncSharedId var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, + _identityService, _options); var result = await sut.UploadOwnCompanyUsersIdentityProviderLinkDataAsync(_document, _identity.CompanyId, CancellationToken.None).ConfigureAwait(false); @@ -275,20 +274,10 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncSharedId [Fact] public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncOtherIdpLinkChangedSuccess() { - var numUsers = 5; + const int numUsers = 5; var unchanged = _fixture.Create(); - var changed = new TestUserData( - unchanged.CompanyUserId, - unchanged.UserEntityId, - unchanged.FirstName, - unchanged.LastName, - unchanged.Email, - unchanged.SharedIdpUserId, - unchanged.SharedIdpUserName, - unchanged.OtherIdpUserId, - _fixture.Create() - ); + var changed = unchanged with { OtherIdpUserName = _fixture.Create() }; var users = new[] { _fixture.Create(), @@ -305,6 +294,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncOtherIdp var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, + _identityService, _options); var result = await sut.UploadOwnCompanyUsersIdentityProviderLinkDataAsync(_document, _identity.CompanyId, CancellationToken.None).ConfigureAwait(false); @@ -326,20 +316,10 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncOtherIdp [Fact] public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncUnknownCompanyUserIdError() { - var numUsers = 5; + const int numUsers = 5; var unchanged = _fixture.Create(); - var unknown = new TestUserData( - _fixture.Create(), - unchanged.UserEntityId, - unchanged.FirstName, - unchanged.LastName, - unchanged.Email, - unchanged.SharedIdpUserId, - unchanged.SharedIdpUserName, - unchanged.OtherIdpUserId, - unchanged.OtherIdpUserName - ); + var unknown = unchanged with { CompanyUserId = _fixture.Create() }; var users = new[] { _fixture.Create(), @@ -356,6 +336,7 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncUnknownC var sut = new IdentityProviderBusinessLogic( _portalRepositories, _provisioningManager, + _identityService, _options); var result = await sut.UploadOwnCompanyUsersIdentityProviderLinkDataAsync(_document, _identity.CompanyId, CancellationToken.None).ConfigureAwait(false); @@ -377,38 +358,1669 @@ public async Task TestUploadOwnCompanyUsersIdentityProviderLinkDataAsyncUnknownC #endregion - #region Setup + #region CreateOwnCompanyIdentityProviderAsync - private void SetupFakes(IEnumerable userData, IEnumerable lines) + [Fact] + public async Task CreateOwnCompanyIdentityProviderAsync_WithNotSupportedProtocol_ThrowsControllerArgumentException() { - A.CallTo(() => _options.Value).Returns(new IdentityProviderSettings { CsvSettings = _csvSettings }); + // Arrange + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); - A.CallTo(() => _document.ContentType).Returns(_options.Value.CsvSettings.ContentType); - A.CallTo(() => _document.OpenReadStream()).ReturnsLazily(() => new AsyncEnumerableStringStream(lines.ToAsyncEnumerable(), _encoding)); + // Act + async Task Act() => await sut.CreateOwnCompanyIdentityProviderAsync(default, IdentityProviderTypeId.OWN, null).ConfigureAwait(false); - A.CallTo(() => _portalRepositories.GetInstance()).Returns(_userRepository); - A.CallTo(() => _portalRepositories.GetInstance()).Returns(_identityProviderRepository); + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.ParamName.Should().Be("protocol"); + } - A.CallTo(() => _userRepository.GetUserEntityDataAsync(A._, A._)).ReturnsLazily((Guid companyUserId, Guid _) => - userData.Where(d => d.CompanyUserId == companyUserId) - .Select(d => - ( - UserEntityId: d.UserEntityId, - FirstName: d.FirstName, - LastName: d.LastName, - Email: d.Email - )).FirstOrDefault()); + [Theory] + [InlineData("a")] + [InlineData("this-is-a-very-long-dispaly-name-and-it-should-be-way-too-long")] + public async Task CreateOwnCompanyIdentityProviderAsync_WithDisplayNameToLong_ThrowsControllerArgumentException(string display) + { + // Arrange + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); - A.CallTo(() => _identityProviderRepository.GetCompanyIdentityProviderCategoryDataUntracked(A.That.Not.IsEqualTo(_companyId))).Returns( - Enumerable.Empty<(Guid IdentityProviderId, IdentityProviderCategoryId CategoryId, string Alias)>().ToAsyncEnumerable()); - A.CallTo(() => _identityProviderRepository.GetCompanyIdentityProviderCategoryDataUntracked(A.That.IsEqualTo(_companyId))).Returns( - new[] { - (IdentityProviderId: _sharedIdentityProviderId, CategoryId: IdentityProviderCategoryId.KEYCLOAK_SHARED, Alias: _sharedIdpAlias), - (IdentityProviderId: _otherIdentityProviderId, CategoryId: IdentityProviderCategoryId.KEYCLOAK_OIDC, Alias: _otherIdpAlias), - }.ToAsyncEnumerable()); + // Act + async Task Act() => await sut.CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol.SAML, IdentityProviderTypeId.OWN, display).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("displayName length must be 2-30 characters"); + } + + [Fact] + public async Task CreateOwnCompanyIdentityProviderAsync_WithInvalidCharacterInDisplayName_ThrowsControllerArgumentException() + { + // Arrange + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + + // Act + async Task Act() => await sut.CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol.SAML, IdentityProviderTypeId.OWN, "$invalid-character").ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("allowed characters in displayName: 'a-zA-Z0-9!?@&#'\"()_-=/*.,;: '"); + } + + [Fact] + public async Task CreateOwnCompanyIdentityProviderAsync_WithInvalidCompany_ThrowsControllerArgumentException() + { + // Arrange + var companyId = Guid.NewGuid(); + SetupCreateOwnCompanyIdentityProvider(); + A.CallTo(() => _identityService.IdentityData).Returns(_identity with { CompanyId = companyId }); + + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + + // Act + async Task Act() => await sut.CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol.SAML, IdentityProviderTypeId.OWN, null).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"company {companyId} does not exist (Parameter 'companyId')"); + ex.ParamName.Should().Be("companyId"); + } + + [Fact] + public async Task CreateOwnCompanyIdentityProviderAsync_WithNotAllowedCompanyForManaged_ThrowsForbiddenException() + { + // Arrange + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + + SetupCreateOwnCompanyIdentityProvider(); + A.CallTo(() => _identityService.IdentityData).Returns(_identity with { CompanyId = _invalidCompanyId }); + + // Act + async Task Act() => await sut.CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol.SAML, IdentityProviderTypeId.MANAGED, null).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("Not allowed to create an identityProvider of type MANAGED"); + A.CallTo(() => _companyRepository.CheckCompanyAndCompanyRolesAsync(_invalidCompanyId, A>.That.IsSameSequenceAs(new[] { CompanyRoleId.OPERATOR, CompanyRoleId.ONBOARDING_SERVICE_PROVIDER }))).MustHaveHappenedOnceExactly(); + } + + [Theory] + [InlineData(IamIdentityProviderProtocol.SAML, IdentityProviderTypeId.OWN, new CompanyRoleId[] { })] + [InlineData(IamIdentityProviderProtocol.OIDC, IdentityProviderTypeId.OWN, new CompanyRoleId[] { })] + [InlineData(IamIdentityProviderProtocol.SAML, IdentityProviderTypeId.MANAGED, new[] { CompanyRoleId.OPERATOR, CompanyRoleId.ONBOARDING_SERVICE_PROVIDER })] + [InlineData(IamIdentityProviderProtocol.OIDC, IdentityProviderTypeId.MANAGED, new[] { CompanyRoleId.OPERATOR, CompanyRoleId.ONBOARDING_SERVICE_PROVIDER })] + public async Task CreateOwnCompanyIdentityProviderAsync_WithValidData_ExecutesExpected(IamIdentityProviderProtocol protocol, IdentityProviderTypeId typeId, IEnumerable companyRoleIds) + { + // Arrange + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + + var idpName = _fixture.Create(); + + var idps = new List(); + var companyIdps = new List(); + var iamIdps = new List(); + SetupCreateOwnCompanyIdentityProvider(protocol, idps, companyIdps, iamIdps); + A.CallTo(() => _provisioningManager.CreateOwnIdpAsync(A._, A._, A._)) + .Returns(idpName); + + var expectedProtocol = protocol switch + { + IamIdentityProviderProtocol.OIDC => IdentityProviderCategoryId.KEYCLOAK_OIDC, + IamIdentityProviderProtocol.SAML => IdentityProviderCategoryId.KEYCLOAK_SAML, + _ => throw new NotImplementedException() + }; + var expectedOwner = typeId switch + { + IdentityProviderTypeId.OWN => (Guid?)null, + IdentityProviderTypeId.MANAGED => _companyId, + _ => throw new NotImplementedException() + }; + + // Act + var result = await sut.CreateOwnCompanyIdentityProviderAsync(protocol, typeId, "test-company").ConfigureAwait(false); + + // Assert + A.CallTo(() => _companyRepository.CheckCompanyAndCompanyRolesAsync(_companyId, A>.That.IsSameSequenceAs(companyRoleIds))).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.CreateOwnIdpAsync("test-company", "test", protocol)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); + + idps.Should().ContainSingle().Which.Should().Match(x => + x.Id == _identityProviderId && + x.OwnerId == expectedOwner && + x.IdentityProviderCategoryId == expectedProtocol && + x.IdentityProviderTypeId == typeId); + + switch (typeId) + { + case IdentityProviderTypeId.OWN: + companyIdps.Should().ContainSingle().Which.Should().Match(x => + x.CompanyId == _companyId && + x.IdentityProviderId == _identityProviderId); + break; + case IdentityProviderTypeId.MANAGED: + companyIdps.Should().BeEmpty(); + break; + default: throw new NotImplementedException(); + } + + iamIdps.Should().ContainSingle().Which.Should().Match(x => + x.IdentityProviderId == _identityProviderId && + x.IamIdpAlias == idpName); + + result.Should().Match(x => + x.mappers.Count() == 3 && + x.enabled == true && + x.redirectUrl == "https://redirect.com/*" && + protocol == IamIdentityProviderProtocol.OIDC + ? x.displayName == "test-oidc" && + x.saml == null && + x.oidc != null && + x.oidc.clientAuthMethod == IamIdentityProviderClientAuthMethod.SECRET_JWT && + x.oidc.signatureAlgorithm == IamIdentityProviderSignatureAlgorithm.RS512 + : x.displayName == "test-saml" && + x.oidc == null && + x.saml != null && + x.saml.singleSignOnServiceUrl == "https://sso.com"); + } + + #endregion + + #region DeleteCompanyIdentityProviderAsync + + [Fact] + public async Task DeleteCompanyIdentityProviderAsync_WithNotExistingProvider_ThrowsNotFoundException() + { + // Arrange + var invalidId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + + // Act + async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(invalidId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {invalidId} does not exist"); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(invalidId, _companyId, true)).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task DeleteCompanyIdentityProviderAsync_WithInvalidCompany_ThrowsConflictException() + { + // Arrange + var idpId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((false, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(idpId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {idpId} is not associated with company {_companyId}"); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(idpId, _companyId, true)).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task DeleteCompanyIdentityProviderAsync_WithManagedIdp_ThrowsConflictException() + { + // Arrange + var idpId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.MANAGED, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(idpId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"IdentityProviders of type MANAGED can not be deleted"); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(idpId, _companyId, true)).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task DeleteCompanyIdentityProviderAsync_WithDisabledIdp_ThrowsControllerArgumentException() + { + // Arrange + var idpId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + 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); + + // Act + async Task Act() => await sut.DeleteCompanyIdentityProviderAsync(idpId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"cannot delete identityProvider {idpId} as it is enabled"); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(idpId, _companyId, true)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task DeleteCompanyIdentityProviderAsync_WithSharedKeycloakValid_CallsExpected() + { + // Arrange + var idpId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, new[] { (_companyId, new[] { "other-alias" }.AsEnumerable()) })); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")) + .Returns(false); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")) + .Returns(true); + + // Act + await sut.DeleteCompanyIdentityProviderAsync(idpId).ConfigureAwait(false); + + // Assert + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(idpId, _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(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _portalRepositories.Remove(A._)).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task DeleteCompanyIdentityProviderAsync_WithValid_CallsExpected() + { + // Arrange + var idpId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "test", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "other-alias" }.AsEnumerable()) })); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("test")) + .Returns(false); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("other-alias")) + .Returns(true); + + // Act + await sut.DeleteCompanyIdentityProviderAsync(idpId).ConfigureAwait(false); + + // Assert + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(idpId, _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(); + } + + #endregion + + #region GetOwnCompanyIdentityProvidersAsync + + [Fact] + public async Task GetOwnCompanyIdentityProvidersAsync_WithValidId_ReturnsExpected() + { + // Arrange + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + var oidcGuid = Guid.NewGuid(); + var samlGuid = Guid.NewGuid(); + var oidc = new ValueTuple(oidcGuid, IdentityProviderCategoryId.KEYCLOAK_OIDC, "oidc-alias", IdentityProviderTypeId.OWN); + var saml = new ValueTuple(samlGuid, IdentityProviderCategoryId.KEYCLOAK_SAML, "saml-alias", IdentityProviderTypeId.OWN); + A.CallTo(() => _identityProviderRepository.GetCompanyIdentityProviderCategoryDataUntracked(A._)) + .Returns(new[] { oidc, saml }.ToAsyncEnumerable()); + A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync("oidc-alias")) + .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-oidc").Create()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("oidc-alias")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataSAMLAsync("saml-alias")) + .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-saml").Create()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("saml-alias")) + .Returns(_fixture.CreateMany(2).ToAsyncEnumerable()); + + // Act + var result = await sut.GetOwnCompanyIdentityProvidersAsync().ToListAsync().ConfigureAwait(false); + + // Assert + A.CallTo(() => _identityProviderRepository.GetCompanyIdentityProviderCategoryDataUntracked(_companyId)).MustHaveHappenedOnceExactly(); + result.Should().HaveCount(2).And.Satisfy( + x => x.displayName == "dis-oidc" && x.mappers.Count() == 3, + x => x.displayName == "dis-saml" && x.mappers.Count() == 2 + ); + } + + #endregion + + #region GetOwnCompanyIdentityProviderAsync + + [Fact] + public async Task GetOwnCompanyIdentityProviderAsync_WithDifferentCompany_ThrowsConflictException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) + .Returns((string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, false, IdentityProviderTypeId.OWN)); + + // Act + async Task Act() => await sut.GetOwnCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} is not associated with company {_companyId}"); + } + + [Fact] + public async Task GetOwnCompanyIdentityProviderAsync_WithAliasNull_ThrowsNotFoundException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) + .Returns(new ValueTuple(null, IdentityProviderCategoryId.KEYCLOAK_OIDC, true, IdentityProviderTypeId.OWN)); + + // Act + async Task Act() => await sut.GetOwnCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} does not exist"); + } + + [Fact] + public async Task GetOwnCompanyIdentityProviderAsync_WithValidOidc_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) + .Returns(new ValueTuple("cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, true, IdentityProviderTypeId.OWN)); + 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")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + // Act + var result = await sut.GetOwnCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); + + // Assert + result.mappers.Should().HaveCount(3); + result.displayName.Should().Be("dis-oidc"); + result.enabled.Should().BeTrue(); + } + + [Fact] + public async Task GetOwnCompanyIdentityProviderAsync_WithValidSaml_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, _companyId)) + .Returns(new ValueTuple("saml-alias", IdentityProviderCategoryId.KEYCLOAK_SAML, true, IdentityProviderTypeId.OWN)); + A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataSAMLAsync("saml-alias")) + .Returns(_fixture.Build().With(x => x.Enabled, true).With(x => x.DisplayName, "dis-saml").Create()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("saml-alias")) + .Returns(_fixture.CreateMany(2).ToAsyncEnumerable()); + + // Act + var result = await sut.GetOwnCompanyIdentityProviderAsync(identityProviderId).ConfigureAwait(false); + + // Assert + result.mappers.Should().HaveCount(2); + result.displayName.Should().Be("dis-saml"); + result.enabled.Should().BeTrue(); + } + + #endregion + + #region SetOwnCompanyIdentityProviderStatusAsync + + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithDifferentCompany_ThrowsNotFoundExecption() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + + // Act + async Task Act() => await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); + ex.Message.Should().Be($"identityProvider {identityProviderId} does not exist"); + } + + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithDifferentCompany_ThrowsConflictException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((false, string.Empty, IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); + ex.Message.Should().Be($"identityProvider {identityProviderId} is not associated with company {_companyId}"); + } + + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithNoOtherEnabledIdp_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).Returns(false); + + // Act + async Task Act() => await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).MustHaveHappenedOnceExactly(); + ex.Message.Should().Be($"cannot disable indentityProvider {identityProviderId} as no other active identityProvider exists for this company"); + } + + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithNoOtherCompany_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + 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")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + // Act + var result = await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.SetCentralIdentityProviderStatusAsync("cl1", false)).MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(3); + result.displayName.Should().Be("dis-oidc"); + result.enabled.Should().BeTrue(); + } + + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidOidc_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + 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()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + // Act + var result = await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, _companyId, true)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.IsCentralIdentityProviderEnabled("alt-cl1")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.SetCentralIdentityProviderStatusAsync("cl1", false)).MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(3); + result.displayName.Should().Be("dis-oidc"); + result.enabled.Should().BeTrue(); + } + + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidSaml_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + 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()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) + .Returns(_fixture.CreateMany(2).ToAsyncEnumerable()); + + // Act + var result = await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.SetCentralIdentityProviderStatusAsync("cl1", false)).MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(2); + result.displayName.Should().Be("dis-saml"); + result.enabled.Should().BeTrue(); + } - A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(A._)).ReturnsLazily((IdentityProviderCategoryId categoryId) => - new IdentityProvider(_sharedIdentityProviderId, categoryId, _fixture.Create())); + [Fact] + public async Task SetOwnCompanyIdentityProviderStatusAsync_WithValidShared_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, new[] { (_companyId, new[] { "alt-cl1" }.AsEnumerable()) })); + 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()); + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers("cl1")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + // Act + var result = await sut.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, false).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.SetSharedIdentityProviderStatusAsync("cl1", false)) + .MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(3); + result.displayName.Should().Be("dis-oidc"); + result.enabled.Should().BeTrue(); + } + + #endregion + + #region UpdateOwnCompanyIdentityProviderAsync + + [Theory] + [InlineData("a", "displayName length must be 2-30 characters")] + [InlineData("way-too-long-display-name-throws-an-error-should-be-long-enough", "displayName length must be 2-30 characters")] + [InlineData("$invalid-character", "allowed characters in displayName: 'a-zA-Z0-9!?@&#'\"()_-=/*.,;: '")] + public async Task UpdateOwnCompanyIdentityProviderAsync_WithInvalidDisplayName_ThrowsControllerArgumentException(string displayName, string errorMessage) + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.displayName, displayName) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be(errorMessage); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_WithNotExistingIdp_ThrowsNotFoundException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns(((bool, string?, IdentityProviderCategoryId, IdentityProviderTypeId, IEnumerable<(Guid, IEnumerable)>?))default); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} does not exist"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_NotOwner_ThrowsForbiddenException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((false, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"User not allowed to run the change for identity provider {identityProviderId}"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_ForOidcWithOidcNull_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, (IdentityProviderEditableDetailsOidc?)null) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("property 'oidc' must not be null (Parameter 'oidc')"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_ForOidcWithSamlNotNull_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, _fixture.Create()) + .With(x => x.saml, _fixture.Create()) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("property 'saml' must be null (Parameter 'saml')"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_WithValidOidc_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, _fixture.Build().With(x => x.secret, "test").Create()) + .With(x => x.saml, (IdentityProviderEditableDetailsSaml?)null) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + 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")) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + // Act + var result = await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.UpdateCentralIdentityProviderDataOIDCAsync(A.That.Matches(x => x.Secret == "test" && x.Alias == "cl1"))) + .MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(3); + result.displayName.Should().Be("dis-oidc"); + result.enabled.Should().BeTrue(); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_ForSamlWithSamlNull_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.saml, (IdentityProviderEditableDetailsSaml?)null) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("property 'saml' must not be null (Parameter 'saml')"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_ForSamlWithOidcNotNull_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, _fixture.Create()) + .With(x => x.saml, _fixture.Create()) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("property 'oidc' must be null (Parameter 'oidc')"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_WithValidSaml_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, (IdentityProviderEditableDetailsOidc?)null) + .With(x => x.saml, _fixture.Build().With(x => x.singleSignOnServiceUrl, "https://sso.com").Create()) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_SAML, IdentityProviderTypeId.OWN, Enumerable.Empty<(Guid, IEnumerable)>())); + 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")) + .Returns(_fixture.CreateMany(2).ToAsyncEnumerable()); + + // Act + var result = await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.UpdateCentralIdentityProviderDataSAMLAsync(A.That.Matches(x => x.singleSignOnServiceUrl == "https://sso.com" && x.alias == "cl1"))) + .MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(2); + result.displayName.Should().Be("dis-saml"); + result.enabled.Should().BeTrue(); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_ForSharedWithOidcNotNull_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, _fixture.Create()) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("property 'oidc' must be null (Parameter 'oidc')"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_ForSharedWithSamlNotNull_ThrowsControllerArgumentException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.oidc, (IdentityProviderEditableDetailsOidc?)null) + .With(x => x.saml, _fixture.Create()) + .With(x => x.displayName, "new-display-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>())); + + // Act + async Task Act() => await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("property 'saml' must be null (Parameter 'saml')"); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProviderAsync_WithValidShared_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.displayName, "dis-shared") + .With(x => x.oidc, (IdentityProviderEditableDetailsOidc?)null) + .With(x => x.saml, (IdentityProviderEditableDetailsSaml?)null) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(A._, A._, A._)) + .Returns((true, "cl1", IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, Enumerable.Empty<(Guid, IEnumerable)>())); + 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")) + .Returns(_fixture.CreateMany(2).ToAsyncEnumerable()); + + // Act + var result = await sut.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, data).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.UpdateSharedIdentityProviderAsync("cl1", "dis-shared")) + .MustHaveHappenedOnceExactly(); + result.mappers.Should().HaveCount(2); + result.displayName.Should().Be("dis-shared"); + result.enabled.Should().BeTrue(); + } + + #endregion + + #region CreateOwnCompanyUserIdentityProviderLinkDataAsync + + [Fact] + public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserId_ThrowsNotFoundException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.identityProviderId, identityProviderId) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple()); + + // Act + async Task Act() => await sut.CreateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"companyUserId {companyUserId} does not exist"); + } + + [Fact] + public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserId_ThrowsUnexpectedConditionException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.identityProviderId, identityProviderId) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(null, "cl1", false)); + + // Act + async Task Act() => await sut.CreateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"companyUserId {companyUserId} is not linked to keycloak"); + } + + [Fact] + public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutAlias_ThrowsNotFoundException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var userEntityId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.identityProviderId, identityProviderId) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), null, false)); + + // Act + async Task Act() => await sut.CreateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} not found in company of user {companyUserId}"); + } + + [Fact] + public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutSameCompany_ThrowsForbiddenException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var userEntityId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.identityProviderId, identityProviderId) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", false)); + + // Act + async Task Act() => await sut.CreateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} is not associated with company {companyId}"); + } + + [Fact] + public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithKeycloakFailing_ThrowsForbiddenException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var userEntityId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.identityProviderId, identityProviderId) + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + A.CallTo(() => _provisioningManager.AddProviderUserLinkToCentralUserAsync(userEntityId.ToString(), A._)) + .Throws(new KeycloakEntityConflictException("test")); + + // Act + async Task Act() => await sut.CreateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProviderLink for identityProvider {identityProviderId} already exists for user {companyUserId}"); + } + + [Fact] + public async Task CreateOwnCompanyUserIdentityProviderLinkDataAsync_WithValid_CallsExpected() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var userEntityId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.identityProviderId, identityProviderId) + .With(x => x.userName, "test-user") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + + // Act + var result = await sut.CreateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, data, companyId).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.AddProviderUserLinkToCentralUserAsync(userEntityId.ToString(), A._)) + .MustHaveHappenedOnceExactly(); + result.userName.Should().Be("test-user"); + } + + #endregion + + #region CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync + + [Fact] + public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserId_ThrowsNotFoundException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.userName, "user-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple()); + + // Act + async Task Act() => await sut.CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"companyUserId {companyUserId} does not exist"); + } + + [Fact] + public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserId_ThrowsUnexpectedConditionException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.userName, "user-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(null, "cl1", false)); + + // Act + async Task Act() => await sut.CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"companyUserId {companyUserId} is not linked to keycloak"); + } + + [Fact] + public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutAlias_ThrowsNotFoundException() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.userName, "user-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), null, false)); + + // Act + async Task Act() => await sut.CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} not found in company of user {companyUserId}"); + } + + [Fact] + public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_WithoutSameCompany_ThrowsForbiddenException() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.userName, "user-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", false)); + + // Act + async Task Act() => await sut.CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, data, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} is not associated with company {companyId}"); + } + + [Fact] + public async Task CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync_WithValid_CallsExpected() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var data = _fixture.Build() + .With(x => x.userName, "user-name") + .Create(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + + // Act + var result = await sut.CreateOrUpdateOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, data, companyId).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.DeleteProviderUserLinkToCentralUserAsync(userEntityId.ToString(), "cl1")) + .MustHaveHappenedOnceExactly(); + A.CallTo(() => _provisioningManager.AddProviderUserLinkToCentralUserAsync(userEntityId.ToString(), A._)) + .MustHaveHappenedOnceExactly(); + result.userName.Should().Be("user-name"); + } + + #endregion + + #region GetOwnCompanyUserIdentityProviderLinkDataAsync + + [Fact] + public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserId_ThrowsNotFoundException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple()); + + // Act + async Task Act() => await sut.GetOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"companyUserId {companyUserId} does not exist"); + } + + [Fact] + public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutIamUserId_ThrowsUnexpectedConditionException() + { + // Arrange + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(null, "cl1", false)); + + // Act + async Task Act() => await sut.GetOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"companyUserId {companyUserId} is not linked to keycloak"); + } + + [Fact] + public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutAlias_ThrowsNotFoundException() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), null, false)); + + // Act + async Task Act() => await sut.GetOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} not found in company of user {companyUserId}"); + } + + [Fact] + public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutSameCompany_ThrowsForbiddenException() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", false)); + + // Act + async Task Act() => await sut.GetOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProvider {identityProviderId} is not associated with company {companyId}"); + } + + [Fact] + public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithoutExistingCompanyUser_ThrowsNotFound() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + A.CallTo(() => _provisioningManager.GetProviderUserLinkDataForCentralUserIdAsync(userEntityId.ToString())) + .Returns(Enumerable.Empty().ToAsyncEnumerable()); + + // Act + async Task Act() => await sut.GetOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProviderLink for identityProvider {identityProviderId} not found in keycloak for user {companyUserId}"); + } + + [Fact] + public async Task GetOwnCompanyUserIdentityProviderLinkDataAsync_WithValid_CallsExpected() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + A.CallTo(() => _provisioningManager.GetProviderUserLinkDataForCentralUserIdAsync(userEntityId.ToString())) + .Returns(Enumerable.Repeat(new IdentityProviderLink("cl1", userEntityId.ToString(), "user-name"), 1).ToAsyncEnumerable()); + + // Act + var result = await sut.GetOwnCompanyUserIdentityProviderLinkDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + result.userName.Should().Be("user-name"); + } + + #endregion + + #region DeleteOwnCompanyUserIdentityProviderDataAsync + + [Fact] + public async Task DeleteOwnCompanyUserIdentityProviderDataAsync_WithKeycloakError_ThrowsNotFound() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + A.CallTo(() => _provisioningManager.DeleteProviderUserLinkToCentralUserAsync(userEntityId.ToString(), "cl1")) + .Throws(new KeycloakEntityNotFoundException("just a test")); + + // Act + async Task Act() => await sut.DeleteOwnCompanyUserIdentityProviderDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"identityProviderLink for identityProvider {identityProviderId} not found in keycloak for user {companyUserId}"); + } + + [Fact] + public async Task DeleteOwnCompanyUserIdentityProviderDataAsync_WithValid_CallsExpected() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + + // Act + await sut.DeleteOwnCompanyUserIdentityProviderDataAsync(companyUserId, identityProviderId, companyId).ConfigureAwait(false); + + // Assert + A.CallTo(() => _provisioningManager.DeleteProviderUserLinkToCentralUserAsync(userEntityId.ToString(), "cl1")) + .MustHaveHappenedOnceExactly(); + } + + #endregion + + #region GetOwnCompanyUsersIdentityProviderDataAsync + + [Fact] + public async Task GetOwnCompanyUsersIdentityProviderDataAsync_WithoutIdentityProviderIds_ThrowsControllerArgumentException() + { + // Arrange + var userEntityId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var companyUserId = Guid.NewGuid(); + var companyId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetIamUserIsOwnCompanyIdentityProviderAliasAsync(companyUserId, identityProviderId, companyId)) + .Returns(new ValueTuple(userEntityId.ToString(), "cl1", true)); + + // Act + async Task Act() => await sut.GetOwnCompanyUsersIdentityProviderDataAsync(Enumerable.Empty(), companyId, false).ToListAsync().ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be("at least one identityProviderId must be specified (Parameter 'identityProviderIds')"); + } + + [Fact] + public async Task GetOwnCompanyUsersIdentityProviderDataAsync_WithoutMatchingIdps_ThrowsControllerArgumentException() + { + // Arrange + var companyId = Guid.NewGuid(); + var identityProviderId = Guid.NewGuid(); + var sut = new IdentityProviderBusinessLogic( + _portalRepositories, + _provisioningManager, + _identityService, + _options); + A.CallTo(() => _identityProviderRepository.GetOwnCompanyIdentityProviderAliasDataUntracked(companyId, A>._)) + .Returns(Enumerable.Empty>().ToAsyncEnumerable()); + + // Act + async Task Act() => await sut.GetOwnCompanyUsersIdentityProviderDataAsync(Enumerable.Repeat(identityProviderId, 1), companyId, false).ToListAsync().ConfigureAwait(false); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"invalid identityProviders: [{identityProviderId}] for company {companyId} (Parameter 'identityProviderIds')"); + } + + #endregion + + #region Setup + + private void SetupCreateOwnCompanyIdentityProvider(IamIdentityProviderProtocol protocol = IamIdentityProviderProtocol.OIDC, ICollection? idps = null, ICollection? companyIdps = null, ICollection? iamIdps = null) + { + A.CallTo(() => _companyRepository.CheckCompanyAndCompanyRolesAsync(_identity.CompanyId, A>._)) + .Returns(new ValueTuple(true, "test", true)); + A.CallTo(() => _companyRepository.CheckCompanyAndCompanyRolesAsync(_invalidCompanyId, A>._)) + .Returns(new ValueTuple(true, "test", false)); + A.CallTo(() => _companyRepository.CheckCompanyAndCompanyRolesAsync(A.That.Not.Matches(x => x == _identity.CompanyId || x == _invalidCompanyId), A>._)) + .Returns(new ValueTuple()); + + if (idps != null) + { + A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(A._, A._, A?>._)) + .ReturnsLazily((IdentityProviderCategoryId identityProviderCategory, IdentityProviderTypeId identityProviderTypeId, Action? setOptionalFields) => + { + var idp = new IdentityProvider(_identityProviderId, identityProviderCategory, identityProviderTypeId, DateTimeOffset.UtcNow); + setOptionalFields?.Invoke(idp); + idps.Add(idp); + return idp; + }); + } + + if (companyIdps != null) + { + A.CallTo(() => _identityProviderRepository.CreateCompanyIdentityProvider(A._, A._)) + .ReturnsLazily((Guid companyId, Guid identityProviderId) => + { + var companyIdp = new CompanyIdentityProvider(companyId, identityProviderId); + companyIdps.Add(companyIdp); + return companyIdp; + }); + } + + if (iamIdps != null) + { + A.CallTo(() => _identityProviderRepository.CreateIamIdentityProvider(A._, A._)) + .ReturnsLazily((Guid identityProviderId, string idpAlias) => + { + var iamIdp = new IamIdentityProvider(idpAlias, identityProviderId); + iamIdps.Add(iamIdp); + return iamIdp; + }); + } + + switch (protocol) + { + case IamIdentityProviderProtocol.OIDC: + A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataOIDCAsync(A._)) + .Returns(new IdentityProviderConfigOidc("test-oidc", "https://redirect.com/*", "cl1-oidc", true, "https://auth.com", IamIdentityProviderClientAuthMethod.SECRET_JWT, IamIdentityProviderSignatureAlgorithm.RS512)); + break; + case IamIdentityProviderProtocol.SAML: + A.CallTo(() => _provisioningManager.GetCentralIdentityProviderDataSAMLAsync(A._)) + .Returns(new IdentityProviderConfigSaml("test-saml", "https://redirect.com/*", "cl1-saml", true, Guid.NewGuid().ToString(), "https://sso.com")); + break; + default: throw new NotImplementedException(); + } + + A.CallTo(() => _provisioningManager.GetIdentityProviderMappers(A._)) + .Returns(_fixture.CreateMany(3).ToAsyncEnumerable()); + + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_identityProviderRepository); + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_companyRepository); + } + + private void SetupFakes(IEnumerable userData, IEnumerable lines) + { + A.CallTo(() => _options.Value).Returns(new IdentityProviderSettings { CsvSettings = _csvSettings }); + + A.CallTo(() => _document.ContentType).Returns(_options.Value.CsvSettings.ContentType); + A.CallTo(() => _document.OpenReadStream()).ReturnsLazily(() => new AsyncEnumerableStringStream(lines.ToAsyncEnumerable(), _encoding)); + + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_userRepository); + A.CallTo(() => _portalRepositories.GetInstance()).Returns(_identityProviderRepository); + + A.CallTo(() => _userRepository.GetUserEntityDataAsync(A._, A._)).ReturnsLazily((Guid companyUserId, Guid _) => + userData.Where(d => d.CompanyUserId == companyUserId) + .Select(d => + ( + UserEntityId: d.UserEntityId, + FirstName: d.FirstName, + LastName: d.LastName, + Email: d.Email + )).FirstOrDefault()); + + A.CallTo(() => _identityProviderRepository.GetCompanyIdentityProviderCategoryDataUntracked(A.That.Not.IsEqualTo(_companyId))).Returns( + Enumerable.Empty<(Guid IdentityProviderId, IdentityProviderCategoryId CategoryId, string Alias, IdentityProviderTypeId TypeId)>().ToAsyncEnumerable()); + A.CallTo(() => _identityProviderRepository.GetCompanyIdentityProviderCategoryDataUntracked(A.That.IsEqualTo(_companyId))).Returns( + new[] { + (IdentityProviderId: _sharedIdentityProviderId, CategoryId: IdentityProviderCategoryId.KEYCLOAK_OIDC, Alias: _sharedIdpAlias, IdentityProviderTypeId.SHARED), + (IdentityProviderId: _otherIdentityProviderId, CategoryId: IdentityProviderCategoryId.KEYCLOAK_OIDC, Alias: _otherIdpAlias, IdentityProviderTypeId.OWN), + }.ToAsyncEnumerable()); + + A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(A._, A._, A?>._)) + .ReturnsLazily((IdentityProviderCategoryId categoryId, IdentityProviderTypeId typeId, Action? setOptionalFields) => + { + var idp = new IdentityProvider(_sharedIdentityProviderId, categoryId, typeId, _fixture.Create()); + setOptionalFields?.Invoke(idp); + return idp; + }); A.CallTo(() => _provisioningManager.GetProviderUserLinkDataForCentralUserIdAsync(A._)).ReturnsLazily((string userEntityId) => { diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs index 81346e3e6b..80b3c59ae6 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/InvitationBusinessLogicTests.cs @@ -109,9 +109,9 @@ public async Task TestExecuteInvitationSuccess() A.CallTo(() => _provisioningManager.SetupSharedIdpAsync(A.That.IsEqualTo(_idpName), A.That.IsEqualTo(invitationData.organisationName), A._)).MustHaveHappened(); A.CallTo(() => _companyRepository.CreateCompany(A.That.IsEqualTo(invitationData.organisationName))).MustHaveHappened(); - A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(A.That.IsEqualTo(IdentityProviderCategoryId.KEYCLOAK_SHARED))).MustHaveHappened(); - A.CallTo(() => _identityProviderRepository.CreateIamIdentityProvider(A.That.Matches(i => i.Companies.Single().Id == _companyId), A.That.IsEqualTo(_idpName))).MustHaveHappened(); - A.CallTo(() => _applicationRepository.CreateCompanyApplication(A.That.IsEqualTo(_companyId), A.That.IsEqualTo(CompanyApplicationStatusId.CREATED))).MustHaveHappened(); + A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(IdentityProviderCategoryId.KEYCLOAK_OIDC, IdentityProviderTypeId.SHARED, A>._)).MustHaveHappened(); + A.CallTo(() => _identityProviderRepository.CreateIamIdentityProvider(A._, A.That.IsEqualTo(_idpName))).MustHaveHappened(); + A.CallTo(() => _applicationRepository.CreateCompanyApplication(_companyId, CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.INTERNAL)).MustHaveHappened(); A.CallTo(() => _userProvisioningService.CreateOwnCompanyIdpUsersAsync( A.That.Matches(d => d.CompanyId == _companyId), @@ -271,11 +271,16 @@ private void SetupFakes() A.CallTo(() => _companyRepository.CreateCompany(A._)).ReturnsLazily((string organisationName) => new Company(_companyId, organisationName, CompanyStatusId.PENDING, _fixture.Create())); - A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(A._)).ReturnsLazily((IdentityProviderCategoryId categoryId) => - new IdentityProvider(_identityProviderId, categoryId, _fixture.Create())); + A.CallTo(() => _identityProviderRepository.CreateIdentityProvider(A._, A._, A?>._)) + .ReturnsLazily((IdentityProviderCategoryId categoryId, IdentityProviderTypeId typeId, Action? setOptionalFields) => + { + var idp = new IdentityProvider(_identityProviderId, categoryId, typeId, _fixture.Create()); + setOptionalFields?.Invoke(idp); + return idp; + }); - A.CallTo(() => _applicationRepository.CreateCompanyApplication(A._, A._)).ReturnsLazily((Guid companyId, CompanyApplicationStatusId applicationStatusId) => - new CompanyApplication(_applicationId, companyId, applicationStatusId, _fixture.Create())); + A.CallTo(() => _applicationRepository.CreateCompanyApplication(A._, A._, A._)) + .ReturnsLazily((Guid companyId, CompanyApplicationStatusId applicationStatusId, CompanyApplicationTypeId typeId) => new CompanyApplication(_applicationId, companyId, applicationStatusId, typeId, _fixture.Create())); A.CallTo(() => _provisioningManager.GetNextCentralIdentityProviderNameAsync()).Returns(_idpName); diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index e56810b584..a98440c6b4 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -451,7 +451,7 @@ public async Task DeclineRegistrationVerification_WithDecline_StateAndCommentSet const string comment = "application rejected because of reasons."; 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, DateTimeOffset.UtcNow); + var application = new CompanyApplication(ApplicationId, company.Id, CompanyApplicationStatusId.SUBMITTED, CompanyApplicationTypeId.INTERNAL, DateTimeOffset.UtcNow); SetupForDeclineRegistrationVerification(entry, application, company, checklistStatusId); // Act diff --git a/tests/administration/Administration.Service.Tests/Controllers/IdentityProviderControllerTests.cs b/tests/administration/Administration.Service.Tests/Controllers/IdentityProviderControllerTests.cs new file mode 100644 index 0000000000..b201d1b8f9 --- /dev/null +++ b/tests/administration/Administration.Service.Tests/Controllers/IdentityProviderControllerTests.cs @@ -0,0 +1,69 @@ +/******************************************************************************** + * 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 + * 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 Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic; +using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Controllers; +using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models; + +namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Tests.Controllers; + +public class IdentityProviderControllerTests +{ + private readonly IIdentityProviderBusinessLogic _logic; + private readonly IdentityProviderController _controller; + private readonly Fixture _fixture; + + public IdentityProviderControllerTests() + { + _fixture = new Fixture(); + _logic = A.Fake(); + this._controller = new IdentityProviderController(_logic); + } + + [Fact] + public async Task UpdateOwnCompanyIdentityProvider_WithValidData_ReturnsOk() + { + //Arrange + var id = Guid.NewGuid(); + var data = _fixture.Create(); + A.CallTo(() => _logic.UpdateOwnCompanyIdentityProviderAsync(A._, A._)) + .Returns(data); + + //Act + var result = await this._controller.UpdateOwnCompanyIdentityProvider(id, new IdentityProviderEditableDetails("test")).ConfigureAwait(false); + + //Assert + result.Should().Be(data); + A.CallTo(() => _logic.UpdateOwnCompanyIdentityProviderAsync(id, A.That.Matches(x => x.displayName == "test"))).MustHaveHappenedOnceExactly(); + } + + [Fact] + public async Task DeleteOwnCompanyIdentityProvider_WithValidData_ReturnsOk() + { + //Arrange + var id = Guid.NewGuid(); + + //Act + await this._controller.DeleteOwnCompanyIdentityProvider(id).ConfigureAwait(false); + + //Assert + A.CallTo(() => _logic.DeleteCompanyIdentityProviderAsync(id)).MustHaveHappenedOnceExactly(); + } +} diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/AgreementRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/AgreementRepositoryTests.cs index 36887c8cbb..2ee4947007 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/AgreementRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/AgreementRepositoryTests.cs @@ -118,7 +118,7 @@ public async Task GetActiveServices_ReturnsExpectedAppCount() // Assert results.Should().NotBeNullOrEmpty(); - results.Should().HaveCount(6); + results.Should().HaveCount(7); } #endregion diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRepositoryTests.cs index 1aa873f629..257c8e6d96 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/CompanyRepositoryTests.cs @@ -495,17 +495,19 @@ public async Task GetCompanyRoleAndConsentAgreementDetailsAsync_ReturnsExpected( var activeDescription = "The participant role is covering the data provider, data consumer or app user scenario. As participant you are an active member of the network with enabled services to particiapte as contributer and user."; var serviceDscription = "The Service Provider is able to offer 3rd party services, such as dataspace service offerings to Catena-X Members. Catena-X members can subscribe for those services."; var appDescription = "The App Provider is a company which is providing application software via the CX marketplace. As app provider you can participate and use the developer hub, release and offer applications to the network and manage your applications."; + var onboardingServiceProviderDescription = "The Onboarding service provider is a Catena-X certified role which enables the company to act as onboarding provider inside the network."; var result = await sut.GetCompanyRoleAndConsentAgreementDataAsync(companyId, Constants.DefaultLanguage).ToListAsync().ConfigureAwait(false); result.Should().NotBeNull() - .And.HaveCount(3) + .And.HaveCount(4) .And.Satisfy( x => x.CompanyRoleId == CompanyRoleId.ACTIVE_PARTICIPANT && x.RoleDescription == activeDescription && x.CompanyRolesActive == false && x.Agreements.Count() == 3 && x.Agreements.All(agreement => agreement.ConsentStatus == 0), x => x.CompanyRoleId == CompanyRoleId.APP_PROVIDER && x.RoleDescription == appDescription && x.CompanyRolesActive == false && x.Agreements.Count() == 1 && x.Agreements.All(agreement => agreement.ConsentStatus == 0), x => x.CompanyRoleId == CompanyRoleId.SERVICE_PROVIDER && x.RoleDescription == serviceDscription && x.CompanyRolesActive == true && x.Agreements.Count() == 2 && x.Agreements.Any(agr => agr.AgreementId == new Guid("aa0a0000-7fbc-1f2f-817f-bce0502c1094") && agr.DocumentId == null && agr.AgreementName == "Terms & Conditions - Consultant" && agr.ConsentStatus == ConsentStatusId.ACTIVE) - && x.Agreements.Any(agr => agr.AgreementId == new Guid("aa0a0000-7fbc-1f2f-817f-bce0502c1017") && agr.DocumentId == new Guid("00000000-0000-0000-0000-000000000004") && agr.AgreementName == "Terms & Conditions Service Provider" && agr.ConsentStatus == 0)); + && x.Agreements.Any(agr => agr.AgreementId == new Guid("aa0a0000-7fbc-1f2f-817f-bce0502c1017") && agr.DocumentId == new Guid("00000000-0000-0000-0000-000000000004") && agr.AgreementName == "Terms & Conditions Service Provider" && agr.ConsentStatus == 0), + x => x.CompanyRoleId == CompanyRoleId.ONBOARDING_SERVICE_PROVIDER && x.RoleDescription == onboardingServiceProviderDescription && x.CompanyRolesActive == false && x.Agreements.Count() == 1 && x.Agreements.All(agreement => agreement.ConsentStatus == 0)); } #endregion diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs new file mode 100644 index 0000000000..ebf6ebd725 --- /dev/null +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/IdentityProviderRepositoryTests.cs @@ -0,0 +1,199 @@ +/******************************************************************************** + * 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 + ********************************************************************************/ + +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Tests.Setup; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using Xunit.Extensions.AssemblyFixture; + +namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Tests; + +public class IdentityProviderRepositoryTests : IAssemblyFixture +{ + private readonly TestDbFixture _dbTestDbFixture; + private readonly Guid _companyId = new("ac861325-bc54-4583-bcdc-9e9f2a38ff84"); + + public IdentityProviderRepositoryTests(TestDbFixture testDbFixture) + { + var fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + fixture.Behaviors.OfType().ToList() + .ForEach(b => fixture.Behaviors.Remove(b)); + + fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + _dbTestDbFixture = testDbFixture; + } + + #region CreateCompanyIdentityProvider + + [Fact] + public async Task CreateCompanyIdentityProvider_WithValid_ReturnsExpected() + { + var identityProviderId = new Guid("38f56465-ce26-4f25-9745-1791620dc198"); + var (sut, context) = await CreateSutWithContext().ConfigureAwait(false); + + var result = sut.CreateCompanyIdentityProvider(_companyId, identityProviderId); + + // Assert + var changeTracker = context.ChangeTracker; + var changedEntries = changeTracker.Entries().ToList(); + result.CompanyId.Should().Be(_companyId); + result.IdentityProviderId.Should().Be(identityProviderId); + changeTracker.HasChanges().Should().BeTrue(); + changedEntries.Should().NotBeEmpty(); + changedEntries.Should().HaveCount(1); + changedEntries.Single().Entity.Should().BeOfType(); + var idp = changedEntries.Single().Entity as CompanyIdentityProvider; + idp!.CompanyId.Should().Be(_companyId); + idp.IdentityProviderId.Should().Be(identityProviderId); + } + + #endregion + + #region CreateIamIdentityProvider + + [Fact] + public async Task CreateIamIdentityProvider_WithValid_ReturnsExpected() + { + var identityProviderId = new Guid("38f56465-ce26-4f25-9745-1791620dc198"); + var (sut, context) = await CreateSutWithContext().ConfigureAwait(false); + + var result = sut.CreateIamIdentityProvider(identityProviderId, "idp-999"); + + // Assert + var changeTracker = context.ChangeTracker; + var changedEntries = changeTracker.Entries().ToList(); + result.IamIdpAlias.Should().Be("idp-999"); + result.IdentityProviderId.Should().Be(identityProviderId); + changeTracker.HasChanges().Should().BeTrue(); + changedEntries.Should().NotBeEmpty(); + changedEntries.Should().HaveCount(1); + changedEntries.Single().Entity.Should().BeOfType(); + var idp = changedEntries.Single().Entity as IamIdentityProvider; + idp!.IamIdpAlias.Should().Be("idp-999"); + idp.IdentityProviderId.Should().Be(identityProviderId); + } + + #endregion + + #region GetOwnCompanyIdentityProviderAliasUntrackedAsync + + [Theory] + [InlineData("38f56465-ce26-4f25-9745-1791620dc198", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", "Idp-123", true, IdentityProviderTypeId.MANAGED)] + [InlineData("38f56465-ce26-4f25-9745-1791620dc198", "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", "Idp-123", true, IdentityProviderTypeId.MANAGED)] + [InlineData("38f56465-ce26-4f25-9745-1791620dc199", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", "Test-Alias", false, IdentityProviderTypeId.OWN)] + [InlineData("38f56465-ce26-4f25-9745-1791620dc199", "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", "Test-Alias", true, IdentityProviderTypeId.OWN)] + [InlineData("38f56465-ce26-4f25-9745-1791620dc201", "ac861325-bc54-4583-bcdc-9e9f2a38ff84", "Shared-Alias", true, IdentityProviderTypeId.SHARED)] + public async Task GetOwnCompanyIdentityProviderAliasUntrackedAsync_WithValid_ReturnsExpected(Guid identityProviderId, Guid companyId, string alias, bool isOwnOrOwner, IdentityProviderTypeId typeId) + { + var sut = await CreateSut().ConfigureAwait(false); + + var result = await sut.GetOwnCompanyIdentityProviderAliasUntrackedAsync(identityProviderId, companyId).ConfigureAwait(false); + + // Assert + result.Alias.Should().Be(alias); + result.IsOwnOrOwnerCompany.Should().Be(isOwnOrOwner); + result.TypeId.Should().Be(typeId); + } + + #endregion + + #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 isOwnOrOwner, IEnumerable? companyIds) + { + var sut = await CreateSut().ConfigureAwait(false); + + var result = await sut.GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(identityProviderId, companyId, query).ConfigureAwait(false); + + // Assert + result.Alias.Should().Be(alias); + result.IsOwnOrOwner.Should().Be(isOwnOrOwner); + if (query) + { + companyIds.Should().NotBeNull(); + if (alias == "Test-Alias2") + { + result.CompanyIdAliase.Should().HaveCount(5).And.Satisfy( + x => x.CompanyId == new Guid("41fd2ab8-71cd-4546-9bef-a388d91b2542") && x.Aliase.SequenceEqual(new[] { "Test-Alias2" }), + x => x.CompanyId == new Guid("41fd2ab8-7123-4546-9bef-a388d91b2999") && x.Aliase.SequenceEqual(new[] { "Test-Alias2" }), + x => x.CompanyId == new Guid("3390c2d7-75c1-4169-aa27-6ce00e1f3cdd") && x.Aliase.Order().SequenceEqual(new[] { "Idp-123", "Test-Alias2" }), + x => x.CompanyId == new Guid("0dcd8209-85e2-4073-b130-ac094fb47106") && x.Aliase.Order().SequenceEqual(new[] { "Idp-123", "Test-Alias2" }), + x => x.CompanyId == new Guid("2dc4249f-b5ca-4d42-bef1-7a7a950a4f88") && x.Aliase.Order().SequenceEqual(new[] { "Test-Alias", "Test-Alias2" }) + ); + } + else + { + result.CompanyIdAliase.Should().Match Aliase)>>(cida => cida.Select(x => x.CompanyId).Order().SequenceEqual(companyIds!.Select(i => new Guid(i)).Order()) && + cida.Select(x => x.Aliase).All(a => a.Order().SequenceEqual(new[] { alias, "Test-Alias2" }))); + } + } + else + { + companyIds.Should().BeNull(); + result.CompanyIdAliase.Should().BeNull(); + } + } + + #endregion + + #region GetCompanyIdentityProviderCategoryDataUntracked + + [Fact] + public async Task GetCompanyIdentityProviderCategoryDataUntracked_WithValid_ReturnsExpected() + { + var sut = await CreateSut().ConfigureAwait(false); + + var results = await sut.GetCompanyIdentityProviderCategoryDataUntracked(_companyId).ToListAsync().ConfigureAwait(false); + + // Assert + results.Should().HaveCount(2); + results.Should().Satisfy( + x => x.Alias == "Idp-123" && x.CategoryId == IdentityProviderCategoryId.KEYCLOAK_OIDC && x.TypeId == IdentityProviderTypeId.MANAGED, + x => x.Alias == "Shared-Alias" && x.CategoryId == IdentityProviderCategoryId.KEYCLOAK_OIDC && x.TypeId == IdentityProviderTypeId.SHARED); + } + + #endregion + + #region Setup + + private async Task<(IdentityProviderRepository, PortalDbContext)> CreateSutWithContext() + { + var context = await _dbTestDbFixture.GetPortalDbContext().ConfigureAwait(false); + var sut = new IdentityProviderRepository(context); + return (sut, context); + } + + private async Task CreateSut() + { + var context = await _dbTestDbFixture.GetPortalDbContext().ConfigureAwait(false); + var sut = new IdentityProviderRepository(context); + return sut; + } + + #endregion +} diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalBackend.DBAccess.Tests.csproj b/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalBackend.DBAccess.Tests.csproj index 6df472fb0b..9a48e0b174 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalBackend.DBAccess.Tests.csproj +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalBackend.DBAccess.Tests.csproj @@ -117,7 +117,7 @@ Seeder\Data\ - + Seeder\Data\ @@ -321,5 +321,14 @@ Seeder\Data\ + + Seeder\Data\ + + + Seeder\Data\ + + + Seeder\Data\ + diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalDbContextTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalDbContextTests.cs index 21fa53dc44..4020506e60 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalDbContextTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/PortalDbContextTests.cs @@ -64,7 +64,7 @@ public async Task SaveChangedAuditableEntity_SetsLastEditorId() // Assert ca.LastEditorId.Should().NotBeNull().And.Be(new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); ca.DateLastChanged.Should().Be(now); - var auditEntries = await sut.AuditCompanyApplication20230214.Where(x => x.Id == ca.Id).ToListAsync(); + var auditEntries = await sut.AuditCompanyApplication20230824.Where(x => x.Id == ca.Id).ToListAsync(); auditEntries.Should().HaveCount(2).And.Satisfy( x => x.ApplicationStatusId == CompanyApplicationStatusId.CONFIRMED && x.AuditV1OperationId == AuditOperationId.INSERT, x => x.ApplicationStatusId == CompanyApplicationStatusId.SELECT_COMPANY_ROLE && x.AuditV1OperationId == AuditOperationId.UPDATE && x.LastEditorId == new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); @@ -80,7 +80,7 @@ public async Task SaveCreatedAuditableEntity_SetsLastEditorId() var before = now.AddDays(-1); var id = Guid.NewGuid(); - var ca = new CompanyApplication(id, new Guid("ac861325-bc54-4583-bcdc-9e9f2a38ff84"), CompanyApplicationStatusId.CREATED, before); + var ca = new CompanyApplication(id, new Guid("ac861325-bc54-4583-bcdc-9e9f2a38ff84"), CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.INTERNAL, before); var sut = await CreateContext().ConfigureAwait(false); using var trans = await sut.Database.BeginTransactionAsync().ConfigureAwait(false); @@ -92,9 +92,9 @@ public async Task SaveCreatedAuditableEntity_SetsLastEditorId() // Assert ca.LastEditorId.Should().NotBeNull().And.Be(new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); ca.DateLastChanged.Should().Be(now); - var auditEntries = await sut.AuditCompanyApplication20230214.Where(x => x.Id == id).ToListAsync(); - auditEntries.Should().ContainSingle().Which.Should().Match( - x => x.ApplicationStatusId == CompanyApplicationStatusId.CREATED && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV1OperationId == AuditOperationId.INSERT && x.LastEditorId == new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); + var auditEntries = await sut.AuditCompanyApplication20230824.Where(x => x.Id == id).ToListAsync(); + auditEntries.Should().ContainSingle().Which.Should().Match( + x => x.ApplicationStatusId == CompanyApplicationStatusId.CREATED && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV1OperationId == AuditOperationId.INSERT && (x.AuditV1DateLastChanged - now) < TimeSpan.FromSeconds(1) && x.LastEditorId == new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); await trans.RollbackAsync().ConfigureAwait(false); } @@ -108,7 +108,7 @@ public async Task SaveDeletedAuditableEntity_SetsLastEditorId() var before = now.AddDays(-1); var id = Guid.NewGuid(); - var ca = new CompanyApplication(id, new Guid("ac861325-bc54-4583-bcdc-9e9f2a38ff84"), CompanyApplicationStatusId.CREATED, before); + var ca = new CompanyApplication(id, new Guid("ac861325-bc54-4583-bcdc-9e9f2a38ff84"), CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.INTERNAL, before); var sut = await CreateContext().ConfigureAwait(false); using var trans = await sut.Database.BeginTransactionAsync().ConfigureAwait(false); @@ -122,7 +122,7 @@ public async Task SaveDeletedAuditableEntity_SetsLastEditorId() // Assert ca.LastEditorId.Should().NotBeNull().And.Be(new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); ca.DateLastChanged.Should().Be(later); - var auditEntries = await sut.AuditCompanyApplication20230214.Where(x => x.Id == id).ToListAsync(); + var auditEntries = await sut.AuditCompanyApplication20230824.Where(x => x.Id == id).ToListAsync(); auditEntries.Should().HaveCount(2).And.Satisfy( x => x.ApplicationStatusId == CompanyApplicationStatusId.CREATED && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV1OperationId == AuditOperationId.INSERT && x.LastEditorId == new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001"), x => x.ApplicationStatusId == CompanyApplicationStatusId.CREATED && (x.DateCreated - before) < TimeSpan.FromSeconds(1) && x.AuditV1OperationId == AuditOperationId.DELETE && (x.AuditV1DateLastChanged - later) < TimeSpan.FromSeconds(1) && x.LastEditorId == new Guid("ac1cf001-7fbc-1f2f-817f-bce058020001")); diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_applications.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_applications.test.json index 67d479dd75..fd0440e260 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_applications.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_applications.test.json @@ -6,6 +6,7 @@ "application_status_id": 8, "company_id": "ac861325-bc54-4583-bcdc-9e9f2a38ff84", "checklist_process_id": "dd371565-9489-4907-a2e4-b8cbfe7a8cd2", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -15,6 +16,7 @@ "application_status_id": 7, "company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", "checklist_process_id": "1f9a3232-9772-4ecb-8f50-c16e97772dfe", + "company_application_type_id": 1, "last_editor_id": null }, { @@ -24,6 +26,7 @@ "application_status_id": 7, "company_id": "41fd2ab8-71cd-4546-9bef-a388d91b2542", "checklist_process_id": "34215ee3-f99f-45e7-8c4e-747a089cf0b1", + "company_application_type_id": 1, "last_editor_id": null } ] \ No newline at end of file diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_identity_providers.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_identity_providers.test.json new file mode 100644 index 0000000000..c280156b3a --- /dev/null +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_identity_providers.test.json @@ -0,0 +1,38 @@ +[ + { + "company_id": "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc198" + }, + { + "company_id": "3390c2d7-75c1-4169-aa27-6ce00e1f3cdd", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc200" + }, + { + "company_id": "0dcd8209-85e2-4073-b130-ac094fb47106", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc198" + }, + { + "company_id": "0dcd8209-85e2-4073-b130-ac094fb47106", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc200" + }, + { + "company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc199" + }, + { + "company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f88", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc200" + }, + { + "company_id": "41fd2ab8-71cd-4546-9bef-a388d91b2542", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc200" + }, + { + "company_id": "41fd2ab8-7123-4546-9bef-a388d91b2999", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc200" + }, + { + "company_id": "ac861325-bc54-4583-bcdc-9e9f2a38ff84", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc201" + } +] \ No newline at end of file diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/iam_identity_providers.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/iam_identity_providers.test.json new file mode 100644 index 0000000000..e1a43853be --- /dev/null +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/iam_identity_providers.test.json @@ -0,0 +1,18 @@ +[ + { + "iam_idp_alias": "Idp-123", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc198" + }, + { + "iam_idp_alias": "Test-Alias", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc199" + }, + { + "iam_idp_alias": "Test-Alias2", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc200" + }, + { + "iam_idp_alias": "Shared-Alias", + "identity_provider_id": "38f56465-ce26-4f25-9745-1791620dc201" + } +] \ No newline at end of file diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_providers.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_providers.test.json new file mode 100644 index 0000000000..3f32d6e4d5 --- /dev/null +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_providers.test.json @@ -0,0 +1,30 @@ +[ + { + "id": "38f56465-ce26-4f25-9745-1791620dc198", + "identity_provider_category_id": 2, + "identity_provider_type_id": 2, + "owner_id": "ac861325-bc54-4583-bcdc-9e9f2a38ff84", + "date_created": "2022-05-05 00:00:00.000000 +00:00" + }, + { + "id": "38f56465-ce26-4f25-9745-1791620dc199", + "identity_provider_category_id": 2, + "identity_provider_type_id": 1, + "owner_id": null, + "date_created": "2022-05-05 00:00:00.000000 +00:00" + }, + { + "id": "38f56465-ce26-4f25-9745-1791620dc200", + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": null, + "date_created": "2022-05-05 00:00:00.000000 +00:00" + }, + { + "id": "38f56465-ce26-4f25-9745-1791620dc201", + "identity_provider_category_id": 2, + "identity_provider_type_id": 3, + "owner_id": null, + "date_created": "2022-05-05 00:00:00.000000 +00:00" + } +] \ No newline at end of file diff --git a/tests/provisioning/Provisioning.Library.Tests/UserProvisioningServiceAuxiliaryMethodsTests.cs b/tests/provisioning/Provisioning.Library.Tests/UserProvisioningServiceAuxiliaryMethodsTests.cs index 2b21119633..26b1e6296d 100644 --- a/tests/provisioning/Provisioning.Library.Tests/UserProvisioningServiceAuxiliaryMethodsTests.cs +++ b/tests/provisioning/Provisioning.Library.Tests/UserProvisioningServiceAuxiliaryMethodsTests.cs @@ -57,7 +57,7 @@ public UserProvisioningServiceAuxiliaryMethodsTests() A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliasUntrackedAsync(A._, A._)).Returns( _resultComposer.Create()); - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)).Returns( + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)).Returns( _sharedIdpComposer.With(x => x.IdpAliase, new[] { _fixture.Create() }).Create()); } @@ -175,7 +175,7 @@ public async void TestGetCompanyNameSharedIdpwithNullCompanyNameAndEmailAliasDat ); - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)) + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)) .Returns(data); // Act @@ -192,7 +192,7 @@ public async void TestGetCompanyNameSharedIdpAliasDataNotFound() { ((Guid, string?, string?), (Guid, string?, string?, string?), IEnumerable) notfound = default; - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)) + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)) .Returns(notfound); var sut = new UserProvisioningService(null!, _portalRepositories); @@ -208,7 +208,7 @@ public async void TestGetCompanyNameSharedIdpAliasDataForApplicationIdNotFound() { ((Guid, string?, string?), (Guid, string?, string?, string?), IEnumerable) notfound = default; - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)) + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)) .Returns(notfound); var applicationId = _fixture.Create(); @@ -224,7 +224,7 @@ public async void TestGetCompanyNameSharedIdpAliasDataForApplicationIdNotFound() [Fact] public async void TestGetCompanyNameSharedIdpAliasDataNoIdpAliasThrows() { - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)) + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)) .Returns(_sharedIdpComposer.With(x => x.IdpAliase, Enumerable.Empty()).Create()); var sut = new UserProvisioningService(null!, _portalRepositories); @@ -238,7 +238,7 @@ public async void TestGetCompanyNameSharedIdpAliasDataNoIdpAliasThrows() [Fact] public async void TestGetCompanyNameSharedIdpAliasDataMultipleIdpAliaseThrows() { - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)) + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)) .Returns(_sharedIdpComposer.With(x => x.IdpAliase, _fixture.CreateMany(2)).Create()); var sut = new UserProvisioningService(null!, _portalRepositories); @@ -254,7 +254,7 @@ public async void TestGetCompanyNameSharedIdpAliasDataCompanyNameNullThrows() { var companyId = _fixture.Create(); - A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._)) + A.CallTo(() => _identityProviderRepository.GetCompanyNameIdpAliaseUntrackedAsync(A._, A._, A._, A._)) .Returns(_sharedIdpComposer .With(x => x.Company, _fixture.Build<(Guid CompanyId, string? CompanyName, string? BusinessPartnerNumber)>() diff --git a/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index 2edafae99c..4e4aea51f6 100644 --- a/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -1581,7 +1581,7 @@ public async Task SubmitRoleConsentsAsync_WithValidData_CallsExpected() A.CallTo(() => _applicationRepository.AttachAndModifyCompanyApplication(A._, A>._)) .Invokes((Guid companyApplicationId, Action setOptionalParameters) => { - var companyApplication = new CompanyApplication(companyApplicationId, Guid.Empty, default!, default!); + var companyApplication = new CompanyApplication(companyApplicationId, Guid.Empty, default!, default!, default!); setOptionalParameters.Invoke(companyApplication); }); A.CallTo(() => _companyRolesRepository.RemoveCompanyAssignedRoles(_identity.CompanyId, A>._)) @@ -1696,7 +1696,7 @@ public async Task SubmitRegistrationAsync_WithDocumentId_Success() A.CallTo(() => _applicationRepository.AttachAndModifyCompanyApplication(A._, A>._)) .Invokes((Guid applicationId, Action setOptionalParameters) => { - application = new CompanyApplication(applicationId, Guid.Empty, default, default); + application = new CompanyApplication(applicationId, Guid.Empty, default, default, default); setOptionalParameters(application); });