Skip to content

Commit

Permalink
feat(technicalUser): add internal external flag to profiles
Browse files Browse the repository at this point in the history
Refs: #1007
  • Loading branch information
Phil91 committed Sep 26, 2024
1 parent 0a9b28b commit 1c54198
Show file tree
Hide file tree
Showing 26 changed files with 148 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public async IAsyncEnumerable<UserRoleWithDescription> GetServiceAccountRolesAsy
userRoles,
languageShortName ?? Constants.DefaultLanguage))
{
yield return userRole;
yield return new UserRoleWithDescription(userRole.UserRoleId, userRole.UserRoleText, userRole.RoleDescription, userRole.External ? UserRoleType.External : UserRoleType.Internal);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/********************************************************************************
* 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
********************************************************************************/

using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using System.Text.Json.Serialization;

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

/// <summary>
/// Basic model for user role data needed to display user roles with description.
/// </summary>
public record UserRoleWithDescription(
[property: JsonPropertyName("roleId")] Guid UserRoleId,
[property: JsonPropertyName("roleName")] string UserRoleText,
[property: JsonPropertyName("roleDescription")] string? RoleDescription,
[property: JsonPropertyName("roleType")] UserRoleType RoleType
);
1 change: 1 addition & 0 deletions src/marketplace/Apps.Service/Apps.Service.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..\..</DockerfileContext>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<NoWarn>CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ private static (Guid AppInstanceId, Guid ClientId, string ClientClientId) GetAnd

/// <inheritdoc />
public Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUserProfilesForOffer(Guid offerId) =>
offerService.GetTechnicalUserProfilesForOffer(offerId, OfferTypeId.APP);
offerService.GetTechnicalUserProfilesForOffer(offerId, OfferTypeId.APP, _settings.DimUserRoles);

/// <inheritdoc />
public Task UpdateTechnicalUserProfiles(Guid appId, IEnumerable<TechnicalUserProfileData> data) =>
Expand Down
4 changes: 4 additions & 0 deletions src/marketplace/Apps.Service/BusinessLogic/AppsSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ public class AppsSettings

[Required(AllowEmptyStrings = true)]
public string BpnDidResolverUrl { get; set; } = null!;

[Required]
[DistinctValues("x => x.ClientId")]
public IEnumerable<UserRoleConfig> DimUserRoles { get; set; } = null!;
}

