Merge pull request #3628 from mposolda/master
KEYCLOAK-4058 Improve LDAPStorageMapper and remove LDAPStorageMapperB…
This commit is contained in:
commit
10064fdac9
29 changed files with 174 additions and 303 deletions
|
@ -152,7 +152,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
List<ComponentModel> sortedMappers = sortMappersAsc(mappers);
|
List<ComponentModel> sortedMappers = sortMappersAsc(mappers);
|
||||||
for (ComponentModel mapperModel : sortedMappers) {
|
for (ComponentModel mapperModel : sortedMappers) {
|
||||||
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
||||||
proxied = ldapMapper.proxy(mapperModel, this, ldapObject, proxied, realm);
|
proxied = ldapMapper.proxy(ldapObject, proxied, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxied;
|
return proxied;
|
||||||
|
@ -283,7 +283,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
List<ComponentModel> sortedMappers = sortMappersAsc(mappers);
|
List<ComponentModel> sortedMappers = sortMappersAsc(mappers);
|
||||||
for (ComponentModel mapperModel : sortedMappers) {
|
for (ComponentModel mapperModel : sortedMappers) {
|
||||||
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
||||||
List<UserModel> users = ldapMapper.getGroupMembers(mapperModel, this, realm, group, firstResult, maxResults);
|
List<UserModel> users = ldapMapper.getGroupMembers(realm, group, firstResult, maxResults);
|
||||||
|
|
||||||
// Sufficient for now
|
// Sufficient for now
|
||||||
if (users.size() > 0) {
|
if (users.size() > 0) {
|
||||||
|
@ -387,7 +387,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
logger.tracef("Using mapper %s during import user from LDAP", mapperModel);
|
logger.tracef("Using mapper %s during import user from LDAP", mapperModel);
|
||||||
}
|
}
|
||||||
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
||||||
ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, imported, realm, true);
|
ldapMapper.onImportUserFromLDAP(ldapUser, imported, realm, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
String userDN = ldapUser.getDn().toString();
|
String userDN = ldapUser.getDn().toString();
|
||||||
|
@ -469,7 +469,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
||||||
logger.tracef("Using mapper %s during import user from LDAP", mapperModel);
|
logger.tracef("Using mapper %s during import user from LDAP", mapperModel);
|
||||||
}
|
}
|
||||||
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
LDAPStorageMapper ldapMapper = getMapper(mapperModel);
|
||||||
processed = processed || ldapMapper.onAuthenticationFailure(mapperModel, this, ldapUser, user, ae, realm);
|
processed = processed || ldapMapper.onAuthenticationFailure(ldapUser, user, ae, realm);
|
||||||
}
|
}
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,12 +360,12 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(KeycloakSession session) {
|
public void run(KeycloakSession session) {
|
||||||
LDAPStorageProvider ldapProvider = (LDAPStorageProvider)session.getProvider(UserStorageProvider.class, model);
|
|
||||||
RealmModel realm = session.realms().getRealm(realmId);
|
RealmModel realm = session.realms().getRealm(realmId);
|
||||||
|
session.getProvider(UserStorageProvider.class, model);
|
||||||
List<ComponentModel> mappers = realm.getComponents(model.getId(), LDAPStorageMapper.class.getName());
|
List<ComponentModel> mappers = realm.getComponents(model.getId(), LDAPStorageMapper.class.getName());
|
||||||
for (ComponentModel mapperModel : mappers) {
|
for (ComponentModel mapperModel : mappers) {
|
||||||
LDAPStorageMapper ldapMapper = session.getProvider(LDAPStorageMapper.class, mapperModel);
|
LDAPStorageMapper ldapMapper = session.getProvider(LDAPStorageMapper.class, mapperModel);
|
||||||
SynchronizationResult syncResult = ldapMapper.syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = ldapMapper.syncDataFromFederationProviderToKeycloak(realm);
|
||||||
if (syncResult.getAdded() > 0 || syncResult.getUpdated() > 0 || syncResult.getRemoved() > 0 || syncResult.getFailed() > 0) {
|
if (syncResult.getAdded() > 0 || syncResult.getUpdated() > 0 || syncResult.getRemoved() > 0 || syncResult.getFailed() > 0) {
|
||||||
logger.infof("Sync of federation mapper '%s' finished. Status: %s", mapperModel.getName(), syncResult.toString());
|
logger.infof("Sync of federation mapper '%s' finished. Status: %s", mapperModel.getName(), syncResult.toString());
|
||||||
}
|
}
|
||||||
|
@ -461,7 +461,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
|
||||||
List<ComponentModel> sortedMappers = ldapFedProvider.sortMappersDesc(federationMappers);
|
List<ComponentModel> sortedMappers = ldapFedProvider.sortMappersDesc(federationMappers);
|
||||||
for (ComponentModel mapperModel : sortedMappers) {
|
for (ComponentModel mapperModel : sortedMappers) {
|
||||||
LDAPStorageMapper ldapMapper = ldapFedProvider.getMapper(mapperModel);
|
LDAPStorageMapper ldapMapper = ldapFedProvider.getMapper(mapperModel);
|
||||||
ldapMapper.onImportUserFromLDAP(mapperModel, ldapFedProvider, ldapUser, currentUser, currentRealm, false);
|
ldapMapper.onImportUserFromLDAP(ldapUser, currentUser, currentRealm, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debugf("Updated user from LDAP: %s", currentUser.getUsername());
|
logger.debugf("Updated user from LDAP: %s", currentUser.getUsername());
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class LDAPUtils {
|
||||||
List<ComponentModel> sortedMappers = ldapProvider.sortMappersAsc(federationMappers);
|
List<ComponentModel> sortedMappers = ldapProvider.sortMappersAsc(federationMappers);
|
||||||
for (ComponentModel mapperModel : sortedMappers) {
|
for (ComponentModel mapperModel : sortedMappers) {
|
||||||
LDAPStorageMapper ldapMapper = ldapProvider.getMapper(mapperModel);
|
LDAPStorageMapper ldapMapper = ldapProvider.getMapper(mapperModel);
|
||||||
ldapMapper.onRegisterUserToLDAP(mapperModel, ldapProvider, ldapUser, user, realm);
|
ldapMapper.onRegisterUserToLDAP(ldapUser, user, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
LDAPUtils.computeAndSetDn(ldapConfig, ldapUser);
|
LDAPUtils.computeAndSetDn(ldapConfig, ldapUser);
|
||||||
|
|
|
@ -155,7 +155,7 @@ public class LDAPQuery {
|
||||||
List<ComponentModel> sortedMappers = ldapFedProvider.sortMappersAsc(mappers);
|
List<ComponentModel> sortedMappers = ldapFedProvider.sortMappersAsc(mappers);
|
||||||
for (ComponentModel mapperModel : sortedMappers) {
|
for (ComponentModel mapperModel : sortedMappers) {
|
||||||
LDAPStorageMapper fedMapper = ldapFedProvider.getMapper(mapperModel);
|
LDAPStorageMapper fedMapper = ldapFedProvider.getMapper(mapperModel);
|
||||||
fedMapper.beforeLDAPQuery(mapperModel, this);
|
fedMapper.beforeLDAPQuery(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<LDAPObject> result = new ArrayList<LDAPObject>();
|
List<LDAPObject> result = new ArrayList<LDAPObject>();
|
||||||
|
|
|
@ -36,57 +36,35 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractLDAPStorageMapper {
|
public abstract class AbstractLDAPStorageMapper implements LDAPStorageMapper {
|
||||||
|
|
||||||
|
protected final KeycloakSession session;
|
||||||
protected final ComponentModel mapperModel;
|
protected final ComponentModel mapperModel;
|
||||||
protected final LDAPStorageProvider ldapProvider;
|
protected final LDAPStorageProvider ldapProvider;
|
||||||
protected final RealmModel realm;
|
|
||||||
|
|
||||||
public AbstractLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public AbstractLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
||||||
this.mapperModel = mapperModel;
|
this.mapperModel = mapperModel;
|
||||||
this.ldapProvider = ldapProvider;
|
this.ldapProvider = ldapProvider;
|
||||||
this.realm = realm;
|
this.session = ldapProvider.getSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see LDAPStorageMapper#syncDataFromFederationProviderToKeycloak(ComponentModel, LDAPStorageProvider, KeycloakSession, RealmModel)
|
public SynchronizationResult syncDataFromFederationProviderToKeycloak(RealmModel realm) {
|
||||||
*/
|
|
||||||
public SynchronizationResult syncDataFromFederationProviderToKeycloak() {
|
|
||||||
return new SynchronizationResult();
|
return new SynchronizationResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see LDAPStorageMapper#syncDataFromKeycloakToFederationProvider(ComponentModel, LDAPStorageProvider, KeycloakSession, RealmModel)
|
public SynchronizationResult syncDataFromKeycloakToFederationProvider(RealmModel realm) {
|
||||||
*/
|
|
||||||
public SynchronizationResult syncDataFromKeycloakToFederationProvider() {
|
|
||||||
return new SynchronizationResult();
|
return new SynchronizationResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see LDAPStorageMapper#beforeLDAPQuery(ComponentModel, LDAPQuery)
|
|
||||||
*/
|
|
||||||
public abstract void beforeLDAPQuery(LDAPQuery query);
|
|
||||||
|
|
||||||
/**
|
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||||
* @see LDAPStorageMapper#proxy(ComponentModel, LDAPStorageProvider, LDAPObject, UserModel, RealmModel)
|
|
||||||
*/
|
|
||||||
public abstract UserModel proxy(LDAPObject ldapUser, UserModel delegate);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see LDAPStorageMapper#onRegisterUserToLDAP(ComponentModel, LDAPStorageProvider, LDAPObject, UserModel, RealmModel)
|
|
||||||
*/
|
|
||||||
public abstract void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see LDAPStorageMapper#onImportUserFromLDAP(ComponentModel, LDAPStorageProvider, LDAPObject, UserModel, RealmModel, boolean)
|
|
||||||
*/
|
|
||||||
public abstract void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate);
|
|
||||||
|
|
||||||
public List<UserModel> getGroupMembers(GroupModel group, int firstResult, int maxResults) {
|
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException) {
|
|
||||||
|
public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException, RealmModel realm) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +74,15 @@ public abstract class AbstractLDAPStorageMapper {
|
||||||
return Boolean.parseBoolean(paramm);
|
return Boolean.parseBoolean(paramm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public LDAPStorageProvider getLdapProvider() {
|
public LDAPStorageProvider getLdapProvider() {
|
||||||
return ldapProvider;
|
return ldapProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RealmModel getRealm() {
|
|
||||||
return realm;
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,7 @@ import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.component.ComponentValidationException;
|
import org.keycloak.component.ComponentValidationException;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.representations.idm.UserFederationMapperSyncConfigRepresentation;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -52,10 +50,15 @@ public abstract class AbstractLDAPStorageMapperFactory implements LDAPStorageMap
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LDAPStorageMapper create(KeycloakSession session, ComponentModel model) {
|
public LDAPStorageMapper create(KeycloakSession session, ComponentModel model) {
|
||||||
return new LDAPStorageMapperBridge(this); }
|
// LDAPStorageProvider is in the session already as mappers are always called from it
|
||||||
|
String ldapProviderModelId = model.getParentId();
|
||||||
|
LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getAttribute(ldapProviderModelId);
|
||||||
|
|
||||||
|
return createMapper(model, ldapProvider);
|
||||||
|
}
|
||||||
|
|
||||||
// Used just by LDAPFederationMapperBridge.
|
// Used just by LDAPFederationMapperBridge.
|
||||||
protected abstract AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm);
|
protected abstract AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
|
|
|
@ -43,12 +43,12 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
public static final String WRITE_ONLY = "write.only";
|
public static final String WRITE_ONLY = "write.only";
|
||||||
|
|
||||||
|
|
||||||
public FullNameLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public FullNameLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
if (isWriteOnly()) {
|
if (isWriteOnly()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
String ldapFullNameAttrName = getLdapFullNameAttrName();
|
String ldapFullNameAttrName = getLdapFullNameAttrName();
|
||||||
String fullName = getFullName(localUser.getFirstName(), localUser.getLastName());
|
String fullName = getFullName(localUser.getFirstName(), localUser.getLastName());
|
||||||
ldapUser.setSingleAttribute(ldapFullNameAttrName, fullName);
|
ldapUser.setSingleAttribute(ldapFullNameAttrName, fullName);
|
||||||
|
@ -83,7 +83,7 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
|
public UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE && !isReadOnly()) {
|
if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE && !isReadOnly()) {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ public class FullNameLDAPStorageMapperFactory extends AbstractLDAPStorageMapperF
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new FullNameLDAPStorageMapper(mapperModel, federationProvider, realm);
|
return new FullNameLDAPStorageMapper(mapperModel, federationProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,8 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
|
|
||||||
public static final String ROLE = "role";
|
public static final String ROLE = "role";
|
||||||
|
|
||||||
public HardcodedLDAPRoleStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public HardcodedLDAPRoleStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,14 +50,14 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
|
public UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
return new UserModelDelegate(delegate) {
|
return new UserModelDelegate(delegate) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<RoleModel> getRealmRoleMappings() {
|
public Set<RoleModel> getRealmRoleMappings() {
|
||||||
Set<RoleModel> roles = super.getRealmRoleMappings();
|
Set<RoleModel> roles = super.getRealmRoleMappings();
|
||||||
|
|
||||||
RoleModel role = getRole();
|
RoleModel role = getRole(realm);
|
||||||
if (role != null && role.getContainer().equals(realm)) {
|
if (role != null && role.getContainer().equals(realm)) {
|
||||||
roles.add(role);
|
roles.add(role);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||||
Set<RoleModel> roles = super.getClientRoleMappings(app);
|
Set<RoleModel> roles = super.getClientRoleMappings(app);
|
||||||
|
|
||||||
RoleModel role = getRole();
|
RoleModel role = getRole(realm);
|
||||||
if (role != null && role.getContainer().equals(app)) {
|
if (role != null && role.getContainer().equals(app)) {
|
||||||
roles.add(role);
|
roles.add(role);
|
||||||
}
|
}
|
||||||
|
@ -79,14 +79,14 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasRole(RoleModel role) {
|
public boolean hasRole(RoleModel role) {
|
||||||
return super.hasRole(role) || role.equals(getRole());
|
return super.hasRole(role) || role.equals(getRole(realm));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<RoleModel> getRoleMappings() {
|
public Set<RoleModel> getRoleMappings() {
|
||||||
Set<RoleModel> roles = super.getRoleMappings();
|
Set<RoleModel> roles = super.getRoleMappings();
|
||||||
|
|
||||||
RoleModel role = getRole();
|
RoleModel role = getRole(realm);
|
||||||
if (role != null) {
|
if (role != null) {
|
||||||
roles.add(role);
|
roles.add(role);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteRoleMapping(RoleModel role) {
|
public void deleteRoleMapping(RoleModel role) {
|
||||||
if (role.equals(getRole())) {
|
if (role.equals(getRole(realm))) {
|
||||||
throw new ModelException("Not possible to delete role. It's hardcoded by LDAP mapper");
|
throw new ModelException("Not possible to delete role. It's hardcoded by LDAP mapper");
|
||||||
} else {
|
} else {
|
||||||
super.deleteRoleMapping(role);
|
super.deleteRoleMapping(role);
|
||||||
|
@ -106,16 +106,16 @@ public class HardcodedLDAPRoleStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private RoleModel getRole() {
|
private RoleModel getRole(RealmModel realm) {
|
||||||
String roleName = mapperModel.getConfig().getFirst(HardcodedLDAPRoleStorageMapper.ROLE);
|
String roleName = mapperModel.getConfig().getFirst(HardcodedLDAPRoleStorageMapper.ROLE);
|
||||||
RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
|
RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
|
||||||
if (role == null) {
|
if (role == null) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class HardcodedLDAPRoleStorageMapperFactory extends AbstractLDAPStorageMa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new HardcodedLDAPRoleStorageMapper(mapperModel, federationProvider, realm);
|
return new HardcodedLDAPRoleStorageMapper(mapperModel, federationProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,10 @@
|
||||||
|
|
||||||
package org.keycloak.storage.ldap.mappers;
|
package org.keycloak.storage.ldap.mappers;
|
||||||
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
|
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
import org.keycloak.storage.user.SynchronizationResult;
|
||||||
|
@ -42,84 +39,66 @@ public interface LDAPStorageMapper extends Provider {
|
||||||
*
|
*
|
||||||
* Applicable just if sync is supported
|
* Applicable just if sync is supported
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
|
||||||
* @param provider
|
|
||||||
* @param session
|
|
||||||
* @param realm
|
|
||||||
*/
|
*/
|
||||||
SynchronizationResult syncDataFromFederationProviderToKeycloak(ComponentModel mapperModel, LDAPStorageProvider provider, KeycloakSession session, RealmModel realm);
|
SynchronizationResult syncDataFromFederationProviderToKeycloak(RealmModel realm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync data from Keycloak back to federated storage
|
* Sync data from Keycloak back to federated storage
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
**/
|
||||||
* @param provider
|
SynchronizationResult syncDataFromKeycloakToFederationProvider(RealmModel realm);
|
||||||
* @param session
|
|
||||||
* @param realm
|
|
||||||
*/
|
|
||||||
SynchronizationResult syncDataFromKeycloakToFederationProvider(ComponentModel mapperModel, LDAPStorageProvider provider, KeycloakSession session, RealmModel realm);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return empty list if doesn't support storing of groups
|
* Return empty list if doesn't support storing of groups
|
||||||
*/
|
*/
|
||||||
List<UserModel> getGroupMembers(ComponentModel mapperModel, LDAPStorageProvider provider, RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when importing user from LDAP to local keycloak DB.
|
* Called when importing user from LDAP to local keycloak DB.
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
|
||||||
* @param ldapProvider
|
|
||||||
* @param ldapUser
|
* @param ldapUser
|
||||||
* @param user
|
* @param user
|
||||||
* @param realm
|
* @param realm
|
||||||
* @param isCreate true if we importing new user from LDAP. False if user already exists in Keycloak, but we are upgrading (syncing) it from LDAP
|
* @param isCreate true if we importing new user from LDAP. False if user already exists in Keycloak, but we are upgrading (syncing) it from LDAP
|
||||||
*/
|
*/
|
||||||
void onImportUserFromLDAP(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate);
|
void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when register new user to LDAP - just after user was created in Keycloak DB
|
* Called when register new user to LDAP - just after user was created in Keycloak DB
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
|
||||||
* @param ldapProvider
|
|
||||||
* @param ldapUser
|
* @param ldapUser
|
||||||
* @param localUser
|
* @param localUser
|
||||||
* @param realm
|
* @param realm
|
||||||
*/
|
*/
|
||||||
void onRegisterUserToLDAP(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel localUser, RealmModel realm);
|
void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when invoke proxy on LDAP federation provider
|
* Called when invoke proxy on LDAP federation provider
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
|
||||||
* @param ldapProvider
|
|
||||||
* @param ldapUser
|
* @param ldapUser
|
||||||
* @param delegate
|
* @param delegate
|
||||||
* @param realm
|
* @param realm
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
UserModel proxy(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel delegate, RealmModel realm);
|
UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before LDAP Identity query for retrieve LDAP users was executed. It allows to change query somehow (add returning attributes from LDAP, change conditions etc)
|
* Called before LDAP Identity query for retrieve LDAP users was executed. It allows to change query somehow (add returning attributes from LDAP, change conditions etc)
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
|
||||||
* @param query
|
* @param query
|
||||||
*/
|
*/
|
||||||
void beforeLDAPQuery(ComponentModel mapperModel, LDAPQuery query);
|
void beforeLDAPQuery(LDAPQuery query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when LDAP authentication of specified user fails. If any mapper returns true from this method, AuthenticationException won't be rethrown!
|
* Called when LDAP authentication of specified user fails. If any mapper returns true from this method, AuthenticationException won't be rethrown!
|
||||||
*
|
*
|
||||||
* @param mapperModel
|
|
||||||
* @param ldapProvider
|
|
||||||
* @param realm
|
|
||||||
* @param user
|
* @param user
|
||||||
* @param ldapUser
|
* @param ldapUser
|
||||||
* @param ldapException
|
* @param ldapException
|
||||||
* @return true if mapper processed the AuthenticationException and did some actions based on that. In that case, AuthenticationException won't be rethrown!
|
* @return true if mapper processed the AuthenticationException and did some actions based on that. In that case, AuthenticationException won't be rethrown!
|
||||||
*/
|
*/
|
||||||
boolean onAuthenticationFailure(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel user, AuthenticationException ldapException, RealmModel realm);
|
boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException, RealmModel realm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.storage.ldap.mappers;
|
|
||||||
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.models.GroupModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
|
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
|
||||||
|
|
||||||
import javax.naming.AuthenticationException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sufficient if mapper implementation is stateless and doesn't need to "close" any state
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class LDAPStorageMapperBridge implements LDAPStorageMapper {
|
|
||||||
|
|
||||||
private final AbstractLDAPStorageMapperFactory factory;
|
|
||||||
|
|
||||||
public LDAPStorageMapperBridge(AbstractLDAPStorageMapperFactory factory) {
|
|
||||||
this.factory = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync groups from LDAP to Keycloak DB
|
|
||||||
@Override
|
|
||||||
public SynchronizationResult syncDataFromFederationProviderToKeycloak(ComponentModel mapperModel, LDAPStorageProvider federationProvider, KeycloakSession session, RealmModel realm) {
|
|
||||||
return getDelegate(mapperModel, federationProvider, realm).syncDataFromFederationProviderToKeycloak();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SynchronizationResult syncDataFromKeycloakToFederationProvider(ComponentModel mapperModel, LDAPStorageProvider federationProvider, KeycloakSession session, RealmModel realm) {
|
|
||||||
return getDelegate(mapperModel, federationProvider, realm).syncDataFromKeycloakToFederationProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onImportUserFromLDAP(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
|
||||||
getDelegate(mapperModel, ldapProvider, realm).onImportUserFromLDAP(ldapUser, user, isCreate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRegisterUserToLDAP(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
|
||||||
getDelegate(mapperModel, ldapProvider, realm).onRegisterUserToLDAP(ldapUser, localUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel proxy(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
|
||||||
return getDelegate(mapperModel, ldapProvider, realm).proxy(ldapUser, delegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeLDAPQuery(ComponentModel mapperModel, LDAPQuery query) {
|
|
||||||
// Improve if needed
|
|
||||||
getDelegate(mapperModel, query.getLdapProvider(), null).beforeLDAPQuery(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> getGroupMembers(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
|
||||||
return getDelegate(mapperModel, ldapProvider, realm).getGroupMembers(group, firstResult, maxResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onAuthenticationFailure(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, LDAPObject ldapUser, UserModel user, AuthenticationException ldapException, RealmModel realm) {
|
|
||||||
return getDelegate(mapperModel, ldapProvider, realm).onAuthenticationFailure(ldapUser, user, ldapException);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AbstractLDAPStorageMapper getDelegate(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
|
||||||
LDAPStorageProvider ldapProvider = (LDAPStorageProvider) federationProvider;
|
|
||||||
return factory.createMapper(mapperModel, ldapProvider, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -81,12 +81,12 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
public static final String ALWAYS_READ_VALUE_FROM_LDAP = "always.read.value.from.ldap";
|
public static final String ALWAYS_READ_VALUE_FROM_LDAP = "always.read.value.from.ldap";
|
||||||
public static final String IS_MANDATORY_IN_LDAP = "is.mandatory.in.ldap";
|
public static final String IS_MANDATORY_IN_LDAP = "is.mandatory.in.ldap";
|
||||||
|
|
||||||
public UserAttributeLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public UserAttributeLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
String userModelAttrName = mapperModel.getConfig().getFirst(USER_MODEL_ATTRIBUTE);
|
String userModelAttrName = mapperModel.getConfig().getFirst(USER_MODEL_ATTRIBUTE);
|
||||||
String ldapAttrName = mapperModel.getConfig().getFirst(LDAP_ATTRIBUTE);
|
String ldapAttrName = mapperModel.getConfig().getFirst(LDAP_ATTRIBUTE);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
String userModelAttrName = mapperModel.getConfig().getFirst(USER_MODEL_ATTRIBUTE);
|
String userModelAttrName = mapperModel.getConfig().getFirst(USER_MODEL_ATTRIBUTE);
|
||||||
String ldapAttrName = mapperModel.getConfig().getFirst(LDAP_ATTRIBUTE);
|
String ldapAttrName = mapperModel.getConfig().getFirst(LDAP_ATTRIBUTE);
|
||||||
boolean isMandatoryInLdap = parseBooleanParameter(mapperModel, IS_MANDATORY_IN_LDAP);
|
boolean isMandatoryInLdap = parseBooleanParameter(mapperModel, IS_MANDATORY_IN_LDAP);
|
||||||
|
@ -172,7 +172,7 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(final LDAPObject ldapUser, UserModel delegate) {
|
public UserModel proxy(final LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
final String userModelAttrName = mapperModel.getConfig().getFirst(USER_MODEL_ATTRIBUTE);
|
final String userModelAttrName = mapperModel.getConfig().getFirst(USER_MODEL_ATTRIBUTE);
|
||||||
final String ldapAttrName = mapperModel.getConfig().getFirst(LDAP_ATTRIBUTE);
|
final String ldapAttrName = mapperModel.getConfig().getFirst(LDAP_ATTRIBUTE);
|
||||||
boolean isAlwaysReadValueFromLDAP = parseBooleanParameter(mapperModel, ALWAYS_READ_VALUE_FROM_LDAP);
|
boolean isAlwaysReadValueFromLDAP = parseBooleanParameter(mapperModel, ALWAYS_READ_VALUE_FROM_LDAP);
|
||||||
|
|
|
@ -95,8 +95,8 @@ public class UserAttributeLDAPStorageMapperFactory extends AbstractLDAPStorageMa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new UserAttributeLDAPStorageMapper(mapperModel, federationProvider, realm);
|
return new UserAttributeLDAPStorageMapper(mapperModel, federationProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -68,8 +68,7 @@ public enum MembershipType {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getGroupMembers(GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup, int firstResult, int maxResults) {
|
public List<UserModel> getGroupMembers(RealmModel realm, GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup, int firstResult, int maxResults) {
|
||||||
RealmModel realm = groupMapper.getRealm();
|
|
||||||
LDAPStorageProvider ldapProvider = groupMapper.getLdapProvider();
|
LDAPStorageProvider ldapProvider = groupMapper.getLdapProvider();
|
||||||
CommonLDAPGroupMapperConfig config = groupMapper.getConfig();
|
CommonLDAPGroupMapperConfig config = groupMapper.getConfig();
|
||||||
|
|
||||||
|
@ -134,7 +133,7 @@ public enum MembershipType {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getGroupMembers(GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup, int firstResult, int maxResults) {
|
public List<UserModel> getGroupMembers(RealmModel realm, GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup, int firstResult, int maxResults) {
|
||||||
String memberAttrName = groupMapper.getConfig().getMembershipLdapAttribute();
|
String memberAttrName = groupMapper.getConfig().getMembershipLdapAttribute();
|
||||||
Set<String> memberUids = LDAPUtils.getExistingMemberships(memberAttrName, ldapGroup);
|
Set<String> memberUids = LDAPUtils.getExistingMemberships(memberAttrName, ldapGroup);
|
||||||
|
|
||||||
|
@ -146,12 +145,12 @@ public enum MembershipType {
|
||||||
int max = Math.min(memberUids.size(), firstResult + maxResults);
|
int max = Math.min(memberUids.size(), firstResult + maxResults);
|
||||||
uids = uids.subList(firstResult, max);
|
uids = uids.subList(firstResult, max);
|
||||||
|
|
||||||
return groupMapper.getLdapProvider().loadUsersByUsernames(uids, groupMapper.getRealm());
|
return groupMapper.getLdapProvider().loadUsersByUsernames(uids, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract Set<LDAPDn> getLDAPSubgroups(GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup);
|
public abstract Set<LDAPDn> getLDAPSubgroups(GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup);
|
||||||
|
|
||||||
public abstract List<UserModel> getGroupMembers(GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup, int firstResult, int maxResults);
|
public abstract List<UserModel> getGroupMembers(RealmModel realm, GroupLDAPStorageMapper groupMapper, LDAPObject ldapGroup, int firstResult, int maxResults);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,8 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
// Flag to avoid syncing multiple times per transaction
|
// Flag to avoid syncing multiple times per transaction
|
||||||
private boolean syncFromLDAPPerformedInThisTransaction = false;
|
private boolean syncFromLDAPPerformedInThisTransaction = false;
|
||||||
|
|
||||||
public GroupLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm, GroupLDAPStorageMapperFactory factory) {
|
public GroupLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, GroupLDAPStorageMapperFactory factory) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
this.config = new GroupMapperConfig(mapperModel);
|
this.config = new GroupMapperConfig(mapperModel);
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
// Sync from Ldap to KC
|
// Sync from Ldap to KC
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SynchronizationResult syncDataFromFederationProviderToKeycloak() {
|
public SynchronizationResult syncDataFromFederationProviderToKeycloak(RealmModel realm) {
|
||||||
SynchronizationResult syncResult = new SynchronizationResult() {
|
SynchronizationResult syncResult = new SynchronizationResult() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -176,7 +176,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
try {
|
try {
|
||||||
List<GroupTreeResolver.GroupTreeEntry> groupTrees = new GroupTreeResolver().resolveGroupTree(ldapGroupsRep);
|
List<GroupTreeResolver.GroupTreeEntry> groupTrees = new GroupTreeResolver().resolveGroupTree(ldapGroupsRep);
|
||||||
|
|
||||||
updateKeycloakGroupTree(groupTrees, ldapGroupsMap, syncResult);
|
updateKeycloakGroupTree(realm, groupTrees, ldapGroupsMap, syncResult);
|
||||||
} catch (GroupTreeResolver.GroupTreeResolveException gre) {
|
} catch (GroupTreeResolver.GroupTreeResolveException gre) {
|
||||||
throw new ModelException("Couldn't resolve groups from LDAP. Fix LDAP or skip preserve inheritance. Details: " + gre.getMessage(), gre);
|
throw new ModelException("Couldn't resolve groups from LDAP. Fix LDAP or skip preserve inheritance. Details: " + gre.getMessage(), gre);
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
// Possibly remove keycloak groups, which doesn't exists in LDAP
|
// Possibly remove keycloak groups, which doesn't exists in LDAP
|
||||||
if (config.isDropNonExistingGroupsDuringSync()) {
|
if (config.isDropNonExistingGroupsDuringSync()) {
|
||||||
dropNonExistingKcGroups(syncResult, visitedGroupIds);
|
dropNonExistingKcGroups(realm, syncResult, visitedGroupIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,20 +212,20 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
return syncResult;
|
return syncResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateKeycloakGroupTree(List<GroupTreeResolver.GroupTreeEntry> groupTrees, Map<String, LDAPObject> ldapGroups, SynchronizationResult syncResult) {
|
private void updateKeycloakGroupTree(RealmModel realm, List<GroupTreeResolver.GroupTreeEntry> groupTrees, Map<String, LDAPObject> ldapGroups, SynchronizationResult syncResult) {
|
||||||
Set<String> visitedGroupIds = new HashSet<>();
|
Set<String> visitedGroupIds = new HashSet<>();
|
||||||
|
|
||||||
for (GroupTreeResolver.GroupTreeEntry groupEntry : groupTrees) {
|
for (GroupTreeResolver.GroupTreeEntry groupEntry : groupTrees) {
|
||||||
updateKeycloakGroupTreeEntry(groupEntry, ldapGroups, null, syncResult, visitedGroupIds);
|
updateKeycloakGroupTreeEntry(realm, groupEntry, ldapGroups, null, syncResult, visitedGroupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possibly remove keycloak groups, which doesn't exists in LDAP
|
// Possibly remove keycloak groups, which doesn't exists in LDAP
|
||||||
if (config.isDropNonExistingGroupsDuringSync()) {
|
if (config.isDropNonExistingGroupsDuringSync()) {
|
||||||
dropNonExistingKcGroups(syncResult, visitedGroupIds);
|
dropNonExistingKcGroups(realm, syncResult, visitedGroupIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateKeycloakGroupTreeEntry(GroupTreeResolver.GroupTreeEntry groupTreeEntry, Map<String, LDAPObject> ldapGroups, GroupModel kcParent, SynchronizationResult syncResult, Set<String> visitedGroupIds) {
|
private void updateKeycloakGroupTreeEntry(RealmModel realm, GroupTreeResolver.GroupTreeEntry groupTreeEntry, Map<String, LDAPObject> ldapGroups, GroupModel kcParent, SynchronizationResult syncResult, Set<String> visitedGroupIds) {
|
||||||
String groupName = groupTreeEntry.getGroupName();
|
String groupName = groupTreeEntry.getGroupName();
|
||||||
|
|
||||||
// Check if group already exists
|
// Check if group already exists
|
||||||
|
@ -259,11 +259,11 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
visitedGroupIds.add(kcGroup.getId());
|
visitedGroupIds.add(kcGroup.getId());
|
||||||
|
|
||||||
for (GroupTreeResolver.GroupTreeEntry childEntry : groupTreeEntry.getChildren()) {
|
for (GroupTreeResolver.GroupTreeEntry childEntry : groupTreeEntry.getChildren()) {
|
||||||
updateKeycloakGroupTreeEntry(childEntry, ldapGroups, kcGroup, syncResult, visitedGroupIds);
|
updateKeycloakGroupTreeEntry(realm, childEntry, ldapGroups, kcGroup, syncResult, visitedGroupIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dropNonExistingKcGroups(SynchronizationResult syncResult, Set<String> visitedGroupIds) {
|
private void dropNonExistingKcGroups(RealmModel realm, SynchronizationResult syncResult, Set<String> visitedGroupIds) {
|
||||||
// Remove keycloak groups, which doesn't exists in LDAP
|
// Remove keycloak groups, which doesn't exists in LDAP
|
||||||
List<GroupModel> allGroups = realm.getGroups();
|
List<GroupModel> allGroups = realm.getGroups();
|
||||||
for (GroupModel kcGroup : allGroups) {
|
for (GroupModel kcGroup : allGroups) {
|
||||||
|
@ -289,7 +289,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected GroupModel findKcGroupByLDAPGroup(LDAPObject ldapGroup) {
|
protected GroupModel findKcGroupByLDAPGroup(RealmModel realm, LDAPObject ldapGroup) {
|
||||||
String groupNameAttr = config.getGroupNameLdapAttribute();
|
String groupNameAttr = config.getGroupNameLdapAttribute();
|
||||||
String groupName = ldapGroup.getAttributeAsString(groupNameAttr);
|
String groupName = ldapGroup.getAttributeAsString(groupNameAttr);
|
||||||
|
|
||||||
|
@ -309,8 +309,8 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GroupModel findKcGroupOrSyncFromLDAP(LDAPObject ldapGroup, UserModel user) {
|
protected GroupModel findKcGroupOrSyncFromLDAP(RealmModel realm, LDAPObject ldapGroup, UserModel user) {
|
||||||
GroupModel kcGroup = findKcGroupByLDAPGroup(ldapGroup);
|
GroupModel kcGroup = findKcGroupByLDAPGroup(realm, ldapGroup);
|
||||||
|
|
||||||
if (kcGroup == null) {
|
if (kcGroup == null) {
|
||||||
|
|
||||||
|
@ -318,8 +318,8 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
// Better to sync all groups from LDAP with preserved inheritance
|
// Better to sync all groups from LDAP with preserved inheritance
|
||||||
if (!syncFromLDAPPerformedInThisTransaction) {
|
if (!syncFromLDAPPerformedInThisTransaction) {
|
||||||
syncDataFromFederationProviderToKeycloak();
|
syncDataFromFederationProviderToKeycloak(realm);
|
||||||
kcGroup = findKcGroupByLDAPGroup(ldapGroup);
|
kcGroup = findKcGroupByLDAPGroup(realm, ldapGroup);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String groupNameAttr = config.getGroupNameLdapAttribute();
|
String groupNameAttr = config.getGroupNameLdapAttribute();
|
||||||
|
@ -348,8 +348,8 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
|
|
||||||
// Sync from Keycloak to LDAP
|
// Sync from Keycloak to LDAP
|
||||||
|
@Override
|
||||||
public SynchronizationResult syncDataFromKeycloakToFederationProvider() {
|
public SynchronizationResult syncDataFromKeycloakToFederationProvider(RealmModel realm) {
|
||||||
SynchronizationResult syncResult = new SynchronizationResult() {
|
SynchronizationResult syncResult = new SynchronizationResult() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -480,20 +480,20 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserModel> getGroupMembers(GroupModel kcGroup, int firstResult, int maxResults) {
|
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel kcGroup, int firstResult, int maxResults) {
|
||||||
LDAPObject ldapGroup = loadLDAPGroupByName(kcGroup.getName());
|
LDAPObject ldapGroup = loadLDAPGroupByName(kcGroup.getName());
|
||||||
if (ldapGroup == null) {
|
if (ldapGroup == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
MembershipType membershipType = config.getMembershipTypeLdapAttribute();
|
MembershipType membershipType = config.getMembershipTypeLdapAttribute();
|
||||||
return membershipType.getGroupMembers(this, ldapGroup, firstResult, maxResults);
|
return membershipType.getGroupMembers(realm, this, ldapGroup, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addGroupMappingInLDAP(String groupName, LDAPObject ldapUser) {
|
public void addGroupMappingInLDAP(RealmModel realm, String groupName, LDAPObject ldapUser) {
|
||||||
LDAPObject ldapGroup = loadLDAPGroupByName(groupName);
|
LDAPObject ldapGroup = loadLDAPGroupByName(groupName);
|
||||||
if (ldapGroup == null) {
|
if (ldapGroup == null) {
|
||||||
syncDataFromKeycloakToFederationProvider();
|
syncDataFromKeycloakToFederationProvider(realm);
|
||||||
ldapGroup = loadLDAPGroupByName(groupName);
|
ldapGroup = loadLDAPGroupByName(groupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,27 +510,31 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
return strategy.getLDAPRoleMappings(this, ldapUser);
|
return strategy.getLDAPRoleMappings(this, ldapUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void beforeLDAPQuery(LDAPQuery query) {
|
public void beforeLDAPQuery(LDAPQuery query) {
|
||||||
String strategyKey = config.getUserGroupsRetrieveStrategy();
|
String strategyKey = config.getUserGroupsRetrieveStrategy();
|
||||||
UserRolesRetrieveStrategy strategy = factory.getUserGroupsRetrieveStrategy(strategyKey);
|
UserRolesRetrieveStrategy strategy = factory.getUserGroupsRetrieveStrategy(strategyKey);
|
||||||
strategy.beforeUserLDAPQuery(query);
|
strategy.beforeUserLDAPQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
|
@Override
|
||||||
|
public UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
final LDAPGroupMapperMode mode = config.getMode();
|
final LDAPGroupMapperMode mode = config.getMode();
|
||||||
|
|
||||||
// For IMPORT mode, all operations are performed against local DB
|
// For IMPORT mode, all operations are performed against local DB
|
||||||
if (mode == LDAPGroupMapperMode.IMPORT) {
|
if (mode == LDAPGroupMapperMode.IMPORT) {
|
||||||
return delegate;
|
return delegate;
|
||||||
} else {
|
} else {
|
||||||
return new LDAPGroupMappingsUserDelegate(delegate, ldapUser);
|
return new LDAPGroupMappingsUserDelegate(realm, delegate, ldapUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
@Override
|
||||||
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
@Override
|
||||||
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
LDAPGroupMapperMode mode = config.getMode();
|
LDAPGroupMapperMode mode = config.getMode();
|
||||||
|
|
||||||
// For now, import LDAP group mappings just during create
|
// For now, import LDAP group mappings just during create
|
||||||
|
@ -541,7 +545,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
// Import role mappings from LDAP into Keycloak DB
|
// Import role mappings from LDAP into Keycloak DB
|
||||||
for (LDAPObject ldapGroup : ldapGroups) {
|
for (LDAPObject ldapGroup : ldapGroups) {
|
||||||
|
|
||||||
GroupModel kcGroup = findKcGroupOrSyncFromLDAP(ldapGroup, user);
|
GroupModel kcGroup = findKcGroupOrSyncFromLDAP(realm, ldapGroup, user);
|
||||||
if (kcGroup != null) {
|
if (kcGroup != null) {
|
||||||
logger.debugf("User '%s' joins group '%s' during import from LDAP", user.getUsername(), kcGroup.getName());
|
logger.debugf("User '%s' joins group '%s' during import from LDAP", user.getUsername(), kcGroup.getName());
|
||||||
user.joinGroup(kcGroup);
|
user.joinGroup(kcGroup);
|
||||||
|
@ -553,13 +557,15 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
public class LDAPGroupMappingsUserDelegate extends UserModelDelegate {
|
public class LDAPGroupMappingsUserDelegate extends UserModelDelegate {
|
||||||
|
|
||||||
|
private final RealmModel realm;
|
||||||
private final LDAPObject ldapUser;
|
private final LDAPObject ldapUser;
|
||||||
|
|
||||||
// Avoid loading group mappings from LDAP more times per-request
|
// Avoid loading group mappings from LDAP more times per-request
|
||||||
private Set<GroupModel> cachedLDAPGroupMappings;
|
private Set<GroupModel> cachedLDAPGroupMappings;
|
||||||
|
|
||||||
public LDAPGroupMappingsUserDelegate(UserModel user, LDAPObject ldapUser) {
|
public LDAPGroupMappingsUserDelegate(RealmModel realm, UserModel user, LDAPObject ldapUser) {
|
||||||
super(user);
|
super(user);
|
||||||
|
this.realm = realm;
|
||||||
this.ldapUser = ldapUser;
|
this.ldapUser = ldapUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,7 +593,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
|
if (config.getMode() == LDAPGroupMapperMode.LDAP_ONLY) {
|
||||||
// We need to create new role mappings in LDAP
|
// We need to create new role mappings in LDAP
|
||||||
cachedLDAPGroupMappings = null;
|
cachedLDAPGroupMappings = null;
|
||||||
addGroupMappingInLDAP(group.getName(), ldapUser);
|
addGroupMappingInLDAP(realm, group.getName(), ldapUser);
|
||||||
} else {
|
} else {
|
||||||
super.joinGroup(group);
|
super.joinGroup(group);
|
||||||
}
|
}
|
||||||
|
@ -635,7 +641,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
Set<GroupModel> result = new HashSet<>();
|
Set<GroupModel> result = new HashSet<>();
|
||||||
for (LDAPObject ldapGroup : ldapGroups) {
|
for (LDAPObject ldapGroup : ldapGroups) {
|
||||||
GroupModel kcGroup = findKcGroupOrSyncFromLDAP(ldapGroup, this);
|
GroupModel kcGroup = findKcGroupOrSyncFromLDAP(realm, ldapGroup, this);
|
||||||
if (kcGroup != null) {
|
if (kcGroup != null) {
|
||||||
result.add(kcGroup);
|
result.add(kcGroup);
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,8 +200,8 @@ public class GroupLDAPStorageMapperFactory extends AbstractLDAPStorageMapperFact
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new GroupLDAPStorageMapper(mapperModel, federationProvider, realm, this);
|
return new GroupLDAPStorageMapper(mapperModel, federationProvider, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UserRolesRetrieveStrategy getUserGroupsRetrieveStrategy(String strategyKey) {
|
protected UserRolesRetrieveStrategy getUserGroupsRetrieveStrategy(String strategyKey) {
|
||||||
|
|
|
@ -58,8 +58,8 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
private final RoleMapperConfig config;
|
private final RoleMapperConfig config;
|
||||||
private final RoleLDAPStorageMapperFactory factory;
|
private final RoleLDAPStorageMapperFactory factory;
|
||||||
|
|
||||||
public RoleLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm, RoleLDAPStorageMapperFactory factory) {
|
public RoleLDAPStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RoleLDAPStorageMapperFactory factory) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
this.config = new RoleMapperConfig(mapperModel);
|
this.config = new RoleMapperConfig(mapperModel);
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
LDAPGroupMapperMode mode = config.getMode();
|
LDAPGroupMapperMode mode = config.getMode();
|
||||||
|
|
||||||
// For now, import LDAP role mappings just during create
|
// For now, import LDAP role mappings just during create
|
||||||
|
@ -90,7 +90,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
for (LDAPObject ldapRole : ldapRoles) {
|
for (LDAPObject ldapRole : ldapRoles) {
|
||||||
String roleName = ldapRole.getAttributeAsString(roleNameAttr);
|
String roleName = ldapRole.getAttributeAsString(roleNameAttr);
|
||||||
|
|
||||||
RoleContainerModel roleContainer = getTargetRoleContainer();
|
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||||
RoleModel role = roleContainer.getRole(roleName);
|
RoleModel role = roleContainer.getRole(roleName);
|
||||||
|
|
||||||
if (role == null) {
|
if (role == null) {
|
||||||
|
@ -104,13 +104,13 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sync roles from LDAP to Keycloak DB
|
// Sync roles from LDAP to Keycloak DB
|
||||||
@Override
|
@Override
|
||||||
public SynchronizationResult syncDataFromFederationProviderToKeycloak() {
|
public SynchronizationResult syncDataFromFederationProviderToKeycloak(RealmModel realm) {
|
||||||
SynchronizationResult syncResult = new SynchronizationResult() {
|
SynchronizationResult syncResult = new SynchronizationResult() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -126,7 +126,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
LDAPQuery ldapRoleQuery = createRoleQuery();
|
LDAPQuery ldapRoleQuery = createRoleQuery();
|
||||||
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapRoleQuery, ldapProvider);
|
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapRoleQuery, ldapProvider);
|
||||||
|
|
||||||
RoleContainerModel roleContainer = getTargetRoleContainer();
|
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||||
String rolesRdnAttr = config.getRoleNameLdapAttribute();
|
String rolesRdnAttr = config.getRoleNameLdapAttribute();
|
||||||
for (LDAPObject ldapRole : ldapRoles) {
|
for (LDAPObject ldapRole : ldapRoles) {
|
||||||
String roleName = ldapRole.getAttributeAsString(rolesRdnAttr);
|
String roleName = ldapRole.getAttributeAsString(rolesRdnAttr);
|
||||||
|
@ -146,7 +146,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
// Sync roles from Keycloak back to LDAP
|
// Sync roles from Keycloak back to LDAP
|
||||||
@Override
|
@Override
|
||||||
public SynchronizationResult syncDataFromKeycloakToFederationProvider() {
|
public SynchronizationResult syncDataFromKeycloakToFederationProvider(RealmModel realm) {
|
||||||
SynchronizationResult syncResult = new SynchronizationResult() {
|
SynchronizationResult syncResult = new SynchronizationResult() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -175,7 +175,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RoleContainerModel roleContainer = getTargetRoleContainer();
|
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||||
Set<RoleModel> keycloakRoles = roleContainer.getRoles();
|
Set<RoleModel> keycloakRoles = roleContainer.getRoles();
|
||||||
|
|
||||||
for (RoleModel keycloakRole : keycloakRoles) {
|
for (RoleModel keycloakRole : keycloakRoles) {
|
||||||
|
@ -220,7 +220,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
return ldapQuery;
|
return ldapQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RoleContainerModel getTargetRoleContainer() {
|
protected RoleContainerModel getTargetRoleContainer(RealmModel realm) {
|
||||||
boolean realmRolesMapping = config.isRealmRolesMapping();
|
boolean realmRolesMapping = config.isRealmRolesMapping();
|
||||||
if (realmRolesMapping) {
|
if (realmRolesMapping) {
|
||||||
return realm;
|
return realm;
|
||||||
|
@ -273,14 +273,14 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
|
public UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
final LDAPGroupMapperMode mode = config.getMode();
|
final LDAPGroupMapperMode mode = config.getMode();
|
||||||
|
|
||||||
// For IMPORT mode, all operations are performed against local DB
|
// For IMPORT mode, all operations are performed against local DB
|
||||||
if (mode == LDAPGroupMapperMode.IMPORT) {
|
if (mode == LDAPGroupMapperMode.IMPORT) {
|
||||||
return delegate;
|
return delegate;
|
||||||
} else {
|
} else {
|
||||||
return new LDAPRoleMappingsUserDelegate(delegate, ldapUser);
|
return new LDAPRoleMappingsUserDelegate(realm, delegate, ldapUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,16 +295,18 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
||||||
|
|
||||||
public class LDAPRoleMappingsUserDelegate extends UserModelDelegate {
|
public class LDAPRoleMappingsUserDelegate extends UserModelDelegate {
|
||||||
|
|
||||||
|
private final RealmModel realm;
|
||||||
private final LDAPObject ldapUser;
|
private final LDAPObject ldapUser;
|
||||||
private final RoleContainerModel roleContainer;
|
private final RoleContainerModel roleContainer;
|
||||||
|
|
||||||
// Avoid loading role mappings from LDAP more times per-request
|
// Avoid loading role mappings from LDAP more times per-request
|
||||||
private Set<RoleModel> cachedLDAPRoleMappings;
|
private Set<RoleModel> cachedLDAPRoleMappings;
|
||||||
|
|
||||||
public LDAPRoleMappingsUserDelegate(UserModel user, LDAPObject ldapUser) {
|
public LDAPRoleMappingsUserDelegate(RealmModel realm, UserModel user, LDAPObject ldapUser) {
|
||||||
super(user);
|
super(user);
|
||||||
|
this.realm = realm;
|
||||||
this.ldapUser = ldapUser;
|
this.ldapUser = ldapUser;
|
||||||
this.roleContainer = getTargetRoleContainer();
|
this.roleContainer = getTargetRoleContainer(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -194,8 +194,8 @@ public class RoleLDAPStorageMapperFactory extends AbstractLDAPStorageMapperFacto
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new RoleLDAPStorageMapper(mapperModel, federationProvider, realm, this);
|
return new RoleLDAPStorageMapper(mapperModel, federationProvider, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UserRolesRetrieveStrategy getUserRolesRetrieveStrategy(String strategyKey) {
|
protected UserRolesRetrieveStrategy getUserRolesRetrieveStrategy(String strategyKey) {
|
||||||
|
|
|
@ -51,8 +51,8 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
|
||||||
private static final Pattern AUTH_EXCEPTION_REGEX = Pattern.compile(".*AcceptSecurityContext error, data ([0-9a-f]*), v.*");
|
private static final Pattern AUTH_EXCEPTION_REGEX = Pattern.compile(".*AcceptSecurityContext error, data ([0-9a-f]*), v.*");
|
||||||
private static final Pattern AUTH_INVALID_NEW_PASSWORD = Pattern.compile(".*error code ([0-9a-f]+) .*WILL_NOT_PERFORM.*");
|
private static final Pattern AUTH_INVALID_NEW_PASSWORD = Pattern.compile(".*error code ([0-9a-f]+) .*WILL_NOT_PERFORM.*");
|
||||||
|
|
||||||
public MSADUserAccountControlStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public MSADUserAccountControlStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
ldapProvider.setUpdater(this);
|
ldapProvider.setUpdater(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,22 +95,22 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
|
public UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
return new MSADUserModelDelegate(delegate, ldapUser);
|
return new MSADUserModelDelegate(delegate, ldapUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException) {
|
public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException, RealmModel realm) {
|
||||||
String exceptionMessage = ldapException.getMessage();
|
String exceptionMessage = ldapException.getMessage();
|
||||||
Matcher m = AUTH_EXCEPTION_REGEX.matcher(exceptionMessage);
|
Matcher m = AUTH_EXCEPTION_REGEX.matcher(exceptionMessage);
|
||||||
if (m.matches()) {
|
if (m.matches()) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class MSADUserAccountControlStorageMapperFactory extends AbstractLDAPStor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new MSADUserAccountControlStorageMapper(mapperModel, federationProvider, realm);
|
return new MSADUserAccountControlStorageMapper(mapperModel, federationProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ public class MSADLDSUserAccountControlStorageMapper extends AbstractLDAPStorageM
|
||||||
private static final Pattern AUTH_EXCEPTION_REGEX = Pattern.compile(".*AcceptSecurityContext error, data ([0-9a-f]*), v.*");
|
private static final Pattern AUTH_EXCEPTION_REGEX = Pattern.compile(".*AcceptSecurityContext error, data ([0-9a-f]*), v.*");
|
||||||
private static final Pattern AUTH_INVALID_NEW_PASSWORD = Pattern.compile("(?s).*problem 1005 \\(CONSTRAINT_ATT_TYPE\\), data [0-9a-f]*, Att 23 \\(userPassword\\).*");
|
private static final Pattern AUTH_INVALID_NEW_PASSWORD = Pattern.compile("(?s).*problem 1005 \\(CONSTRAINT_ATT_TYPE\\), data [0-9a-f]*, Att 23 \\(userPassword\\).*");
|
||||||
|
|
||||||
public MSADLDSUserAccountControlStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public MSADLDSUserAccountControlStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
||||||
super(mapperModel, ldapProvider, realm);
|
super(mapperModel, ldapProvider);
|
||||||
ldapProvider.setUpdater(this);
|
ldapProvider.setUpdater(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,22 +94,22 @@ public class MSADLDSUserAccountControlStorageMapper extends AbstractLDAPStorageM
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
|
public UserModel proxy(LDAPObject ldapUser, UserModel delegate, RealmModel realm) {
|
||||||
return new MSADUserModelDelegate(delegate, ldapUser);
|
return new MSADUserModelDelegate(delegate, ldapUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
|
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
|
public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, RealmModel realm, boolean isCreate) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException) {
|
public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException, RealmModel realm) {
|
||||||
String exceptionMessage = ldapException.getMessage();
|
String exceptionMessage = ldapException.getMessage();
|
||||||
Matcher m = AUTH_EXCEPTION_REGEX.matcher(exceptionMessage);
|
Matcher m = AUTH_EXCEPTION_REGEX.matcher(exceptionMessage);
|
||||||
if (m.matches()) {
|
if (m.matches()) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class MSADLDSUserAccountControlStorageMapperFactory extends AbstractLDAPS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) {
|
protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider) {
|
||||||
return new MSADLDSUserAccountControlStorageMapper(mapperModel, federationProvider, realm);
|
return new MSADLDSUserAccountControlStorageMapper(mapperModel, federationProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Provider> T getProvider(Class<T> clazz, ComponentModel componentModel) {
|
public <T extends Provider> T getProvider(Class<T> clazz, ComponentModel componentModel) {
|
||||||
String modelId = componentModel.getProviderType() + "::" + componentModel.getId();
|
String modelId = componentModel.getId();
|
||||||
|
|
||||||
Object found = getAttribute(modelId);
|
Object found = getAttribute(modelId);
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
|
|
|
@ -147,19 +147,17 @@ public class UserStorageProviderResource {
|
||||||
if (parentModel == null) throw new NotFoundException("Parent model not found");
|
if (parentModel == null) throw new NotFoundException("Parent model not found");
|
||||||
ComponentModel mapperModel = realm.getComponent(mapperId);
|
ComponentModel mapperModel = realm.getComponent(mapperId);
|
||||||
if (mapperModel == null) throw new NotFoundException("Mapper model not found");
|
if (mapperModel == null) throw new NotFoundException("Mapper model not found");
|
||||||
LDAPStorageMapper mapper = session.getProvider(LDAPStorageMapper.class, mapperModel);
|
|
||||||
ProviderFactory factory = session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, parentModel.getProviderId());
|
|
||||||
|
|
||||||
LDAPStorageProviderFactory providerFactory = (LDAPStorageProviderFactory)factory;
|
LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class, parentModel);
|
||||||
LDAPStorageProvider federationProvider = providerFactory.create(session, parentModel);
|
LDAPStorageMapper mapper = session.getProvider(LDAPStorageMapper.class, mapperModel);
|
||||||
|
|
||||||
ServicesLogger.LOGGER.syncingDataForMapper(mapperModel.getName(), mapperModel.getProviderId(), direction);
|
ServicesLogger.LOGGER.syncingDataForMapper(mapperModel.getName(), mapperModel.getProviderId(), direction);
|
||||||
|
|
||||||
SynchronizationResult syncResult;
|
SynchronizationResult syncResult;
|
||||||
if ("fedToKeycloak".equals(direction)) {
|
if ("fedToKeycloak".equals(direction)) {
|
||||||
syncResult = mapper.syncDataFromFederationProviderToKeycloak(mapperModel, federationProvider, session, realm);
|
syncResult = mapper.syncDataFromFederationProviderToKeycloak(realm);
|
||||||
} else if ("keycloakToFed".equals(direction)) {
|
} else if ("keycloakToFed".equals(direction)) {
|
||||||
syncResult = mapper.syncDataFromKeycloakToFederationProvider(mapperModel, federationProvider, session, realm);
|
syncResult = mapper.syncDataFromKeycloakToFederationProvider(realm);
|
||||||
} else {
|
} else {
|
||||||
throw new BadRequestException("Unknown direction: " + direction);
|
throw new BadRequestException("Unknown direction: " + direction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
realm.updateComponent(mapperModel);
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
// Sync from Keycloak into LDAP
|
// Sync from Keycloak into LDAP
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.stopSession(session, true);
|
keycloakRule.stopSession(session, true);
|
||||||
|
@ -143,7 +143,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
|
||||||
// Sync from LDAP back into Keycloak
|
// Sync from LDAP back into Keycloak
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak. All are at top level
|
// Assert groups are imported to keycloak. All are at top level
|
||||||
|
@ -179,7 +179,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
realm.updateComponent(mapperModel);
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
// Sync from Keycloak into LDAP
|
// Sync from Keycloak into LDAP
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.stopSession(session, true);
|
keycloakRule.stopSession(session, true);
|
||||||
|
@ -207,7 +207,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
|
||||||
// Sync from LDAP back into Keycloak
|
// Sync from LDAP back into Keycloak
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak. All are at top level
|
// Assert groups are imported to keycloak. All are at top level
|
||||||
|
@ -242,7 +242,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group3");
|
LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group3");
|
||||||
|
|
||||||
// Sync and assert our group is still in LDAP
|
// Sync and assert our group is still in LDAP
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 4, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 0, 4, 0, 0);
|
||||||
Assert.assertNotNull(LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
Assert.assertNotNull(LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
realm.updateComponent(mapperModel);
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
// Sync and assert group removed from LDAP
|
// Sync and assert group removed from LDAP
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 4, 1, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 0, 4, 1, 0);
|
||||||
Assert.assertNull(LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
Assert.assertNull(LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group12, group1, true);
|
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group12, group1, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
Assert.fail("Not expected group sync to pass");
|
Assert.fail("Not expected group sync to pass");
|
||||||
} catch (ModelException expected) {
|
} catch (ModelException expected) {
|
||||||
Assert.assertTrue(expected.getMessage().contains("Recursion detected"));
|
Assert.assertTrue(expected.getMessage().contains("Recursion detected"));
|
||||||
|
@ -157,7 +157,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
||||||
realm.updateComponent(mapperModel);
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak. All are at top level
|
// Assert groups are imported to keycloak. All are at top level
|
||||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||||
|
@ -206,7 +206,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||||
|
|
||||||
// Sync groups with inheritance
|
// Sync groups with inheritance
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak including their inheritance from LDAP
|
// Assert groups are imported to keycloak including their inheritance from LDAP
|
||||||
|
@ -232,7 +232,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
ldapProvider.getLdapIdentityStore().update(group12);
|
ldapProvider.getLdapIdentityStore().update(group12);
|
||||||
|
|
||||||
// Sync and assert groups updated
|
// Sync and assert groups updated
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
||||||
|
|
||||||
// Assert attributes changed in keycloak
|
// Assert attributes changed in keycloak
|
||||||
|
@ -254,7 +254,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
|
||||||
// Sync groups with inheritance
|
// Sync groups with inheritance
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak including their inheritance from LDAP
|
// Assert groups are imported to keycloak including their inheritance from LDAP
|
||||||
|
@ -271,7 +271,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
realm.moveGroup(model2, kcGroup1);
|
realm.moveGroup(model2, kcGroup1);
|
||||||
|
|
||||||
// Sync groups again from LDAP. Nothing deleted
|
// Sync groups again from LDAP. Nothing deleted
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
LDAPTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
||||||
|
|
||||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
||||||
|
@ -284,7 +284,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
realm.updateComponent(mapperModel);
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
// Sync groups again from LDAP. Assert LDAP non-existing groups deleted
|
// Sync groups again from LDAP. Assert LDAP non-existing groups deleted
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
Assert.assertEquals(3, syncResult.getUpdated());
|
Assert.assertEquals(3, syncResult.getUpdated());
|
||||||
Assert.assertTrue(syncResult.getRemoved() == 2);
|
Assert.assertTrue(syncResult.getRemoved() == 2);
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapProvider, realm);
|
LDAPTestUtils.removeAllLDAPUsers(ldapProvider, realm);
|
||||||
LDAPObject johnLdap = LDAPTestUtils.addLDAPUser(ldapProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
LDAPObject johnLdap = LDAPTestUtils.addLDAPUser(ldapProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapProvider, johnLdap, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ldapProvider, johnLdap, "Password1");
|
||||||
groupMapper.addGroupMappingInLDAP("group11", johnLdap);
|
groupMapper.addGroupMappingInLDAP(realm, "group11", johnLdap);
|
||||||
|
|
||||||
// Assert groups not yet imported to Keycloak DB
|
// Assert groups not yet imported to Keycloak DB
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class LDAPGroupMapperTest {
|
||||||
|
|
||||||
// Sync LDAP groups to Keycloak DB
|
// Sync LDAP groups to Keycloak DB
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
||||||
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(mapperModel, ldapFedProvider, session, appRealm);
|
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
|
||||||
|
|
||||||
// Delete all LDAP users
|
// Delete all LDAP users
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||||
|
@ -220,8 +220,8 @@ public class LDAPGroupMapperTest {
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||||
groupMapper.addGroupMappingInLDAP("group1", maryLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, "group1", maryLdap);
|
||||||
groupMapper.addGroupMappingInLDAP("group11", maryLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, "group11", maryLdap);
|
||||||
|
|
||||||
// Add some group mapping to model
|
// Add some group mapping to model
|
||||||
mary.joinGroup(group12);
|
mary.joinGroup(group12);
|
||||||
|
@ -282,8 +282,8 @@ public class LDAPGroupMapperTest {
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
|
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
|
||||||
groupMapper.addGroupMappingInLDAP("group11", robLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, "group11", robLdap);
|
||||||
groupMapper.addGroupMappingInLDAP("group12", robLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, "group12", robLdap);
|
||||||
|
|
||||||
// Get user and check that he has requested groupa from LDAP
|
// Get user and check that he has requested groupa from LDAP
|
||||||
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
||||||
|
@ -349,7 +349,7 @@ public class LDAPGroupMapperTest {
|
||||||
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group2, nonExistentLdapUser, true);
|
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group2, nonExistentLdapUser, true);
|
||||||
|
|
||||||
// 4 - Check group members. Just existing user rob should be present
|
// 4 - Check group members. Just existing user rob should be present
|
||||||
groupMapper.syncDataFromFederationProviderToKeycloak();
|
groupMapper.syncDataFromFederationProviderToKeycloak(appRealm);
|
||||||
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2");
|
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2");
|
||||||
List<UserModel> groupUsers = session.users().getGroupMembers(appRealm, kcGroup2, 0, 5);
|
List<UserModel> groupUsers = session.users().getGroupMembers(appRealm, kcGroup2, 0, 5);
|
||||||
Assert.assertEquals(1, groupUsers.size());
|
Assert.assertEquals(1, groupUsers.size());
|
||||||
|
|
|
@ -238,11 +238,11 @@ public class LDAPTestUtils {
|
||||||
ComponentModel mapperModel = getSubcomponentByName(realm, providerModel, "realmRolesMapper");
|
ComponentModel mapperModel = getSubcomponentByName(realm, providerModel, "realmRolesMapper");
|
||||||
RoleLDAPStorageMapper roleMapper = getRoleMapper(mapperModel, ldapProvider, realm);
|
RoleLDAPStorageMapper roleMapper = getRoleMapper(mapperModel, ldapProvider, realm);
|
||||||
|
|
||||||
roleMapper.syncDataFromFederationProviderToKeycloak();
|
roleMapper.syncDataFromFederationProviderToKeycloak(realm);
|
||||||
|
|
||||||
mapperModel = getSubcomponentByName(realm, providerModel, "financeRolesMapper");
|
mapperModel = getSubcomponentByName(realm, providerModel, "financeRolesMapper");
|
||||||
roleMapper = getRoleMapper(mapperModel, ldapProvider, realm);
|
roleMapper = getRoleMapper(mapperModel, ldapProvider, realm);
|
||||||
roleMapper.syncDataFromFederationProviderToKeycloak();
|
roleMapper.syncDataFromFederationProviderToKeycloak(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeAllLDAPUsers(LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public static void removeAllLDAPUsers(LDAPStorageProvider ldapProvider, RealmModel realm) {
|
||||||
|
@ -296,11 +296,11 @@ public class LDAPTestUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GroupLDAPStorageMapper getGroupMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public static GroupLDAPStorageMapper getGroupMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
||||||
return new GroupLDAPStorageMapper(mapperModel, ldapProvider, realm, new GroupLDAPStorageMapperFactory());
|
return new GroupLDAPStorageMapper(mapperModel, ldapProvider, new GroupLDAPStorageMapperFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RoleLDAPStorageMapper getRoleMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
public static RoleLDAPStorageMapper getRoleMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) {
|
||||||
return new RoleLDAPStorageMapper(mapperModel, ldapProvider, realm, new RoleLDAPStorageMapperFactory());
|
return new RoleLDAPStorageMapper(mapperModel, ldapProvider, new RoleLDAPStorageMapperFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue