Skip to content

Commit

Permalink
Merge pull request #1190 from eclipse-tractusx/release/v2.3.0-RC4
Browse files Browse the repository at this point in the history
build(2.3.0-rc4): bump version and update docs
  • Loading branch information
evegufy authored Nov 29, 2024
2 parents a49ff30 + 3e54d85 commit 5b0121c
Show file tree
Hide file tree
Showing 35 changed files with 2,231 additions and 378 deletions.
10 changes: 5 additions & 5 deletions .tractusx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

leadingRepository: "https://github.com/eclipse-tractusx/portal"
openApiSpecs:
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC3/docs/api/administration-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC3/docs/api/apps-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC3/docs/api/notifications-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC3/docs/api/registration-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC3/docs/api/services-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC4/docs/api/administration-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC4/docs/api/apps-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC4/docs/api/notifications-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC4/docs/api/registration-service.yaml"
- "https://raw.githubusercontent.com/eclipse-tractusx/portal-backend/refs/tags/v2.3.0-RC4/docs/api/services-service.yaml"
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ New features, fixed bugs, known defects and other noteworthy changes to each rel

## Unreleased

## 2.3.0-RC4

### Change

* **Keycloak realm seeding job**: made seeder configurable [#1174](https://github.com/eclipse-tractusx/portal-backend/pull/1174)

## 2.3.0-RC3

### Technical Support
Expand Down
2 changes: 1 addition & 1 deletion docs/api/administration-service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.1
info:
title: Org.Eclipse.TractusX.Portal.Backend.Administration.Service
version: v2.3.0-RC3
version: v2.3.0-RC4
paths:
/api/administration/companydata/ownCompanyDetails:
get:
Expand Down
2 changes: 1 addition & 1 deletion docs/api/apps-service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.1
info:
title: Org.Eclipse.TractusX.Portal.Backend.Apps.Service
version: v2.3.0-RC3
version: v2.3.0-RC4
paths:
'/api/apps/AppChange/{appId}/role/activeapp':
post:
Expand Down
2 changes: 1 addition & 1 deletion docs/api/notifications-service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.1
info:
title: Org.Eclipse.TractusX.Portal.Backend.Notifications.Service
version: v2.3.0-RC3
version: v2.3.0-RC4
paths:
/api/notification/errormessage:
get:
Expand Down
2 changes: 1 addition & 1 deletion docs/api/registration-service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.1
info:
title: Org.Eclipse.TractusX.Portal.Backend.Registration.Service
version: v2.3.0-RC3
version: v2.3.0-RC4
paths:
/api/registration/errormessage:
get:
Expand Down
2 changes: 1 addition & 1 deletion docs/api/services-service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.1
info:
title: Org.Eclipse.TractusX.Portal.Backend.Services.Service
version: v2.3.0-RC3
version: v2.3.0-RC4
paths:
/api/services/errormessage:
get:
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.3.0</VersionPrefix>
<VersionSuffix>RC3</VersionSuffix>
<VersionSuffix>RC4</VersionSuffix>
</PropertyGroup>
</Project>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,22 @@
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.Roles;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Seeding.Extensions;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Seeding.Models;

namespace Org.Eclipse.TractusX.Portal.Backend.Keycloak.Seeding.BusinessLogic;

public class ClientScopeMapperUpdater : IClientScopeMapperUpdater
public class ClientScopeMapperUpdater(IKeycloakFactory keycloakFactory, ISeedDataHandler seedDataHandler)
: IClientScopeMapperUpdater
{
private readonly IKeycloakFactory _keycloakFactory;
private readonly ISeedDataHandler _seedData;

public ClientScopeMapperUpdater(IKeycloakFactory keycloakFactory, ISeedDataHandler seedDataHandler)
{
_keycloakFactory = keycloakFactory;
_seedData = seedDataHandler;
}

public async Task UpdateClientScopeMapper(string instanceName, CancellationToken cancellationToken)
{
var keycloak = _keycloakFactory.CreateKeycloakClient(instanceName);
var realm = _seedData.Realm;
var keycloak = keycloakFactory.CreateKeycloakClient(instanceName);
var realm = seedDataHandler.Realm;
var seederConfig = seedDataHandler.GetSpecificConfiguration(ConfigurationKey.ClientScopes);

var clients = await keycloak.GetClientsAsync(realm, null, true, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
foreach (var (clientName, mappingModels) in _seedData.ClientScopeMappings)
foreach (var (clientName, mappingModels) in seedDataHandler.ClientScopeMappings)
{
var client = clients.SingleOrDefault(x => x.ClientId == clientName);
if (client?.Id is null)
Expand All @@ -60,17 +55,23 @@ public async Task UpdateClientScopeMapper(string instanceName, CancellationToken
}
var clientRoles = await keycloak.GetClientRolesScopeMappingsForClientAsync(realm, clientScope.Id, client.Id, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
var mappingModelRoles = mappingModel.Roles?.Select(roleName => roles.SingleOrDefault(r => r.Name == roleName) ?? throw new ConflictException($"No role with name {roleName} found")) ?? Enumerable.Empty<Role>();
await AddAndDeleteRoles(keycloak, realm, clientScope.Id, client.Id, clientRoles, mappingModelRoles, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await AddAndDeleteRoles(keycloak, realm, clientScope.Id, client.Id, clientRoles, mappingModelRoles, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}
}
}

private static async Task AddAndDeleteRoles(KeycloakClient keycloak, string realm, string clientScopeId, string clientId, IEnumerable<Role> roles, IEnumerable<Role> updateRoles, CancellationToken cancellationToken)
private static async Task AddAndDeleteRoles(KeycloakClient keycloak, string realm, string clientScopeId, string clientId, IEnumerable<Role> roles, IEnumerable<Role> updateRoles, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
await updateRoles.ExceptBy(roles.Select(role => role.Name), roleModel => roleModel.Name).IfAnyAwait(rolesToAdd =>
keycloak.AddClientRolesScopeMappingToClientAsync(realm, clientScopeId, clientId, rolesToAdd, cancellationToken)).ConfigureAwait(false);
await updateRoles
.Where(x => seederConfig.ModificationAllowed(ModificationType.Create, x.Name))
.ExceptBy(roles.Select(role => role.Name), roleModel => roleModel.Name)
.IfAnyAwait(rolesToAdd =>
keycloak.AddClientRolesScopeMappingToClientAsync(realm, clientScopeId, clientId, rolesToAdd, cancellationToken)).ConfigureAwait(false);

await roles.ExceptBy(updateRoles.Select(roleModel => roleModel.Name), role => role.Name).IfAnyAwait(rolesToDelete =>
keycloak.RemoveClientRolesFromClientScopeForClientAsync(realm, clientScopeId, clientId, rolesToDelete, cancellationToken)).ConfigureAwait(false);
await roles
.Where(x => seederConfig.ModificationAllowed(ModificationType.Delete, x.Name))
.ExceptBy(updateRoles.Select(roleModel => roleModel.Name), role => role.Name)
.IfAnyAwait(rolesToDelete =>
keycloak.RemoveClientRolesFromClientScopeForClientAsync(realm, clientScopeId, clientId, rolesToDelete, cancellationToken)).ConfigureAwait(false);
}
}
85 changes: 49 additions & 36 deletions src/keycloak/Keycloak.Seeding/BusinessLogic/ClientScopesUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,38 @@
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Library;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Library.Models.ClientScopes;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Library.Models.ProtocolMappers;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Seeding.Extensions;
using Org.Eclipse.TractusX.Portal.Backend.Keycloak.Seeding.Models;

namespace Org.Eclipse.TractusX.Portal.Backend.Keycloak.Seeding.BusinessLogic;

public class ClientScopesUpdater : IClientScopesUpdater
public class ClientScopesUpdater(IKeycloakFactory keycloakFactory, ISeedDataHandler seedDataHandler)
: IClientScopesUpdater
{
private readonly IKeycloakFactory _keycloakFactory;
private readonly ISeedDataHandler _seedData;

public ClientScopesUpdater(IKeycloakFactory keycloakFactory, ISeedDataHandler seedDataHandler)
{
_keycloakFactory = keycloakFactory;
_seedData = seedDataHandler;
}

public async Task UpdateClientScopes(string instanceName, CancellationToken cancellationToken)
{
var keycloak = _keycloakFactory.CreateKeycloakClient(instanceName);
var realm = _seedData.Realm;
var keycloak = keycloakFactory.CreateKeycloakClient(instanceName);
var realm = seedDataHandler.Realm;
var seederConfig = seedDataHandler.GetSpecificConfiguration(ConfigurationKey.ClientScopes);

var clientScopes = await keycloak.GetClientScopesAsync(realm, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
var seedClientScopes = _seedData.ClientScopes;
var seedClientScopes = seedDataHandler.ClientScopes;

await RemoveObsoleteClientScopes(keycloak, realm, clientScopes, seedClientScopes, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await CreateMissingClientScopes(keycloak, realm, clientScopes, seedClientScopes, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await UpdateExistingClientScopes(keycloak, realm, clientScopes, seedClientScopes, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ModificationType.Delete, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, RemoveObsoleteClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ModificationType.Create, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, CreateMissingClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ModificationType.Update, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, UpdateExistingClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
}

private static async Task RemoveObsoleteClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, CancellationToken cancellationToken)
private static Task CheckAndExecute(ModificationType modificationType, KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken, Func<KeycloakClient, string, IEnumerable<ClientScope>, IEnumerable<ClientScopeModel>, KeycloakSeederConfigModel, CancellationToken, Task> executeLogic) =>
seederConfig.ModificationAllowed(modificationType)
? executeLogic(keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken)
: Task.CompletedTask;

private static async Task RemoveObsoleteClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var deleteScope in clientScopes.ExceptBy(seedClientScopes.Select(x => x.Name), x => x.Name))
foreach (var deleteScope in clientScopes
.Where(x => seederConfig.ModificationAllowed(ModificationType.Delete, x.Name))
.ExceptBy(seedClientScopes.Select(x => x.Name), x => x.Name))
{
await keycloak.DeleteClientScopeAsync(
realm,
Expand All @@ -61,32 +62,38 @@ await keycloak.DeleteClientScopeAsync(
}
}

private static async Task CreateMissingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, CancellationToken cancellationToken)
private static async Task CreateMissingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var addScope in seedClientScopes.ExceptBy(clientScopes.Select(x => x.Name), x => x.Name))
foreach (var addScope in seedClientScopes
.Where(x => seederConfig.ModificationAllowed(ModificationType.Create, x.Name))
.ExceptBy(clientScopes.Select(x => x.Name), x => x.Name))
{
await keycloak.CreateClientScopeAsync(realm, CreateClientScope(null, addScope, true), cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}
}

private static async Task UpdateExistingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, CancellationToken cancellationToken)
private static async Task UpdateExistingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var (clientScope, update) in clientScopes
.Where(x => seederConfig.ModificationAllowed(ModificationType.Update, x.Name))
.Join(
seedClientScopes,
x => x.Name,
x => x.Name,
(clientScope, update) => (ClientScope: clientScope, Update: update)))
{
await UpdateClientScopeWithProtocolMappers(keycloak, realm, clientScope, update, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await UpdateClientScopeWithProtocolMappers(keycloak, realm, clientScope, update, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}
}

private static async Task UpdateClientScopeWithProtocolMappers(KeycloakClient keycloak, string realm, ClientScope clientScope, ClientScopeModel update, CancellationToken cancellationToken)
private static async Task UpdateClientScopeWithProtocolMappers(KeycloakClient keycloak, string realm, ClientScope clientScope, ClientScopeModel update, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
if (clientScope.Id == null)
throw new ConflictException($"clientScope.Id is null: {clientScope.Name}");

if (clientScope.Name == null)
throw new ConflictException($"clientScope.Name is null: {clientScope.Name}");

if (!CompareClientScope(clientScope, update))
{
await keycloak.UpdateClientScopeAsync(
Expand All @@ -99,14 +106,16 @@ await keycloak.UpdateClientScopeAsync(
var mappers = clientScope.ProtocolMappers ?? Enumerable.Empty<ProtocolMapper>();
var updateMappers = update.ProtocolMappers ?? Enumerable.Empty<ProtocolMapperModel>();

await DeleteObsoleteProtocolMappers(keycloak, realm, clientScope.Id, mappers, updateMappers, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await CreateMissingProtocolMappers(keycloak, realm, clientScope.Id, mappers, updateMappers, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await UpdateExistingProtocolMappers(keycloak, realm, clientScope.Id, mappers, updateMappers, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await DeleteObsoleteProtocolMappers(keycloak, realm, clientScope.Name, clientScope.Id, mappers, updateMappers, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await CreateMissingProtocolMappers(keycloak, realm, clientScope.Name, clientScope.Id, mappers, updateMappers, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
await UpdateExistingProtocolMappers(keycloak, realm, clientScope.Name, clientScope.Id, mappers, updateMappers, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}

private static async Task DeleteObsoleteProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, CancellationToken cancellationToken)
private static async Task DeleteObsoleteProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var mapper in mappers.ExceptBy(updateMappers.Select(x => x.Name), x => x.Name))
foreach (var mapper in mappers
.Where(x => seederConfig.ModificationAllowed(clientScopeName, ConfigurationKey.ProtocolMappers, ModificationType.Delete, x.Name))
.ExceptBy(updateMappers.Select(x => x.Name), x => x.Name))
{
await keycloak.DeleteProtocolMapperAsync(
realm,
Expand All @@ -116,9 +125,11 @@ await keycloak.DeleteProtocolMapperAsync(
}
}

private static async Task CreateMissingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, CancellationToken cancellationToken)
private static async Task CreateMissingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var update in updateMappers.ExceptBy(mappers.Select(x => x.Name), x => x.Name))
foreach (var update in updateMappers
.Where(x => seederConfig.ModificationAllowed(clientScopeName, ConfigurationKey.ProtocolMappers, ModificationType.Create, x.Name))
.ExceptBy(mappers.Select(x => x.Name), x => x.Name))
{
await keycloak.CreateProtocolMapperAsync(
realm,
Expand All @@ -128,13 +139,15 @@ await keycloak.CreateProtocolMapperAsync(
}
}

private static async Task UpdateExistingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, CancellationToken cancellationToken)
private static async Task UpdateExistingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var (mapper, update) in mappers.Join(
updateMappers,
x => x.Name,
x => x.Name,
(mapper, update) => (Mapper: mapper, Update: update))
foreach (var (mapper, update) in mappers
.Where(x => seederConfig.ModificationAllowed(clientScopeName, ConfigurationKey.ProtocolMappers, ModificationType.Update, x.Name))
.Join(
updateMappers,
x => x.Name,
x => x.Name,
(mapper, update) => (Mapper: mapper, Update: update))
.Where(x => !ProtocolMappersUpdater.CompareProtocolMapper(x.Mapper, x.Update)))
{
await keycloak.UpdateProtocolMapperAsync(
Expand Down
Loading

0 comments on commit 5b0121c

Please sign in to comment.