Skip to content

Commit

Permalink
fix(registration): delete idp on application decline (#371)
Browse files Browse the repository at this point in the history
* remove both idp-related entities in portal-db and corresponding entries in keycloak:
* shared idps: remove both shared realm and corresponding idp plus companyAssignedIdentityProvider-entry
* own idp: remove idp and companyAssignedIdentityProvider-entry
* managed idp: only remove companyAssignedIdentityProvider-entry
* support deletion of multiple idps
---------
Refs: TEST-1642
Co-authored-by: Norbert Truchsess <[email protected]>
Reviewed-by: Norbert Truchsess <[email protected]>
  • Loading branch information
Phil91 authored Dec 15, 2023
1 parent b9ce922 commit fb5b9a3
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Extensions;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.Processes.ApplicationChecklist.Library;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library;
using Org.Eclipse.TractusX.Portal.Backend.SdFactory.Library.BusinessLogic;
using Org.Eclipse.TractusX.Portal.Backend.SdFactory.Library.Models;
using System.Text.RegularExpressions;
Expand All @@ -49,6 +51,7 @@ public sealed class RegistrationBusinessLogic : IRegistrationBusinessLogic
private readonly IApplicationChecklistService _checklistService;
private readonly IClearinghouseBusinessLogic _clearinghouseBusinessLogic;
private readonly ISdFactoryBusinessLogic _sdFactoryBusinessLogic;
private readonly IProvisioningManager _provisioningManager;
private readonly ILogger<RegistrationBusinessLogic> _logger;

public RegistrationBusinessLogic(
Expand All @@ -58,6 +61,7 @@ public RegistrationBusinessLogic(
IApplicationChecklistService checklistService,
IClearinghouseBusinessLogic clearinghouseBusinessLogic,
ISdFactoryBusinessLogic sdFactoryBusinessLogic,
IProvisioningManager provisioningManager,
ILogger<RegistrationBusinessLogic> logger)
{
_portalRepositories = portalRepositories;
Expand All @@ -66,6 +70,7 @@ public RegistrationBusinessLogic(
_checklistService = checklistService;
_clearinghouseBusinessLogic = clearinghouseBusinessLogic;
_sdFactoryBusinessLogic = sdFactoryBusinessLogic;
_provisioningManager = provisioningManager;
_logger = logger;
}

Expand Down Expand Up @@ -419,7 +424,7 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com
throw new ArgumentException($"CompanyApplication {applicationId} is not in status SUBMITTED", nameof(applicationId));
}

var (companyId, companyName, processId) = result;
var (companyId, companyName, processId, idps, companyUserIds) = result;

var context = await _checklistService
.VerifyChecklistEntryAndProcessSteps(
Expand All @@ -443,6 +448,22 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com
},
null);

var identityProviderRepository = _portalRepositories.GetInstance<IIdentityProviderRepository>();
foreach (var (idpId, idpAlias, idpType) in idps)
{
if (idpType == IdentityProviderTypeId.SHARED)
{
await _provisioningManager.DeleteSharedIdpRealmAsync(idpAlias).ConfigureAwait(false);
}
identityProviderRepository.DeleteCompanyIdentityProvider(companyId, idpId);
if (idpType == IdentityProviderTypeId.OWN || idpType == IdentityProviderTypeId.SHARED)
{
await _provisioningManager.DeleteCentralIdentityProviderAsync(idpAlias).ConfigureAwait(false);
identityProviderRepository.DeleteIamIdentityProvider(idpAlias);
identityProviderRepository.DeleteIdentityProvider(idpId);
}
}

_portalRepositories.GetInstance<IApplicationRepository>().AttachAndModifyCompanyApplication(applicationId, application =>
{
application.ApplicationStatusId = CompanyApplicationStatusId.DECLINED;
Expand All @@ -453,6 +474,16 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com
company.CompanyStatusId = CompanyStatusId.REJECTED;
});

foreach (var userId in companyUserIds)
{
var iamUserId = await _provisioningManager.GetUserByUserName(userId.ToString()).ConfigureAwait(false);
if (iamUserId != null)
{
await _provisioningManager.DeleteCentralRealmUserAsync(iamUserId).ConfigureAwait(false);
}
}
_portalRepositories.GetInstance<IUserRepository>().AttachAndModifyIdentities(companyUserIds.Select(userId => new ValueTuple<Guid, Action<Identity>>(userId, identity => { identity.UserStatusId = UserStatusId.DELETED; })));

if (processId != null)
{
_portalRepositories.GetInstance<IProcessStepRepository>().CreateProcessStepRange(Enumerable.Repeat(new ValueTuple<ProcessStepTypeId, ProcessStepStatusId, Guid>(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_DECLINED, ProcessStepStatusId.TODO, processId.Value), 1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,16 @@ public IAsyncEnumerable<Guid> GetSubmittedApplicationIdsByBpn(string bpn) =>
/// </summary>
/// <param name="applicationId">Id of the application</param>
/// <returns>Returns the company id</returns>
public Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId)> GetCompanyIdNameForSubmittedApplication(Guid applicationId) =>
public Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId, IEnumerable<(Guid IdentityProviderId, string IamAlias, IdentityProviderTypeId TypeId)> Idps, IEnumerable<Guid> CompanyUserIds)> GetCompanyIdNameForSubmittedApplication(Guid applicationId) =>
_dbContext.CompanyApplications
.AsSplitQuery()
.Where(x => x.Id == applicationId && x.ApplicationStatusId == CompanyApplicationStatusId.SUBMITTED)
.Select(x => new ValueTuple<Guid, string, Guid?>(
.Select(x => new ValueTuple<Guid, string, Guid?, IEnumerable<(Guid, string, IdentityProviderTypeId)>, IEnumerable<Guid>>(
x.CompanyId,
x.Company!.Name,
x.Company!.NetworkRegistration!.ProcessId))
x.Company.NetworkRegistration!.ProcessId,
x.Company.IdentityProviders.Select(idp => new ValueTuple<Guid, string, IdentityProviderTypeId>(idp.Id, idp.IamIdentityProvider!.IamIdpAlias, idp.IdentityProviderTypeId)),
x.Company.Identities.Where(i => i.IdentityTypeId == IdentityTypeId.COMPANY_USER && i.UserStatusId != UserStatusId.DELETED).Select(i => i.Id)))
.SingleOrDefaultAsync();

public Task<bool> IsValidApplicationForCompany(Guid applicationId, Guid companyId) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public interface IApplicationRepository
/// </summary>
/// <param name="applicationId">Id of the application</param>
/// <returns>The id of the company for the given application</returns>
Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId)> GetCompanyIdNameForSubmittedApplication(Guid applicationId);
Task<(Guid CompanyId, string CompanyName, Guid? NetworkRegistrationProcessId, IEnumerable<(Guid IdentityProviderId, string IamAlias, IdentityProviderTypeId TypeId)> Idps, IEnumerable<Guid> CompanyUserIds)> GetCompanyIdNameForSubmittedApplication(Guid applicationId);

Task<bool> IsValidApplicationForCompany(Guid applicationId, Guid companyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositorie
public interface IIdentityProviderRepository
{
IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory, IdentityProviderTypeId identityProviderTypeId, Guid owner, Action<IdentityProvider>? setOptionalFields);
void DeleteIdentityProvider(Guid identityProviderId);
IamIdentityProvider CreateIamIdentityProvider(Guid identityProviderId, string idpAlias);
void DeleteIamIdentityProvider(string idpAlias);
CompanyIdentityProvider CreateCompanyIdentityProvider(Guid companyId, Guid identityProviderId);
void DeleteCompanyIdentityProvider(Guid companyId, Guid identityProviderId);
void CreateCompanyIdentityProviders(IEnumerable<(Guid CompanyId, Guid IdentityProviderId)> companyIdIdentityProviderIds);
Task<string?> GetSharedIdentityProviderIamAliasDataUntrackedAsync(Guid companyId);
Task<(string? Alias, bool IsValidUser)> GetIdpCategoryIdByUserIdAsync(Guid companyUserId, Guid userCompanyId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;

namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;

Expand Down Expand Up @@ -123,4 +122,5 @@ public interface IUserRepository
Identity AttachAndModifyIdentity(Guid identityId, Action<Identity>? initialize, Action<Identity> modify);
CompanyUserAssignedIdentityProvider AddCompanyUserAssignedIdentityProvider(Guid companyUserId, Guid identityProviderId, string providerId, string userName);
IAsyncEnumerable<CompanyUserIdentityProviderProcessData> GetUserAssignedIdentityProviderForNetworkRegistration(Guid networkRegistrationId);
void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action<Identity> Modify)> identityData);
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ public IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identi
.Add(idp).Entity;
}

