parent
26901dce19
commit
60ce949304
2 changed files with 92 additions and 22 deletions
|
@ -92,10 +92,15 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
|
||||
// Import role mappings from LDAP into Keycloak DB
|
||||
String roleNameAttr = config.getRoleNameLdapAttribute();
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||
if (roleContainer == null) {
|
||||
logger.warnf("Ignored client role grant for federation mapper '%s' as client not found: '%s'", mapperModel.getName(), config.getClientId());
|
||||
return;
|
||||
}
|
||||
|
||||
for (LDAPObject ldapRole : ldapRoles) {
|
||||
String roleName = ldapRole.getAttributeAsString(roleNameAttr);
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||
RoleModel role = roleContainer.getRole(roleName);
|
||||
|
||||
if (role == null) {
|
||||
|
@ -127,11 +132,16 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
|
||||
logger.debugf("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getName());
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||
if (roleContainer == null) {
|
||||
logger.warnf("Ignored sync for federation mapper '%s' as client not found: '%s'", mapperModel.getName(), config.getClientId());
|
||||
return syncResult;
|
||||
}
|
||||
|
||||
// Send LDAP query to load all roles
|
||||
try (LDAPQuery ldapRoleQuery = createRoleQuery(false)) {
|
||||
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapRoleQuery, ldapProvider);
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||
String rolesRdnAttr = config.getRoleNameLdapAttribute();
|
||||
for (LDAPObject ldapRole : ldapRoles) {
|
||||
String roleName = ldapRole.getAttributeAsString(rolesRdnAttr);
|
||||
|
@ -169,6 +179,12 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
|
||||
logger.debugf("Syncing roles from Keycloak into LDAP. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getName());
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||
if (roleContainer == null) {
|
||||
logger.warnf("Ignored sync for federation mapper '%s' as client not found: '%s'", mapperModel.getName(), config.getClientId());
|
||||
return syncResult;
|
||||
}
|
||||
|
||||
// Send LDAP query to see which roles exists there
|
||||
try (LDAPQuery ldapQuery = createRoleQuery(false)) {
|
||||
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapQuery, ldapProvider);
|
||||
|
@ -181,7 +197,6 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
}
|
||||
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
|
||||
Stream<RoleModel> keycloakRoles = roleContainer.getRolesStream();
|
||||
|
||||
Consumer<String> syncRoleFromKCToLDAP = roleName -> {
|
||||
|
@ -242,7 +257,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
}
|
||||
ClientModel client = realm.getClientByClientId(clientId);
|
||||
if (client == null) {
|
||||
throw new ModelException("Can't found requested client with clientId: " + clientId);
|
||||
logger.warnf("Cannot find requested client with clientId '%s' in federation mapper '%s'", clientId, mapperModel.getName());
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
@ -296,8 +311,12 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
// For IMPORT mode, all operations are performed against local DB
|
||||
if (mode == LDAPGroupMapperMode.IMPORT) {
|
||||
return delegate;
|
||||
}
|
||||
final RoleContainerModel targetRoleContainer = getTargetRoleContainer(realm);
|
||||
if (targetRoleContainer == null) {
|
||||
return delegate;
|
||||
} else {
|
||||
return new LDAPRoleMappingsUserDelegate(realm, delegate, ldapUser);
|
||||
return new LDAPRoleMappingsUserDelegate(realm, delegate, ldapUser, targetRoleContainer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,11 +343,11 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
|
|||
// Avoid loading role mappings from LDAP more times per-request
|
||||
private Set<RoleModel> cachedLDAPRoleMappings;
|
||||
|
||||
public LDAPRoleMappingsUserDelegate(RealmModel realm, UserModel user, LDAPObject ldapUser) {
|
||||
public LDAPRoleMappingsUserDelegate(RealmModel realm, UserModel user, LDAPObject ldapUser, RoleContainerModel targetRoleContainer) {
|
||||
super(user);
|
||||
this.realm = realm;
|
||||
this.ldapUser = ldapUser;
|
||||
this.roleContainer = getTargetRoleContainer(realm);
|
||||
this.roleContainer = targetRoleContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,9 @@ import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig;
|
|||
import org.keycloak.testsuite.util.LDAPRule;
|
||||
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author rmartinc
|
||||
|
@ -62,29 +65,29 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
|
|||
// check users
|
||||
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||
Assert.assertNotNull(john);
|
||||
Assert.assertThat(john.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
assertThat(john.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||
Assert.assertNotNull(mary);
|
||||
Assert.assertThat(mary.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
assertThat(mary.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
UserModel rob = session.users().getUserByUsername(appRealm, "robkeycloak");
|
||||
Assert.assertNotNull(rob);
|
||||
Assert.assertThat(rob.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1"));
|
||||
assertThat(rob.getRealmRoleMappingsStream().map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1"));
|
||||
UserModel james = session.users().getUserByUsername(appRealm, "jameskeycloak");
|
||||
Assert.assertNotNull(james);
|
||||
Assert.assertThat(james.getRealmRoleMappingsStream().collect(Collectors.toSet()), Matchers.empty());
|
||||
assertThat(james.getRealmRoleMappingsStream().collect(Collectors.toSet()), Matchers.empty());
|
||||
|
||||
// check groups
|
||||
RoleModel group1 = appRealm.getRole("group1");
|
||||
Assert.assertNotNull(group1);
|
||||
Assert.assertThat(session.users().getRoleMembersStream(appRealm, group1).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
assertThat(session.users().getRoleMembersStream(appRealm, group1).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak", "robkeycloak"));
|
||||
RoleModel group2 = appRealm.getRole("group2");
|
||||
Assert.assertNotNull(group2);
|
||||
Assert.assertThat(session.users().getRoleMembersStream(appRealm, group2).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
assertThat(session.users().getRoleMembersStream(appRealm, group2).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak"));
|
||||
RoleModel group3 = appRealm.getRole("group3");
|
||||
Assert.assertNotNull(group3);
|
||||
Assert.assertThat(session.users().getRoleMembersStream(appRealm, group3).collect(Collectors.toSet()), Matchers.empty());
|
||||
assertThat(session.users().getRoleMembersStream(appRealm, group3).collect(Collectors.toSet()), Matchers.empty());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -110,29 +113,77 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
|
|||
// check users
|
||||
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||
Assert.assertNotNull(john);
|
||||
Assert.assertThat(john.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
assertThat(john.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||
Assert.assertNotNull(mary);
|
||||
Assert.assertThat(mary.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
assertThat(mary.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1", "group2"));
|
||||
UserModel rob = session.users().getUserByUsername(appRealm, "robkeycloak");
|
||||
Assert.assertNotNull(rob);
|
||||
Assert.assertThat(rob.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1"));
|
||||
assertThat(rob.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.containsInAnyOrder("group1"));
|
||||
UserModel james = session.users().getUserByUsername(appRealm, "jameskeycloak");
|
||||
Assert.assertNotNull(james);
|
||||
Assert.assertThat(james.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty());
|
||||
assertThat(james.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty());
|
||||
|
||||
// check groups
|
||||
RoleModel group1 = rolesClient.getRole("group1");
|
||||
Assert.assertNotNull(group1);
|
||||
Assert.assertThat(session.users().getRoleMembersStream(appRealm, group1).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
assertThat(session.users().getRoleMembersStream(appRealm, group1).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak", "robkeycloak"));
|
||||
RoleModel group2 = rolesClient.getRole("group2");
|
||||
Assert.assertNotNull(group2);
|
||||
Assert.assertThat(session.users().getRoleMembersStream(appRealm, group2).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
assertThat(session.users().getRoleMembersStream(appRealm, group2).map(UserModel::getUsername).collect(Collectors.toSet()),
|
||||
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak"));
|
||||
RoleModel group3 = rolesClient.getRole("group3");
|
||||
Assert.assertNotNull(group3);
|
||||
Assert.assertThat(session.users().getRoleMembersStream(appRealm, group3).collect(Collectors.toSet()), Matchers.empty());
|
||||
assertThat(session.users().getRoleMembersStream(appRealm, group3).collect(Collectors.toSet()), Matchers.empty());
|
||||
|
||||
} finally {
|
||||
appRealm.removeClient(rolesClient.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03RoleMapperClientRoles() {
|
||||
testingClient.server().run(session -> {
|
||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||
RealmModel appRealm = ctx.getRealm();
|
||||
|
||||
// create a client to set the roles in it
|
||||
ClientModel rolesClient = session.clients().addClient(appRealm, "role-mapper-client");
|
||||
final String clientId = rolesClient.getClientId();
|
||||
|
||||
try {
|
||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "rolesMapper");
|
||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel,
|
||||
RoleMapperConfig.USE_REALM_ROLES_MAPPING, "false",
|
||||
RoleMapperConfig.CLIENT_ID, clientId);
|
||||
appRealm.updateComponent(mapperModel);
|
||||
|
||||
rolesClient.setClientId(clientId + "-suffix");
|
||||
rolesClient.updateClient();
|
||||
|
||||
// synch to the client to create the roles at the client
|
||||
new RoleLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
|
||||
|
||||
// check users
|
||||
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||
Assert.assertNotNull(john);
|
||||
assertThat(john.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty());
|
||||
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
|
||||
Assert.assertNotNull(mary);
|
||||
assertThat(mary.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty());
|
||||
UserModel rob = session.users().getUserByUsername(appRealm, "robkeycloak");
|
||||
Assert.assertNotNull(rob);
|
||||
assertThat(rob.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty());
|
||||
UserModel james = session.users().getUserByUsername(appRealm, "jameskeycloak");
|
||||
Assert.assertNotNull(james);
|
||||
assertThat(james.getClientRoleMappingsStream(rolesClient).map(RoleModel::getName).collect(Collectors.toSet()), Matchers.empty());
|
||||
|
||||
// check groups
|
||||
assertThat(rolesClient.getRole("group1"), nullValue());
|
||||
assertThat(rolesClient.getRole("group2"), nullValue());
|
||||
assertThat(rolesClient.getRole("group3"), nullValue());
|
||||
|
||||
} finally {
|
||||
appRealm.removeClient(rolesClient.getId());
|
||||
|
|
Loading…
Reference in a new issue