From 55052475c6c368a952be5d9283993c3f47776ff8 Mon Sep 17 00:00:00 2001 From: Hugo Renard Date: Tue, 3 May 2022 16:20:38 +0200 Subject: [PATCH] add propagation options + simplify auth config --- src/main/java/sh/libre/scim/core/Adapter.java | 3 +- .../java/sh/libre/scim/core/ScimClient.java | 6 +-- .../sh/libre/scim/core/ScimDispatcher.java | 7 +++- .../scim/event/ScimEventListenerProvider.java | 26 ++++++------- .../storage/ScimStorageProviderFactory.java | 38 ++++++++++++------- 5 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/main/java/sh/libre/scim/core/Adapter.java b/src/main/java/sh/libre/scim/core/Adapter.java index 2f8f40cb44..2de3124155 100644 --- a/src/main/java/sh/libre/scim/core/Adapter.java +++ b/src/main/java/sh/libre/scim/core/Adapter.java @@ -10,7 +10,6 @@ import org.jboss.logging.Logger; import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RoleMapperModel; - import sh.libre.scim.jpa.ScimResource; public abstract class Adapter { @@ -124,7 +123,7 @@ public abstract class Adapter getResourceStream(); public abstract Boolean skipRefresh(); diff --git a/src/main/java/sh/libre/scim/core/ScimClient.java b/src/main/java/sh/libre/scim/core/ScimClient.java index cd6ac1d2bf..702ff39ba2 100644 --- a/src/main/java/sh/libre/scim/core/ScimClient.java +++ b/src/main/java/sh/libre/scim/core/ScimClient.java @@ -38,12 +38,12 @@ public class ScimClient { var target = client.target(model.get("endpoint")); switch (model.get("auth-mode")) { case "BEARER": - target = target.register(new BearerAuthentication(model.get("auth-bearer-token"))); + target = target.register(new BearerAuthentication(model.get("auth-pass"))); break; case "BASIC_AUTH": target = target.register(new BasicAuthentication( - model.get("auth-basic-auth-user"), - model.get("auth-basic-auth-pass"))); + model.get("auth-user"), + model.get("auth-pass"))); } scimService = new ScimService(target); diff --git a/src/main/java/sh/libre/scim/core/ScimDispatcher.java b/src/main/java/sh/libre/scim/core/ScimDispatcher.java index db00e5842a..c8beede198 100644 --- a/src/main/java/sh/libre/scim/core/ScimDispatcher.java +++ b/src/main/java/sh/libre/scim/core/ScimDispatcher.java @@ -7,6 +7,9 @@ import org.keycloak.models.KeycloakSession; import sh.libre.scim.storage.ScimStorageProviderFactory; public class ScimDispatcher { + public static final String SCOPE_USER = "user"; + public static final String SCOPE_GROUP = "group"; + final private KeycloakSession session; final private Logger LOGGER = Logger.getLogger(ScimDispatcher.class); @@ -14,10 +17,10 @@ public class ScimDispatcher { this.session = session; } - public void run(Consumer f) { + public void run(String scope, Consumer f) { session.getContext().getRealm().getComponentsStream() .filter((m) -> { - return ScimStorageProviderFactory.ID.equals(m.getProviderId()) && m.get("enabled").equals("true"); + return ScimStorageProviderFactory.ID.equals(m.getProviderId()) && m.get("enabled").equals("true") && m.get("propagation-"+scope).equals("true"); }) .forEach(m -> { LOGGER.infof("%s %s %s %s", m.getId(), m.getName(), m.getProviderId(), m.getProviderType()); diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java index 58d791c3df..95efe5aa7b 100644 --- a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java +++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java @@ -35,14 +35,14 @@ public class ScimEventListenerProvider implements EventListenerProvider { public void onEvent(Event event) { if (event.getType() == EventType.REGISTER) { var user = getUser(event.getUserId()); - dispatcher.run((client) -> client.create(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.create(UserAdapter.class, user)); } if (event.getType() == EventType.UPDATE_EMAIL || event.getType() == EventType.UPDATE_PROFILE) { var user = getUser(event.getUserId()); - dispatcher.run((client) -> client.replace(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.replace(UserAdapter.class, user)); } if (event.getType() == EventType.DELETE_ACCOUNT) { - dispatcher.run((client) -> client.delete(UserAdapter.class, event.getUserId())); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.delete(UserAdapter.class, event.getUserId())); } } @@ -53,14 +53,14 @@ public class ScimEventListenerProvider implements EventListenerProvider { LOGGER.infof("%s %s", userId, event.getOperationType()); if (event.getOperationType() == OperationType.CREATE) { var user = getUser(userId); - dispatcher.run((client) -> client.create(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.create(UserAdapter.class, user)); } if (event.getOperationType() == OperationType.UPDATE) { var user = getUser(userId); - dispatcher.run((client) -> client.replace(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.replace(UserAdapter.class, user)); } if (event.getOperationType() == OperationType.DELETE) { - dispatcher.run((client) -> client.delete(UserAdapter.class, userId)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.delete(UserAdapter.class, userId)); } } if (event.getResourceType() == ResourceType.GROUP) { @@ -68,14 +68,14 @@ public class ScimEventListenerProvider implements EventListenerProvider { LOGGER.infof("%s %s", event.getResourcePath(), event.getOperationType()); if (event.getOperationType() == OperationType.CREATE) { var group = getGroup(groupId); - dispatcher.run((client) -> client.create(GroupAdapter.class, group)); + dispatcher.run(ScimDispatcher.SCOPE_GROUP, (client) -> client.create(GroupAdapter.class, group)); } if (event.getOperationType() == OperationType.UPDATE) { var group = getGroup(groupId); - dispatcher.run((client) -> client.replace(GroupAdapter.class, group)); + dispatcher.run(ScimDispatcher.SCOPE_GROUP, (client) -> client.replace(GroupAdapter.class, group)); } if (event.getOperationType() == OperationType.DELETE) { - dispatcher.run((client) -> client.delete(GroupAdapter.class, groupId)); + dispatcher.run(ScimDispatcher.SCOPE_GROUP, (client) -> client.delete(GroupAdapter.class, groupId)); } } if (event.getResourceType() == ResourceType.GROUP_MEMBERSHIP) { @@ -86,9 +86,9 @@ public class ScimEventListenerProvider implements EventListenerProvider { var groupId = matcher.group(2); LOGGER.infof("%s %s from %s", event.getOperationType(), userId, groupId); var group = getGroup(groupId); - dispatcher.run((client) -> client.replace(GroupAdapter.class, group)); + dispatcher.run(ScimDispatcher.SCOPE_GROUP, (client) -> client.replace(GroupAdapter.class, group)); var user = getUser(userId); - dispatcher.run((client) -> client.replace(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.replace(UserAdapter.class, user)); } } if (event.getResourceType() == ResourceType.REALM_ROLE_MAPPING) { @@ -100,11 +100,11 @@ public class ScimEventListenerProvider implements EventListenerProvider { LOGGER.infof("%s %s %s roles", event.getOperationType(), type, id); if (type.equals("users")) { var user = getUser(id); - dispatcher.run((client) -> client.replace(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.replace(UserAdapter.class, user)); } else if (type.equals("groups")) { var group = getGroup(id); session.users().getGroupMembersStream(session.getContext().getRealm(), group).forEach(user -> { - dispatcher.run((client) -> client.replace(UserAdapter.class, user)); + dispatcher.run(ScimDispatcher.SCOPE_USER, (client) -> client.replace(UserAdapter.class, user)); }); } } diff --git a/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java b/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java index 3f18b7bd34..505d884122 100644 --- a/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java +++ b/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java @@ -52,24 +52,32 @@ public class ScimStorageProviderFactory .type(ProviderConfigProperty.LIST_TYPE) .label("Auth mode") .helpText("Select the authorization mode") - .options("NONE", "BEARER", "BASIC_AUTH") + .options("NONE", "BASIC_AUTH", "BEARER") .defaultValue("NONE") .add() .property() - .name("auth-bearer-token") - .type(ProviderConfigProperty.PASSWORD) - .label("Bearer token") - .helpText("Add a bearer token in the authorization header") - .add() - .property() - .name("auth-basic-auth-user") + .name("auth-user") .type(ProviderConfigProperty.STRING_TYPE) - .label("BasicAuth user") + .label("Auth username") + .helpText("Required for basic authentification.") .add() .property() - .name("auth-basic-auth-pass") + .name("auth-pass") .type(ProviderConfigProperty.PASSWORD) - .label("BasicAuth password") + .label("Auth password/token") + .helpText("Password or token required for basic or bearer authentification.") + .add() + .property() + .name("propagation-user") + .type(ProviderConfigProperty.BOOLEAN_TYPE) + .label("Enable user propagation") + .defaultValue("true") + .add() + .property() + .name("propagation-group") + .type(ProviderConfigProperty.BOOLEAN_TYPE) + .label("Enable group propagation") + .defaultValue("true") .add() .property() .name("sync-import") @@ -120,8 +128,12 @@ public class ScimStorageProviderFactory RealmModel realm = session.realms().getRealm(realmId); session.getContext().setRealm(realm); var client = new ScimClient(model, session); - client.sync(UserAdapter.class, result); - client.sync(GroupAdapter.class, result); + if (model.get("propagation-user").equals("true")) { + client.sync(UserAdapter.class, result); + } + if (model.get("propagation-group").equals("true")) { + client.sync(GroupAdapter.class, result); + } client.close(); }