Skip to content

Commit

Permalink
build(2.2.0-rc2): merge release into main eclipse-tractusx#936
Browse files Browse the repository at this point in the history
Reviewed-By: Evelyn Gurschler <evelyn.gurschler@bmw.de>
  • Loading branch information
Phil91 authored Aug 14, 2024
2 parents 4c39a2f + bcb8125 commit c37d62e
Show file tree
Hide file tree
Showing 24 changed files with 336 additions and 63 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

New features, fixed bugs, known defects and other noteworthy changes to each release of the Catena-X Portal Backend.

## 2.2.0-RC2

### Change

* **Network Registration (Administration Service)**
* enhanced endpoint `GET /api/administration/registration/network/companies` with additional fields and filter possibilities [#916](https://github.com/eclipse-tractusx/portal-backend/pull/916)

### Bugfixes

* **Application Activation**
* adjusted the set of the theme only for shared idps [#852](https://github.com/eclipse-tractusx/portal-backend/pull/852)
* **App Roles**
* added a duplication check for roles before adding them [#877](https://github.com/eclipse-tractusx/portal-backend/pull/877)
* **BPDM**
* adjusted the structure of the bpdm request for the `input/business-partners` request [#928](https://github.com/eclipse-tractusx/portal-backend/pull/928)

## 2.2.0-RC1

### Change
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
<Project>
<PropertyGroup>
<VersionPrefix>2.2.0</VersionPrefix>
<VersionSuffix>RC1</VersionSuffix>
<VersionSuffix>RC2</VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ 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);
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 @@ -161,33 +161,37 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu
.AsAsyncEnumerable()));
}

