Skip to content

Commit

Permalink
feat(worker): split keycloak calls
Browse files Browse the repository at this point in the history
only sending mails from mailing process

Refs: CPLP-3383
  • Loading branch information
Phil91 committed Jan 17, 2024
1 parent ba6ecf4 commit cecfc06
Show file tree
Hide file tree
Showing 27 changed files with 595 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private async Task ExecuteInvitationInternalAsync(CompanyInvitationData invitati
public Task RetriggerCreateSharedIdpServiceAccount(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT);
public Task RetriggerUpdateCentralIdpUrls(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_UPDATE_CENTRAL_IDP_URLS);
public Task RetriggerCreateCentralIdpOrgMapper(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER);
public Task RetriggerCreateSharedRealmIdpClient(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM_IDP_CLIENT);
public Task RetriggerCreateSharedRealmIdpClient(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM);
public Task RetriggerEnableCentralIdp(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_ENABLE_CENTRAL_IDP);
public Task RetriggerCreateDatabaseIdp(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_DATABASE_IDP);
public Task RetriggerInvitationCreateUser(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_USER);
Expand All @@ -88,7 +88,7 @@ private async Task TriggerProcessStepInternal(Guid processId, ProcessStepTypeId
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT => ProcessStepTypeId.INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT,
ProcessStepTypeId.RETRIGGER_INVITATION_UPDATE_CENTRAL_IDP_URLS => ProcessStepTypeId.INVITATION_UPDATE_CENTRAL_IDP_URLS,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER => ProcessStepTypeId.INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM_IDP_CLIENT => ProcessStepTypeId.INVITATION_CREATE_SHARED_REALM_IDP_CLIENT,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM => ProcessStepTypeId.INVITATION_CREATE_SHARED_REALM,
ProcessStepTypeId.RETRIGGER_INVITATION_ENABLE_CENTRAL_IDP => ProcessStepTypeId.INVITATION_ENABLE_CENTRAL_IDP,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_USER => ProcessStepTypeId.INVITATION_CREATE_USER,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_DATABASE_IDP => ProcessStepTypeId.INVITATION_CREATE_DATABASE_IDP,
Expand Down
4 changes: 3 additions & 1 deletion src/externalsystems/Provisioning.Library/IIdpManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ public interface IIdpManagement
{
ValueTask<string> GetNextCentralIdentityProviderNameAsync();
Task CreateCentralIdentityProviderAsync(string alias, string displayName);
Task<(string ClientId, string Secret)> CreateSharedIdpServiceAccountAsync(string realm);
Task<(string ClientId, string Secret, string ServiceAccountUserId)> CreateSharedIdpServiceAccountAsync(string realm);
ValueTask UpdateCentralIdentityProviderUrlsAsync(string alias, string organisationName, string loginTheme, string clientId, string secret);
Task CreateCentralIdentityProviderOrganisationMapperAsync(string alias, string organisationName);
Task CreateSharedRealmIdpClientAsync(string realm, string loginTheme, string organisationName, string clientId, string secret);
ValueTask EnableCentralIdentityProviderAsync(string alias);
Task AddRealmRoleMappingsToUserAsync(string serviceAccountUserId);
Task CreateSharedClientAsync(string realm, string clientId, string secret);
}
29 changes: 18 additions & 11 deletions src/externalsystems/Provisioning.Library/IdpManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,26 @@ public Task CreateCentralIdentityProviderAsync(string alias, string displayName)
return _centralIdp.CreateIdentityProviderAsync(_settings.CentralRealm, newIdp);
}

public async Task<(string ClientId, string Secret)> CreateSharedIdpServiceAccountAsync(string realm)
public async Task<(string ClientId, string Secret, string ServiceAccountUserId)> CreateSharedIdpServiceAccountAsync(string realm)
{
var sharedIdp = _factory.CreateKeycloakClient("shared");
var clientId = GetServiceAccountClientId(realm);
var internalClientId = await CreateServiceAccountClient(sharedIdp, "master", clientId, clientId, IamClientAuthMethod.SECRET, true);
var serviceAccountUser = await sharedIdp.GetUserForServiceAccountAsync("master", internalClientId).ConfigureAwait(false);
if (serviceAccountUser == null)
if (serviceAccountUser == null || string.IsNullOrWhiteSpace(serviceAccountUser.Id))
{
throw new NotFoundException("ServiceAccount could not be found for client id: {internalClientId}");
}

var roleCreateRealm = await sharedIdp.GetRoleByNameAsync("master", "create-realm").ConfigureAwait(false);

await sharedIdp.AddRealmRoleMappingsToUserAsync("master", serviceAccountUser.Id!, Enumerable.Repeat(roleCreateRealm, 1)).ConfigureAwait(false);

var credentials = await sharedIdp.GetClientSecretAsync("master", internalClientId).ConfigureAwait(false);
return new ValueTuple<string, string>(clientId, credentials.Value);
return new(clientId, credentials.Value, serviceAccountUser.Id);
}

public async Task AddRealmRoleMappingsToUserAsync(string serviceAccountUserId)
{
var sharedIdp = _factory.CreateKeycloakClient("shared");
var roleCreateRealm = await sharedIdp.GetRoleByNameAsync("master", "create-realm").ConfigureAwait(false);
await sharedIdp.AddRealmRoleMappingsToUserAsync("master", serviceAccountUserId, Enumerable.Repeat(roleCreateRealm, 1)).ConfigureAwait(false);
}

private async Task<string> CreateServiceAccountClient(KeycloakClient keycloak, string realm, string clientId, string name, IamClientAuthMethod iamClientAuthMethod, bool enabled)
Expand Down Expand Up @@ -140,18 +143,23 @@ public Task CreateCentralIdentityProviderOrganisationMapperAsync(string alias, s
});

