keycloak-aplcache

role name mapper

3/11/2015 10:59:56 AM

Details

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 ec0f720..26075e4 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.protocol.ProtocolMapperUtils;
 import org.keycloak.protocol.oidc.OIDCLoginProtocol;
 import org.keycloak.representations.AccessToken;
 
@@ -65,12 +66,11 @@ 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 appName = null;
-        int scopeIndex = role.indexOf('.');
-        if (scopeIndex > -1) {
-            appName = role.substring(0, scopeIndex);
-            role = role.substring(scopeIndex + 1);
-            token.addAccess(appName).addRole(role);
+        String[] scopedRole = ProtocolMapperUtils.parseRole(role);
+        String appName = scopedRole[0];
+        String roleName = scopedRole[1];
+        if (appName != null) {
+            token.addAccess(appName).addRole(roleName);
         } else {
             AccessToken.Access access = token.getRealmAccess();
             if (access == 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 f60246c..eaee955 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
@@ -76,29 +76,35 @@ public class RoleNameMapper extends AbstractOIDCProtocolMapper implements OIDCAc
                                             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);
+
+        String[] scopedRole = ProtocolMapperUtils.parseRole(role);
+        String[] newScopedRole = ProtocolMapperUtils.parseRole(newName);
+        String appName = scopedRole[0];
+        String roleName = scopedRole[1];
+        if (appName != null) {
             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);
+            if (!access.getRoles().contains(roleName)) return token;
+            access.getRoles().remove(roleName);
         } else {
             AccessToken.Access access = token.getRealmAccess();
             if (access == null) return token;
-            access.getRoles().remove(role);
+            access.getRoles().remove(roleName);
         }
 
-        String newAppName = null;
-        scopeIndex = newName.indexOf('.');
-        if (scopeIndex > -1) {
-            newAppName = role.substring(0, scopeIndex);
-            newName = role.substring(scopeIndex + 1);
-            token.addAccess(newAppName).addRole(newName);
+        String newAppName = newScopedRole[0];
+        String newRoleName = newScopedRole[1];
+        AccessToken.Access access = null;
+        if (newAppName == null) {
+            access = token.getRealmAccess();
+            if (access == null) {
+                access = new AccessToken.Access();
+                token.setRealmAccess(access);
+            }
+        } else {
+            access = token.addAccess(newAppName);
         }
+        access.addRole(newRoleName);
         return token;
     }
 
diff --git a/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java b/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java
index 727d74d..b91b754 100755
--- a/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java
+++ b/services/src/main/java/org/keycloak/protocol/ProtocolMapperUtils.java
@@ -3,6 +3,7 @@ package org.keycloak.protocol;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.AccessToken;
 
 import java.lang.reflect.Method;
 import java.util.List;
@@ -41,4 +42,18 @@ public class ProtocolMapperUtils {
         }
         return null;
     }
+
+    public static String[] parseRole(String role) {
+        int scopeIndex = role.indexOf('.');
+        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/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 0091e33..b6f45bd 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -607,6 +607,7 @@ public class AccessTokenTest {
             app.addProtocolMapper(UserAttributeMapper.createClaimMapper("nested phone", "phone", "home.phone", "String", true, "", true, true));
             app.addProtocolMapper(HardcodedRole.create("hard-realm", "hardcoded"));
             app.addProtocolMapper(HardcodedRole.create("hard-app", "app.hardcoded"));
+            app.addProtocolMapper(RoleNameMapper.create("rename-app-role", "test-app.customer-user", "realm-user"));
             session.getTransaction().commit();
             session.close();
         }
@@ -647,6 +648,8 @@ public class AccessTokenTest {
             nested = (Map)accessToken.getOtherClaims().get("home");
             Assert.assertEquals("617-777-6666", nested.get("phone"));
             Assert.assertTrue(accessToken.getRealmAccess().getRoles().contains("hardcoded"));
+            Assert.assertTrue(accessToken.getRealmAccess().getRoles().contains("realm-user"));
+            Assert.assertFalse(accessToken.getResourceAccess("test-app").getRoles().contains("customer-user"));
             Assert.assertTrue(accessToken.getResourceAccess("app").getRoles().contains("hardcoded"));
 
 
@@ -665,6 +668,7 @@ public class AccessTokenTest {
                         || model.getName().equals("hard-nested")
                         || model.getName().equals("custom phone")
                         || model.getName().equals("nested phone")
+                        || model.getName().equals("rename-app-role")
                         || model.getName().equals("hard-realm")
                         || model.getName().equals("hard-app")
                         )   {