public Task<Pagination.Response<CompanyDetailsOspOnboarding>> GetOspCompanyDetailsAsync(int page, int size, CompanyApplicationStatusFilter? companyApplicationStatusFilter, string? companyName)
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("name", "CompanyName")]);
}
var applications = portalRepositories.GetInstance<IApplicationRepository>()
var applicationsQuery = portalRepositories.GetInstance<IApplicationRepository>()
.GetExternalCompanyApplicationsFilteredQuery(_identityData.CompanyId,
companyName?.Length >= 3 ? companyName : null,
companyName?.Length >= 3 ? companyName : null, externalId,
GetCompanyApplicationStatusIds(companyApplicationStatusFilter));

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>(
applications.CountAsync(),
applications
.AsSplitQuery()
.OrderByDescending(application => application.DateCreated)
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),
Expand All @@ -210,7 +214,7 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu
_settings.ApplicationsMaxPageSize,
(skip, take) => new Pagination.AsyncSource<CompanyApplicationWithCompanyUserDetails>(
applications.CountAsync(),
applications.OrderByDescending(application => application.DateCreated)
applications.OrderByDescending(application => application.Company!.DateCreated)
.Skip(skip)
.Take(take)
.Select(application => new
Expand Down Expand Up @@ -394,7 +398,7 @@ public Task TriggerChecklistAsync(Guid applicationId, ApplicationChecklistEntryT
throw new ControllerArgumentException($"The processStep {processStepTypeId} is not retriggerable");
}

var nextStepData = processStepTypeId.GetNextProcessStepDataForManualTriggerProcessStepId(_settings.ClearinghouseConnectDisabled);
var nextStepData = processStepTypeId.GetNextProcessStepDataForManualTriggerProcessStepId();
if (nextStepData == default)
{
throw new UnexpectedConditionException($"While the processStep {processStepTypeId} is configured to be retriggerable there is no next step configured");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ public class RegistrationSettings
public string HelpAddress { get; set; } = null!;

public bool UseDimWallet { get; set; }

/// <summary>
/// If <c>true</c> all sd factory calls are disabled and won't be called. The respective process steps will be skipped.
/// </summary>
public bool ClearinghouseConnectDisabled { get; set; }
}

public static class RegistrationSettingsExtension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private async Task<IEnumerable<UserRoleWithId>> ModifyUserRolesInternal(
var distinctRoles = roles.Where(role => !string.IsNullOrWhiteSpace(role)).Distinct().ToImmutableList();
var existingRoles = await getUserRoleModificationData(companyUserId, distinctRoles, offerId).ToListAsync().ConfigureAwait(false);
existingRoles.DuplicatesBy(x => x.CompanyUserRoleText).IfAny(
duplicateRoles => throw new ConflictException($"roles {string.Join(",", $"{duplicateRoles.Select(role => $"[{role.CompanyUserRoleText}, {role.CompanyUserRoleId}]")}")} are ambigous"));
duplicateRoles => throw new ConflictException($"roles {string.Join(",", duplicateRoles.Select(role => $"[{role.CompanyUserRoleText}, {role.CompanyUserRoleId}]"))} are ambigous"));

distinctRoles.Except(existingRoles.Where(r => r.IsAssignable).Select(r => r.CompanyUserRoleText)).IfAny(
nonExistingRoles => throw new ControllerArgumentException($"Invalid roles {string.Join(",", nonExistingRoles)}", nameof(roles)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ public async Task<NoContentResult> RetriggerDeleteCentralUser([FromRoute] Guid p
/// <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 />
Expand All @@ -579,6 +581,7 @@ public async Task<NoContentResult> RetriggerDeleteCentralUser([FromRoute] Guid p
[Authorize(Policy = PolicyTypes.ValidCompany)]
[Route("network/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) =>
_logic.GetOspCompanyDetailsAsync(page, size, companyApplicationStatusFilter, companyName);
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);
}

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

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

/// <summary>
/// Filter operations for the CompanyApplicationStatus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
public record CompanyDetailsOspOnboarding(

[property: JsonPropertyName("companyId")] Guid CompanyId,
[property: JsonPropertyName("externalId")] string? ExternalId,
[property: JsonPropertyName("applicationId")] Guid ApplicationId,
[property: JsonPropertyName("applicationStatus")] CompanyApplicationStatusId CompanyApplicationStatusId,
[property: JsonPropertyName("applicationDateCreated")] DateTimeOffset DateCreated,
[property: JsonPropertyName("applicationDateCreated")] DateTimeOffset ApplicationDateCreated,
[property: JsonPropertyName("dateCreated")] DateTimeOffset DateCreated,
[property: JsonPropertyName("lastChangedDate")] DateTimeOffset? DateLastChanged,
[property: JsonPropertyName("companyName")] string CompanyName,
[property: JsonPropertyName("companyRoles")] IEnumerable<CompanyRoleId> CompanyRoles,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/********************************************************************************
* Copyright (c) 2022 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.Administration.Service.Models;

public enum DateCreatedOrderFilter
{
ASC,
DESC
}
3 changes: 1 addition & 2 deletions src/administration/Administration.Service/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@
"Registration": {
"ApplicationsMaxPageSize": 20,
"DocumentTypeIds": [],
"UseDimWallet": false,
"ClearinghouseConnectDisabled": false
"UseDimWallet": false
},
"UserManagement": {
"ApplicationsMaxPageSize": 20,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,5 @@ public record BpdmLegalEntityData(
BpdmLegalEntity LegalEntity,
BpdmSite? Site,
BpdmAddress Address,
bool OwnCompanyData
bool IsOwnCompanyData
);
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,19 @@ private async Task<IEnumerable<AppRoleData>> InsertActiveAppUserRoleAsync(Guid a
{
throw new ForbiddenException($"Company {_identityData.CompanyId} is not the provider company of app {appId}");
}
var roleData = await AppExtensions.CreateUserRolesWithDescriptions(_portalRepositories.GetInstance<IUserRolesRepository>(), appId, userRoles);

// When user will try to upload the same role names which are already attched to an APP.
// so, no role will be added against the given appId so, no need to procced further
// No need to Add roles to client
// No need to update the Offer entity
// When nothing has happened, no need to send notifications
if (!roleData.Any())
return roleData;

var roleData = AppExtensions.CreateUserRolesWithDescriptions(_portalRepositories.GetInstance<IUserRolesRepository>(), appId, userRoles);
foreach (var clientId in result.ClientClientIds)
{
await _provisioningManager.AddRolesToClientAsync(clientId, userRoles.Select(x => x.Role)).ConfigureAwait(ConfigureAwaitOptions.None);
await _provisioningManager.AddRolesToClientAsync(clientId, roleData.Select(x => x.RoleName)).ConfigureAwait(ConfigureAwaitOptions.None);
}

_portalRepositories.GetInstance<IOfferRepository>().AttachAndModifyOffer(appId, offer =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,13 @@ private async Task<IEnumerable<AppRoleData>> InsertAppUserRoleAsync(Guid appId,
{
throw new ForbiddenException($"Company {companyId} is not the provider company of app {appId}");
}
var roleData = AppExtensions.CreateUserRolesWithDescriptions(_portalRepositories.GetInstance<IUserRolesRepository>(), appId, userRoles);
var roleData = await AppExtensions.CreateUserRolesWithDescriptions(_portalRepositories.GetInstance<IUserRolesRepository>(), appId, userRoles);

// When user will try to upload the same role names which are already attched to an APP.
// so, no role will be added against the given appId so, no need to procced further
// No need to update the Offer entity
if (!roleData.Any())
return roleData;

_portalRepositories.GetInstance<IOfferRepository>().AttachAndModifyOffer(appId, offer =>
offer.DateLastChanged = DateTimeOffset.UtcNow);
Expand Down
23 changes: 21 additions & 2 deletions src/marketplace/Apps.Service/Extensions/AppExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

using Org.Eclipse.TractusX.Portal.Backend.Apps.Service.ViewModels;
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;

Expand Down Expand Up @@ -46,6 +47,7 @@ public static void ValidateAppUserRole(Guid appId, IEnumerable<AppUserRole> appU
{
throw new ControllerArgumentException("Language Code must not be empty");
}
appUserRolesDescription.DuplicatesBy(x => x.Role).IfAny(duplicateRoles => throw new ControllerArgumentException($"Roles are ambiguous: {string.Join(",", duplicateRoles.Select(x => x.Role))}"));
}

/// <summary>
Expand All @@ -56,13 +58,30 @@ public static void ValidateAppUserRole(Guid appId, IEnumerable<AppUserRole> appU
/// <param name="appId">id of the app to create the roles for</param>
/// <param name="userRoles">the user roles to add</param>
/// <returns>returns the created appRoleData</returns>
public static IEnumerable<AppRoleData> CreateUserRolesWithDescriptions(IUserRolesRepository userRolesRepository, Guid appId, IEnumerable<AppUserRole> userRoles) =>
userRoles.Zip(
public static async Task<IEnumerable<AppRoleData>> CreateUserRolesWithDescriptions(IUserRolesRepository userRolesRepository, Guid appId, IEnumerable<AppUserRole> userRoles)
{
userRoles = await GetUniqueAppUserRoles(userRolesRepository, appId, userRoles);
return userRoles.Zip(
userRolesRepository.CreateAppUserRoles(userRoles.Select(x => (appId, x.Role))),
(AppUserRole appUserRole, UserRole userRole) =>
{
userRolesRepository.CreateAppUserRoleDescriptions(appUserRole.Descriptions.Select(appUserRoleDescription => (userRole.Id, appUserRoleDescription.LanguageCode, appUserRoleDescription.Description)));
return new AppRoleData(userRole.Id, appUserRole.Role);
})
.ToList();
}

/// <summary>
/// Get unique roles by eleminating the duplicate roles from the request (client) and existing roles from the Database
/// </summary>
/// <remarks></remarks>
/// <param name="userRolesRepository">repository</param>
/// <param name="appId">id of the app</param>
/// <param name="userRoles">the app user roles</param>
/// <returns>returns the filtered and unique roles</returns>
private static async Task<IEnumerable<AppUserRole>> GetUniqueAppUserRoles(IUserRolesRepository userRolesRepository, Guid appId, IEnumerable<AppUserRole> userRoles)
{
var existingRoles = await userRolesRepository.GetUserRolesForOfferIdAsync(appId).ToListAsync().ConfigureAwait(false);
return userRoles.ExceptBy(existingRoles, userRole => userRole.Role);
}
}
Loading

0 comments on commit c37d62e

Please sign in to comment.