public async Task CreateSharedRealmIdpClientAsync(string realm, string loginTheme, string organisationName, string clientId, string secret)
{
await CreateSharedRealmAsync(realm, organisationName, loginTheme, clientId, secret).ConfigureAwait(false);
}

public async Task CreateSharedClientAsync(string realm, string clientId, string secret)
{
var redirectUrl = await GetCentralBrokerEndpointOIDCAsync(realm).ConfigureAwait(false);
var jwksUrl = await GetCentralRealmJwksUrlAsync().ConfigureAwait(false);
var config = new IdentityProviderClientConfig(
$"{redirectUrl}/*",
jwksUrl);
var keycloak = await CreateSharedRealmAsync(realm, organisationName, loginTheme, clientId, secret).ConfigureAwait(false);
var sharedKeycloak = _factory.CreateKeycloakClient("shared", clientId, secret);
var newClient = _settings.SharedRealmClient.Clone();
newClient.RedirectUris = Enumerable.Repeat(config.RedirectUri, 1);
newClient.Attributes ??= new Dictionary<string, string>();
newClient.Attributes["jwks.url"] = config.JwksUrl;
await keycloak.CreateClientAsync(realm, newClient).ConfigureAwait(false);
await sharedKeycloak.CreateClientAsync(realm, newClient).ConfigureAwait(false);
}

private async ValueTask<string> GetCentralBrokerEndpointOIDCAsync(string alias)
Expand All @@ -178,8 +186,7 @@ public async ValueTask EnableCentralIdentityProviderAsync(string alias)
await _centralIdp.UpdateIdentityProviderAsync(_settings.CentralRealm, alias, identityProvider).ConfigureAwait(false);
}

private async Task<KeycloakClient> CreateSharedRealmAsync(string idpName, string organisationName, string? loginTheme, string clientId,
string secret)
private async Task<KeycloakClient> CreateSharedRealmAsync(string idpName, string organisationName, string? loginTheme, string clientId, string secret)
{
var sharedKeycloak = _factory.CreateKeycloakClient("shared", clientId, secret);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,38 @@
* SOFTWARE.
********************************************************************************/

using System.Text.Json.Serialization;
using Newtonsoft.Json;

namespace Org.Eclipse.TractusX.Portal.Backend.Keycloak.Library.Models.IdentityProviders;

using System.Text.Json;

public class IdentityProvider
{
[JsonPropertyName("alias")]
[JsonProperty("alias")]
public string? Alias { get; set; }
[JsonPropertyName("internalId")]
[JsonProperty("internalId")]
public string? InternalId { get; set; }
[JsonPropertyName("providerId")]
[JsonProperty("providerId")]
public string? ProviderId { get; set; }
[JsonPropertyName("enabled")]
[JsonProperty("enabled")]
public bool? Enabled { get; set; }
[JsonPropertyName("updateProfileFirstLoginMode")]
[JsonProperty("updateProfileFirstLoginMode")]
public string? UpdateProfileFirstLoginMode { get; set; }
[JsonPropertyName("trustEmail")]
[JsonProperty("trustEmail")]
public bool? TrustEmail { get; set; }
[JsonPropertyName("storeToken")]
[JsonProperty("storeToken")]
public bool? StoreToken { get; set; }
[JsonPropertyName("addReadTokenRoleOnCreate")]
[JsonProperty("addReadTokenRoleOnCreate")]
public bool? AddReadTokenRoleOnCreate { get; set; }
[JsonPropertyName("authenticateByDefault")]
[JsonProperty("authenticateByDefault")]
public bool? AuthenticateByDefault { get; set; }
[JsonPropertyName("linkOnly")]
[JsonProperty("linkOnly")]
public bool? LinkOnly { get; set; }
[JsonPropertyName("firstBrokerLoginFlowAlias")]
[JsonProperty("firstBrokerLoginFlowAlias")]
public string? FirstBrokerLoginFlowAlias { get; set; }
[JsonPropertyName("postBrokerLoginFlowAlias")]
[JsonProperty("postBrokerLoginFlowAlias")]
public string? PostBrokerLoginFlowAlias { get; set; }
[JsonPropertyName("displayName")]
[JsonProperty("displayName")]
public string? DisplayName { get; set; }
[JsonPropertyName("config")]
[JsonProperty("config")]
public Config? Config { get; set; }
}
Loading

0 comments on commit cecfc06

Please sign in to comment.