Skip to content

Commit

Permalink
feat(n2n): add database structure for n2n (#243)
Browse files Browse the repository at this point in the history
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 <norbert.truchsess@t-online.de>
Reviewed-By: Norbert Truchsess <norbert.truchsess@t-online.de>
  • Loading branch information
Phil91 authored Sep 7, 2023
1 parent e17f73b commit 10ad44f
Show file tree
Hide file tree
Showing 57 changed files with 10,922 additions and 338 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@
********************************************************************************/

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;

namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;

public interface IIdentityProviderBusinessLogic
{
IAsyncEnumerable<IdentityProviderDetails> GetOwnCompanyIdentityProvidersAsync(Guid companyId);
ValueTask<IdentityProviderDetails> CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol protocol, string? displayName, Guid companyId);
ValueTask<IdentityProviderDetails> GetOwnCompanyIdentityProviderAsync(Guid identityProviderId, Guid companyId);
ValueTask<IdentityProviderDetails> SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled, Guid companyId);
ValueTask<IdentityProviderDetails> UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details, Guid companyId);
ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId, Guid companyId);
IAsyncEnumerable<IdentityProviderDetails> GetOwnCompanyIdentityProvidersAsync();
ValueTask<IdentityProviderDetails> CreateOwnCompanyIdentityProviderAsync(IamIdentityProviderProtocol protocol, IdentityProviderTypeId typeId, string? displayName);
ValueTask<IdentityProviderDetails> GetOwnCompanyIdentityProviderAsync(Guid identityProviderId);
ValueTask<IdentityProviderDetails> SetOwnCompanyIdentityProviderStatusAsync(Guid identityProviderId, bool enabled);
ValueTask<IdentityProviderDetails> UpdateOwnCompanyIdentityProviderAsync(Guid identityProviderId, IdentityProviderEditableDetails details);
ValueTask DeleteCompanyIdentityProviderAsync(Guid identityProviderId);
IAsyncEnumerable<UserIdentityProviderData> GetOwnCompanyUsersIdentityProviderDataAsync(IEnumerable<Guid> identityProviderIds, Guid companyId, bool unlinkedUsersOnly);
(Stream FileStream, string ContentType, string FileName, Encoding Encoding) GetOwnCompanyUsersIdentityProviderLinkDataStream(IEnumerable<Guid> identityProviderIds, Guid companyId, bool unlinkedUsersOnly);
ValueTask<IdentityProviderUpdateStats> UploadOwnCompanyUsersIdentityProviderLinkDataAsync(IFormFile document, Guid companyId, CancellationToken cancellationToken);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ private async Task ExecuteInvitationInternalAsync(CompanyInvitationData invitati
var company = _portalRepositories.GetInstance<ICompanyRepository>().CreateCompany(invitationData.organisationName);

var identityProviderRepository = _portalRepositories.GetInstance<IIdentityProviderRepository>();
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<IApplicationRepository>();
var application = applicationRepository.CreateCompanyApplication(company.Id, CompanyApplicationStatusId.CREATED);
var application = applicationRepository.CreateCompanyApplication(company.Id, CompanyApplicationStatusId.CREATED, CompanyApplicationTypeId.INTERNAL);

await _portalRepositories.SaveAsync().ConfigureAwait(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -63,7 +64,7 @@ public IdentityProviderController(IIdentityProviderBusinessLogic identityProvide
[ProducesResponseType(typeof(List<IdentityProviderDetails>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)]
public ValueTask<List<IdentityProviderDetails>> GetOwnCompanyIdentityProviderDetails() =>
this.WithCompanyId(companyId => _businessLogic.GetOwnCompanyIdentityProvidersAsync(companyId).ToListAsync());
_businessLogic.GetOwnCompanyIdentityProvidersAsync().ToListAsync();

/// <summary>
/// Create an identity provider
Expand All @@ -84,9 +85,9 @@ public ValueTask<List<IdentityProviderDetails>> GetOwnCompanyIdentityProviderDet
[ProducesResponseType(typeof(IdentityProviderDetails), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)]
public async ValueTask<ActionResult<IdentityProviderDetails>> CreateOwnCompanyIdentityProvider([FromQuery] IamIdentityProviderProtocol protocol, [FromQuery] string? displayName = null)
public async ValueTask<ActionResult<IdentityProviderDetails>> 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<IdentityProviderDetails>)CreatedAtRoute(nameof(GetOwnCompanyIdentityProvider), new { identityProviderId = details.identityProviderId }, details);
}

Expand All @@ -111,7 +112,7 @@ public async ValueTask<ActionResult<IdentityProviderDetails>> CreateOwnCompanyId
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)]
public ValueTask<IdentityProviderDetails> GetOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId) =>
this.WithCompanyId(companyId => _businessLogic.GetOwnCompanyIdentityProviderAsync(identityProviderId, companyId));
_businessLogic.GetOwnCompanyIdentityProviderAsync(identityProviderId);

