Skip to content

Commit

Permalink
refactor into IIdentityProviderProvisioningService
Browse files Browse the repository at this point in the history
  • Loading branch information
ntruchsess committed Nov 4, 2024
1 parent 8f5da99 commit f8ff20a
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,39 @@ public async IAsyncEnumerable<IdentityProviderMapperModel> GetIdentityProviderMa
public async Task<string?> GetIdentityProviderDisplayName(string alias) =>
(await GetCentralIdentityProviderAsync(alias).ConfigureAwait(ConfigureAwaitOptions.None)).DisplayName;

public async Task UpdateOrCreateCentralIdentityProviderOrganisationMapperAsync(string idpAlias, string organisationName)
{
var mapperName = _settings.MappedCompanyAttribute + "-mapper";
IdentityProviderMapper? mapper;
try
{
mapper = (await _centralIdp.GetIdentityProviderMappersAsync(_settings.CentralRealm, idpAlias).ConfigureAwait(ConfigureAwaitOptions.None))
.SingleOrDefault(z => z.Name == mapperName);
}
catch (InvalidOperationException)
{
throw new KeycloakEntityConflictException($"idp {idpAlias} attribute-mapper {mapperName} is ambigous in keycloak");
}
if (mapper is null)
{
await CreateCentralIdentityProviderOrganisationMapperAsync(idpAlias, organisationName);
}
else
{
mapper.Config ??= new Dictionary<string, string>
{
["syncMode"] = "INHERIT",
["attribute"] = _settings.MappedCompanyAttribute,
};
mapper.Config["attribute.value"] = organisationName;
await _centralIdp.UpdateIdentityProviderMapperAsync(
_settings.CentralRealm,
idpAlias,
mapper.Id ?? throw new KeycloakEntityConflictException($"idp {idpAlias} attribute-mapper {mapperName} has no Id"),
mapper).ConfigureAwait(ConfigureAwaitOptions.None);
}
}

private async ValueTask<string> GetCentralBrokerEndpointOIDCAsync(string alias)
{
var openidconfig = await _centralIdp.GetOpenIDConfigurationAsync(_settings.CentralRealm).ConfigureAwait(ConfigureAwaitOptions.None);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ public interface IProvisioningManager
Task<string?> GetIdentityProviderDisplayName(string alias);
Task DeleteSharedRealmAsync(string alias);
Task DeleteIdpSharedServiceAccount(string alias);
ValueTask UpdateCentralIdentityProviderOrganisationMapperAsync(string idpAlias, string companyName);
Task UpdateOrCreateCentralIdentityProviderOrganisationMapperAsync(string idpAlias, string organisationName);
}
32 changes: 0 additions & 32 deletions src/provisioning/Provisioning.Library/ProvisioningManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Factory;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Library;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Library.Models.IdentityProviders;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Enums;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models;
Expand Down Expand Up @@ -183,37 +182,6 @@ public async ValueTask UpdateSharedIdentityProviderAsync(string alias, string di
await UpdateCentralIdentityProviderAsync(alias, identityProvider).ConfigureAwait(ConfigureAwaitOptions.None);
}

public async ValueTask UpdateCentralIdentityProviderOrganisationMapperAsync(string idpAlias, string companyName)
{
var mappers = await _centralIdp.GetIdentityProviderMappersAsync(_settings.CentralRealm, idpAlias).ConfigureAwait(ConfigureAwaitOptions.None);
var organisationMapperId = mappers.FirstOrDefault(z => z.Name == $"{_settings.MappedCompanyAttribute}-mapper")?.Id ?? string.Empty;
if (!string.IsNullOrEmpty(organisationMapperId))
{
await UpdateAttributeInIdentityProvider(idpAlias, organisationMapperId, _settings.MappedCompanyAttribute, companyName);
}
else
{
await CreateCentralIdentityProviderOrganisationMapperAsync(idpAlias, companyName);
}
}

