Skip to content

Commit

Permalink
feat: relocate endpoint and adjust permission for osp management (#1037)
Browse files Browse the repository at this point in the history
* relocate endpoint api/administration/registration/network/companies to api/administration/network/companies
* adjust permisssion from 'view_submitted_applications' to 'configure_partner_registration'
Refs: #994
  • Loading branch information
Phil91 authored Oct 1, 2024
1 parent 2922d43 commit ba5abce
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 255 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
********************************************************************************/

using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;

namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;
Expand All @@ -26,4 +27,5 @@ public interface INetworkBusinessLogic
{
Task HandlePartnerRegistration(PartnerRegistrationData data);
Task RetriggerProcessStep(string externalId, ProcessStepTypeId processStepTypeId);
Task<Pagination.Response<CompanyDetailsOspOnboarding>> GetOspCompanyDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter, string? companyName, string? externalId, DateCreatedOrderFilter? dateCreatedOrderFilter);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public interface IRegistrationBusinessLogic
{
Task<CompanyWithAddressData> GetCompanyWithAddressAsync(Guid applicationId);
Task<Pagination.Response<CompanyApplicationDetails>> GetCompanyApplicationDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter, string? companyName);
Task<Pagination.Response<CompanyDetailsOspOnboarding>> GetOspCompanyDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter, string? companyName, string? externalId, DateCreatedOrderFilter? dateCreatedOrderFilter);
Task<Pagination.Response<CompanyApplicationWithCompanyUserDetails>> GetAllCompanyApplicationsDetailsAsync(int page, int size, string? companyName);
Task UpdateCompanyBpn(Guid applicationId, string bpn);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.DependencyInjection;
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Extensions;
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq;
Expand Down Expand Up @@ -296,4 +298,45 @@ private static void ValidateUsers(UserDetailData user)
throw new ControllerArgumentException("Lastname does not match expected format");
}
}

