Skip to content

Commit

Permalink
Added workaround to remove flow overrides before delete and restore a…
Browse files Browse the repository at this point in the history
…fter create. Add variable to set Keycloak log level.
  • Loading branch information
ma1uta committed Nov 11, 2024
1 parent a403ca0 commit 55996a3
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@

import de.adorsys.keycloak.config.model.RealmImport;
import de.adorsys.keycloak.config.repository.AuthenticationFlowRepository;
import de.adorsys.keycloak.config.repository.ClientRepository;
import de.adorsys.keycloak.config.repository.IdentityProviderRepository;
import de.adorsys.keycloak.config.repository.RealmRepository;
import org.apache.logging.log4j.util.Strings;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.slf4j.Logger;
Expand All @@ -41,16 +43,19 @@ public class UsedAuthenticationFlowWorkaroundFactory {
private final RealmRepository realmRepository;
private final IdentityProviderRepository identityProviderRepository;
private final AuthenticationFlowRepository authenticationFlowRepository;
private final ClientRepository clientRepository;

@Autowired
public UsedAuthenticationFlowWorkaroundFactory(
RealmRepository realmRepository,
IdentityProviderRepository identityProviderRepository,
AuthenticationFlowRepository authenticationFlowRepository
AuthenticationFlowRepository authenticationFlowRepository,
ClientRepository clientRepository
) {
this.realmRepository = realmRepository;
this.identityProviderRepository = identityProviderRepository;
this.authenticationFlowRepository = authenticationFlowRepository;
this.clientRepository = clientRepository;
}

public UsedAuthenticationFlowWorkaround buildFor(RealmImport realmImport) {
Expand Down Expand Up @@ -93,6 +98,56 @@ public void disableTopLevelFlowIfNeeded(String topLevelFlowAlias) {
disablePostBrokerLoginFlowsIfNeeded(topLevelFlowAlias, existingRealm);
}

/**
* Find and remove flow overrides with specified ID in all realm clients.
*
* @param flowId flow ID to remove overrides
* @return Map "client" -> "auth name" -> "flow id" which were removed. Used to restore overrides.
*/
public Map<String, Map<String, String>> removeFlowOverridesInClients(String flowId) {
final Map<String, Map<String, String>> clientsWithFlow = new HashMap<>();
// For all clients
for (ClientRepresentation client : clientRepository.getAll(realmImport.getRealm())) {
boolean updateClient = false;
final Map<String, String> authenticationFlowBindingOverrides = client.getAuthenticationFlowBindingOverrides();
// Search overrides with flowId
for (Map.Entry<String, String> flowBinding : authenticationFlowBindingOverrides.entrySet()) {
if (flowId.equals(flowBinding.getValue())) {
final Map<String, String> clientBinding = clientsWithFlow.computeIfAbsent(client.getClientId(), k -> new HashMap<>());
// Save override and ...
clientBinding.put(flowBinding.getKey(), flowBinding.getValue());
// Set null to the value to remove this override on update
authenticationFlowBindingOverrides.put(flowBinding.getKey(), null);
updateClient = true;
}
}
// Update client only if needed
if (updateClient) {
clientRepository.update(realmImport.getRealm(), client);
}
}

return clientsWithFlow;
}

/**
* Restore flow overrides in clients.
*
* @param clientsWithFlow map "client" -> "auth name" -> "flow id" to restore flow overrides.
*/
public void restoreClientOverrides(Map<String, Map<String, String>> clientsWithFlow) {
// restore overrides with the new patched flow
for (Map.Entry<String, Map<String, String>> clientWithFlow : clientsWithFlow.entrySet()) {
final String clientId = clientWithFlow.getKey();
final Map<String, String> overrides = clientWithFlow.getValue();

final ClientRepresentation client = clientRepository.getByClientId(realmImport.getRealm(), clientId);
// Add all overrides with patched flow to existing overrides
client.getAuthenticationFlowBindingOverrides().putAll(overrides);
clientRepository.update(realmImport.getRealm(), client);
}
}

private void disableBrowserFlowIfNeeded(String topLevelFlowAlias, RealmRepresentation existingRealm) {
if (Objects.equals(existingRealm.getBrowserFlow(), topLevelFlowAlias)) {
logger.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -313,10 +314,14 @@ private void recreateTopLevelFlow(
UsedAuthenticationFlowWorkaroundFactory.UsedAuthenticationFlowWorkaround workaround = workaroundFactory.buildFor(realmImport);
workaround.disableTopLevelFlowIfNeeded(topLevelFlowToImport.getAlias());

final Map<String, Map<String, String>> overrides = workaround.removeFlowOverridesInClients(patchedAuthenticationFlow.getId());

authenticatorConfigImportService.deleteAuthenticationConfigs(realmImport, patchedAuthenticationFlow);
authenticationFlowRepository.delete(realmImport.getRealm(), patchedAuthenticationFlow.getId());
authenticationFlowRepository.createTopLevel(realmImport.getRealm(), patchedAuthenticationFlow);

workaround.restoreClientOverrides(overrides);

AuthenticationFlowRepresentation createdTopLevelFlow = authenticationFlowRepository.getByAlias(
realmImport.getRealm(), topLevelFlowToImport.getAlias()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ abstract public class AbstractImportIT extends AbstractImportTest {
.withEnv("KEYCLOAK_ADMIN", "admin")
.withEnv("KEYCLOAK_ADMIN_PASSWORD", "admin123")
.withEnv("QUARKUS_PROFILE", "dev")
.withEnv("KC_LOG_LEVEL", KEYCLOAK_LOG_LEVEL)
.withExtraHost("host.docker.internal", "host-gateway")
.waitingFor(Wait.forHttp("/"))
.withStartupTimeout(Duration.ofSeconds(300));
Expand Down

0 comments on commit 55996a3

Please sign in to comment.