/// <summary>
/// Sets the status of the given Identity Provider
Expand Down Expand Up @@ -139,7 +140,7 @@ public ValueTask<IdentityProviderDetails> GetOwnCompanyIdentityProvider([FromRou
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)]
public ValueTask<IdentityProviderDetails> SetOwnCompanyIdentityProviderStatus([FromRoute] Guid identityProviderId, [FromQuery] bool enabled) =>
this.WithCompanyId(companyId => _businessLogic.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, enabled, companyId));
_businessLogic.SetOwnCompanyIdentityProviderStatusAsync(identityProviderId, enabled);

/// <summary>
/// Updates the details of the identity provider
Expand Down Expand Up @@ -167,7 +168,7 @@ public ValueTask<IdentityProviderDetails> SetOwnCompanyIdentityProviderStatus([F
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status500InternalServerError)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status502BadGateway)]
public ValueTask<IdentityProviderDetails> UpdateOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId, [FromBody] IdentityProviderEditableDetails details) =>
this.WithCompanyId(companyId => _businessLogic.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, details, companyId));
_businessLogic.UpdateOwnCompanyIdentityProviderAsync(identityProviderId, details);

/// <summary>
/// Deletes the identity provider with the given id
Expand All @@ -187,16 +188,16 @@ public ValueTask<IdentityProviderDetails> 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<ActionResult> DeleteOwnCompanyIdentityProvider([FromRoute] Guid identityProviderId)
public async Task<NoContentResult> 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();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<IdentityProviderMapperModel> mappers)
public record IdentityProviderDetails(Guid identityProviderId, string alias, IdentityProviderCategoryId identityProviderCategoryId, IdentityProviderTypeId IdentityProviderTypeId, string displayName, string redirectUrl, bool enabled, IEnumerable<IdentityProviderMapperModel> mappers)
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public IdentityProviderDetailsOidc? oidc { get; init; } = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<CompanyApplication> 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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,14 @@ public IAsyncEnumerable<OperatorBpnData> GetOperatorBpns() =>
x.Name,
x.BusinessPartnerNumber!))
.AsAsyncEnumerable();

public Task<(bool IsValidCompany, string CompanyName, bool IsAllowed)> CheckCompanyAndCompanyRolesAsync(Guid companyId, IEnumerable<CompanyRoleId> companyRoles) =>
_context.Companies
.Where(x => x.Id == companyId)
.Select(x => new ValueTuple<bool, string, bool>(
true,
x.Name,
!companyRoles.Any() || x.CompanyAssignedRoles.Any(role => companyRoles.Contains(role.CompanyRoleId))
))
.SingleOrDefaultAsync();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<CompanyApplication> setOptionalParameters);
Invitation CreateInvitation(Guid applicationId, Guid companyUserId);
void DeleteInvitations(IEnumerable<Guid> invitationIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,6 @@ public interface ICompanyRepository
/// </summary>
/// <returns>Async enumerable of bpns</returns>
IAsyncEnumerable<OperatorBpnData> GetOperatorBpns();

Task<(bool IsValidCompany, string CompanyName, bool IsAllowed)> CheckCompanyAndCompanyRolesAsync(Guid companyId, IEnumerable<CompanyRoleId> companyRoles);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,19 @@ namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositorie
/// </summary>
public interface IIdentityProviderRepository
{
IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory);
IamIdentityProvider CreateIamIdentityProvider(IdentityProvider identityProvider, string idpAlias);
IdentityProvider CreateIdentityProvider(IdentityProviderCategoryId identityProviderCategory, IdentityProviderTypeId identityProviderTypeId, Action<IdentityProvider>? setOptionalFields);
IamIdentityProvider CreateIamIdentityProvider(Guid identityProviderId, string idpAlias);
CompanyIdentityProvider CreateCompanyIdentityProvider(Guid companyId, Guid identityProviderId);
Task<string?> GetSharedIdentityProviderIamAliasDataUntrackedAsync(Guid companyId);
Task<IdpUser?> 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<string> Aliase)> GetOwnCompanyIdentityProviderUpdateDataUntrackedAsync(Guid identityProviderId, Guid companyId);
Task<(bool IsValidCompanyId, int LinkedCompaniesCount, string Alias, IdentityProviderCategoryId IdentityProviderCategory, IEnumerable<string> 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<string> 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<Guid> 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<string> 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<string> 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,
Expand Down
Loading

0 comments on commit 10ad44f

Please sign in to comment.