From a36fe19adc7a05f44f0a457b224faa802a7ef24b Mon Sep 17 00:00:00 2001 From: Alex Morel Date: Fri, 19 Jul 2024 10:36:34 +0200 Subject: [PATCH] Only refresh SCIM endpoints when a SCIM configuration is deleted --- ...dpointConfigurationStorageProviderFactory.java | 1 - .../scim/core/service/AbstractScimService.java | 2 +- .../sh/libre/scim/core/service/ScimClient.java | 8 ++++---- .../scim/event/ScimEventListenerProvider.java | 15 +++++++++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/sh/libre/scim/core/ScimEndpointConfigurationStorageProviderFactory.java b/src/main/java/sh/libre/scim/core/ScimEndpointConfigurationStorageProviderFactory.java index 1197980b24..b73df47725 100644 --- a/src/main/java/sh/libre/scim/core/ScimEndpointConfigurationStorageProviderFactory.java +++ b/src/main/java/sh/libre/scim/core/ScimEndpointConfigurationStorageProviderFactory.java @@ -45,7 +45,6 @@ public class ScimEndpointConfigurationStorageProviderFactory RealmModel realm = session.realms().getRealm(realmId); session.getContext().setRealm(realm); ScimDispatcher dispatcher = new ScimDispatcher(session); - LOGGER.info("-->" + model.get(ScrimEndPointConfiguration.CONF_KEY_PROPAGATION_USER) + "//" + model.get(ScrimEndPointConfiguration.CONF_KEY_PROPAGATION_GROUP)); if (BooleanUtils.TRUE.equals(model.get(ScrimEndPointConfiguration.CONF_KEY_PROPAGATION_USER))) { dispatcher.dispatchUserModificationToOne(model, client -> client.sync(result)); } diff --git a/src/main/java/sh/libre/scim/core/service/AbstractScimService.java b/src/main/java/sh/libre/scim/core/service/AbstractScimService.java index af2e938695..b2109b48ec 100644 --- a/src/main/java/sh/libre/scim/core/service/AbstractScimService.java +++ b/src/main/java/sh/libre/scim/core/service/AbstractScimService.java @@ -182,7 +182,7 @@ public abstract class AbstractScimService implements AutoCloseable { try { Retry retry = retryRegistry.retry("create-%s".formatted(id.asString())); if (logAllRequests) { - LOGGER.warn("[SCIM] Sending " + scimForCreation.toPrettyString() + "\n to " + getScimEndpoint()); + LOGGER.info("[SCIM] Sending CREATE " + scimForCreation.toPrettyString() + "\n to " + getScimEndpoint()); } ServerResponse response = retry.executeSupplier(() -> scimRequestBuilder .create(getResourceClass(), getScimEndpoint()) @@ -92,7 +92,7 @@ public class ScimClient implements AutoCloseable { private void checkResponseIsSuccess(ServerResponse response) throws InvalidResponseFromScimEndpointException { if (logAllRequests) { - LOGGER.warn("[SCIM] Server response " + response.getHttpStatus() + "\n" + response.getResponseBody()); + LOGGER.info("[SCIM] Server response " + response.getHttpStatus() + "\n" + response.getResponseBody()); } if (!response.isSuccess()) { throw new InvalidResponseFromScimEndpointException(response, "Server answered with status " + response.getResponseBody() + ": " + response.getResponseBody()); @@ -111,7 +111,7 @@ public class ScimClient implements AutoCloseable { Retry retry = retryRegistry.retry("replace-%s".formatted(externalId.asString())); try { if (logAllRequests) { - LOGGER.warn("[SCIM] Sending Update " + scimForReplace.toPrettyString() + "\n to " + getScimEndpoint()); + LOGGER.info("[SCIM] Sending UPDATE " + scimForReplace.toPrettyString() + "\n to " + getScimEndpoint()); } ServerResponse response = retry.executeSupplier(() -> scimRequestBuilder .update(getResourceClass(), getScimEndpoint(), externalId.asString()) @@ -128,7 +128,7 @@ public class ScimClient implements AutoCloseable { public void delete(EntityOnRemoteScimId externalId) throws InvalidResponseFromScimEndpointException { Retry retry = retryRegistry.retry("delete-%s".formatted(externalId.asString())); if (logAllRequests) { - LOGGER.warn("[SCIM] Sending DELETE to " + getScimEndpoint()); + LOGGER.info("[SCIM] Sending DELETE to " + getScimEndpoint()); } try { ServerResponse response = retry.executeSupplier(() -> scimRequestBuilder diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java index 7d765b6004..2c177b0e47 100644 --- a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java +++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java @@ -1,6 +1,7 @@ package sh.libre.scim.event; import org.jboss.logging.Logger; +import org.keycloak.component.ComponentModel; import org.keycloak.events.Event; import org.keycloak.events.EventListenerProvider; import org.keycloak.events.EventType; @@ -11,6 +12,7 @@ import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.UserModel; import sh.libre.scim.core.ScimDispatcher; +import sh.libre.scim.core.ScimEndpointConfigurationStorageProviderFactory; import sh.libre.scim.core.service.KeycloakDao; import sh.libre.scim.core.service.KeycloakId; import sh.libre.scim.core.service.ScimResourceType; @@ -18,6 +20,7 @@ import sh.libre.scim.core.service.ScimResourceType; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; /** * An Event listener reacting to Keycloak models modification @@ -204,18 +207,22 @@ public class ScimEventListenerProvider implements EventListenerProvider { } private void handleScimEndpointConfigurationEvent(AdminEvent event, String id) { - LOGGER.infof("[SCIM] SCIM Endpoint configuration %s - %s ", event.getOperationType(), id); - // In case of a component deletion if (event.getOperationType() == OperationType.DELETE) { // Check if it was a Scim endpoint configuration, and forward deletion if so - // TODO : determine if deleted element is of ScimStorageProvider class and only refresh in that case - dispatcher.refreshActiveScimEndpoints(); + Stream scimEndpointConfigurationsWithDeletedId = session.getContext().getRealm().getComponentsStream() + .filter(m -> ScimEndpointConfigurationStorageProviderFactory.ID.equals(m.getProviderId()) + && id.equals(m.getId())); + if (scimEndpointConfigurationsWithDeletedId.iterator().hasNext()) { + LOGGER.infof("[SCIM] SCIM Endpoint configuration DELETE - %s ", id); + dispatcher.refreshActiveScimEndpoints(); + } } else { // In case of CREATE or UPDATE, we can directly use the string representation // to check if it defines a SCIM endpoint (faster) if (event.getRepresentation() != null && event.getRepresentation().contains("\"providerId\":\"scim\"")) { + LOGGER.infof("[SCIM] SCIM Endpoint configuration CREATE - %s ", id); dispatcher.refreshActiveScimEndpoints(); } }