keycloak-memoizeit

Details

diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java
index c2c628d..f9e50e5 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java
@@ -40,6 +40,8 @@ import static org.keycloak.testsuite.broker.BrokerTestTools.waitForPage;
  */
 public abstract class AbstractBaseBrokerTest extends AbstractKeycloakTest {
 
+    protected static final String ATTRIBUTE_VALUE = "attribute.value";
+
     @Page
     protected AccountUpdateProfilePage accountUpdateProfilePage;
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
index 6f3314f..f6e575f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
@@ -3,10 +3,14 @@ package org.keycloak.testsuite.broker;
 import org.junit.Before;
 import org.junit.Test;
 
+import org.keycloak.admin.client.resource.IdentityProviderResource;
 import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.UserResource;
 import org.keycloak.admin.client.resource.UsersResource;
 import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.pages.ConsentPage;
@@ -14,8 +18,10 @@ import org.keycloak.testsuite.util.*;
 
 import org.openqa.selenium.TimeoutException;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -26,6 +32,8 @@ import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
 
 import org.jboss.arquillian.graphene.page.Page;
 
+import javax.ws.rs.core.Response;
+
 import static org.keycloak.testsuite.broker.BrokerTestTools.*;
 
 public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
@@ -41,7 +49,7 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
         user.setEnabled(true);
 
         RealmResource realmResource = adminClient.realm(bc.providerRealmName());
-        String userId = createUserWithAdminClient(realmResource, user);
+        userId = createUserWithAdminClient(realmResource, user);
 
         resetUserPassword(realmResource.users().get(userId), bc.getUserPassword(), false);
     }
@@ -314,4 +322,60 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
         Assert.assertTrue("Should be on " + bc.consumerRealmName() + " realm on login page",
                 driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/protocol/openid-connect/"));
     }
