From 39dea4b07813acf6f13a14aa4f2db230ae6d899d Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Thu, 22 Jun 2017 16:51:46 -0400 Subject: [PATCH] restricting admin role mapping --- .../java/org/keycloak/models/AdminRoles.java | 11 + .../admin/permissions/RolePermissions.java | 135 +++- .../permissions/UserPermissionEvaluator.java | 2 + .../admin/permissions/UserPermissions.java | 7 +- .../admin/IllegalAdminUpgradeTest.java | 648 ++++++++++++++++++ 5 files changed, 800 insertions(+), 3 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java diff --git a/server-spi-private/src/main/java/org/keycloak/models/AdminRoles.java b/server-spi-private/src/main/java/org/keycloak/models/AdminRoles.java index cf605d16c5..c2304e8572 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/AdminRoles.java +++ b/server-spi-private/src/main/java/org/keycloak/models/AdminRoles.java @@ -17,6 +17,7 @@ package org.keycloak.models; +import java.util.HashSet; import java.util.Set; /** @@ -55,4 +56,14 @@ public class AdminRoles { public static String[] ALL_REALM_ROLES = {CREATE_CLIENT, VIEW_REALM, VIEW_USERS, VIEW_CLIENTS, VIEW_EVENTS, VIEW_IDENTITY_PROVIDERS, VIEW_AUTHORIZATION, MANAGE_REALM, MANAGE_USERS, MANAGE_CLIENTS, MANAGE_EVENTS, MANAGE_IDENTITY_PROVIDERS, MANAGE_AUTHORIZATION, QUERY_USERS, QUERY_CLIENTS, QUERY_REALMS, QUERY_GROUPS}; + public static Set ALL_ROLES = new HashSet<>(); + static { + for (String name : ALL_REALM_ROLES) { + ALL_ROLES.add(name); + } + ALL_ROLES.add(ImpersonationConstants.IMPERSONATION_ROLE); + ALL_ROLES.add(ADMIN); + ALL_ROLES.add(CREATE_REALM); + ALL_ROLES.add(CREATE_CLIENT); + } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java index e01f4eb65f..d220a3908a 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java @@ -17,6 +17,7 @@ package org.keycloak.services.resources.admin.permissions; import org.jboss.logging.Logger; +import org.keycloak.Config; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.Resource; @@ -25,6 +26,7 @@ import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.store.ResourceStore; import org.keycloak.models.AdminRoles; import org.keycloak.models.ClientModel; +import org.keycloak.models.ImpersonationConstants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; @@ -129,6 +131,131 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme return root.resourceServer(client); } + private boolean checkAdminRoles(RoleModel role) { + if (AdminRoles.ALL_ROLES.contains(role.getName())) { + if (root.admin().hasRole(role)) return true; + + ClientModel adminClient = root.getRealmManagementClient(); + if (adminClient.equals(role.getContainer())) { + // if this is realm admin role, then check to see if admin has similar permissions + // we do this so that the authz service is invoked + if (role.getName().equals(AdminRoles.MANAGE_CLIENTS)) { + if (!root.clients().canManage()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.VIEW_CLIENTS)) { + if (!root.clients().canView()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.QUERY_CLIENTS)) { + return true; + } else if (role.getName().equals(AdminRoles.QUERY_USERS)) { + return true; + } else if (role.getName().equals(AdminRoles.QUERY_GROUPS)) { + return true; + } else if (role.getName().equals(AdminRoles.MANAGE_AUTHORIZATION)) { + if (!root.realm().canManageAuthorization()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.VIEW_AUTHORIZATION)) { + if (!root.realm().canViewAuthorization()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.MANAGE_EVENTS)) { + if (!root.realm().canManageEvents()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.VIEW_EVENTS)) { + if (!root.realm().canViewEvents()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.MANAGE_USERS)) { + if (!root.users().canManage()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.VIEW_USERS)) { + if (!root.users().canView()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.MANAGE_IDENTITY_PROVIDERS)) { + if (!root.realm().canManageIdentityProviders()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.VIEW_IDENTITY_PROVIDERS)) { + if (!root.realm().canViewIdentityProviders()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.MANAGE_REALM)) { + if (!root.realm().canManageRealm()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(AdminRoles.VIEW_REALM)) { + if (!root.realm().canViewRealm()) { + return adminConflictMessage(role); + } else { + return true; + } + } else if (role.getName().equals(ImpersonationConstants.IMPERSONATION_ROLE)) { + if (!root.users().canImpersonate()) { + return adminConflictMessage(role); + } else { + return true; + } + } else { + return adminConflictMessage(role); + } + + } else { + // now we need to check to see if this is a master admin role + if (role.getContainer() instanceof RealmModel) { + RealmModel realm = (RealmModel)role.getContainer(); + // If realm role is master admin role then abort + if (realm.getName().equals(Config.getAdminRealm())) { + return adminConflictMessage(role); + } + } else { + ClientModel container = (ClientModel)role.getContainer(); + // abort if this is an role in master realm and role is an admin role of any realm + if (container.getRealm().getName().equals(Config.getAdminRealm()) + && container.getClientId().endsWith("-realm")) { + return adminConflictMessage(role); + } + } + return true; + } + + } + return true; + + } + + private boolean adminConflictMessage(RoleModel role) { + logger.debug("Trying to assign admin privileges of role: " + role.getName() + " but admin doesn't have same privilege"); + return false; + } + /** * Is admin allowed to map this role? * @@ -137,7 +264,7 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme */ @Override public boolean canMapRole(RoleModel role) { - if (root.users().canManageDefault()) return true; + if (root.users().canManageDefault()) return checkAdminRoles(role); if (!root.isAdminSameRealm()) { return false; } @@ -159,7 +286,11 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme Resource roleResource = resource(role); Scope mapRoleScope = mapRoleScope(resourceServer); - return root.evaluatePermission(roleResource, mapRoleScope, resourceServer); + if (root.evaluatePermission(roleResource, mapRoleScope, resourceServer)) { + return checkAdminRoles(role); + } else { + return true; + } } @Override diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java index 74163d9145..40b1f8f44f 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java @@ -49,6 +49,8 @@ public interface UserPermissionEvaluator { boolean canImpersonate(UserModel user); + boolean canImpersonate(); + void requireImpersonate(UserModel user); Map getAccess(UserModel user); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java index 13f8aca4a6..46a9d0161c 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java @@ -451,6 +451,12 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme @Override public boolean canImpersonate(UserModel user) { + return canImpersonate(); + + } + + @Override + public boolean canImpersonate() { if (root.hasOneAdminRole(ImpersonationConstants.IMPERSONATION_ROLE)) return true; if (!root.isAdminSameRealm()) { @@ -476,7 +482,6 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme Scope scope = root.realmScope(IMPERSONATE_SCOPE); return root.evaluatePermission(resource, scope, server); - } @Override diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java new file mode 100644 index 0000000000..7c6ced5e29 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java @@ -0,0 +1,648 @@ +/* + * 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.admin; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.authorization.model.Policy; +import org.keycloak.authorization.model.ResourceServer; +import org.keycloak.models.AdminRoles; +import org.keycloak.models.ClientModel; +import org.keycloak.models.Constants; +import org.keycloak.models.GroupModel; +import org.keycloak.models.ImpersonationConstants; +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.idm.ClientRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.idm.authorization.UserPolicyRepresentation; +import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement; +import org.keycloak.services.resources.admin.permissions.AdminPermissions; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.util.AdminClientUtil; + +import javax.ws.rs.ClientErrorException; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class IllegalAdminUpgradeTest extends AbstractKeycloakTest { + + public static final String CLIENT_NAME = "application"; + + @Override + public void addTestRealms(List testRealms) { + RealmRepresentation testRealmRep = new RealmRepresentation(); + testRealmRep.setId(TEST); + testRealmRep.setRealm(TEST); + testRealmRep.setEnabled(true); + testRealms.add(testRealmRep); + } + + protected boolean isImportAfterEachMethod() { + return true; + } + + + public static void setupUsers(KeycloakSession session) { + RealmModel realm = session.realms().getRealmByName(TEST); + RealmModel master = session.realms().getRealmByName("master"); + ClientModel realmAdminClient = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID); + ClientModel realmMasterAdminClient = realm.getMasterAdminClient(); + RoleModel realmManageUsers = realmAdminClient.getRole(AdminRoles.MANAGE_USERS); + RoleModel masterManageUsers = realmMasterAdminClient.getRole(AdminRoles.MANAGE_USERS); + RoleModel masterMasterManageUSers = master.getMasterAdminClient().getRole(AdminRoles.MANAGE_USERS); + + UserModel realmUser = session.users().addUser(realm, "userAdmin"); + realmUser.grantRole(realmManageUsers); + realmUser.setEnabled(true); + session.userCredentialManager().updateCredential(realm, realmUser, UserCredentialModel.password("password")); + + UserModel masterUser = session.users().addUser(master, "userAdmin"); + masterUser.grantRole(masterManageUsers); + masterUser.setEnabled(true); + session.userCredentialManager().updateCredential(master, masterUser, UserCredentialModel.password("password")); + + UserModel masterAdmin = session.users().addUser(master, "masterAdmin"); + masterAdmin.grantRole(masterMasterManageUSers); + masterAdmin.setEnabled(true); + session.userCredentialManager().updateCredential(master, masterAdmin, UserCredentialModel.password("password")); + + UserModel user = session.users().addUser(master, "user"); + user.grantRole(masterManageUsers); + user.setEnabled(true); + session.userCredentialManager().updateCredential(master, user, UserCredentialModel.password("password")); + + user = session.users().addUser(realm, "user"); + user.grantRole(realmManageUsers); + user.setEnabled(true); + session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password("password")); + } + + @Test + public void testRestEvaluation() throws Exception { + testingClient.server().run(IllegalAdminUpgradeTest::setupUsers); + + UserRepresentation realmUserAdmin = adminClient.realm(TEST).users().search("userAdmin").get(0); + UserRepresentation masterUserAdmin = adminClient.realm("master").users().search("userAdmin").get(0); + UserRepresentation realmUser = adminClient.realm(TEST).users().search("user").get(0); + UserRepresentation masterUser = adminClient.realm("master").users().search("user").get(0); + + ClientRepresentation realmAdminClient = adminClient.realm(TEST).clients().findByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID).get(0); + RoleRepresentation realmManageAuthorization = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.MANAGE_AUTHORIZATION).toRepresentation(); + RoleRepresentation realmViewAuthorization = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.VIEW_AUTHORIZATION).toRepresentation(); + RoleRepresentation realmManageClients = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.MANAGE_CLIENTS).toRepresentation(); + RoleRepresentation realmViewClients = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.VIEW_CLIENTS).toRepresentation(); + RoleRepresentation realmManageEvents = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.MANAGE_EVENTS).toRepresentation(); + RoleRepresentation realmViewEvents = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.VIEW_EVENTS).toRepresentation(); + RoleRepresentation realmManageIdentityProviders = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.MANAGE_IDENTITY_PROVIDERS).toRepresentation(); + RoleRepresentation realmViewIdentityProviders = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.VIEW_IDENTITY_PROVIDERS).toRepresentation(); + RoleRepresentation realmManageRealm = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.MANAGE_REALM).toRepresentation(); + RoleRepresentation realmViewRealm = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.VIEW_REALM).toRepresentation(); + RoleRepresentation realmImpersonate = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(ImpersonationConstants.IMPERSONATION_ROLE).toRepresentation(); + RoleRepresentation realmManageUsers = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.MANAGE_USERS).toRepresentation(); + RoleRepresentation realmViewUsers = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.VIEW_USERS).toRepresentation(); + RoleRepresentation realmQueryUsers = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.QUERY_USERS).toRepresentation(); + RoleRepresentation realmQueryClients = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.QUERY_CLIENTS).toRepresentation(); + RoleRepresentation realmQueryGroups = adminClient.realm(TEST).clients().get(realmAdminClient.getId()).roles().get(AdminRoles.QUERY_GROUPS).toRepresentation(); + + ClientRepresentation masterClient = adminClient.realm("master").clients().findByClientId(TEST + "-realm").get(0); + RoleRepresentation masterManageAuthorization = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.MANAGE_AUTHORIZATION).toRepresentation(); + RoleRepresentation masterViewAuthorization = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.VIEW_AUTHORIZATION).toRepresentation(); + RoleRepresentation masterManageClients = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.MANAGE_CLIENTS).toRepresentation(); + RoleRepresentation masterViewClients = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.VIEW_CLIENTS).toRepresentation(); + RoleRepresentation masterManageEvents = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.MANAGE_EVENTS).toRepresentation(); + RoleRepresentation masterViewEvents = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.VIEW_EVENTS).toRepresentation(); + RoleRepresentation masterManageIdentityProviders = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.MANAGE_IDENTITY_PROVIDERS).toRepresentation(); + RoleRepresentation masterViewIdentityProviders = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.VIEW_IDENTITY_PROVIDERS).toRepresentation(); + RoleRepresentation masterManageRealm = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.MANAGE_REALM).toRepresentation(); + RoleRepresentation masterViewRealm = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.VIEW_REALM).toRepresentation(); + RoleRepresentation masterImpersonate = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(ImpersonationConstants.IMPERSONATION_ROLE).toRepresentation(); + RoleRepresentation masterManageUsers = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.MANAGE_USERS).toRepresentation(); + RoleRepresentation masterViewUsers = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.VIEW_USERS).toRepresentation(); + RoleRepresentation masterQueryUsers = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.QUERY_USERS).toRepresentation(); + RoleRepresentation masterQueryClients = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.QUERY_CLIENTS).toRepresentation(); + RoleRepresentation masterQueryGroups = adminClient.realm("master").clients().get(masterClient.getId()).roles().get(AdminRoles.QUERY_GROUPS).toRepresentation(); + + List roles = new LinkedList<>(); + + { + ClientRepresentation client = realmAdminClient; + Keycloak realmClient = AdminClientUtil.createAdminClient(suiteContext.isAdapterCompatTesting(), + TEST, "userAdmin", "password", Constants.ADMIN_CLI_CLIENT_ID, null); + roles.clear(); + roles.add(realmManageAuthorization); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmViewAuthorization); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmManageClients); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmViewClients); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmManageEvents); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmViewEvents); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmManageIdentityProviders); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmViewIdentityProviders); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmManageRealm); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmViewRealm); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmImpersonate); + try { + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(realmManageUsers); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmViewUsers); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmQueryUsers); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmQueryGroups); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmQueryClients); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + realmClient.close(); + } + // test master manageUsers only admin can do with master realm admin roles + { + ClientRepresentation client = masterClient; + Keycloak realmClient = AdminClientUtil.createAdminClient(suiteContext.isAdapterCompatTesting(), + "master", "masterAdmin", "password", Constants.ADMIN_CLI_CLIENT_ID, null); + roles.clear(); + roles.add(masterManageAuthorization); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterViewAuthorization); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterManageClients); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterViewClients); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterManageEvents); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterViewEvents); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterManageIdentityProviders); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterViewIdentityProviders); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterManageRealm); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterViewRealm); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterImpersonate); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterManageUsers); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterViewUsers); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterQueryUsers); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterQueryGroups); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + roles.clear(); + roles.add(masterQueryClients); + try { + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + Assert.fail("should fail with forbidden exception"); + } catch (ClientErrorException e) { + Assert.assertEquals(e.getResponse().getStatus(), 403); + + } + + realmClient.close(); + } + // test master admin can add all admin roles in realm + { + ClientRepresentation client = realmAdminClient; + Keycloak realmClient = AdminClientUtil.createAdminClient(); + roles.clear(); + roles.add(realmManageAuthorization); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmViewAuthorization); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmManageClients); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmViewClients); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmManageEvents); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmViewEvents); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmManageIdentityProviders); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmViewIdentityProviders); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmManageRealm); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmViewRealm); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmImpersonate); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmManageUsers); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + + roles.clear(); + roles.add(realmViewUsers); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + + roles.clear(); + roles.add(realmQueryUsers); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + + roles.clear(); + roles.add(realmQueryGroups); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(realmQueryClients); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm(TEST).users().get(realmUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + realmClient.close(); + } + // test that "admin" in master realm can assign all roles of master realm realm client admin roles + { + ClientRepresentation client = masterClient; + Keycloak realmClient = AdminClientUtil.createAdminClient(); + roles.clear(); + roles.add(masterManageAuthorization); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterViewAuthorization); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterManageClients); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterViewClients); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterManageEvents); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterViewEvents); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterManageIdentityProviders); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterViewIdentityProviders); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterManageRealm); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterViewRealm); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterImpersonate); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterManageUsers); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + + roles.clear(); + roles.add(masterViewUsers); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + + roles.clear(); + roles.add(masterQueryUsers); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + + roles.clear(); + roles.add(masterQueryGroups); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + roles.clear(); + roles.add(masterQueryClients); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).add(roles); + realmClient.realm("master").users().get(masterUser.getId()).roles().clientLevel(client.getId()).remove(roles); + + realmClient.close(); + } + } + + + + +}