/// <summary>
Expand Down
3 changes: 2 additions & 1 deletion src/marketplace/Apps.Service/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"DeleteDocumentTypeIds": [],
"SubmitAppDocumentTypeIds": [],
"OfferSubscriptionAddress": "",
"OfferDetailAddress": ""
"OfferDetailAddress": "",
"DimUserRoles": []
},
"Provisioning": {
"CentralRealm": "",
Expand Down
3 changes: 2 additions & 1 deletion src/marketplace/Offers.Library/Service/IOfferService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,9 @@ Task CreateOrUpdateOfferSubscriptionAgreementConsentAsync(Guid subscriptionId,
/// </summary>
/// <param name="offerId">Id of the offer</param>
/// <param name="offerTypeId">Id of the offer type</param>
/// <param name="externalUserRoles">The ExternalUserRoles</param>
/// <returns>IEnumerable with the technical user profile information</returns>
Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUserProfilesForOffer(Guid offerId, OfferTypeId offerTypeId);
Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUserProfilesForOffer(Guid offerId, OfferTypeId offerTypeId, IEnumerable<UserRoleConfig> externalUserRoles);

/// <summary>
/// Creates or updates the technical user profiles
Expand Down
17 changes: 14 additions & 3 deletions src/marketplace/Offers.Library/Service/OfferService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -699,11 +699,14 @@ public async Task DeleteDocumentsAsync(Guid documentId, IEnumerable<DocumentType
await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

public async Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUserProfilesForOffer(Guid offerId, OfferTypeId offerTypeId)
public async Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUserProfilesForOffer(Guid offerId, OfferTypeId offerTypeId, IEnumerable<UserRoleConfig> externalUserRoles)
{
var companyId = _identityData.CompanyId;
var userRoles = await portalRepositories.GetInstance<IUserRolesRepository>().GetUserRoleIdsUntrackedAsync(externalUserRoles)
.ToListAsync()
.ConfigureAwait(false);
var result = await portalRepositories.GetInstance<ITechnicalUserProfileRepository>()
.GetTechnicalUserProfileInformation(offerId, companyId, offerTypeId).ConfigureAwait(ConfigureAwaitOptions.None);
.GetTechnicalUserProfileInformation(offerId, companyId, offerTypeId, userRoles).ConfigureAwait(ConfigureAwaitOptions.None);
if (result == default)
{
throw new NotFoundException($"Offer {offerId} does not exist");
Expand All @@ -714,7 +717,15 @@ public async Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUser
throw new ForbiddenException($"Company {companyId} is not the providing company");
}

return result.Information;
return result.Information
.Select(x => new TechnicalUserProfileInformation(
x.TechnicalUserProfileId,
x.UserRoles
.Select(ur => new UserRoleInformation(
ur.UserRoleId,
ur.UserRoleText,
ur.External ? UserRoleType.External : UserRoleType.Internal))
));
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public Task DeleteServiceDocumentsAsync(Guid documentId) =>

/// <inheritdoc />
public Task<IEnumerable<TechnicalUserProfileInformation>> GetTechnicalUserProfilesForOffer(Guid offerId) =>
_offerService.GetTechnicalUserProfilesForOffer(offerId, OfferTypeId.SERVICE);
_offerService.GetTechnicalUserProfilesForOffer(offerId, OfferTypeId.SERVICE, _settings.DimUserRoles);

/// <inheritdoc />
public Task UpdateTechnicalUserProfiles(Guid serviceId, IEnumerable<TechnicalUserProfileData> data) =>
Expand Down
4 changes: 4 additions & 0 deletions src/marketplace/Services.Service/ServiceSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ public class ServiceSettings
/// </summary>
[Required(AllowEmptyStrings = false)]
public string OfferDetailAddress { get; init; } = null!;

[Required]
[DistinctValues("x => x.ClientId")]
public IEnumerable<UserRoleConfig> DimUserRoles { get; set; } = null!;
}

public static class ServiceSettingsExtension
Expand Down
3 changes: 2 additions & 1 deletion src/marketplace/Services.Service/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"DeleteDocumentTypeIds": [],
"TechnicalUserProfileClient": "",
"OfferSubscriptionAddress": "",
"OfferDetailAddress": ""
"OfferDetailAddress": "",
"DimUserRoles": []
},
"Provisioning": {
"CentralRealm": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,21 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using System.Text.Json.Serialization;

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

public record TechnicalUserProfileInformation(
[property: JsonPropertyName("technicalUserProfileId")] Guid TechnicalUserProfileId,
[property: JsonPropertyName("userRoles")] IEnumerable<UserRoleInformation> UserRoles
);

public record TechnicalUserProfileInformationTransferData(
Guid TechnicalUserProfileId,
IEnumerable<UserRoleInformation> UserRoles
IEnumerable<UserRoleInformationTransferData> UserRoles
);

public record UserRoleInformationTransferData(
Guid UserRoleId,
string UserRoleText,
bool External);
15 changes: 8 additions & 7 deletions src/portalbackend/PortalBackend.DBAccess/Models/UserRoleData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@ public record UserRoleData(
/// <summary>
/// Basic model for user role data needed to display user roles with description.
/// </summary>
public record UserRoleWithDescription(
[property: JsonPropertyName("roleId")] Guid UserRoleId,
[property: JsonPropertyName("roleName")] string UserRoleText,
[property: JsonPropertyName("roleDescription")] string? RoleDescription,
[property: JsonPropertyName("roleType")] UserRoleType RoleType
);
public record UserRoleWithDescriptionTransferData(
Guid UserRoleId,
string UserRoleText,
string? RoleDescription,
bool External
);

public record UserRoleInformation(
[property: JsonPropertyName("roleId")] Guid UserRoleId,
[property: JsonPropertyName("roleName")] string UserRoleText);
[property: JsonPropertyName("roleName")] string UserRoleText,
[property: JsonPropertyName("type")] UserRoleType RoleType);

public enum UserRoleType
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration;
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;
Expand Down Expand Up @@ -67,6 +68,7 @@ public interface ITechnicalUserProfileRepository
/// <param name="offerId">Id of the offer</param>
/// <param name="usersCompanyId"></param>
/// <param name="offerTypeId">Id of the offertype</param>
/// <param name="externalUserRoles">The external user roles</param>
/// <returns>List of the technical user profile information</returns>
Task<(bool IsUserOfProvidingCompany, IEnumerable<TechnicalUserProfileInformation> Information)> GetTechnicalUserProfileInformation(Guid offerId, Guid usersCompanyId, OfferTypeId offerTypeId);
Task<(bool IsUserOfProvidingCompany, IEnumerable<TechnicalUserProfileInformationTransferData> Information)> GetTechnicalUserProfileInformation(Guid offerId, Guid usersCompanyId, OfferTypeId offerTypeId, IEnumerable<Guid> externalUserRoles);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public interface IUserRolesRepository
IAsyncEnumerable<OfferRoleInfo> GetAppRolesAsync(Guid offerId, Guid companyId, string languageShortName);
IAsyncEnumerable<string> GetClientRolesCompositeAsync(string keyCloakClientId);

IAsyncEnumerable<UserRoleWithDescription> GetServiceAccountRolesAsync(Guid companyId, string clientId, IEnumerable<Guid> externalRoleIds, string languageShortName);
IAsyncEnumerable<UserRoleWithDescriptionTransferData> GetServiceAccountRolesAsync(Guid companyId, string clientId, IEnumerable<Guid> externalRoleIds, string languageShortName);

/// <summary>
/// Gets all user role ids for the given offerId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

using Microsoft.EntityFrameworkCore;
using Org.Eclipse.TractusX.Portal.Backend.Framework.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
Expand Down Expand Up @@ -69,14 +70,17 @@ public void RemoveTechnicalUserProfilesForOffer(Guid offerId)
}

/// <inheritdoc />
public Task<(bool IsUserOfProvidingCompany, IEnumerable<TechnicalUserProfileInformation> Information)>
GetTechnicalUserProfileInformation(Guid offerId, Guid usersCompanyId, OfferTypeId offerTypeId) =>
public Task<(bool IsUserOfProvidingCompany, IEnumerable<TechnicalUserProfileInformationTransferData> Information)> GetTechnicalUserProfileInformation(Guid offerId, Guid usersCompanyId, OfferTypeId offerTypeId, IEnumerable<Guid> externalUserRoles) =>
_context.Offers
.Where(x => x.Id == offerId && x.OfferTypeId == offerTypeId)
.Select(x => new ValueTuple<bool, IEnumerable<TechnicalUserProfileInformation>>(
.Select(x => new ValueTuple<bool, IEnumerable<TechnicalUserProfileInformationTransferData>>(
x.ProviderCompanyId == usersCompanyId,
x.TechnicalUserProfiles.Select(tup => new TechnicalUserProfileInformation(
x.TechnicalUserProfiles.Select(tup => new TechnicalUserProfileInformationTransferData(
tup.Id,
tup.TechnicalUserProfileAssignedUserRoles.Select(ur => new UserRoleInformation(ur.UserRole!.Id, ur.UserRole.UserRoleText))))))
tup.TechnicalUserProfileAssignedUserRoles
.Select(ur => new UserRoleInformationTransferData(
ur.UserRole!.Id,
ur.UserRole.UserRoleText,
externalUserRoles.Contains(ur.UserRoleId)))))))
.SingleOrDefaultAsync();
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,19 +214,19 @@ public IAsyncEnumerable<string> GetClientRolesCompositeAsync(string keyCloakClie
.Select(userRole => userRole.UserRoleText)
.AsAsyncEnumerable();

IAsyncEnumerable<UserRoleWithDescription> IUserRolesRepository.GetServiceAccountRolesAsync(Guid companyId, string clientId, IEnumerable<Guid> externalRoleIds, string languageShortName) =>
IAsyncEnumerable<UserRoleWithDescriptionTransferData> IUserRolesRepository.GetServiceAccountRolesAsync(Guid companyId, string clientId, IEnumerable<Guid> externalRoleIds, string languageShortName) =>
_dbContext.UserRoles
.AsNoTracking()
.Where(ur => ur.Offer!.AppInstances.Any(ai => ai.IamClient!.ClientClientId == clientId) &&
ur.UserRoleCollections.Any(urc =>
urc.CompanyRoleAssignedRoleCollection!.CompanyRole!.CompanyAssignedRoles.Any(car =>
car.CompanyId == companyId)))
.Select(userRole => new UserRoleWithDescription(
.Select(userRole => new UserRoleWithDescriptionTransferData(
userRole.Id,
userRole.UserRoleText,
userRole.UserRoleDescriptions.SingleOrDefault(desc =>
desc.LanguageShortName == languageShortName)!.Description,
externalRoleIds.Contains(userRole.Id) ? UserRoleType.External : UserRoleType.Internal))
externalRoleIds.Contains(userRole.Id)))
.AsAsyncEnumerable();

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ public async Task DeleteOwnCompanyServiceAccountAsync_WithoutClient_CallsExpecte
public async Task GetServiceAccountRolesAsync_GetsExpectedData()
{
// Arrange
var data = _fixture.CreateMany<UserRoleWithDescription>(15);
var data = _fixture.CreateMany<UserRoleWithDescriptionTransferData>(15);

A.CallTo(() => _userRolesRepository.GetServiceAccountRolesAsync(A<Guid>._, A<string>._, A<IEnumerable<Guid>>._, A<string>._))
.Returns(data.ToAsyncEnumerable());
Expand All @@ -676,7 +676,8 @@ public async Task GetServiceAccountRolesAsync_GetsExpectedData()
// Sonar fix -> Return value of pure method is not used
result.Should().AllSatisfy(ur =>
{
data.Contains(ur).Should().BeTrue();
var transferData = new UserRoleWithDescriptionTransferData(ur.UserRoleId, ur.UserRoleText, ur.RoleDescription, ur.RoleType == UserRoleType.External);
data.Contains(transferData).Should().BeTrue();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
********************************************************************************/

using FluentAssertions;
using Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
using Org.Eclipse.TractusX.Portal.Backend.Apps.Service.ViewModels;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq;
using Org.Eclipse.TractusX.Portal.Backend.Offers.Library.Models;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ public async Task GetTechnicalUserProfilesForOffer_ReturnsExpected()
{
// Arrange
var appId = Guid.NewGuid();
A.CallTo(() => _offerService.GetTechnicalUserProfilesForOffer(appId, OfferTypeId.APP))
A.CallTo(() => _offerService.GetTechnicalUserProfilesForOffer(appId, OfferTypeId.APP, A<IEnumerable<UserRoleConfig>>._))
.Returns(_fixture.CreateMany<TechnicalUserProfileInformation>(5));
var sut = new AppReleaseBusinessLogic(null!, Options.Create(new AppsSettings()), _offerService, _offerDocumentService, null!, _identityService);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,15 @@
"OfferDetailAddress": "https://detail.de",
"DecentralIdentityManagementAuthUrl": "https://test.org/auth",
"IssuerDid": "did:web:example.org:test123",
"BpnDidResolverUrl": "https://test.org/bpn-did"
"BpnDidResolverUrl": "https://test.org/bpn-did",
"DimUserRoles": [
{
"ClientId": "technical_roles_management",
"UserRoleNames": [
"Identity Wallet Management"
]
}
]
},
"Provisioning": {
"CentralRealm": "CX-Central",
Expand Down
Loading

0 comments on commit 1c54198

Please sign in to comment.