keycloak-aplcache
Changes
broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ExternalKeycloakRoleToRoleMapper.java 5(+3 -2)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/FullNameLDAPFederationMapperFactory.java 2(+1 -1)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapper.java 109(+109 -0)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapperFactory.java 78(+78 -0)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapperFactory.java 2(+1 -1)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/role/RoleLDAPFederationMapperFactory.java 2(+1 -1)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/UserAttributeLDAPFederationMapperFactory.java 2(+1 -1)
federation/ldap/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory 1(+1 -0)
Details
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedRoleMapper.java b/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedRoleMapper.java
index 309e26a..6f0b02a 100755
--- a/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedRoleMapper.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/HardcodedRoleMapper.java
@@ -1,14 +1,11 @@
package org.keycloak.broker.provider;
-import org.keycloak.broker.provider.AbstractIdentityProviderMapper;
-import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.IdentityBrokerException;
-import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.ProviderConfigProperty;
import java.util.ArrayList;
@@ -20,7 +17,7 @@ import java.util.List;
*/
public class HardcodedRoleMapper extends AbstractIdentityProviderMapper {
public static final String ROLE = "role";
- protected static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
+ protected static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
static {
ProviderConfigProperty property;
@@ -32,34 +29,6 @@ public class HardcodedRoleMapper extends AbstractIdentityProviderMapper {
configProperties.add(property);
}
-
-
- public static String[] parseRole(String role) {
- int scopeIndex = role.lastIndexOf('.');
- if (scopeIndex > -1) {
- String appName = role.substring(0, scopeIndex);
- role = role.substring(scopeIndex + 1);
- String[] rtn = {appName, role};
- return rtn;
- } else {
- String[] rtn = {null, role};
- return rtn;
-
- }
- }
-
- public static RoleModel getRoleFromString(RealmModel realm, String roleName) {
- String[] parsedRole = parseRole(roleName);
- RoleModel role = null;
- if (parsedRole[0] == null) {
- role = realm.getRole(parsedRole[1]);
- } else {
- ClientModel client = realm.getClientByClientId(parsedRole[0]);
- role = client.getRole(parsedRole[1]);
- }
- return role;
- }
-
@Override
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
@@ -93,7 +62,7 @@ public class HardcodedRoleMapper extends AbstractIdentityProviderMapper {
@Override
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
String roleName = mapperModel.getConfig().get(ROLE);
- RoleModel role = getRoleFromString(realm, roleName);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName);
user.grantRole(role);
}
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToRoleMapper.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToRoleMapper.java
index b3bd191..2d79a5b 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToRoleMapper.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToRoleMapper.java
@@ -10,6 +10,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.ProviderConfigProperty;
import java.util.ArrayList;
@@ -80,7 +81,7 @@ public class ClaimToRoleMapper extends AbstractClaimMapper {
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
String roleName = mapperModel.getConfig().get(HardcodedRoleMapper.ROLE);
if (hasClaimValue(mapperModel, context)) {
- RoleModel role = HardcodedRoleMapper.getRoleFromString(realm, roleName);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName);
user.grantRole(role);
}
@@ -90,7 +91,7 @@ public class ClaimToRoleMapper extends AbstractClaimMapper {
public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
String roleName = mapperModel.getConfig().get(HardcodedRoleMapper.ROLE);
if (!hasClaimValue(mapperModel, context)) {
- RoleModel role = HardcodedRoleMapper.getRoleFromString(realm, roleName);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName);
user.deleteRoleMapping(role);
}
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ExternalKeycloakRoleToRoleMapper.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ExternalKeycloakRoleToRoleMapper.java
index e4e0de0..f7ddb76 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ExternalKeycloakRoleToRoleMapper.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/ExternalKeycloakRoleToRoleMapper.java
@@ -11,6 +11,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.JsonWebToken;
@@ -85,7 +86,7 @@ public class ExternalKeycloakRoleToRoleMapper extends AbstractClaimMapper {
JsonWebToken token = (JsonWebToken)context.getContextData().get(KeycloakOIDCIdentityProvider.VALIDATED_ACCESS_TOKEN);
//if (token == null) return;
String roleName = mapperModel.getConfig().get(HardcodedRoleMapper.ROLE);
- String[] parseRole = HardcodedRoleMapper.parseRole(mapperModel.getConfig().get(EXTERNAL_ROLE));
+ String[] parseRole = KeycloakModelUtils.parseRole(mapperModel.getConfig().get(EXTERNAL_ROLE));
String externalRoleName = parseRole[1];
String claimName = null;
if (parseRole[0] == null) {
@@ -95,7 +96,7 @@ public class ExternalKeycloakRoleToRoleMapper extends AbstractClaimMapper {
}
Object claim = getClaimValue(token, claimName);
if (valueEquals(externalRoleName, claim)) {
- RoleModel role = HardcodedRoleMapper.getRoleFromString(realm, roleName);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName);
return role;
}
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/mappers/AttributeToRoleMapper.java b/broker/saml/src/main/java/org/keycloak/broker/saml/mappers/AttributeToRoleMapper.java
index 4014a9a..48d2ac8 100755
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/mappers/AttributeToRoleMapper.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/mappers/AttributeToRoleMapper.java
@@ -15,6 +15,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.JsonWebToken;
@@ -95,7 +96,7 @@ public class AttributeToRoleMapper extends AbstractIdentityProviderMapper {
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
String roleName = mapperModel.getConfig().get(HardcodedRoleMapper.ROLE);
if (isAttributePresent(mapperModel, context)) {
- RoleModel role = HardcodedRoleMapper.getRoleFromString(realm, roleName);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName);
user.grantRole(role);
}
@@ -125,7 +126,7 @@ public class AttributeToRoleMapper extends AbstractIdentityProviderMapper {
public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
String roleName = mapperModel.getConfig().get(HardcodedRoleMapper.ROLE);
if (!isAttributePresent(mapperModel, context)) {
- RoleModel role = HardcodedRoleMapper.getRoleFromString(realm, roleName);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName);
user.deleteRoleMapping(role);
}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/FullNameLDAPFederationMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/FullNameLDAPFederationMapperFactory.java
index e08429e..7fbcf06 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/FullNameLDAPFederationMapperFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/FullNameLDAPFederationMapperFactory.java
@@ -75,7 +75,7 @@ public class FullNameLDAPFederationMapperFactory extends AbstractLDAPFederationM
}
@Override
- public void validateConfig(UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
+ public void validateConfig(RealmModel realm, UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
checkMandatoryConfigAttribute(FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE, "LDAP Full Name Attribute", mapperModel);
}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapper.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapper.java
new file mode 100644
index 0000000..866d2b1
--- /dev/null
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapper.java
@@ -0,0 +1,109 @@
+package org.keycloak.federation.ldap.mappers;
+
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+import org.keycloak.federation.ldap.LDAPFederationProvider;
+import org.keycloak.federation.ldap.idm.model.LDAPObject;
+import org.keycloak.federation.ldap.idm.query.internal.LDAPQuery;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ModelException;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserFederationMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.UserModelDelegate;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class HardcodedLDAPRoleMapper extends AbstractLDAPFederationMapper {
+
+ private static final Logger logger = Logger.getLogger(HardcodedLDAPRoleMapper.class);
+
+ public static final String ROLE = "role";
+
+ public HardcodedLDAPRoleMapper(UserFederationMapperModel mapperModel, LDAPFederationProvider ldapProvider, RealmModel realm) {
+ super(mapperModel, ldapProvider, realm);
+ }
+
+ @Override
+ public void beforeLDAPQuery(LDAPQuery query) {
+ }
+
+ @Override
+ public UserModel proxy(LDAPObject ldapUser, UserModel delegate) {
+ return new UserModelDelegate(delegate) {
+
+ @Override
+ public Set<RoleModel> getRealmRoleMappings() {
+ Set<RoleModel> roles = super.getRealmRoleMappings();
+
+ RoleModel role = getRole();
+ if (role != null && role.getContainer().equals(realm)) {
+ roles.add(role);
+ }
+
+ return roles;
+ }
+
+ @Override
+ public Set<RoleModel> getClientRoleMappings(ClientModel app) {
+ Set<RoleModel> roles = super.getClientRoleMappings(app);
+
+ RoleModel role = getRole();
+ if (role != null && role.getContainer().equals(app)) {
+ roles.add(role);
+ }
+
+ return roles;
+ }
+
+ @Override
+ public boolean hasRole(RoleModel role) {
+ return super.hasRole(role) || role.equals(getRole());
+ }
+
+ @Override
+ public Set<RoleModel> getRoleMappings() {
+ Set<RoleModel> roles = super.getRoleMappings();
+
+ RoleModel role = getRole();
+ if (role != null) {
+ roles.add(role);
+ }
+
+ return roles;
+ }
+
+ @Override
+ public void deleteRoleMapping(RoleModel role) {
+ if (role.equals(getRole())) {
+ throw new ModelException("Not possible to delete role. It's hardcoded by LDAP mapper");
+ } else {
+ super.deleteRoleMapping(role);
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) {
+
+ }
+
+ @Override
+ public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) {
+
+ }
+
+ private RoleModel getRole() {
+ String roleName = mapperModel.getConfig().get(HardcodedLDAPRoleMapper.ROLE);
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
+ if (role == null) {
+ logger.warnf("Hardcoded role '%s' configured in mapper '%s' is not available anymore");
+ }
+ return role;
+ }
+}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapperFactory.java
new file mode 100644
index 0000000..508a333
--- /dev/null
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/HardcodedLDAPRoleMapperFactory.java
@@ -0,0 +1,78 @@
+package org.keycloak.federation.ldap.mappers;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.federation.ldap.LDAPFederationProvider;
+import org.keycloak.mappers.MapperConfigValidationException;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserFederationMapperModel;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.provider.ProviderConfigProperty;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class HardcodedLDAPRoleMapperFactory extends AbstractLDAPFederationMapperFactory {
+
+ public static final String PROVIDER_ID = "hardcoded-ldap-role-mapper";
+ protected static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
+
+ static {
+ ProviderConfigProperty roleAttr = createConfigProperty(HardcodedLDAPRoleMapper.ROLE, "Role",
+ "Role to grant to user. Click 'Select Role' button to browse roles, or just type it in the textbox. To reference an application role the syntax is appname.approle, i.e. myapp.myrole",
+ ProviderConfigProperty.ROLE_TYPE, null);
+ configProperties.add(roleAttr);
+ }
+
+ @Override
+ public String getHelpText() {
+ return "When user is imported from LDAP, he will be automatically added into this configured role.";
+ }
+
+ @Override
+ public String getDisplayCategory() {
+ return ROLE_MAPPER_CATEGORY;
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Hardcoded Role";
+ }
+
+ @Override
+ public List<ProviderConfigProperty> getConfigProperties() {
+ return configProperties;
+ }
+
+ @Override
+ public Map<String, String> getDefaultConfig(UserFederationProviderModel providerModel) {
+ return new HashMap<>();
+ }
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public void validateConfig(RealmModel realm, UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
+ String roleName = mapperModel.getConfig().get(HardcodedLDAPRoleMapper.ROLE);
+ if (roleName == null) {
+ throw new MapperConfigValidationException("Role can't be null");
+ }
+ RoleModel role = KeycloakModelUtils.getRoleFromString(realm, roleName);
+ if (role == null) {
+ throw new MapperConfigValidationException("There is no role corresponding to configured value");
+ }
+ }
+
+ @Override
+ protected AbstractLDAPFederationMapper createMapper(UserFederationMapperModel mapperModel, LDAPFederationProvider federationProvider, RealmModel realm) {
+ return new HardcodedLDAPRoleMapper(mapperModel, federationProvider, realm);
+ }
+}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapperFactory.java
index 464cc0d..fa43ac9 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapperFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapperFactory.java
@@ -168,7 +168,7 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
}
@Override
- public void validateConfig(UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
+ public void validateConfig(RealmModel realm, UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
checkMandatoryConfigAttribute(GroupMapperConfig.GROUPS_DN, "LDAP Groups DN", mapperModel);
checkMandatoryConfigAttribute(GroupMapperConfig.MODE, "Mode", mapperModel);
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/role/RoleLDAPFederationMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/role/RoleLDAPFederationMapperFactory.java
index a4ba60f..fe0b1e1 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/role/RoleLDAPFederationMapperFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/role/RoleLDAPFederationMapperFactory.java
@@ -161,7 +161,7 @@ public class RoleLDAPFederationMapperFactory extends AbstractLDAPFederationMappe
}
@Override
- public void validateConfig(UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
+ public void validateConfig(RealmModel realm, UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
checkMandatoryConfigAttribute(RoleMapperConfig.ROLES_DN, "LDAP Roles DN", mapperModel);
checkMandatoryConfigAttribute(RoleMapperConfig.MODE, "Mode", mapperModel);
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/UserAttributeLDAPFederationMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/UserAttributeLDAPFederationMapperFactory.java
index 9b061a6..5d92900 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/UserAttributeLDAPFederationMapperFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/UserAttributeLDAPFederationMapperFactory.java
@@ -87,7 +87,7 @@ public class UserAttributeLDAPFederationMapperFactory extends AbstractLDAPFedera
}
@Override
- public void validateConfig(UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
+ public void validateConfig(RealmModel realm, UserFederationMapperModel mapperModel) throws MapperConfigValidationException {
checkMandatoryConfigAttribute(UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "User Model Attribute", mapperModel);
checkMandatoryConfigAttribute(UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "LDAP Attribute", mapperModel);
}
diff --git a/federation/ldap/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory b/federation/ldap/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory
index 9e4a658..ac130a5 100644
--- a/federation/ldap/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory
+++ b/federation/ldap/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory
@@ -1,4 +1,5 @@
org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapperFactory
org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory
+org.keycloak.federation.ldap.mappers.HardcodedLDAPRoleMapperFactory
org.keycloak.federation.ldap.mappers.membership.role.RoleLDAPFederationMapperFactory
org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapperFactory
\ No newline at end of file
diff --git a/model/api/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java b/model/api/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java
index f009c3e..eebc3d7 100644
--- a/model/api/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java
+++ b/model/api/src/main/java/org/keycloak/mappers/UserFederationMapperFactory.java
@@ -2,6 +2,7 @@ package org.keycloak.mappers;
import java.util.Map;
+import org.keycloak.models.RealmModel;
import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.provider.ConfiguredProvider;
@@ -37,7 +38,7 @@ public interface UserFederationMapperFactory extends ProviderFactory<UserFederat
* @param mapperModel
* @throws MapperConfigValidationException if configuration provided in mapperModel is not valid
*/
- void validateConfig(UserFederationMapperModel mapperModel) throws MapperConfigValidationException;
+ void validateConfig(RealmModel realm, UserFederationMapperModel mapperModel) throws MapperConfigValidationException;
/**
* Used to detect what are default values for ProviderConfigProperties specified during mapper creation
diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index f08eee4..6a77ac6 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -540,4 +540,34 @@ public final class KeycloakModelUtils {
return result;
}
+ // Used in various role mappers
+ public static RoleModel getRoleFromString(RealmModel realm, String roleName) {
+ String[] parsedRole = parseRole(roleName);
+ RoleModel role = null;
+ if (parsedRole[0] == null) {
+ role = realm.getRole(parsedRole[1]);
+ } else {
+ ClientModel client = realm.getClientByClientId(parsedRole[0]);
+ if (client != null) {
+ role = client.getRole(parsedRole[1]);
+ }
+ }
+ return role;
+ }
+
+ // Used for hardcoded role mappers
+ public static String[] parseRole(String role) {
+ int scopeIndex = role.lastIndexOf('.');
+ if (scopeIndex > -1) {
+ String appName = role.substring(0, scopeIndex);
+ role = role.substring(scopeIndex + 1);
+ String[] rtn = {appName, role};
+ return rtn;
+ } else {
+ String[] rtn = {null, role};
+ return rtn;
+
+ }
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java
index c49eebb..a839e31 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java
@@ -4,6 +4,7 @@ import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.provider.ProviderConfigProperty;
@@ -67,7 +68,7 @@ public class HardcodedRole extends AbstractOIDCProtocolMapper implements OIDCAcc
public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
UserSessionModel userSession, ClientSessionModel clientSession) {
String role = mappingModel.getConfig().get(ROLE_CONFIG);
- String[] scopedRole = ProtocolMapperUtils.parseRole(role);
+ String[] scopedRole = KeycloakModelUtils.parseRole(role);
String appName = scopedRole[0];
String roleName = scopedRole[1];
if (appName != null) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java
index 3ce1e19..5f0178c 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java
@@ -5,6 +5,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.provider.ProviderConfigProperty;
@@ -78,8 +79,8 @@ public class RoleNameMapper extends AbstractOIDCProtocolMapper implements OIDCAc
String role = mappingModel.getConfig().get(ROLE_CONFIG);
String newName = mappingModel.getConfig().get(NEW_ROLE_NAME);
- String[] scopedRole = ProtocolMapperUtils.parseRole(role);
- String[] newScopedRole = ProtocolMapperUtils.parseRole(newName);
+ String[] scopedRole = KeycloakModelUtils.parseRole(role);
+ String[] newScopedRole = KeycloakModelUtils.parseRole(newName);
String appName = scopedRole[0];
String roleName = scopedRole[1];
if (appName != null) {
diff --git a/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java b/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java
index 2b86773..9022c26 100755
--- a/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java
+++ b/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java
@@ -47,20 +47,6 @@ public class ProtocolMapperUtils {
return null;
}
- public static String[] parseRole(String role) {
- int scopeIndex = role.lastIndexOf('.');
- if (scopeIndex > -1) {
- String appName = role.substring(0, scopeIndex);
- role = role.substring(scopeIndex + 1);
- String[] rtn = {appName, role};
- return rtn;
- } else {
- String[] rtn = {null, role};
- return rtn;
-
- }
- }
-
/**
* Find the builtin locale mapper.
*
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
index 1046276..2940247 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
@@ -353,7 +353,7 @@ public class UserFederationProviderResource {
private void validateModel(UserFederationMapperModel model) {
try {
UserFederationMapperFactory mapperFactory = (UserFederationMapperFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationMapper.class, model.getFederationMapperType());
- mapperFactory.validateConfig(model);
+ mapperFactory.validateConfig(realm, model);
} catch (MapperConfigValidationException ex) {
throw new ErrorResponseException("Validation error", ex.getMessage(), Response.Status.BAD_REQUEST);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/base/FederationProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/base/FederationProvidersIntegrationTest.java
index 5702a45..1d41595 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/base/FederationProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/ldap/base/FederationProvidersIntegrationTest.java
@@ -15,11 +15,15 @@ import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
import org.keycloak.federation.ldap.idm.model.LDAPObject;
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper;
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory;
+import org.keycloak.federation.ldap.mappers.HardcodedLDAPRoleMapper;
+import org.keycloak.federation.ldap.mappers.HardcodedLDAPRoleMapperFactory;
import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
+import org.keycloak.models.ModelException;
import org.keycloak.models.ModelReadOnlyException;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationMapperModel;
@@ -525,6 +529,50 @@ public class FederationProvidersIntegrationTest {
}
@Test
+ public void testHardcodedRoleMapper() {
+ KeycloakSession session = keycloakRule.startSession();
+ UserFederationMapperModel firstNameMapper = null;
+
+ try {
+ RealmModel appRealm = new RealmManager(session).getRealmByName("test");
+ RoleModel hardcodedRole = appRealm.addRole("hardcoded-role");
+
+ // assert that user "johnkeycloak" doesn't have hardcoded role
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ Assert.assertFalse(john.hasRole(hardcodedRole));
+
+ UserFederationMapperModel hardcodedMapperModel = KeycloakModelUtils.createUserFederationMapperModel("hardcoded role", ldapModel.getId(), HardcodedLDAPRoleMapperFactory.PROVIDER_ID,
+ HardcodedLDAPRoleMapper.ROLE, "hardcoded-role");
+ appRealm.addUserFederationMapper(hardcodedMapperModel);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+
+ session = keycloakRule.startSession();
+ try {
+ RealmModel appRealm = new RealmManager(session).getRealmByName("test");
+ RoleModel hardcodedRole = appRealm.getRole("hardcoded-role");
+
+ // Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ Assert.assertTrue(john.hasRole(hardcodedRole));
+
+ // Can't remove user from hardcoded role
+ try {
+ john.deleteRoleMapping(hardcodedRole);
+ Assert.fail("Didn't expected to remove role mapping");
+ } catch (ModelException expected) {
+ }
+
+ // Revert mappers
+ UserFederationMapperModel hardcodedMapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "hardcoded role");
+ appRealm.removeUserFederationMapper(hardcodedMapperModel);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+ @Test
public void testImportExistingUserFromLDAP() throws Exception {
// Add LDAP user with same email like existing model user
keycloakRule.update(new KeycloakRule.KeycloakSetup() {