private async Task UpdateAttributeInIdentityProvider(string alias, string mapperId, string attributeName, string value) => await _centralIdp.UpdateIdentityProviderMapperAsync(
_settings.CentralRealm,
alias,
mapperId,
new IdentityProviderMapper
{
Id = mapperId,
Name = attributeName + "-mapper",
_IdentityProviderMapper = "hardcoded-attribute-idp-mapper",
IdentityProviderAlias = alias,
Config = new Dictionary<string, string>
{
["syncMode"] = "INHERIT",
["attribute"] = attributeName,
["attribute.value"] = value
}
}).ConfigureAwait(ConfigureAwaitOptions.None);
public async ValueTask UpdateSharedRealmTheme(string alias, string loginTheme)
{
var identityProvider = await GetCentralIdentityProviderAsync(alias).ConfigureAwait(ConfigureAwaitOptions.None);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/********************************************************************************
* Copyright (c) 2024 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.Provisioning.Library.Service;

public interface IIdentityProviderProvisioningService
{
Task<string?> GetIdentityProviderDisplayName(string idpAlias);
Task UpdateCompanyNameInSharedIdentityProvider(Guid companyId, string companyName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ public interface IUserProvisioningService
Task HandleCentralKeycloakCreation(UserCreationRoleDataIdpInfo user, Guid companyUserId, string companyName, string? businessPartnerNumber, Identity? identity, IEnumerable<IdentityProviderLink> identityProviderLinks, IUserRepository userRepository, IUserRolesRepository userRolesRepository);
Task<(CompanyNameIdpAliasData IdpAliasData, string NameCreatedBy)> GetCompanyNameIdpAliasData(Guid identityProviderId, Guid companyUserId);
Task<(CompanyNameIdpAliasData IdpAliasData, string NameCreatedBy)> GetCompanyNameSharedIdpAliasData(Guid companyUserId, Guid? applicationId = null);
Task<string?> GetIdentityProviderDisplayName(string idpAlias);
IAsyncEnumerable<UserRoleData> GetRoleDatas(IEnumerable<UserRoleConfig> clientRoles);
Task<IEnumerable<UserRoleData>> GetOwnCompanyPortalRoleDatas(string clientId, IEnumerable<string> roles, Guid companyId);
Task<(Identity? Identity, Guid CompanyUserId)> GetOrCreateCompanyUser(IUserRepository userRepository, string alias, UserCreationRoleDataIdpInfo user, Guid companyId, Guid identityProviderId, string? businessPartnerNumber);
Task AssignRolesToNewUserAsync(IUserRolesRepository userRolesRepository, IEnumerable<UserRoleData> roleDatas, (string IamUserId, Guid CompanyUserId) userdata);
Task UpdateCompanyNameInIdentityProvider(Guid identityId, string companyName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/********************************************************************************
* Copyright (c) 2024 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.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;

namespace Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Service;

public class IdentityProviderProvisioningService(IPortalRepositories portalRepositories, IProvisioningManager provisioningManager) : IIdentityProviderProvisioningService
{
public Task<string?> GetIdentityProviderDisplayName(string idpAlias) =>
provisioningManager.GetCentralIdentityProviderDisplayName(idpAlias);

public async Task UpdateCompanyNameInSharedIdentityProvider(Guid companyId, string companyName)
{
var idpAlias = await portalRepositories.GetInstance<IIdentityProviderRepository>().GetSharedIdentityProviderIamAliasDataUntrackedAsync(companyId).ConfigureAwait(false) ?? throw new ConflictException($"company {companyId} is not associated with any shared idp");
await provisioningManager.UpdateSharedIdentityProviderAsync(idpAlias, companyName).ConfigureAwait(false);
await provisioningManager.UpdateOrCreateCentralIdentityProviderOrganisationMapperAsync(idpAlias, companyName).ConfigureAwait(ConfigureAwaitOptions.None);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,6 @@ private Task<string> CreateSharedIdpUserOrReturnUserId(UserCreationRoleDataIdpIn
return (new CompanyNameIdpAliasData(company.CompanyId, company.CompanyName, company.BusinessPartnerNumber, idpAlias.Alias, idpAlias.IdentityProviderId, true), createdByName);
}

public Task<string?> GetIdentityProviderDisplayName(string idpAlias) =>
_provisioningManager.GetCentralIdentityProviderDisplayName(idpAlias);

private async Task<Guid> ValidateDuplicateIdpUsersAsync(IUserRepository userRepository, string alias, UserCreationRoleDataIdpInfo user, Guid companyId)
{
var existingCompanyUserId = Guid.Empty;
Expand Down Expand Up @@ -337,11 +334,4 @@ private static void ValidateRoleData(IEnumerable<UserRoleData> roleData, string
throw new ControllerArgumentException($"invalid roles: clientId: '{clientId}', roles: [{string.Join(", ", invalid)}]");
}
}

public async Task UpdateCompanyNameInIdentityProvider(Guid identityId, string companyName)
{
var (aliasData, _) = await GetCompanyNameSharedIdpAliasData(identityId).ConfigureAwait(ConfigureAwaitOptions.None);
await _provisioningManager.UpdateSharedIdentityProviderAsync(aliasData.IdpAlias, companyName).ConfigureAwait(false);
await _provisioningManager.UpdateCentralIdentityProviderOrganisationMapperAsync(aliasData.IdpAlias, companyName).ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class RegistrationBusinessLogic(
IOptions<RegistrationSettings> settings,
IBpnAccess bpnAccess,
IUserProvisioningService userProvisioningService,
IIdentityProviderProvisioningService identityProviderProvisioningService,
ILogger<RegistrationBusinessLogic> logger,
IPortalRepositories portalRepositories,
IApplicationChecklistCreationService checklistService,
Expand Down Expand Up @@ -264,7 +265,7 @@ await companyDetails.ValidateDatabaseData(
UpdateApplicationStatus(applicationId, companyApplicationData.ApplicationStatusId, UpdateApplicationSteps.CompanyWithAddress, applicationRepository, dateTimeProvider);
if (existingCompanyName != companyDetails.Name)
{
await userProvisioningService.UpdateCompanyNameInIdentityProvider(_identityData.IdentityId, companyDetails.Name);
await identityProviderProvisioningService.UpdateCompanyNameInSharedIdentityProvider(_identityData.CompanyId, companyDetails.Name).ConfigureAwait(ConfigureAwaitOptions.None);
}
await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}
Expand Down Expand Up @@ -412,7 +413,7 @@ private async Task<int> InviteNewUserInternalAsync(Guid applicationId, UserCreat

var modified = await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);

var companyDisplayName = await userProvisioningService.GetIdentityProviderDisplayName(companyNameIdpAliasData.IdpAlias).ConfigureAwait(ConfigureAwaitOptions.None) ?? companyNameIdpAliasData.IdpAlias;
var companyDisplayName = await identityProviderProvisioningService.GetIdentityProviderDisplayName(companyNameIdpAliasData.IdpAlias).ConfigureAwait(ConfigureAwaitOptions.None) ?? companyNameIdpAliasData.IdpAlias;
var mailParameters = ImmutableDictionary.CreateRange(new[]
{
KeyValuePair.Create("password", password),
Expand Down
Loading

0 comments on commit f8ff20a

Please sign in to comment.