public Task<Pagination.Response<CompanyDetailsOspOnboarding>> GetOspCompanyDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter, string? companyName, string? externalId, DateCreatedOrderFilter? dateCreatedOrderFilter)
{
if (companyName != null && !companyName.IsValidCompanyName())
{
throw ControllerArgumentException.Create(ValidationExpressionErrors.INCORRECT_COMPANY_NAME, [new ErrorParameter("name", "CompanyName")]);
}

var applicationsQuery = portalRepositories.GetInstance<IApplicationRepository>()
.GetExternalCompanyApplicationsFilteredQuery(_identityData.CompanyId,
companyName?.Length >= 3 ? companyName : null, externalId,
companyApplicationStatusFilter.GetCompanyApplicationStatusIds());

var orderedQuery = dateCreatedOrderFilter == null || dateCreatedOrderFilter.Value == DateCreatedOrderFilter.DESC
? applicationsQuery.AsSplitQuery().OrderByDescending(application => application.DateCreated)
: applicationsQuery.AsSplitQuery().OrderBy(application => application.DateCreated);

return Pagination.CreateResponseAsync(
page,
size,
_settings.ApplicationsMaxPageSize,
(skip, take) => new Pagination.AsyncSource<CompanyDetailsOspOnboarding>(
applicationsQuery.CountAsync(),
orderedQuery
.Skip(skip)
.Take(take)
.Select(application => new CompanyDetailsOspOnboarding(
application.CompanyId,
application.NetworkRegistration!.ExternalId,
application.Id,
application.ApplicationStatusId,
application.DateCreated,
application.Company!.DateCreated,
application.DateLastChanged,
application.Company!.Name,
application.Company.CompanyAssignedRoles.Select(companyAssignedRoles => companyAssignedRoles.CompanyRoleId),
application.Company.IdentityProviders.Select(x => new IdentityProvidersDetails(x.Id, x.IamIdentityProvider!.IamIdpAlias)),
application.Company.BusinessPartnerNumber,
application.Company.Identities.Count(x => x.CompanyUser!.Identity!.UserStatusId != UserStatusId.DELETED)))
.AsAsyncEnumerable()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,11 @@ public sealed class RegistrationBusinessLogic(
IIssuerComponentBusinessLogic issuerComponentBusinessLogic,
IProvisioningManager provisioningManager,
IMailingProcessCreation mailingProcessCreation,
IIdentityService identityService,
ILogger<RegistrationBusinessLogic> logger)
: IRegistrationBusinessLogic
{
private static readonly Regex BpnRegex = new(ValidationExpressions.Bpn, RegexOptions.Compiled, TimeSpan.FromSeconds(1));

private readonly IIdentityData _identityData = identityService.IdentityData;
private readonly RegistrationSettings _settings = configuration.Value;

public Task<CompanyWithAddressData> GetCompanyWithAddressAsync(Guid applicationId)
Expand Down Expand Up @@ -162,45 +160,6 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu
.AsAsyncEnumerable()));
}

public Task<Pagination.Response<CompanyDetailsOspOnboarding>> GetOspCompanyDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter, string? companyName, string? externalId, DateCreatedOrderFilter? dateCreatedOrderFilter)
{
if (companyName != null && !companyName.IsValidCompanyName())
{
throw ControllerArgumentException.Create(ValidationExpressionErrors.INCORRECT_COMPANY_NAME, [new ErrorParameter("name", "CompanyName")]);
}
var applicationsQuery = portalRepositories.GetInstance<IApplicationRepository>()
.GetExternalCompanyApplicationsFilteredQuery(_identityData.CompanyId,
companyName?.Length >= 3 ? companyName : null, externalId,
companyApplicationStatusFilter.GetCompanyApplicationStatusIds());

var orderedQuery = dateCreatedOrderFilter == null || dateCreatedOrderFilter.Value == DateCreatedOrderFilter.DESC
? applicationsQuery.AsSplitQuery().OrderByDescending(application => application.DateCreated)
: applicationsQuery.AsSplitQuery().OrderBy(application => application.DateCreated);

return Pagination.CreateResponseAsync(
page,
size,
_settings.ApplicationsMaxPageSize,
(skip, take) => new Pagination.AsyncSource<CompanyDetailsOspOnboarding>(
applicationsQuery.CountAsync(),
orderedQuery
.Skip(skip)
.Take(take)
.Select(application => new CompanyDetailsOspOnboarding(
application.CompanyId,
application.NetworkRegistration!.ExternalId,
application.Id,
application.ApplicationStatusId,
application.DateCreated,
application.Company!.DateCreated,
application.DateLastChanged,
application.Company!.Name,
application.Company.CompanyAssignedRoles.Select(companyAssignedRoles => companyAssignedRoles.CompanyRoleId),
application.Company.IdentityProviders.Select(x => new IdentityProvidersDetails(x.Id, x.IamIdentityProvider!.IamIdpAlias)),
application.Company.BusinessPartnerNumber,
application.Company.Identities.Count(x => x.CompanyUser!.Identity!.UserStatusId != UserStatusId.DELETED)))
.AsAsyncEnumerable()));
}
public Task<Pagination.Response<CompanyApplicationWithCompanyUserDetails>> GetAllCompanyApplicationsDetailsAsync(int page, int size, string? companyName)
{
if (companyName != null && !companyName.IsValidCompanyName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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.Web;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Models;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Web;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.Web.Identity;
Expand All @@ -32,33 +33,23 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Controllers
[EnvironmentRoute("MVC_ROUTING_BASEPATH", "registration/[controller]")]
[Produces("application/json")]
[Consumes("application/json")]
public class NetworkController : ControllerBase
public class NetworkController(INetworkBusinessLogic logic)
: ControllerBase
{
private readonly INetworkBusinessLogic _logic;

/// <summary>
/// Creates a new instance of <see cref="NetworkController"/>
/// </summary>
/// <param name="logic">The business logic for the registration</param>
public NetworkController(INetworkBusinessLogic logic)
{
_logic = logic;
}

/// <summary>
/// Registers a partner company
/// </summary>
/// <param name="data">Data for the registration</param>
/// Example: POST: api/administration/registration/network/{externalId}/retrigger-synchronize-users
/// Example: POST: api/administration/registration/network/{externalId}/partnerRegistration
/// <response code="200">Empty response on success.</response>
[HttpPost]
[Authorize(Policy = PolicyTypes.ValidCompany)]
[Authorize(Roles = "create_partner_registration")]
[Authorize(Roles = "configure_partner_registration")]
[Route("partnerRegistration")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<OkResult> PartnerRegister([FromBody] PartnerRegistrationData data)
{
await _logic.HandlePartnerRegistration(data).ConfigureAwait(ConfigureAwaitOptions.None);
await logic.HandlePartnerRegistration(data).ConfigureAwait(ConfigureAwaitOptions.None);
return Ok();
}

Expand All @@ -79,7 +70,7 @@ public async Task<OkResult> PartnerRegister([FromBody] PartnerRegistrationData d
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerSynchronizeUser([FromRoute] string externalId)
{
await _logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_SYNCHRONIZE_USER).ConfigureAwait(ConfigureAwaitOptions.None);
await logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_SYNCHRONIZE_USER).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

Expand All @@ -100,7 +91,7 @@ public async Task<NoContentResult> RetriggerSynchronizeUser([FromRoute] string e
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerCallbackOspApprove([FromRoute] string externalId)
{
await _logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_APPROVED).ConfigureAwait(ConfigureAwaitOptions.None);
await logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_APPROVED).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

Expand All @@ -121,7 +112,7 @@ public async Task<NoContentResult> RetriggerCallbackOspApprove([FromRoute] strin
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerCallbackOspDecline([FromRoute] string externalId)
{
await _logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_DECLINED).ConfigureAwait(ConfigureAwaitOptions.None);
await logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_DECLINED).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

Expand All @@ -142,7 +133,7 @@ public async Task<NoContentResult> RetriggerCallbackOspDecline([FromRoute] strin
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerCallbackOspSubmitted([FromRoute] string externalId)
{
await _logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_SUBMITTED).ConfigureAwait(ConfigureAwaitOptions.None);
await logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_CALLBACK_OSP_SUBMITTED).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

Expand All @@ -163,7 +154,30 @@ public async Task<NoContentResult> RetriggerCallbackOspSubmitted([FromRoute] str
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerRemoveKeycloakUser([FromRoute] string externalId)
{
await _logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_REMOVE_KEYCLOAK_USERS).ConfigureAwait(ConfigureAwaitOptions.None);
await logic.RetriggerProcessStep(externalId, ProcessStepTypeId.RETRIGGER_REMOVE_KEYCLOAK_USERS).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

/// <summary>
/// Get OSP Company Application Detail by Company Name or Status
/// </summary>
/// <param name="page">page index start from 0</param>
/// <param name="size">size to get number of records</param>
/// <param name="companyApplicationStatusFilter">Search by company applicationstatus</param>
/// <param name="companyName">search by company name</param>
/// <param name="externalId">search by external Id</param>
/// <param name="dateCreatedOrderFilter">sort result by dateCreated ascending or descending</param>
/// <returns>OSp Company Application Details</returns>
/// <remarks>
/// Example: GET: api/administration/registration/network/companies?companyName=Car&amp;page=0&amp;size=4&amp;companyApplicationStatus=Closed <br />
/// Example: GET: api/administration/registration/network/companies?page=0&amp;size=4
/// </remarks>
/// <response code="200">Result as a OSP Company Application Details</response>
[HttpGet]
[Authorize(Roles = "configure_partner_registration")]
[Authorize(Policy = PolicyTypes.ValidCompany)]
[Route("companies")]
[ProducesResponseType(typeof(Pagination.Response<CompanyDetailsOspOnboarding>), StatusCodes.Status200OK)]
public Task<Pagination.Response<CompanyDetailsOspOnboarding>> GetOspCompanyDetailsAsync([FromQuery] int page, [FromQuery] int size, [FromQuery] CompanyApplicationStatusFilter? companyApplicationStatusFilter = null, [FromQuery] string? companyName = null, [FromQuery] string? externalId = null, [FromQuery] DateCreatedOrderFilter? dateCreatedOrderFilter = null) =>
logic.GetOspCompanyDetailsAsync(page, size, companyApplicationStatusFilter, companyName, externalId, dateCreatedOrderFilter);
}
Loading

0 comments on commit ba5abce

Please sign in to comment.