add propagation options + simplify auth config
This commit is contained in:
parent
4a2cdb5e86
commit
55052475c6
5 changed files with 47 additions and 33 deletions
|
@ -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<M extends RoleMapperModel, S extends com.unboundid.scim2.common.ScimResource> {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<ScimClient> f) {
|
||||
public void run(String scope, Consumer<ScimClient> 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());
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue