Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(technicalUser): add internal external flag to profiles #1038

Merged
merged 2 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>

<Target Name="openapi" AfterTargets="Build">
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 @@ -233,6 +233,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 @@ -164,6 +164,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
@@ -1,5 +1,4 @@
/********************************************************************************
* Copyright (c) 2022 BMW Group AG
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
Expand All @@ -18,9 +17,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 @@ -69,14 +69,17 @@ public void RemoveTechnicalUserProfilesForOffer(Guid offerId)
}

/// <inheritdoc />
public Task<(bool IsUserOfProvidingCompany, IEnumerable<TechnicalUserProfileInformation> Information)>
GetTechnicalUserProfileInformation(Guid offerId, Guid usersCompanyId, OfferTypeId offerTypeId) =>
_context.Offers
.Where(x => x.Id == offerId && x.OfferTypeId == offerTypeId)
.Select(x => new ValueTuple<bool, IEnumerable<TechnicalUserProfileInformation>>(
x.ProviderCompanyId == usersCompanyId,
x.TechnicalUserProfiles.Select(tup => new TechnicalUserProfileInformation(
tup.Id,
tup.TechnicalUserProfileAssignedUserRoles.Select(ur => new UserRoleInformation(ur.UserRole!.Id, ur.UserRole.UserRoleText))))))
.SingleOrDefaultAsync();
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<TechnicalUserProfileInformationTransferData>>(
x.ProviderCompanyId == usersCompanyId,
x.TechnicalUserProfiles.Select(tup => new TechnicalUserProfileInformationTransferData(
tup.Id,
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
Loading
Loading