diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java index f0a37adfd6..dca666fab9 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ApiUtil.java @@ -110,6 +110,13 @@ public class ApiUtil { if (ur.size() == 1) { user = ur.get(0); } + + if (ur.size() > 1) { // try to be more specific + for (UserRepresentation rep : ur) { + if (rep.getUsername().equalsIgnoreCase(username)) return rep; + } + } + return user; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/AbstractCompositeKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/AbstractCompositeKeycloakTest.java new file mode 100644 index 0000000000..ca546a8b5b --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/AbstractCompositeKeycloakTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package org.keycloak.testsuite.composites; + +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.admin.ApiUtil; + +/** + * + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public abstract class AbstractCompositeKeycloakTest extends AbstractKeycloakTest { + + protected RealmResource testRealm() { + return adminClient.realm("test"); + } + + protected String getUserId(String username) { + return ApiUtil.findUserByUsername(testRealm(), username).getId(); + } +} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java similarity index 69% rename from testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java rename to testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java index b7547a1aa4..854f6ce376 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java @@ -17,64 +17,39 @@ package org.keycloak.testsuite.composites; import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; import org.keycloak.representations.AccessToken; import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.services.managers.RealmManager; -import org.keycloak.testsuite.ApplicationServlet; -import org.keycloak.testsuite.OAuthClient; -import org.keycloak.testsuite.OAuthClient.AccessTokenResponse; import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.rule.AbstractKeycloakRule; -import org.keycloak.testsuite.rule.WebResource; -import org.keycloak.testsuite.rule.WebRule; -import org.keycloak.testsuite.KeycloakServer; -import org.openqa.selenium.WebDriver; +import java.util.List; +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse; -import java.security.PublicKey; +import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; /** * @author Stian Thorgersen + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. */ -public class CompositeImportRoleTest { +public class CompositeImportRoleTest extends AbstractCompositeKeycloakTest { - public static PublicKey realmPublicKey; - @ClassRule - public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){ - @Override - protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) { - RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/testcomposite.json"), RealmRepresentation.class); - representation.setId("test"); - RealmModel realm = manager.importRealm(representation); + @Override + public void addTestRealms(List testRealms) { + RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/testcomposite.json"), RealmRepresentation.class); + testRealm.setId("test"); + testRealm.setPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"); + testRealm.setPrivateKey("MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y="); - realmPublicKey = realm.getPublicKey(); + testRealms.add(testRealm); + } - deployServlet("app", "/app", ApplicationServlet.class); - - } - }; - - @Rule - public WebRule webRule = new WebRule(this); - - @WebResource - protected WebDriver driver; - - @WebResource - protected OAuthClient oauth; - - @WebResource + @Page protected LoginPage loginPage; @Test public void testAppCompositeUser() throws Exception { oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); oauth.clientId("APP_COMPOSITE_APPLICATION"); oauth.doLogin("APP_COMPOSITE_USER", "password"); @@ -87,7 +62,7 @@ public class CompositeImportRoleTest { AccessToken token = oauth.verifyToken(response.getAccessToken()); - Assert.assertEquals(keycloakRule.getUser("test", "APP_COMPOSITE_USER").getId(), token.getSubject()); + Assert.assertEquals(getUserId("APP_COMPOSITE_USER"), token.getSubject()); Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size()); Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); @@ -99,7 +74,6 @@ public class CompositeImportRoleTest { @Test public void testRealmAppCompositeUser() throws Exception { oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); oauth.clientId("APP_ROLE_APPLICATION"); oauth.doLogin("REALM_APP_COMPOSITE_USER", "password"); @@ -112,7 +86,7 @@ public class CompositeImportRoleTest { AccessToken token = oauth.verifyToken(response.getAccessToken()); - Assert.assertEquals(keycloakRule.getUser("test", "REALM_APP_COMPOSITE_USER").getId(), token.getSubject()); + Assert.assertEquals(getUserId("REALM_APP_COMPOSITE_USER"), token.getSubject()); Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size()); Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); @@ -123,7 +97,6 @@ public class CompositeImportRoleTest { @Test public void testRealmOnlyWithUserCompositeAppComposite() throws Exception { oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); @@ -136,7 +109,7 @@ public class CompositeImportRoleTest { AccessToken token = oauth.verifyToken(response.getAccessToken()); - Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject()); + Assert.assertEquals(getUserId("REALM_COMPOSITE_1_USER"), token.getSubject()); Assert.assertEquals(2, token.getRealmAccess().getRoles().size()); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1")); @@ -146,7 +119,6 @@ public class CompositeImportRoleTest { @Test public void testRealmOnlyWithUserCompositeAppRole() throws Exception { oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); oauth.clientId("REALM_ROLE_1_APPLICATION"); oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); @@ -159,7 +131,7 @@ public class CompositeImportRoleTest { AccessToken token = oauth.verifyToken(response.getAccessToken()); - Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject()); + Assert.assertEquals(getUserId("REALM_COMPOSITE_1_USER"), token.getSubject()); Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); @@ -168,7 +140,6 @@ public class CompositeImportRoleTest { @Test public void testRealmOnlyWithUserRoleAppComposite() throws Exception { oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); oauth.doLogin("REALM_ROLE_1_USER", "password"); @@ -181,7 +152,7 @@ public class CompositeImportRoleTest { AccessToken token = oauth.verifyToken(response.getAccessToken()); - Assert.assertEquals(keycloakRule.getUser("test", "REALM_ROLE_1_USER").getId(), token.getSubject()); + Assert.assertEquals(getUserId("REALM_ROLE_1_USER"), token.getSubject()); Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java new file mode 100755 index 0000000000..a43aae8475 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java @@ -0,0 +1,348 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.keycloak.testsuite.composites; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.OAuth2Constants; +import org.keycloak.representations.AccessToken; +import org.keycloak.testsuite.pages.LoginPage; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import org.jboss.arquillian.graphene.page.Page; +import org.junit.Before; +import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.admin.client.resource.RoleResource; +import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.common.enums.SslRequired; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.util.ClientBuilder; +import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse; +import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testsuite.util.RoleBuilder; +import org.keycloak.testsuite.util.RolesBuilder; +import org.keycloak.testsuite.util.UserBuilder; + +/** + * @author Stian Thorgersen + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public class CompositeRoleTest extends AbstractCompositeKeycloakTest { + + @Override + public void addTestRealms(List testRealms) { + RealmBuilder realmBuilder = RealmBuilder.create() + .name("test") + .publicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB") + .privateKey("MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=") + .ssoSessionIdleTimeout(3000) + .accessTokenLifespan(10000) + .ssoSessionMaxLifespan(10000) + .accessCodeLifespanUserAction(1000) + .accessCodeLifespan(1000) + .sslRequired(SslRequired.EXTERNAL.toString()); + + + RoleRepresentation realmRole1 = RoleBuilder.create().name("REALM_ROLE_1").build(); + RoleRepresentation realmComposite1 = RoleBuilder.create() + .name("REALM_COMPOSITE_1") + .composite() + .realmComposite(realmRole1) + .build(); + + RolesBuilder roles = RolesBuilder.create() + .realmRole(realmRole1) + .realmRole(RoleBuilder.create().name("REALM_ROLE_2").build()) + .realmRole(RoleBuilder.create().name("REALM_ROLE_3").build()) + .realmRole(realmComposite1); + realmBuilder.roles(roles); + + UserBuilder realmCompositeUser = UserBuilder.create() + .username("REALM_COMPOSITE_1_USER") + .enabled(true) + .password("password") + .addRoles(realmComposite1.getName()); + realmBuilder.user(realmCompositeUser); + + UserBuilder realmRole1User = UserBuilder.create() + .username("REALM_ROLE_1_USER") + .enabled(true) + .password("password") + .addRoles(realmRole1.getName()); + realmBuilder.user(realmRole1User); + + ClientBuilder realmComposite1Application = ClientBuilder.create() + .clientId("REALM_COMPOSITE_1_APPLICATION") + .name("REALM_COMPOSITE_1_APPLICATION") + .fullScopeEnabled(Boolean.FALSE) + // addScopeMapping(realmComposite1) + .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .baseUrl("http://localhost:8180/auth/realms/master/app/auth") + .adminUrl("http://localhost:8180/auth/realms/master/app/logout") + .secret("password"); + realmBuilder.client(realmComposite1Application); + + ClientBuilder realmRole1Application = ClientBuilder.create() + .clientId("REALM_ROLE_1_APPLICATION") + .name("REALM_ROLE_1_APPLICATION") + .fullScopeEnabled(Boolean.FALSE) + // addScopeMapping(realmRole1) + .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .baseUrl("http://localhost:8180/auth/realms/master/app/auth") + .adminUrl("http://localhost:8180/auth/realms/master/app/logout") + .secret("password"); + realmBuilder.client(realmRole1Application); + + ClientBuilder appRoleApplication = ClientBuilder.create() + .clientId("APP_ROLE_APPLICATION") + .name("APP_ROLE_APPLICATION") + .fullScopeEnabled(Boolean.FALSE) + .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .baseUrl("http://localhost:8180/auth/realms/master/app/auth") + .adminUrl("http://localhost:8180/auth/realms/master/app/logout") + .defaultRoles("APP_ROLE_1", "APP_ROLE_2") + .secret("password"); + realmBuilder.client(appRoleApplication); + + UserBuilder realmAppCompositeUser = UserBuilder.create() + .username("REALM_APP_COMPOSITE_USER") + .password("password"); + realmBuilder.user(realmAppCompositeUser); + + UserBuilder realmAppRoleUser = UserBuilder.create() + .username("REALM_APP_ROLE_USER") + .password("password") + .addRoles("APP_ROLE_2"); + realmBuilder.user(realmAppRoleUser); + + ClientBuilder appCompositeApplication = ClientBuilder.create() + .clientId("APP_COMPOSITE_APPLICATION") + .name("APP_COMPOSITE_APPLICATION") + .fullScopeEnabled(Boolean.FALSE) + //.scopeMapping(appRole2) + .defaultRoles("APP_COMPOSITE_ROLE") + .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .baseUrl("http://localhost:8180/auth/realms/master/app/auth") + .adminUrl("http://localhost:8180/auth/realms/master/app/logout") + .secret("password"); + realmBuilder.client(appCompositeApplication); + + UserBuilder appCompositeUser = UserBuilder.create() + .username("APP_COMPOSITE_USER") + .password("password") + .addRoles("REALM_COMPOSITE_1"); + realmBuilder.user(appCompositeUser); + + testRealms.add(realmBuilder.build()); + } + + @Before + public void addScopeMappings() { + addRealmLevelScopeMapping("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1"); + addRealmLevelScopeMapping("REALM_ROLE_1_APPLICATION", "REALM_ROLE_1"); + addClientLevelScopeMapping("APP_COMPOSITE_APPLICATION", "APP_ROLE_APPLICATION", "APP_ROLE_2"); + } + + private void addRealmLevelScopeMapping(String clientId, String roleName) { + ClientResource client = ApiUtil.findClientByClientId(testRealm(), clientId); + RoleRepresentation role = testRealm().roles().get(roleName).toRepresentation(); + client.getScopeMappings().realmLevel().add(Collections.singletonList(role)); + } + + private void addClientLevelScopeMapping(String targetClientId, String sourceClientId, String roleName) { + ClientResource targetClient = ApiUtil.findClientByClientId(testRealm(), targetClientId); + ClientResource sourceClient = ApiUtil.findClientByClientId(testRealm(), sourceClientId); + RoleRepresentation role = sourceClient.roles().get(roleName).toRepresentation(); + targetClient.getScopeMappings().clientLevel(sourceClient.toRepresentation().getId()).add(Collections.singletonList(role)); + } + + @Before + public void createRealmAppCompositeRole() { + ClientResource appRoleApplication = ApiUtil.findClientByClientId(testRealm(), "APP_ROLE_APPLICATION"); + RoleResource appRole1 = appRoleApplication.roles().get("APP_ROLE_1"); + + RoleBuilder realmAppCompositeRole = RoleBuilder.create() + .name("REALM_APP_COMPOSITE_ROLE"); + + testRealm().roles().create(realmAppCompositeRole.build()); + String id = testRealm().roles().get("REALM_APP_COMPOSITE_ROLE").toRepresentation().getId(); + testRealm().rolesById().addComposites(id, Collections.singletonList(appRole1.toRepresentation())); + } + + @Before + public void addRealmAppCompositeToUsers() { + UserResource userRsc = ApiUtil.findUserByUsernameId(testRealm(), "REALM_APP_COMPOSITE_USER"); + RoleRepresentation realmAppCompositeRole = testRealm().roles().get("REALM_APP_COMPOSITE_ROLE").toRepresentation(); + userRsc.roles().realmLevel().add(Collections.singletonList(realmAppCompositeRole)); + } + + @Before + public void addRealmAppCompositeToUser2() { + UserResource userRsc = ApiUtil.findUserByUsernameId(testRealm(), "APP_COMPOSITE_USER"); + RoleRepresentation realmAppCompositeRole = testRealm().roles().get("REALM_APP_COMPOSITE_ROLE").toRepresentation(); + userRsc.roles().realmLevel().add(Collections.singletonList(realmAppCompositeRole)); + } + + @Before + public void addCompositeRolesToAppCompositeRoleInAppCompositeApplication() { + ClientResource appCompositeApplication = ApiUtil.findClientByClientId(testRealm(), "APP_COMPOSITE_APPLICATION"); + RoleResource appCompositeRole = appCompositeApplication.roles().get("APP_COMPOSITE_ROLE"); + + List toAdd = new LinkedList<>(); + toAdd.add(testRealm().roles().get("REALM_ROLE_1").toRepresentation()); + toAdd.add(testRealm().roles().get("REALM_ROLE_2").toRepresentation()); + toAdd.add(testRealm().roles().get("REALM_ROLE_3").toRepresentation()); + + ClientResource appRolesApplication = ApiUtil.findClientByClientId(testRealm(), "APP_ROLE_APPLICATION"); + RoleRepresentation appRole1 = appRolesApplication.roles().get("APP_ROLE_1").toRepresentation(); + toAdd.add(appRole1); + + appCompositeRole.addComposites(toAdd); + } + + @Page + protected LoginPage loginPage; + + @Test + public void testAppCompositeUser() throws Exception { + oauth.realm("test"); + oauth.clientId("APP_COMPOSITE_APPLICATION"); + oauth.doLogin("APP_COMPOSITE_USER", "password"); + + String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + AccessToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals(getUserId("APP_COMPOSITE_USER"), token.getSubject()); + + Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size()); + Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); + Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); + + AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); + Assert.assertEquals(200, refreshResponse.getStatusCode()); + } + + + @Test + public void testRealmAppCompositeUser() throws Exception { + oauth.realm("test"); + oauth.clientId("APP_ROLE_APPLICATION"); + oauth.doLogin("REALM_APP_COMPOSITE_USER", "password"); + + String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + AccessToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals(getUserId("REALM_APP_COMPOSITE_USER"), token.getSubject()); + + Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size()); + Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); + + AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); + Assert.assertEquals(200, refreshResponse.getStatusCode()); + } + + @Test + public void testRealmOnlyWithUserCompositeAppComposite() throws Exception { + oauth.realm("test"); + oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); + oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); + + String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + AccessToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals(getUserId("REALM_COMPOSITE_1_USER"), token.getSubject()); + + Assert.assertEquals(2, token.getRealmAccess().getRoles().size()); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1")); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); + + AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); + Assert.assertEquals(200, refreshResponse.getStatusCode()); + } + + @Test + public void testRealmOnlyWithUserCompositeAppRole() throws Exception { + oauth.realm("test"); + oauth.clientId("REALM_ROLE_1_APPLICATION"); + oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); + + String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + AccessToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals(getUserId("REALM_COMPOSITE_1_USER"), token.getSubject()); + + Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); + + AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); + Assert.assertEquals(200, refreshResponse.getStatusCode()); + } + + @Test + public void testRealmOnlyWithUserRoleAppComposite() throws Exception { + oauth.realm("test"); + oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); + oauth.doLogin("REALM_ROLE_1_USER", "password"); + + String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + AccessToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals(getUserId("REALM_ROLE_1_USER"), token.getSubject()); + + Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); + + AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); + Assert.assertEquals(200, refreshResponse.getStatusCode()); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java index b98877de2d..febf487949 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java @@ -59,6 +59,11 @@ public class ClientBuilder { return this; } + public ClientBuilder defaultRoles(String... roles) { + rep.setDefaultRoles(roles); + return this; + } + public ClientBuilder serviceAccount() { rep.setServiceAccountsEnabled(true); return this; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java index 445cc14fed..b01ba5ea75 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java @@ -21,15 +21,11 @@ import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.events.EventsListenerProviderFactory; -import sun.security.krb5.Realm; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; - -import static org.keycloak.testsuite.util.MailServerConfiguration.FROM; -import static org.keycloak.testsuite.util.MailServerConfiguration.HOST; -import static org.keycloak.testsuite.util.MailServerConfiguration.PORT; +import org.keycloak.representations.idm.RolesRepresentation; /** * @author Stian Thorgersen @@ -67,6 +63,15 @@ public class RealmBuilder { return this; } + public RealmBuilder roles(RolesBuilder roles) { + return roles(roles.build()); + } + + public RealmBuilder roles(RolesRepresentation roles) { + rep.setRoles(roles); + return this; + } + public RealmBuilder testMail() { Map config = new HashMap<>(); config.put("from", MailServerConfiguration.FROM); @@ -159,6 +164,26 @@ public class RealmBuilder { return this; } + public RealmBuilder ssoSessionMaxLifespan(int ssoSessionMaxLifespan) { + rep.setSsoSessionMaxLifespan(ssoSessionMaxLifespan); + return this; + } + + public RealmBuilder accessCodeLifespanUserAction(int accessCodeLifespanUserAction) { + rep.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction); + return this; + } + + public RealmBuilder accessCodeLifespan(int accessCodeLifespan) { + rep.setAccessCodeLifespan(accessCodeLifespan); + return this; + } + + public RealmBuilder sslRequired(String sslRequired) { + rep.setSslRequired(sslRequired); + return this; + } + public RealmBuilder ssoSessionIdleTimeout(int sessionIdleTimeout) { rep.setSsoSessionIdleTimeout(sessionIdleTimeout); return this; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RoleBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RoleBuilder.java index caaf4dfb74..84f38b92a8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RoleBuilder.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RoleBuilder.java @@ -17,7 +17,12 @@ package org.keycloak.testsuite.util; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.RoleRepresentation.Composites; /** * @author Stian Thorgersen @@ -53,6 +58,51 @@ public class RoleBuilder { return this; } + public RoleBuilder composite() { + rep.setComposite(true); + return this; + } + + private void checkCompositesNull() { + if (rep.getComposites() == null) { + rep.setComposites(new Composites()); + } + } + + public RoleBuilder realmComposite(RoleRepresentation role) { + return realmComposite(role.getName()); + } + + public RoleBuilder realmComposite(String compositeRole) { + checkCompositesNull(); + + if (rep.getComposites().getRealm() == null) { + rep.getComposites().setRealm(new HashSet()); + } + + rep.getComposites().getRealm().add(compositeRole); + return this; + } + + public RoleBuilder clientComposite(String client, RoleRepresentation compositeRole) { + return clientComposite(client, compositeRole.getName()); + } + + public RoleBuilder clientComposite(String client, String compositeRole) { + checkCompositesNull(); + + if (rep.getComposites().getClient() == null) { + rep.getComposites().setClient(new HashMap>()); + } + + if (rep.getComposites().getClient().get(client) == null) { + rep.getComposites().getClient().put(client, new LinkedList()); + } + + rep.getComposites().getClient().get(client).add(compositeRole); + return this; + } + public RoleRepresentation build() { return rep; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RolesBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RolesBuilder.java new file mode 100644 index 0000000000..75bd6a0066 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RolesBuilder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package org.keycloak.testsuite.util; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.RolesRepresentation; + +/** + * + * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. + */ +public class RolesBuilder { + + private RolesRepresentation rep; + + public static RolesBuilder create() { + return new RolesBuilder(); + } + + private RolesBuilder() { + rep = new RolesRepresentation(); + } + + public RolesBuilder realmRole(RoleRepresentation role) { + if (rep.getRealm() == null) { + rep.setRealm(new LinkedList()); + } + + rep.getRealm().add(role); + return this; + } + + public RolesBuilder clientRole(String client, RoleRepresentation role) { + if (rep.getClient() == null) { + rep.setClient(new HashMap>()); + } + + List clientList = rep.getClient().get(client); + if (clientList == null) { + rep.getClient().put(client, new LinkedList()); + } + + rep.getClient().get(client).add(role); + return this; + } + + public RolesRepresentation build() { + return rep; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json new file mode 100644 index 0000000000..e7819e6d81 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json @@ -0,0 +1,203 @@ +{ + "id": "test", + "realm": "test", + "enabled": true, + "accessTokenLifespan": 600, + "accessCodeLifespan": 600, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "registrationAllowed": true, + "resetPasswordAllowed": true, + "requiredCredentials": [ "password" ], + "smtpServer": { + "from": "auto@keycloak.org", + "host": "localhost", + "port":"3025" + }, + "users" : [ + { + "username" : "REALM_COMPOSITE_1_USER", + "enabled": true, + "email" : "test-user1@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_COMPOSITE_1" ] + }, + { + "username" : "REALM_ROLE_1_USER", + "enabled": true, + "email" : "test-user2@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["REALM_ROLE_1"] + }, + { + "username" : "REALM_APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user3@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["REALM_APP_COMPOSITE_ROLE"] + }, + { + "username" : "REALM_APP_ROLE_USER", + "enabled": true, + "email" : "test-user4@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "applicationRoles": { + "APP_ROLE_APPLICATION": [ "APP_ROLE_2" ] + } + }, + { + "username" : "APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user5@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"] + } + ], + "oauthClients" : [ + { + "name" : "third-party", + "enabled": true, + "secret": "password" + } + ], + "scopeMappings": [ + { + "client": "REALM_COMPOSITE_1_APPLICATION", + "roles": ["REALM_COMPOSITE_1"] + }, + { + "client": "REALM_ROLE_1_APPLICATION", + "roles": ["REALM_ROLE_1"] + } + ], + "applications": [ + { + "name": "REALM_COMPOSITE_1_APPLICATION", + "enabled": true, + "fullScopeAllowed": false, + "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", + "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/*" + ], + "secret": "password" + }, + { + "name": "REALM_ROLE_1_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", + "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/*" + ], + "secret": "password" + }, + { + "name": "APP_ROLE_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", + "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/*" + ], + "secret": "password" + }, + { + "name": "APP_COMPOSITE_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", + "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/*" + ], + "secret": "password" + } + ], + "roles" : { + "realm" : [ + { + "name": "REALM_ROLE_1" + }, + { + "name": "REALM_ROLE_2" + }, + { + "name": "REALM_ROLE_3" + }, + { + "name": "REALM_COMPOSITE_1", + "composites": { + "realm": ["REALM_ROLE_1"] + } + }, + { + "name": "REALM_APP_COMPOSITE_ROLE", + "composites": { + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ] + } + } + } + ], + "application" : { + "APP_ROLE_APPLICATION" : [ + { + "name": "APP_ROLE_1" + }, + { + "name": "APP_ROLE_2" + } + ], + "APP_COMPOSITE_APPLICATION" : [ + { + "name": "APP_COMPOSITE_ROLE", + "composites": { + "realm" : [ + "REALM_ROLE_1", + "REALM_ROLE_2", + "REALM_ROLE_3" + ], + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ] + } + } + }, + { + "name": "APP_ROLE_2" + } + ] + } + + }, + + "applicationScopeMappings": { + "APP_ROLE_APPLICATION": [ + { + "client": "APP_COMPOSITE_APPLICATION", + "roles": ["APP_ROLE_2"] + } + ] + } +} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java deleted file mode 100755 index 6972a1d674..0000000000 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.testsuite.composites; - -import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.keycloak.OAuth2Constants; -import org.keycloak.common.enums.SslRequired; -import org.keycloak.models.ClientModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.representations.AccessToken; -import org.keycloak.services.managers.RealmManager; -import org.keycloak.testsuite.ApplicationServlet; -import org.keycloak.testsuite.OAuthClient; -import org.keycloak.testsuite.OAuthClient.AccessTokenResponse; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.rule.AbstractKeycloakRule; -import org.keycloak.testsuite.rule.WebResource; -import org.keycloak.testsuite.rule.WebRule; -import org.openqa.selenium.WebDriver; - -import java.security.PublicKey; - -/** - * @author Stian Thorgersen - */ -public class CompositeRoleTest { - - public static PublicKey realmPublicKey; - @ClassRule - public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){ - @Override - protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) { - RealmModel realm = manager.createRealm("test"); - KeycloakModelUtils.generateRealmKeys(realm); - realmPublicKey = realm.getPublicKey(); - realm.setSsoSessionIdleTimeout(3000); - realm.setAccessTokenLifespan(10000); - realm.setSsoSessionMaxLifespan(10000); - realm.setAccessCodeLifespanUserAction(1000); - realm.setAccessCodeLifespan(1000); - realm.setSslRequired(SslRequired.EXTERNAL); - realm.setEnabled(true); - realm.addRequiredCredential(UserCredentialModel.PASSWORD); - final RoleModel realmRole1 = realm.addRole("REALM_ROLE_1"); - final RoleModel realmRole2 = realm.addRole("REALM_ROLE_2"); - final RoleModel realmRole3 = realm.addRole("REALM_ROLE_3"); - final RoleModel realmComposite1 = realm.addRole("REALM_COMPOSITE_1"); - realmComposite1.addCompositeRole(realmRole1); - - final UserModel realmComposite1User = session.users().addUser(realm, "REALM_COMPOSITE_1_USER"); - realmComposite1User.setEnabled(true); - realmComposite1User.updateCredential(UserCredentialModel.password("password")); - realmComposite1User.grantRole(realmComposite1); - - final UserModel realmRole1User = session.users().addUser(realm, "REALM_ROLE_1_USER"); - realmRole1User.setEnabled(true); - realmRole1User.updateCredential(UserCredentialModel.password("password")); - realmRole1User.grantRole(realmRole1); - - final ClientModel realmComposite1Application = KeycloakModelUtils.createClient(realm, "REALM_COMPOSITE_1_APPLICATION"); - realmComposite1Application.setFullScopeAllowed(false); - realmComposite1Application.setEnabled(true); - realmComposite1Application.addScopeMapping(realmComposite1); - realmComposite1Application.addRedirectUri("http://localhost:8081/app/*"); - realmComposite1Application.setBaseUrl("http://localhost:8081/app"); - realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout"); - realmComposite1Application.setSecret("password"); - - final ClientModel realmRole1Application = KeycloakModelUtils.createClient(realm, "REALM_ROLE_1_APPLICATION"); - realmRole1Application.setFullScopeAllowed(false); - realmRole1Application.setEnabled(true); - realmRole1Application.addScopeMapping(realmRole1); - realmRole1Application.addRedirectUri("http://localhost:8081/app/*"); - realmRole1Application.setBaseUrl("http://localhost:8081/app"); - realmRole1Application.setManagementUrl("http://localhost:8081/app/logout"); - realmRole1Application.setSecret("password"); - - - final ClientModel appRoleApplication = KeycloakModelUtils.createClient(realm, "APP_ROLE_APPLICATION"); - appRoleApplication.setFullScopeAllowed(false); - appRoleApplication.setEnabled(true); - appRoleApplication.addRedirectUri("http://localhost:8081/app/*"); - appRoleApplication.setBaseUrl("http://localhost:8081/app"); - appRoleApplication.setManagementUrl("http://localhost:8081/app/logout"); - appRoleApplication.setSecret("password"); - final RoleModel appRole1 = appRoleApplication.addRole("APP_ROLE_1"); - final RoleModel appRole2 = appRoleApplication.addRole("APP_ROLE_2"); - - final RoleModel realmAppCompositeRole = realm.addRole("REALM_APP_COMPOSITE_ROLE"); - realmAppCompositeRole.addCompositeRole(appRole1); - - final UserModel realmAppCompositeUser = session.users().addUser(realm, "REALM_APP_COMPOSITE_USER"); - realmAppCompositeUser.setEnabled(true); - realmAppCompositeUser.updateCredential(UserCredentialModel.password("password")); - realmAppCompositeUser.grantRole(realmAppCompositeRole); - - final UserModel realmAppRoleUser = session.users().addUser(realm, "REALM_APP_ROLE_USER"); - realmAppRoleUser.setEnabled(true); - realmAppRoleUser.updateCredential(UserCredentialModel.password("password")); - realmAppRoleUser.grantRole(appRole2); - - final ClientModel appCompositeApplication = KeycloakModelUtils.createClient(realm, "APP_COMPOSITE_APPLICATION"); - appCompositeApplication.setFullScopeAllowed(false); - appCompositeApplication.setEnabled(true); - appCompositeApplication.addRedirectUri("http://localhost:8081/app/*"); - appCompositeApplication.setBaseUrl("http://localhost:8081/app"); - appCompositeApplication.setManagementUrl("http://localhost:8081/app/logout"); - appCompositeApplication.setSecret("password"); - final RoleModel appCompositeRole = appCompositeApplication.addRole("APP_COMPOSITE_ROLE"); - appCompositeApplication.addScopeMapping(appRole2); - appCompositeRole.addCompositeRole(realmRole1); - appCompositeRole.addCompositeRole(realmRole2); - appCompositeRole.addCompositeRole(realmRole3); - appCompositeRole.addCompositeRole(appRole1); - - final UserModel appCompositeUser = session.users().addUser(realm, "APP_COMPOSITE_USER"); - appCompositeUser.setEnabled(true); - appCompositeUser.updateCredential(UserCredentialModel.password("password")); - appCompositeUser.grantRole(realmAppCompositeRole); - appCompositeUser.grantRole(realmComposite1); - - deployServlet("app", "/app", ApplicationServlet.class); - - } - }; - - @Rule - public WebRule webRule = new WebRule(this); - - @WebResource - protected WebDriver driver; - - @WebResource - protected OAuthClient oauth; - - @WebResource - protected LoginPage loginPage; - - @Test - public void testAppCompositeUser() throws Exception { - oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); - oauth.clientId("APP_COMPOSITE_APPLICATION"); - oauth.doLogin("APP_COMPOSITE_USER", "password"); - - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); - AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); - - Assert.assertEquals(200, response.getStatusCode()); - - Assert.assertEquals("bearer", response.getTokenType()); - - AccessToken token = oauth.verifyToken(response.getAccessToken()); - - Assert.assertEquals(keycloakRule.getUser("test", "APP_COMPOSITE_USER").getId(), token.getSubject()); - - Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size()); - Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); - Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); - Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); - - AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); - Assert.assertEquals(200, refreshResponse.getStatusCode()); - } - - - @Test - public void testRealmAppCompositeUser() throws Exception { - oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); - oauth.clientId("APP_ROLE_APPLICATION"); - oauth.doLogin("REALM_APP_COMPOSITE_USER", "password"); - - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); - AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); - - Assert.assertEquals(200, response.getStatusCode()); - - Assert.assertEquals("bearer", response.getTokenType()); - - AccessToken token = oauth.verifyToken(response.getAccessToken()); - - Assert.assertEquals(keycloakRule.getUser("test", "REALM_APP_COMPOSITE_USER").getId(), token.getSubject()); - - Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size()); - Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); - - AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); - Assert.assertEquals(200, refreshResponse.getStatusCode()); - } - - @Test - public void testRealmOnlyWithUserCompositeAppComposite() throws Exception { - oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); - oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); - oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); - - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); - AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); - - Assert.assertEquals(200, response.getStatusCode()); - - Assert.assertEquals("bearer", response.getTokenType()); - - AccessToken token = oauth.verifyToken(response.getAccessToken()); - - Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject()); - - Assert.assertEquals(2, token.getRealmAccess().getRoles().size()); - Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1")); - Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); - - AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); - Assert.assertEquals(200, refreshResponse.getStatusCode()); - } - - @Test - public void testRealmOnlyWithUserCompositeAppRole() throws Exception { - oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); - oauth.clientId("REALM_ROLE_1_APPLICATION"); - oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); - - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); - AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); - - Assert.assertEquals(200, response.getStatusCode()); - - Assert.assertEquals("bearer", response.getTokenType()); - - AccessToken token = oauth.verifyToken(response.getAccessToken()); - - Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject()); - - Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); - Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); - - AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); - Assert.assertEquals(200, refreshResponse.getStatusCode()); - } - - @Test - public void testRealmOnlyWithUserRoleAppComposite() throws Exception { - oauth.realm("test"); - oauth.realmPublicKey(realmPublicKey); - oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); - oauth.doLogin("REALM_ROLE_1_USER", "password"); - - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); - AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); - - Assert.assertEquals(200, response.getStatusCode()); - - Assert.assertEquals("bearer", response.getTokenType()); - - AccessToken token = oauth.verifyToken(response.getAccessToken()); - - Assert.assertEquals(keycloakRule.getUser("test", "REALM_ROLE_1_USER").getId(), token.getSubject()); - - Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); - Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); - - AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password"); - Assert.assertEquals(200, refreshResponse.getStatusCode()); - } - -}