+
+    protected void createRolesForRealm(String realm) {
+        RoleRepresentation managerRole = new RoleRepresentation("manager",null, false);
+        RoleRepresentation userRole = new RoleRepresentation("user",null, false);
+        adminClient.realm(realm).roles().create(managerRole);
+        adminClient.realm(realm).roles().create(userRole);
+    }
+
+    protected void createRoleMappersForConsumerRealm() {
+        log.debug("adding mappers to identity provider in realm " + bc.consumerRealmName());
+
+        RealmResource realm = adminClient.realm(bc.consumerRealmName());
+
+        IdentityProviderResource idpResource = realm.identityProviders().get(bc.getIDPAlias());
+        for (IdentityProviderMapperRepresentation mapper : createIdentityProviderMappers()) {
+            mapper.setIdentityProviderAlias(bc.getIDPAlias());
+            Response resp = idpResource.addMapper(mapper);
+            resp.close();
+        }
+    }
+
+    protected abstract Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers();
+
+    // KEYCLOAK-3987
+    @Test
+    public void grantNewRoleFromToken() {
+        createRolesForRealm(bc.providerRealmName());
+        createRolesForRealm(bc.consumerRealmName());
+
+        createRoleMappersForConsumerRealm();
+
+        RoleRepresentation managerRole = adminClient.realm(bc.providerRealmName()).roles().get("manager").toRepresentation();
+        RoleRepresentation userRole = adminClient.realm(bc.providerRealmName()).roles().get("user").toRepresentation();
+
+        UserResource userResource = adminClient.realm(bc.providerRealmName()).users().get(userId);
+        userResource.roles().realmLevel().add(Collections.singletonList(managerRole));
+
+        logInAsUserInIDPForFirstTime();
+
+        List<RoleRepresentation> currentRoles = userResource.roles().realmLevel().listAll();
+        assertEquals("There should be manager role",1, currentRoles.stream().filter(role -> role.getName().equals("manager")).collect(Collectors.toList()).size());
+        assertEquals("User shouldn't have user role", 0, currentRoles.stream().filter(role -> role.getName().equals("user")).collect(Collectors.toList()).size());
+
+        logoutFromRealm(bc.consumerRealmName());
+
+        userResource.roles().realmLevel().add(Collections.singletonList(userRole));
+
+        logInAsUserInIDP();
+
+        currentRoles = userResource.roles().realmLevel().listAll();
+        assertEquals("There should be manager role",1, currentRoles.stream().filter(role -> role.getName().equals("manager")).collect(Collectors.toList()).size());
+        assertEquals("There should be user role",1, currentRoles.stream().filter(role -> role.getName().equals("user")).collect(Collectors.toList()).size());
+
+        logoutFromRealm(bc.providerRealmName());
+        logoutFromRealm(bc.consumerRealmName());
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java
index c71ef3e..ef740da 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java
@@ -1,9 +1,35 @@
 package org.keycloak.testsuite.broker;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.keycloak.broker.oidc.mappers.ExternalKeycloakRoleToRoleMapper;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+
 public class KcOidcBrokerTest extends AbstractBrokerTest {
 
     @Override
     protected BrokerConfiguration getBrokerConfiguration() {
         return KcOidcBrokerConfiguration.INSTANCE;
     }
+
+    @Override
+    protected Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers() {
+        IdentityProviderMapperRepresentation attrMapper1 = new IdentityProviderMapperRepresentation();
+        attrMapper1.setName("manager-role-mapper");
+        attrMapper1.setIdentityProviderMapper(ExternalKeycloakRoleToRoleMapper.PROVIDER_ID);
+        attrMapper1.setConfig(ImmutableMap.<String,String>builder()
+                .put("external.role", "manager")
+                .put("role", "manager")
+                .build());
+
+        IdentityProviderMapperRepresentation attrMapper2 = new IdentityProviderMapperRepresentation();
+        attrMapper2.setName("user-role-mapper");
+        attrMapper2.setIdentityProviderMapper(ExternalKeycloakRoleToRoleMapper.PROVIDER_ID);
+        attrMapper2.setConfig(ImmutableMap.<String,String>builder()
+                .put("external.role", "user")
+                .put("role", "user")
+                .build());
+
+        return Lists.newArrayList(attrMapper1, attrMapper2);
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java
index 225df81..b5ded3e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java
@@ -1,9 +1,38 @@
 package org.keycloak.testsuite.broker;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.keycloak.broker.saml.mappers.AttributeToRoleMapper;
+import org.keycloak.broker.saml.mappers.UserAttributeMapper;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+
 public class KcSamlBrokerTest extends AbstractBrokerTest {
 
     @Override
     protected BrokerConfiguration getBrokerConfiguration() {
         return KcSamlBrokerConfiguration.INSTANCE;
     }
+
+    @Override
+    protected Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers() {
+        IdentityProviderMapperRepresentation attrMapper1 = new IdentityProviderMapperRepresentation();
+        attrMapper1.setName("manager-role-mapper");
+        attrMapper1.setIdentityProviderMapper(AttributeToRoleMapper.PROVIDER_ID);
+        attrMapper1.setConfig(ImmutableMap.<String,String>builder()
+                .put(UserAttributeMapper.ATTRIBUTE_NAME, "Role")
+                .put(ATTRIBUTE_VALUE, "manager")
+                .put("role", "manager")
+                .build());
+
+        IdentityProviderMapperRepresentation attrMapper2 = new IdentityProviderMapperRepresentation();
+        attrMapper2.setName("user-role-mapper");
+        attrMapper2.setIdentityProviderMapper(AttributeToRoleMapper.PROVIDER_ID);
+        attrMapper2.setConfig(ImmutableMap.<String,String>builder()
+                .put(UserAttributeMapper.ATTRIBUTE_NAME, "Role")
+                .put(ATTRIBUTE_VALUE, "user")
+                .put("role", "user")
+                .build());
+
+        return Lists.newArrayList(attrMapper1, attrMapper2);
+    }
 }