keycloak-aplcache

KEYCLOAK-8148 Duplication of listed roles assigned through

10/5/2018 5:24:58 PM

Details

diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java
index eafcfcd..87f931e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java
@@ -37,6 +37,7 @@ import org.keycloak.representations.AddressClaimSet;
 import org.keycloak.representations.IDToken;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.ClientScopeRepresentation;
+import org.keycloak.representations.idm.GroupRepresentation;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
@@ -105,10 +106,14 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
 
     private void deleteMappers(ProtocolMappersResource protocolMappers) {
         ProtocolMapperRepresentation mapper = ProtocolMapperUtil.getMapperByNameAndProtocol(protocolMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "Realm roles mapper");
-        protocolMappers.delete(mapper.getId());
+        if (mapper != null) {
+            protocolMappers.delete(mapper.getId());
+        }
 
         mapper = ProtocolMapperUtil.getMapperByNameAndProtocol(protocolMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, "Client roles mapper");
-        protocolMappers.delete(mapper.getId());
+        if (mapper != null) {
+            protocolMappers.delete(mapper.getId());
+        }
     }
 
     @Override
@@ -525,6 +530,42 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
     }
 
 
+    // KEYCLOAK-8148 -- Test the scenario where:
+    // -- user is member of 2 groups
+    // -- both groups have same role "customer-user" assigned
+    // -- User login. Role will appear just once in the token (not twice)
+    @Test
+    public void testRoleMapperWithRoleInheritedFromMoreGroups() throws Exception {
+        // Create client-mapper
+        String clientId = "test-app";
+        ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom.test-app", true, true);
+
+        ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers();
+        protocolMappers.createMapper(Arrays.asList(clientMapper));
+
+        // Add user 'level2GroupUser' to the group 'level2Group2'
+        GroupRepresentation level2Group2 = adminClient.realm("test").getGroupByPath("/topGroup/level2group2");
+        UserResource level2GroupUser = ApiUtil.findUserByUsernameId(adminClient.realm("test"), "level2GroupUser");
+        level2GroupUser.joinGroup(level2Group2.getId());
+
+        oauth.clientId(clientId);
+        OAuthClient.AccessTokenResponse response = browserLogin("password", "level2GroupUser", "password");
+        IDToken idToken = oauth.verifyIDToken(response.getIdToken());
+
+        // Verify attribute is filled AND it is filled only once
+        Map<String, Object> roleMappings = (Map<String, Object>)idToken.getOtherClaims().get("roles-custom");
+        Assert.assertThat(roleMappings.keySet(), containsInAnyOrder(clientId));
+        String testAppScopeMappings = (String) roleMappings.get(clientId);
+        assertRolesString(testAppScopeMappings,
+                "customer-user"      // from assignment to level2group or level2group2. It is filled just once
+        );
+
+        // Revert
+        level2GroupUser.leaveGroup(level2Group2.getId());
+        deleteMappers(protocolMappers);
+    }
+
+
     @Test
     public void testUserGroupRoleToAttributeMappers() throws Exception {
         // Add mapper for realm roles