keycloak-aplcache

more mappers

3/5/2015 9:55:53 PM

Details

diff --git a/core/src/main/java/org/keycloak/representations/AccessToken.java b/core/src/main/java/org/keycloak/representations/AccessToken.java
index 4d099ca..81d3615 100755
--- a/core/src/main/java/org/keycloak/representations/AccessToken.java
+++ b/core/src/main/java/org/keycloak/representations/AccessToken.java
@@ -125,9 +125,11 @@ public class AccessToken extends IDToken {
     }
 
     public Access addAccess(String service) {
-        Access token = new Access();
-        resourceAccess.put(service, token);
-        return token;
+        Access access = resourceAccess.get(service);
+        if (access != null) return access;
+        access = new Access();
+        resourceAccess.put(service, access);
+        return access;
     }
 
     public AccessToken clientSession(String session) {
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLRoleListMapper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLRoleListMapper.java
new file mode 100755
index 0000000..b2d500f
--- /dev/null
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLRoleListMapper.java
@@ -0,0 +1,17 @@
+package org.keycloak.protocol.saml.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserSessionModel;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface SAMLRoleListMapper {
+
+    void mapRoles(AttributeStatementType roleAttributeStatement, ProtocolMapperModel mappingModel, KeycloakSession session,
+                                     UserSessionModel userSession, ClientSessionModel clientSession);
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java
new file mode 100755
index 0000000..fad7bd6
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java
@@ -0,0 +1,127 @@
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.IDToken;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OIDCAddClaimMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper {
+
+    private static final List<ConfigProperty> configProperties = new ArrayList<ConfigProperty>();
+
+    public static final String CLAIM_VALUE = "claim.value";
+
+    static {
+        ConfigProperty property;
+        property = new ConfigProperty();
+        property.setName(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
+        property.setLabel(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME_LABEL);
+        property.setType(ConfigProperty.STRING_TYPE);
+        property.setHelpText("Claim name you want to hard code into the token.  This can be a fully qualified name like 'address.street'.  In this case, a nested json object will be created.");
+        configProperties.add(property);
+        property = new ConfigProperty();
+        property.setName(CLAIM_VALUE);
+        property.setLabel("Claim value");
+        property.setType(ConfigProperty.STRING_TYPE);
+        property.setHelpText("Value of the claim you want to hard code.  'true' and 'false can be used for boolean values.");
+        configProperties.add(property);
+        property = new ConfigProperty();
+        property.setName(OIDCAttributeMapperHelper.JSON_TYPE);
+        property.setLabel(OIDCAttributeMapperHelper.JSON_TYPE);
+        property.setType(ConfigProperty.STRING_TYPE);
+        property.setDefaultValue(ConfigProperty.STRING_TYPE);
+        property.setHelpText("JSON type that should be used for the value of the claim.  long, int, boolean, and String are valid values.");
+        configProperties.add(property);
+        property = new ConfigProperty();
+        property.setName(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN);
+        property.setLabel(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN_LABEL);
+        property.setType(ConfigProperty.BOOLEAN_TYPE);
+        property.setDefaultValue("true");
+        property.setHelpText(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN_HELP_TEXT);
+        configProperties.add(property);
+        property = new ConfigProperty();
+        property.setName(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN);
+        property.setLabel(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN_LABEL);
+        property.setType(ConfigProperty.BOOLEAN_TYPE);
+        property.setDefaultValue("true");
+        property.setHelpText(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN_HELP_TEXT);
+        configProperties.add(property);
+
+    }
+
+    public static final String PROVIDER_ID = "oidc-add-claim-mapper";
+
+
+    public List<ConfigProperty> getConfigProperties() {
+        return configProperties;
+    }
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "Hard coded claim";
+    }
+
+    @Override
+    public String getDisplayCategory() {
+        return TOKEN_MAPPER_CATEGORY;
+    }
+
+    @Override
+    public String getHelpText() {
+        return "Hardcode a claim into the token.";
+    }
+
+    @Override
+    public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
+                                            UserSessionModel userSession, ClientSessionModel clientSession) {
+        if (!OIDCAttributeMapperHelper.includeInAccessToken(mappingModel)) return token;
+
+        setClaim(token, mappingModel, userSession);
+        return token;
+    }
+
+    protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
+        String attributeValue = mappingModel.getConfig().get(CLAIM_VALUE);
+        if (attributeValue == null) return;
+        OIDCAttributeMapperHelper.mapClaim(token, mappingModel, attributeValue);
+    }
+
+    @Override
+    public IDToken transformIDToken(IDToken token, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
+        if (!OIDCAttributeMapperHelper.includeInIDToken(mappingModel)) return token;
+        setClaim(token, mappingModel, userSession);
+        return token;
+    }
+
+    public static ProtocolMapperModel createClaimMapper(String name,
+                                      String userAttribute,
+                                      String tokenClaimName, String claimType,
+                                      boolean consentRequired, String consentText,
+                                      boolean accessToken, boolean idToken) {
+        return OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute,
+                tokenClaimName, claimType,
+                consentRequired, consentText,
+                accessToken, idToken,
+                PROVIDER_ID);
+    }
+
+
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddRoleMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddRoleMapper.java
new file mode 100755
index 0000000..c46b9d4
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddRoleMapper.java
@@ -0,0 +1,81 @@
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.representations.AccessToken;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Add a role to a token
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OIDCAddRoleMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
+
+    private static final List<ConfigProperty> configProperties = new ArrayList<ConfigProperty>();
+
+    public static final String ROLE_CONFIG = "role";
+
+    static {
+        ConfigProperty property;
+        property = new ConfigProperty();
+        property.setName(ROLE_CONFIG);
+        property.setLabel("Role");
+        property.setHelpText("Role you want added to the token.  To specify an application role the syntax is appname.approle, i.e. myapp.myrole");
+        property.setType(ConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+    }
+
+    public static final String PROVIDER_ID = "oidc-role-mapper";
+
+
+    public List<ConfigProperty> getConfigProperties() {
+        return configProperties;
+    }
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "Add Role";
+    }
+
+    @Override
+    public String getDisplayCategory() {
+        return TOKEN_MAPPER_CATEGORY;
+    }
+
+    @Override
+    public String getHelpText() {
+        return "Hardcode any role specify into the token.";
+    }
+
+    @Override
+    public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
+                                            UserSessionModel userSession, ClientSessionModel clientSession) {
+        String role = mappingModel.getConfig().get(ROLE_CONFIG);
+        String appName = null;
+        int scopeIndex = role.indexOf('.');
+        if (scopeIndex > -1) {
+            appName = role.substring(0, scopeIndex);
+            role = role.substring(scopeIndex + 1);
+            token.addAccess(appName).addRole(role);
+        } else {
+            AccessToken.Access access = token.getRealmAccess();
+            if (access == null) {
+                access = new AccessToken.Access();
+                token.setRealmAccess(access);
+            }
+            access.addRole(role);
+        }
+        return token;
+    }
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java
index 8819713..b91c233 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java
@@ -15,7 +15,8 @@ import java.util.Map;
  * @version $Revision: 1 $
  */
 public class OIDCAttributeMapperHelper {
-    public static final String TOKEN_CLAIM_NAME = "Token Claim Name";
+    public static final String TOKEN_CLAIM_NAME = "claim.name";
+    public static final String TOKEN_CLAIM_NAME_LABEL = "Token Claim Name";
     public static final String JSON_TYPE = "Claim JSON Type";
     public static final String INCLUDE_IN_ACCESS_TOKEN = "access.token.claim";
     public static final String INCLUDE_IN_ACCESS_TOKEN_LABEL = "Add to access token";
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCRoleMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCRoleMapper.java
new file mode 100755
index 0000000..10724ef
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCRoleMapper.java
@@ -0,0 +1,100 @@
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.IDToken;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Map an assigned role to a different position and name in the token
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OIDCRoleMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
+
+    private static final List<ConfigProperty> configProperties = new ArrayList<ConfigProperty>();
+
+    public static final String ROLE_CONFIG = "role";
+    public static String NEW_ROLE_NAME = "new.role.name";
+
+    static {
+        ConfigProperty property;
+        property = new ConfigProperty();
+        property.setName(ROLE_CONFIG);
+        property.setLabel("Role");
+        property.setHelpText("Role name you want changed.  To reference an application role the syntax is appname.approle, i.e. myapp.myrole");
+        property.setType(ConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+        property.setName(NEW_ROLE_NAME);
+        property.setLabel("New Role Name");
+        property.setHelpText("The new role name.  The new name format corresponds to where in the access token the role will be mapped to.  So, a new name of 'myapp.newname' will map the role to that position in the access token.  A new name of 'newname' will map the role to the realm roles in the token.");
+        property.setType(ConfigProperty.STRING_TYPE);
+        configProperties.add(property);
+    }
+
+    public static final String PROVIDER_ID = "oidc-role-mapper";
+
+
+    public List<ConfigProperty> getConfigProperties() {
+        return configProperties;
+    }
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public String getDisplayType() {
+        return "Role Mapper";
+    }
+
+    @Override
+    public String getDisplayCategory() {
+        return TOKEN_MAPPER_CATEGORY;
+    }
+
+    @Override
+    public String getHelpText() {
+        return "Map an assigned role to a new name or position in the token.";
+    }
+
+    @Override
+    public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
+                                            UserSessionModel userSession, ClientSessionModel clientSession) {
+        String role = mappingModel.getConfig().get(ROLE_CONFIG);
+        String newName = mappingModel.getConfig().get(NEW_ROLE_NAME);
+        String appName = null;
+        int scopeIndex = role.indexOf('.');
+        if (scopeIndex > -1) {
+            appName = role.substring(0, scopeIndex);
+            AccessToken.Access access = token.getResourceAccess(appName);
+            if (access == null) return token;
+
+            role = role.substring(scopeIndex + 1);
+            if (!access.getRoles().contains(role)) return token;
+            access.getRoles().remove(role);
+        } else {
+            AccessToken.Access access = token.getRealmAccess();
+            if (access == null) return token;
+            access.getRoles().remove(role);
+        }
+
+        String newAppName = null;
+        scopeIndex = newName.indexOf('.');
+        if (scopeIndex > -1) {
+            newAppName = role.substring(0, scopeIndex);
+            newName = role.substring(scopeIndex + 1);
+            token.addAccess(newAppName).addRole(newName);
+        }
+        return token;
+    }
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java
index f0f5657..b2ea92d 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java
@@ -35,7 +35,7 @@ public class OIDCUserAttributeMapper extends AbstractOIDCProtocolMapper implemen
         configProperties.add(property);
         property = new ConfigProperty();
         property.setName(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
-        property.setLabel(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
+        property.setLabel(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME_LABEL);
         property.setType(ConfigProperty.STRING_TYPE);
         property.setHelpText("Name of the claim to insert into the token.  This can be a fully qualified name like 'address.street'.  In this case, a nested json object will be created.");
         configProperties.add(property);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java
index cd0cd03..3b559e2 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java
@@ -34,7 +34,7 @@ public class OIDCUserModelMapper extends AbstractOIDCProtocolMapper implements O
         configProperties.add(property);
         property = new ConfigProperty();
         property.setName(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
-        property.setLabel(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
+        property.setLabel(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME_LABEL);
         property.setType(ConfigProperty.STRING_TYPE);
         property.setHelpText("Name of the claim to insert into the token.  This can be a fully qualified name like 'address.street'.  In this case, a nested json object will be created.");
         configProperties.add(property);
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper b/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
index 1615ecc..d89c1bf 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
+++ b/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
@@ -2,5 +2,8 @@ org.keycloak.protocol.oidc.mappers.OIDCUserAttributeMapper
 org.keycloak.protocol.oidc.mappers.OIDCFullNameMapper
 org.keycloak.protocol.oidc.mappers.OIDCUserModelMapper
 org.keycloak.protocol.oidc.mappers.OIDCAddressMapper
+org.keycloak.protocol.oidc.mappers.OIDCAddClaimMapper
+org.keycloak.protocol.oidc.mappers.OIDCAddRoleMapper
+org.keycloak.protocol.oidc.mappers.OIDCRoleMapper