public void DeleteIdentityProvider(Guid identityProviderId) =>
_context.IdentityProviders.Remove(new IdentityProvider(identityProviderId, default, default, Guid.Empty, default));

public CompanyIdentityProvider CreateCompanyIdentityProvider(Guid companyId, Guid identityProviderId) =>
_context.CompanyIdentityProviders
.Add(new CompanyIdentityProvider(
companyId,
identityProviderId
)).Entity;

public void DeleteCompanyIdentityProvider(Guid companyId, Guid identityProviderId) =>
_context.Remove(new CompanyIdentityProvider(companyId, identityProviderId));

public void CreateCompanyIdentityProviders(IEnumerable<(Guid CompanyId, Guid IdentityProviderId)> companyIdIdentityProviderIds) =>
_context.CompanyIdentityProviders
.AddRange(companyIdIdentityProviderIds.Select(x => new CompanyIdentityProvider(
Expand All @@ -74,6 +80,9 @@ public IamIdentityProvider CreateIamIdentityProvider(Guid identityProviderId, st
idpAlias,
identityProviderId)).Entity;

public void DeleteIamIdentityProvider(string idpAlias) =>
_context.IamIdentityProviders.Remove(new IamIdentityProvider(idpAlias, Guid.Empty));

public Task<string?> GetSharedIdentityProviderIamAliasDataUntrackedAsync(Guid companyId) =>
_context.IdentityProviders
.AsNoTracking()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
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 Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Identities;

namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;

Expand Down Expand Up @@ -446,4 +445,16 @@ public IAsyncEnumerable<CompanyUserIdentityProviderProcessData> GetUserAssignedI
cu.CompanyUserAssignedIdentityProviders.Select(assigned => new ProviderLinkData(assigned.UserName, assigned.IdentityProvider!.IamIdentityProvider!.IamIdpAlias, assigned.ProviderId))
))
.ToAsyncEnumerable();

public void AttachAndModifyIdentities(IEnumerable<(Guid IdentityId, Action<Identity> Modify)> identityData)
{
var initial = identityData.Select(x =>
{
var identity = new Identity(x.IdentityId, default, Guid.Empty, default, default);
return (Identity: identity, x.Modify);
}
).ToList();
_dbContext.AttachRange(initial.Select(x => x.Identity));
initial.ForEach(x => x.Modify(x.Identity));
}
}
Loading

0 comments on commit fb5b9a3

Please sign in to comment.