keycloak-aplcache
Changes
services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationAuth.java 85(+58 -27)
services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java 2(+1 -1)
services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java 18(+4 -14)
services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java 2(+2 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java 4(+4 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java 44(+23 -21)
services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java 4(+4 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java 4(+4 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java 117(+93 -24)
services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java 68(+64 -4)
services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java 4(+3 -1)
services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java 5(+3 -2)
services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmsPermissionEvaluator.java 33(+33 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java 58(+34 -24)
services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java 11(+10 -1)
services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java 6(+6 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java 193(+180 -13)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java 44(+43 -1)
Details
diff --git a/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationAuth.java b/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationAuth.java
index 8382155..fa2f9a2 100644
--- a/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationAuth.java
+++ b/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationAuth.java
@@ -31,12 +31,15 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
import org.keycloak.protocol.oidc.utils.AuthorizeClientUtil;
import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.clientregistration.policy.RegistrationAuth;
import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyException;
import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyManager;
+import org.keycloak.services.managers.RealmManager;
import org.keycloak.util.TokenUtil;
import javax.ws.rs.core.HttpHeaders;
@@ -231,42 +234,70 @@ public class ClientRegistrationAuth {
return initialAccessModel;
}
- private boolean hasRole(String... role) {
+ private boolean hasRole(String... roles) {
try {
- Map<String, Object> otherClaims = jwt.getOtherClaims();
- if (otherClaims != null) {
- Map<String, Map<String, List<String>>> resourceAccess = (Map<String, Map<String, List<String>>>) jwt.getOtherClaims().get("resource_access");
- if (resourceAccess == null) {
- return false;
- }
+ if (jwt.getIssuedFor().equals(Constants.ADMIN_CLI_CLIENT_ID)
+ || jwt.getIssuedFor().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
+ return hasRoleInModel(roles);
- List<String> roles = null;
+ } else {
+ return hasRoleInToken(roles);
+ }
+ } catch (Throwable t) {
+ return false;
+ }
+ }
- Map<String, List<String>> map;
- if (realm.getName().equals(Config.getAdminRealm())) {
- map = resourceAccess.get(realm.getMasterAdminClient().getClientId());
- } else {
- map = resourceAccess.get(Constants.REALM_MANAGEMENT_CLIENT_ID);
- }
+ private boolean hasRoleInModel(String[] roles) {
+ ClientModel roleNamespace;
+ UserModel user = session.users().getUserById(jwt.getSubject(), realm);
+ if (user == null) {
+ return false;
+ }
+ if (realm.getName().equals(Config.getAdminRealm())) {
+ roleNamespace = realm.getMasterAdminClient();
+ } else {
+ roleNamespace = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
+ }
+ for (String role : roles) {
+ RoleModel roleModel = roleNamespace.getRole(role);
+ if (user.hasRole(roleModel)) return true;
+ }
+ return false;
+ }
- if (map != null) {
- roles = map.get("roles");
- }
+ private boolean hasRoleInToken(String[] role) {
+ Map<String, Object> otherClaims = jwt.getOtherClaims();
+ if (otherClaims != null) {
+ Map<String, Map<String, List<String>>> resourceAccess = (Map<String, Map<String, List<String>>>) jwt.getOtherClaims().get("resource_access");
+ if (resourceAccess == null) {
+ return false;
+ }
- if (roles == null) {
- return false;
- }
+ List<String> roles = null;
+
+ Map<String, List<String>> map;
+ if (realm.getName().equals(Config.getAdminRealm())) {
+ map = resourceAccess.get(realm.getMasterAdminClient().getClientId());
+ } else {
+ map = resourceAccess.get(Constants.REALM_MANAGEMENT_CLIENT_ID);
+ }
- for (String r : role) {
- if (roles.contains(r)) {
- return true;
- }
+ if (map != null) {
+ roles = map.get("roles");
+ }
+
+ if (roles == null) {
+ return false;
+ }
+
+ for (String r : role) {
+ if (roles.contains(r)) {
+ return true;
}
}
- return false;
- } catch (Throwable t) {
- return false;
}
+ return false;
}
private boolean authenticateClient(ClientModel client) {
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 21df21f..95dc02a 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -159,7 +159,6 @@ public class RealmManager {
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationClientId);
adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
}
- adminConsole.addScopeMapping(adminRole);
}
protected void setupAdminConsoleLocaleMapper(RealmModel realm) {
@@ -194,7 +193,6 @@ public class RealmManager {
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationClientId);
adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
}
- adminCli.addScopeMapping(adminRole);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
index ba7eccc..88650c1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
@@ -834,7 +834,7 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RequiredActionProviderRepresentation> getRequiredActions() {
- auth.realm().requireViewRealm();
+ auth.requireAnyAdminRole();
List<RequiredActionProviderRepresentation> list = new LinkedList<>();
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
index c619669..ae7d519 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
@@ -140,7 +140,7 @@ public class ClientRoleMappingsResource {
Set<RoleModel> available = client.getRoles();
available = available.stream().filter(r ->
- canMapRole(r)
+ auth.roles().canMapRole(r)
).collect(Collectors.toSet());
return getAvailableRoles(user, available);
}
@@ -174,23 +174,13 @@ public class ClientRoleMappingsResource {
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException("Role not found");
}
- checkMapRolePermission(roleModel);
+ auth.roles().requireMapRole(roleModel);
user.grantRole(roleModel);
}
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
}
- private void checkMapRolePermission(RoleModel roleModel) {
- if (!canMapRole(roleModel)) {
- throw new ForbiddenException();
- }
- }
-
- private boolean canMapRole(RoleModel roleModel) {
- return auth.roles().canMapRole(roleModel);
- }
-
/**
* Delete client-level roles from user role mapping
*
@@ -210,7 +200,7 @@ public class ClientRoleMappingsResource {
ClientModel client = (ClientModel) roleModel.getContainer();
if (!client.getId().equals(this.client.getId())) continue;
}
- checkMapRolePermission(roleModel);
+ auth.roles().requireMapRole(roleModel);
user.deleteRoleMapping(roleModel);
roles.add(ModelToRepresentation.toRepresentation(roleModel));
}
@@ -222,7 +212,7 @@ public class ClientRoleMappingsResource {
throw new NotFoundException("Role not found");
}
- checkMapRolePermission(roleModel);
+ auth.roles().requireMapRole(roleModel);
try {
user.deleteRoleMapping(roleModel);
} catch (ModelException me) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java
index 839aa41..1e8105d 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java
@@ -76,13 +76,20 @@ public class ClientTemplatesResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<ClientTemplateRepresentation> getClientTemplates() {
- auth.clients().requireView();
+ auth.clients().requireListTemplates();
List<ClientTemplateRepresentation> rep = new ArrayList<>();
List<ClientTemplateModel> clientModels = realm.getClientTemplates();
+ boolean viewable = auth.clients().canViewTemplates();
for (ClientTemplateModel clientModel : clientModels) {
- rep.add(ModelToRepresentation.toRepresentation(clientModel));
+ if (viewable) rep.add(ModelToRepresentation.toRepresentation(clientModel));
+ else {
+ ClientTemplateRepresentation tempRep = new ClientTemplateRepresentation();
+ tempRep.setName(clientModel.getName());
+ tempRep.setId(clientModel.getId());
+ tempRep.setProtocol(clientModel.getProtocol());
+ }
}
return rep;
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java
index 56be4cf..19abaf4 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java
@@ -25,6 +25,8 @@ import org.keycloak.services.resources.admin.AdminAuth;
public interface AdminPermissionEvaluator {
RealmPermissionEvaluator realm();
+ void requireAnyAdminRole();
+
AdminAuth adminAuth();
RolePermissionEvaluator roles();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java
index 61a8bff..ef1c1ae 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java
@@ -35,6 +35,10 @@ public class AdminPermissions {
return new MgmtPermissions(session, realm, adminsRealm, admin);
}
+ public static RealmsPermissionEvaluator realms(KeycloakSession session, AdminAuth auth) {
+ return new MgmtPermissions(session, auth);
+ }
+
public static AdminPermissionManagement management(KeycloakSession session, RealmModel realm) {
return new MgmtPermissions(session, realm);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java
index 39f7b4d..1f41e70 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java
@@ -115,16 +115,12 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
String managePermissionName = getManagePermissionName(client);
Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
if (managePermission == null) {
- RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_CLIENTS);
- Policy manageClientsPolicy = root.roles().rolePolicy(server, role);
- Helper.addScopePermission(authz, server, managePermissionName, resource, manageScope, manageClientsPolicy);
+ Helper.addEmptyScopePermission(authz, server, managePermissionName, resource, manageScope);
}
String viewPermissionName = getViewPermissionName(client);
Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
if (viewPermission == null) {
- RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.VIEW_CLIENTS);
- Policy viewClientsPolicy = root.roles().rolePolicy(server, role);
- Helper.addScopePermission(authz, server, viewPermissionName, resource, viewScope, viewClientsPolicy);
+ Helper.addEmptyScopePermission(authz, server, viewPermissionName, resource, viewScope);
}
String mapRolePermissionName = getMapRolesPermissionName(client);
Policy mapRolePermission = authz.getStoreFactory().getPolicyStore().findByName(mapRolePermissionName, server.getId());
@@ -216,7 +212,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
throw new ForbiddenException();
}
}
- public boolean canManageClientDefault() {
+ public boolean canManageClientsDefault() {
return root.hasOneAdminRole(AdminRoles.MANAGE_CLIENTS);
}
public boolean canViewClientDefault() {
@@ -225,7 +221,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
@Override
public boolean canManage() {
- return canManageClientDefault();
+ return canManageClientsDefault();
}
@Override
@@ -236,7 +232,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
}
@Override
public boolean canView() {
- return canManageClientDefault() || canViewClientDefault();
+ return canManageClientsDefault() || canViewClientDefault();
}
@Override
@@ -269,25 +265,26 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
@Override
public boolean canManage(ClientModel client) {
+ if (canManageClientsDefault()) return true;
if (!root.isAdminSameRealm()) {
- return canManage();
+ return false;
}
ResourceServer server = resourceServer(client);
- if (server == null) return canManage();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());
- if (resource == null) return canManage();
+ if (resource == null) return false;
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getManagePermissionName(client), server.getId());
if (policy == null) {
- return canManage();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then just do default behavior
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return canManage();
+ return false;
}
Scope scope = manageScope(server);
@@ -303,25 +300,30 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
@Override
public boolean canView(ClientModel client) {
+ return hasView(client) || canManage(client);
+ }
+
+ private boolean hasView(ClientModel client) {
+ if (canView()) return true;
if (!root.isAdminSameRealm()) {
- return canView();
+ return false;
}
ResourceServer server = resourceServer(client);
- if (server == null) return canView();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());
- if (resource == null) return canView();
+ if (resource == null) return false;
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getViewPermissionName(client), server.getId());
if (policy == null) {
- return canView();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then just do default behavior
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return canView();
+ return false;
}
Scope scope = viewScope(server);
@@ -344,7 +346,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
@Override
public boolean canManageTemplates() {
- return canManageClientDefault();
+ return canManageClientsDefault();
}
@Override
@@ -362,7 +364,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
@Override
public boolean canManage(ClientTemplateModel template) {
- return canManageClientDefault();
+ return canManageClientsDefault();
}
@Override
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java
index 450b074..d3a5213 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java
@@ -53,5 +53,9 @@ public interface GroupPermissionEvaluator {
void requireManageMembers(GroupModel group);
+ boolean canManageMembership(GroupModel group);
+
+ void requireManageMembership(GroupModel group);
+
Map<String, Boolean> getAccess(GroupModel group);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java
index 5fcfbbb..2ec602c 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java
@@ -33,10 +33,14 @@ public interface GroupPermissionManagement {
Policy viewMembersPermission(GroupModel group);
Policy manageMembersPermission(GroupModel group);
+
+ Policy manageMembershipPermission(GroupModel group);
+
Policy viewPermission(GroupModel group);
Policy managePermission(GroupModel group);
Resource resource(GroupModel group);
Map<String, String> getPermissions(GroupModel group);
+
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java
index 2223802..0475b46 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java
@@ -41,6 +41,7 @@ import java.util.Set;
class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManagement {
private static final Logger logger = Logger.getLogger(GroupPermissions.class);
public static final String MAP_ROLE_SCOPE = "map-role";
+ public static final String MANAGE_MEMBERSHIP_SCOPE = "manage.membership";
public static final String MANAGE_MEMBERS_SCOPE = "manage.members";
public static final String VIEW_MEMBERS_SCOPE = "view.members";
protected final KeycloakSession session;
@@ -68,6 +69,10 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
return "manage.members.permission.group." + group.getId();
}
+ public static String getManageMembershipPermissionGroup(GroupModel group) {
+ return "manage.membership.permission.group." + group.getId();
+ }
+
public static String getGroupSuffix(GroupModel group) {
return ModelToRepresentation.buildGroupPath(group).replace('/', '.');
}
@@ -88,6 +93,7 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
Scope viewScope = root.realmViewScope();
Scope manageMembersScope = root.initializeRealmScope(MANAGE_MEMBERS_SCOPE);
Scope viewMembersScope = root.initializeRealmScope(VIEW_MEMBERS_SCOPE);
+ Scope manageMembershipScope = root.initializeRealmScope(MANAGE_MEMBERSHIP_SCOPE);
String groupResourceName = getGroupResourceName(group);
Resource groupResource = authz.getStoreFactory().getResourceStore().findByName(groupResourceName, server.getId());
@@ -96,19 +102,19 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
Set<Scope> scopeset = new HashSet<>();
scopeset.add(manageScope);
scopeset.add(viewScope);
+ scopeset.add(manageMembershipScope);
+ scopeset.add(manageMembersScope);
groupResource.updateScopes(scopeset);
}
String managePermissionName = getManagePermissionGroup(group);
Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
if (managePermission == null) {
- Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
- Helper.addScopePermission(authz, server, managePermissionName, groupResource, manageScope, manageUsersPolicy);
+ Helper.addEmptyScopePermission(authz, server, managePermissionName, groupResource, manageScope);
}
String viewPermissionName = getViewPermissionGroup(group);
Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
if (viewPermission == null) {
- Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
- Helper.addScopePermission(authz, server, viewPermissionName, groupResource, viewScope, viewUsersPolicy);
+ Helper.addEmptyScopePermission(authz, server, viewPermissionName, groupResource, viewScope);
}
String manageMembersPermissionName = getManageMembersPermissionGroup(group);
Policy manageMembersPermission = authz.getStoreFactory().getPolicyStore().findByName(manageMembersPermissionName, server.getId());
@@ -120,6 +126,12 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
if (viewMembersPermission == null) {
Helper.addEmptyScopePermission(authz, server, viewMembersPermissionName, groupResource, viewMembersScope);
}
+ String manageMembershipPermissionName = getManageMembershipPermissionGroup(group);
+ Policy manageMembershipPermission = authz.getStoreFactory().getPolicyStore().findByName(manageMembershipPermissionName, server.getId());
+ if (manageMembershipPermission == null) {
+ Helper.addEmptyScopePermission(authz, server, manageMembershipPermissionName, groupResource, manageMembershipScope);
+ }
+
}
@Override
@@ -200,6 +212,14 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
}
@Override
+ public Policy manageMembershipPermission(GroupModel group) {
+ ResourceServer server = root.realmResourceServer();
+ if (server == null) return null;
+ String manageMembershipPermissionName = getManageMembershipPermissionGroup(group);
+ return authz.getStoreFactory().getPolicyStore().findByName(manageMembershipPermissionName, server.getId());
+ }
+
+ @Override
public Policy viewPermission(GroupModel group) {
ResourceServer server = root.realmResourceServer();
if (server == null) return null;
@@ -231,6 +251,7 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
scopes.put(AdminPermissionManagement.MANAGE_SCOPE, managePermission(group).getId());
scopes.put(MANAGE_MEMBERS_SCOPE, manageMembersPermission(group).getId());
scopes.put(VIEW_MEMBERS_SCOPE, viewMembersPermission(group).getId());
+ scopes.put(MANAGE_MEMBERSHIP_SCOPE, manageMembershipPermission(group).getId());
return scopes;
}
@@ -239,25 +260,26 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
@Override
public boolean canManage(GroupModel group) {
+ if (canManage()) return true;
if (!root.isAdminSameRealm()) {
- return canManage();
+ return false;
}
ResourceServer server = root.realmResourceServer();
- if (server == null) return canManage();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
- if (resource == null) return canManage();
+ if (resource == null) return false;
Policy policy = managePermission(group);
if (policy == null) {
- return canManage();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then just do default behavior
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return canManage();
+ return false;
}
Scope scope = root.realmManageScope();
@@ -272,25 +294,31 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
}
@Override
public boolean canView(GroupModel group) {
+ return hasView(group) || canManage(group);
+ }
+
+ private boolean hasView(GroupModel group) {
+ if (canView()) return true;
+
if (!root.isAdminSameRealm()) {
- return canView();
+ return false;
}
ResourceServer server = root.realmResourceServer();
- if (server == null) return canView();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
- if (resource == null) return canView();
+ if (resource == null) return false;
Policy policy = viewPermission(group);
if (policy == null) {
- return canView();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then abort
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return canView();
+ return false;
}
Scope scope = root.realmViewScope();
@@ -335,25 +363,27 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
}
private boolean canViewMembersEvaluation(GroupModel group) {
+ if (root.users().canView()) return true;
+
if (!root.isAdminSameRealm()) {
- return root.users().canView();
+ return false;
}
ResourceServer server = root.realmResourceServer();
- if (server == null) return root.users().canView();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
- if (resource == null) return root.users().canView();
+ if (resource == null) return false;
Policy policy = viewMembersPermission(group);
if (policy == null) {
- return root.users().canView();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then just do default behavior
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return root.users().canView();
+ return false;
}
Scope scope = authz.getStoreFactory().getScopeStore().findByName(VIEW_MEMBERS_SCOPE, server.getId());
@@ -372,25 +402,27 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
@Override
public boolean canManageMembers(GroupModel group) {
+ if (root.users().canManage()) return true;
+
if (!root.isAdminSameRealm()) {
- return root.users().canManage();
+ return false;
}
ResourceServer server = root.realmResourceServer();
- if (server == null) return root.users().canManage();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
- if (resource == null) return root.users().canManage();
+ if (resource == null) return false;
Policy policy = manageMembersPermission(group);
if (policy == null) {
- return root.users().canManage();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then just do default behavior
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return root.users().canManage();
+ return false;
}
Scope scope = authz.getStoreFactory().getScopeStore().findByName(MANAGE_MEMBERS_SCOPE, server.getId());
@@ -405,10 +437,47 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
}
@Override
+ public boolean canManageMembership(GroupModel group) {
+ if (canManage(group)) return true;
+
+ if (!root.isAdminSameRealm()) {
+ return false;
+ }
+
+ ResourceServer server = root.realmResourceServer();
+ if (server == null) return false;
+
+ Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
+ if (resource == null) return false;
+
+ Policy policy = manageMembershipPermission(group);
+ if (policy == null) {
+ return false;
+ }
+
+ Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+ // if no policies attached to permission then just do default behavior
+ if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+ return false;
+ }
+
+ Scope scope = authz.getStoreFactory().getScopeStore().findByName(MANAGE_MEMBERSHIP_SCOPE, server.getId());
+ return root.evaluatePermission(resource, scope, server);
+ }
+
+ @Override
+ public void requireManageMembership(GroupModel group) {
+ if (!canManageMembership(group)) {
+ throw new ForbiddenException();
+ }
+ }
+
+ @Override
public Map<String, Boolean> getAccess(GroupModel group) {
Map<String, Boolean> map = new HashMap<>();
map.put("view", canView(group));
map.put("manage", canManage(group));
+ map.put("manageMembership", canManageMembership(group));
return map;
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
index a356d05..8c9e584 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
@@ -40,6 +40,7 @@ import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.services.ForbiddenException;
import org.keycloak.services.managers.RealmManager;
@@ -51,7 +52,7 @@ import java.util.List;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
-class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManagement {
+class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManagement, RealmsPermissionEvaluator {
private static final Logger logger = Logger.getLogger(MgmtPermissions.class);
protected RealmModel realm;
@@ -85,7 +86,21 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
&& !auth.getRealm().equals(new RealmManager(session).getKeycloakAdminstrationRealm())) {
throw new ForbiddenException();
}
- if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)) {
+ if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
+ || auth.getClient().getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
+ this.identity = new UserModelIdentity(auth.getRealm(), auth.getUser());
+
+ } else {
+ this.identity = new KeycloakIdentity(auth.getToken(), session);
+ }
+ }
+ MgmtPermissions(KeycloakSession session, AdminAuth auth) {
+ this.session = session;
+ this.auth = auth;
+ this.admin = auth.getUser();
+ this.adminsRealm = auth.getRealm();
+ if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
+ || auth.getClient().getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
this.identity = new UserModelIdentity(auth.getRealm(), auth.getUser());
} else {
@@ -117,17 +132,36 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
+ @Override
+ public void requireAnyAdminRole() {
+ if (!hasAnyAdminRole()) {
+ throw new ForbiddenException();
+ }
+ }
+
public boolean hasAnyAdminRole() {
return hasOneAdminRole(AdminRoles.ALL_REALM_ROLES);
}
+ public boolean hasAnyAdminRole(RealmModel realm) {
+ return hasOneAdminRole(realm, AdminRoles.ALL_REALM_ROLES);
+ }
+
public boolean hasOneAdminRole(String... adminRoles) {
String clientId;
+ RealmModel realm = this.realm;
+ return hasOneAdminRole(realm, adminRoles);
+ }
+
+ public boolean hasOneAdminRole(RealmModel realm, String... adminRoles) {
+ String clientId;
RealmManager realmManager = new RealmManager(session);
if (adminsRealm.equals(realmManager.getKeycloakAdminstrationRealm())) {
clientId = realm.getMasterAdminClient().getClientId();
+ } else if (adminsRealm.equals(realm)) {
+ clientId = realm.getClientByClientId(realmManager.getRealmAdminClientId(realm)).getClientId();
} else {
- clientId = realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())).getClientId();
+ return false;
}
for (String adminRole : adminRoles) {
if (identity.hasClientRole(clientId, adminRole)) return true;
@@ -136,7 +170,6 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
}
-
public boolean isAdminSameRealm() {
return auth == null || realm.getId().equals(auth.getRealm().getId());
}
@@ -274,6 +307,33 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
}
}
+ @Override
+ public boolean canView(RealmModel realm) {
+ return hasOneAdminRole(realm, AdminRoles.VIEW_REALM, AdminRoles.MANAGE_REALM);
+ }
+
+ @Override
+ public boolean isAdmin(RealmModel realm) {
+ return hasAnyAdminRole(realm);
+ }
+
+ @Override
+ public boolean canCreateRealm() {
+ RealmManager realmManager = new RealmManager(session);
+ if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
+ return false;
+ }
+ return identity.hasRealmRole(AdminRoles.CREATE_REALM);
+ }
+
+ @Override
+ public void requireCreateRealm() {
+ if (!canCreateRealm()) {
+ throw new ForbiddenException();
+ }
+ }
+
+
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java
index cf350a1..7020667 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java
@@ -16,12 +16,14 @@
*/
package org.keycloak.services.resources.admin.permissions;
+import org.keycloak.models.RealmModel;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface RealmPermissionEvaluator {
- boolean canListRealm();
+ boolean canListRealms();
void requireViewRealmNameList();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java
index 1d54c55..3fc752f 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java
@@ -76,17 +76,18 @@ class RealmPermissions implements RealmPermissionEvaluator {
}
@Override
- public boolean canListRealm() {
+ public boolean canListRealms() {
return root.hasAnyAdminRole();
}
@Override
public void requireViewRealmNameList() {
- if (!canListRealm()) {
+ if (!canListRealms()) {
throw new ForbiddenException();
}
}
+
@Override
public boolean canManageRealm() {
return canManageRealmDefault();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmsPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmsPermissionEvaluator.java
new file mode 100644
index 0000000..b58202f
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmsPermissionEvaluator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.services.resources.admin.permissions;
+
+import org.keycloak.models.RealmModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface RealmsPermissionEvaluator {
+ boolean canView(RealmModel realm);
+
+ boolean isAdmin(RealmModel realm);
+
+ boolean canCreateRealm();
+
+ void requireCreateRealm();
+}
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 83838de..a5fee73 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
@@ -69,10 +69,15 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
} else {
ResourceServer server = resourceServer(role);
if (server == null) return;
+ Policy policy = mapRolePermission(role);
+ if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+ policy = mapClientScopePermission(role);
+ if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+ policy = mapCompositePermission(role);
+ if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId());
if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId());
- Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), server.getId());
- if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
}
}
@@ -140,20 +145,22 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
*/
@Override
public boolean canMapRole(RoleModel role) {
+ if (root.users().canManageDefault()) return true;
if (!root.isAdminSameRealm()) {
- return root.users().canManageDefault();
+ return false;
}
+
if (role.getContainer() instanceof ClientModel) {
if (root.clients().canMapRoles((ClientModel)role.getContainer())) return true;
}
if (!isPermissionsEnabled(role)){
- return root.users().canManageDefault();
+ return false;
}
ResourceServer resourceServer = getResourceServer(role);
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), resourceServer.getId());
if (policy.getAssociatedPolicies().isEmpty()) {
- return root.users().canManageDefault(); // if no policies applied, just do default
+ return false;
}
Resource roleResource = resource(role);
@@ -216,20 +223,22 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
@Override
public boolean canMapComposite(RoleModel role) {
+ if (canManageDefault(role)) return true;
+
if (!root.isAdminSameRealm()) {
- return canManage(role);
+ return false;
}
if (role.getContainer() instanceof ClientModel) {
if (root.clients().canMapCompositeRoles((ClientModel)role.getContainer())) return true;
}
if (!isPermissionsEnabled(role)){
- return canManage(role);
+ return false;
}
ResourceServer resourceServer = getResourceServer(role);
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapCompositePermissionName(role), resourceServer.getId());
if (policy.getAssociatedPolicies().isEmpty()) {
- return canManage(role);
+ return false;
}
Resource roleResource = resource(role);
@@ -248,20 +257,21 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
@Override
public boolean canMapClientScope(RoleModel role) {
+ if (root.clients().canManageClientsDefault()) return true;
if (!root.isAdminSameRealm()) {
- return root.clients().canManage();
+ return false;
}
if (role.getContainer() instanceof ClientModel) {
if (root.clients().canMapClientScopeRoles((ClientModel)role.getContainer())) return true;
}
if (!isPermissionsEnabled(role)){
- return root.clients().canManage();
+ return false;
}
ResourceServer resourceServer = getResourceServer(role);
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapClientScopePermissionName(role), resourceServer.getId());
if (policy.getAssociatedPolicies().isEmpty()) {
- return root.clients().canManage();
+ return false;
}
Resource roleResource = resource(role);
@@ -288,6 +298,16 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
return false;
}
+ public boolean canManageDefault(RoleModel role) {
+ if (role.getContainer() instanceof RealmModel) {
+ return root.realm().canManageRealmDefault();
+ } else if (role.getContainer() instanceof ClientModel) {
+ ClientModel client = (ClientModel)role.getContainer();
+ return root.clients().canManageClientsDefault();
+ }
+ return false;
+ }
+
@Override
public void requireManage(RoleModel role) {
if (!canManage(role)) {
@@ -375,25 +395,15 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
Resource resource = authz.getStoreFactory().getResourceStore().create(getRoleResourceName(role), server, server.getClientId());
resource.setType("Role");
Scope mapRoleScope = getMapRoleScope(server);
- Policy policy = manageUsersPolicy(server);
- Policy mapRolePermission = Helper.addScopePermission(authz, server, getMapRolePermissionName(role), resource, mapRoleScope, policy);
+ Policy mapRolePermission = Helper.addEmptyScopePermission(authz, server, getMapRolePermissionName(role), resource, mapRoleScope);
mapRolePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
Scope mapClientScope = getMapClientScope(server);
- RoleModel mngClients = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_CLIENTS);
- Policy mngClientsPolicy = rolePolicy(server, mngClients);
- Policy mapClientScopePermission = Helper.addScopePermission(authz, server, getMapClientScopePermissionName(role), resource, mapClientScope, mngClientsPolicy);
+ Policy mapClientScopePermission = Helper.addEmptyScopePermission(authz, server, getMapClientScopePermissionName(role), resource, mapClientScope);
mapClientScopePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
Scope mapCompositeScope = getMapCompositeScope(server);
- if (role.getContainer() instanceof RealmModel) {
- RoleModel mngRealm = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_REALM);
- policy = rolePolicy(server, mngRealm);
- } else {
- policy = mngClientsPolicy;
-
- }
- Policy mapCompositePermission = Helper.addScopePermission(authz, server, getMapCompositePermissionName(role), resource, mapCompositeScope, policy);
+ Policy mapCompositePermission = Helper.addEmptyScopePermission(authz, server, getMapCompositePermissionName(role), resource, mapCompositeScope);
mapCompositePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
return resource;
}
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 05ce719..74163d9 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
@@ -16,6 +16,7 @@
*/
package org.keycloak.services.resources.admin.permissions;
+import org.keycloak.authorization.model.Policy;
import org.keycloak.models.UserModel;
import java.util.Map;
@@ -25,7 +26,7 @@ import java.util.Map;
* @version $Revision: 1 $
*/
public interface UserPermissionEvaluator {
- boolean canManage();
+ boolean canManage();
void requireManage();
@@ -51,4 +52,12 @@ public interface UserPermissionEvaluator {
void requireImpersonate(UserModel user);
Map<String, Boolean> getAccess(UserModel user);
+
+ boolean canMapRoles(UserModel user);
+
+ void requireMapRoles(UserModel user);
+
+ boolean canManageGroupMembership(UserModel user);
+
+ void requireManageGroupMembership(UserModel user);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java
index b57b710..d4184ed 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java
@@ -38,4 +38,10 @@ public interface UserPermissionManagement {
Policy managePermission();
Policy viewPermission();
+
+ Policy manageGroupMembershipPermission();
+
+ Policy mapRolesPermission();
+
+ Policy impersonatePermission();
}
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 f8dd53b..6666a7e 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
@@ -45,6 +45,12 @@ import java.util.Set;
*/
class UserPermissions implements UserPermissionEvaluator, UserPermissionManagement {
private static final Logger logger = Logger.getLogger(UserPermissions.class);
+ public static final String MAP_ROLES_SCOPE="map-roles";
+ public static final String IMPERSONATE_SCOPE="impersonate";
+ public static final String MANAGE_GROUP_MEMBERSHIP_SCOPE="manage-group-membership";
+ public static final String MAP_ROLES_PERMISSION_USERS = "map-roles.permission.users";
+ public static final String IMPERSONATE_PERMISSION_USERS = "impersonate.permission.users";
+ public static final String MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS = "manage-group-membership.permission.users";
public static final String MANAGE_PERMISSION_USERS = "manage.permission.users";
public static final String VIEW_PERMISSION_USERS = "view.permission.users";
public static final String USERS_RESOURCE = "Users";
@@ -67,6 +73,9 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
ResourceServer server = root.realmResourceServer();
Scope manageScope = root.realmManageScope();
Scope viewScope = root.realmViewScope();
+ Scope mapRolesScope = root.initializeRealmScope(MAP_ROLES_SCOPE);
+ Scope impersonateScope = root.initializeRealmScope(IMPERSONATE_SCOPE);
+ Scope manageGroupMembershipScope = root.initializeRealmScope(MANAGE_GROUP_MEMBERSHIP_SCOPE);
Resource usersResource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
if (usersResource == null) {
@@ -74,17 +83,30 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
Set<Scope> scopeset = new HashSet<>();
scopeset.add(manageScope);
scopeset.add(viewScope);
+ scopeset.add(mapRolesScope);
+ scopeset.add(impersonateScope);
+ scopeset.add(manageGroupMembershipScope);
usersResource.updateScopes(scopeset);
}
Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
if (managePermission == null) {
- Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
- Helper.addScopePermission(authz, server, MANAGE_PERMISSION_USERS, usersResource, manageScope, manageUsersPolicy);
+ Helper.addEmptyScopePermission(authz, server, MANAGE_PERMISSION_USERS, usersResource, manageScope);
}
Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
if (viewPermission == null) {
- Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
- Helper.addScopePermission(authz, server, VIEW_PERMISSION_USERS, usersResource, viewScope, viewUsersPolicy);
+ Helper.addEmptyScopePermission(authz, server, VIEW_PERMISSION_USERS, usersResource, viewScope);
+ }
+ Policy mapRolesPermission = authz.getStoreFactory().getPolicyStore().findByName(MAP_ROLES_PERMISSION_USERS, server.getId());
+ if (mapRolesPermission == null) {
+ Helper.addEmptyScopePermission(authz, server, MAP_ROLES_PERMISSION_USERS, usersResource, mapRolesScope);
+ }
+ Policy membershipPermission = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, server.getId());
+ if (membershipPermission == null) {
+ Helper.addEmptyScopePermission(authz, server, MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, usersResource, manageGroupMembershipScope);
+ }
+ Policy impersonatePermission = authz.getStoreFactory().getPolicyStore().findByName(IMPERSONATE_PERMISSION_USERS, server.getId());
+ if (impersonatePermission == null) {
+ Helper.addEmptyScopePermission(authz, server, IMPERSONATE_PERMISSION_USERS, usersResource, impersonateScope);
}
}
@@ -93,6 +115,9 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
Map<String, String> scopes = new HashMap<>();
scopes.put(AdminPermissionManagement.MANAGE_SCOPE, managePermission().getId());
scopes.put(AdminPermissionManagement.VIEW_SCOPE, viewPermission().getId());
+ scopes.put(MAP_ROLES_SCOPE, mapRolesPermission().getId());
+ scopes.put(MANAGE_GROUP_MEMBERSHIP_SCOPE, manageGroupMembershipPermission().getId());
+ scopes.put(IMPERSONATE_SCOPE, impersonatePermission().getId());
return scopes;
}
@@ -117,7 +142,22 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
} else {
ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
if (server == null) return;
- Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
+ Policy policy = managePermission();
+ if (policy == null) {
+ authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+
+ }
+ policy = viewPermission();
+ if (policy == null) {
+ authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+
+ }
+ policy = mapRolesPermission();
+ if (policy == null) {
+ authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+
+ }
+ policy = manageGroupMembershipPermission();
if (policy == null) {
authz.getStoreFactory().getPolicyStore().delete(policy.getId());
@@ -153,6 +193,25 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
return authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
}
+ @Override
+ public Policy manageGroupMembershipPermission() {
+ ResourceServer server = root.realmResourceServer();
+ return authz.getStoreFactory().getPolicyStore().findByName(MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, server.getId());
+ }
+
+ @Override
+ public Policy mapRolesPermission() {
+ ResourceServer server = root.realmResourceServer();
+ return authz.getStoreFactory().getPolicyStore().findByName(MAP_ROLES_PERMISSION_USERS, server.getId());
+ }
+
+
+ @Override
+ public Policy impersonatePermission() {
+ ResourceServer server = root.realmResourceServer();
+ return authz.getStoreFactory().getPolicyStore().findByName(IMPERSONATE_PERMISSION_USERS, server.getId());
+ }
+
/**
@@ -170,25 +229,26 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
*/
@Override
public boolean canManage() {
+ if (canManageDefault()) return true;
if (!root.isAdminSameRealm()) {
- return canManageDefault();
+ return false;
}
ResourceServer server = root.realmResourceServer();
- if (server == null) return canManageDefault();
+ if (server == null) return false;
Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
- if (resource == null) return canManageDefault();
+ if (resource == null) return false;
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
if (policy == null) {
- return canManageDefault();
+ return false;
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
// if no policies attached to permission then just do default behavior
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
- return canManageDefault();
+ return false;
}
Scope scope = root.realmManageScope();
@@ -321,14 +381,15 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
*/
@Override
public boolean canView() {
+ if (canViewDefault()) return true;
if (!root.isAdminSameRealm()) {
- return canViewDefault();
+ return false;
}
return hasViewPermission() || canManage();
}
- public boolean hasViewPermission() {
+ private boolean hasViewPermission() {
ResourceServer server = root.realmResourceServer();
if (server == null) return canViewDefault();
@@ -382,7 +443,32 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
@Override
public boolean canImpersonate(UserModel user) {
- return root.hasOneAdminRole(ImpersonationConstants.IMPERSONATION_ROLE);
+ if (root.hasOneAdminRole(ImpersonationConstants.IMPERSONATION_ROLE)) return true;
+
+ if (!root.isAdminSameRealm()) {
+ return false;
+ }
+
+ ResourceServer server = root.realmResourceServer();
+ if (server == null) return false;
+
+ Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+ if (resource == null) return false;
+
+ Policy policy = authz.getStoreFactory().getPolicyStore().findByName(IMPERSONATE_PERMISSION_USERS, server.getId());
+ if (policy == null) {
+ return false;
+ }
+
+ Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+ // if no policies attached to permission then just do default behavior
+ if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+ return false;
+ }
+
+ Scope scope = root.realmScope(IMPERSONATE_SCOPE);
+ return root.evaluatePermission(resource, scope, server);
+
}
@Override
@@ -397,9 +483,90 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
Map<String, Boolean> map = new HashMap<>();
map.put("view", canView(user));
map.put("manage", canManage(user));
+ map.put("mapRoles", canMapRoles(user));
+ map.put("manageGroupMembership", canManageGroupMembership(user));
+ map.put("impersonate", canImpersonate(user));
return map;
}
+ @Override
+ public boolean canMapRoles(UserModel user) {
+ if (canManage(user)) return true;
+
+ if (!root.isAdminSameRealm()) {
+ return false;
+ }
+
+ ResourceServer server = root.realmResourceServer();
+ if (server == null) return false;
+
+ Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+ if (resource == null) return false;
+
+ Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MAP_ROLES_PERMISSION_USERS, server.getId());
+ if (policy == null) {
+ return false;
+ }
+
+ Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+ // if no policies attached to permission then just do default behavior
+ if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+ return false;
+ }
+
+ Scope scope = root.realmScope(MAP_ROLES_SCOPE);
+ return root.evaluatePermission(resource, scope, server);
+
+ }
+
+ @Override
+ public void requireMapRoles(UserModel user) {
+ if (!canMapRoles(user)) {
+ throw new ForbiddenException();
+ }
+
+ }
+
+
+ @Override
+ public boolean canManageGroupMembership(UserModel user) {
+ if (canManage(user)) return true;
+
+ if (!root.isAdminSameRealm()) {
+ return false;
+ }
+
+ ResourceServer server = root.realmResourceServer();
+ if (server == null) return false;
+
+ Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+ if (resource == null) return false;
+
+ Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, server.getId());
+ if (policy == null) {
+ return false;
+ }
+
+ Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+ // if no policies attached to permission then just do default behavior
+ if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+ return false;
+ }
+
+ Scope scope = root.realmScope(MANAGE_GROUP_MEMBERSHIP_SCOPE);
+ return root.evaluatePermission(resource, scope, server);
+
+ }
+
+ @Override
+ public void requireManageGroupMembership(UserModel user) {
+ if (!canManageGroupMembership(user)) {
+ throw new ForbiddenException();
+ }
+
+ }
+
+
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index 9e0a89e..b00f2e4 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -96,18 +96,11 @@ public class RealmsAdminResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<RealmRepresentation> getRealms() {
- RealmManager realmManager = new RealmManager(session);
List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
- if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
- List<RealmModel> realms = session.realms().getRealms();
- for (RealmModel realm : realms) {
- addRealmRep(reps, realm, realm.getMasterAdminClient());
- }
- } else {
- ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm()));
- addRealmRep(reps, auth.getRealm(), adminApp);
+ List<RealmModel> realms = session.realms().getRealms();
+ for (RealmModel realm : realms) {
+ addRealmRep(reps, realm);
}
-
if (reps.isEmpty()) {
throw new ForbiddenException();
}
@@ -116,10 +109,10 @@ public class RealmsAdminResource {
return reps;
}
- protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ClientModel realmManagementClient) {
- if (auth.hasAppRole(realmManagementClient, AdminRoles.VIEW_REALM)) {
+ protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm) {
+ if (AdminPermissions.realms(session, auth).canView(realm)) {
reps.add(ModelToRepresentation.toRepresentation(realm, false));
- } else if (auth.hasOneOfAppRole(realmManagementClient, AdminRoles.ALL_REALM_ROLES)) {
+ } else if (AdminPermissions.realms(session, auth).isAdmin(realm)) {
RealmRepresentation rep = new RealmRepresentation();
rep.setRealm(realm.getName());
reps.add(rep);
@@ -140,12 +133,7 @@ public class RealmsAdminResource {
public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) {
RealmManager realmManager = new RealmManager(session);
realmManager.setContextPath(keycloak.getContextPath());
- if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
- throw new ForbiddenException();
- }
- if (!auth.hasRealmRole(AdminRoles.CREATE_REALM)) {
- throw new ForbiddenException();
- }
+ AdminPermissions.realms(session, auth).requireCreateRealm();
logger.debugv("importRealm: {0}", rep.getRealm());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
index 8db0591..b785b1a 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
@@ -232,7 +232,7 @@ public class RoleMapperResource {
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException("Role not found");
}
- checkMapRolePermission(roleModel);
+ auth.roles().requireMapRole(roleModel);
roleMapper.grantRole(roleModel);
}
@@ -256,7 +256,7 @@ public class RoleMapperResource {
roles = new LinkedList<>();
for (RoleModel roleModel : roleModels) {
- checkMapRolePermission(roleModel);
+ auth.roles().requireMapRole(roleModel);
roleMapper.deleteRoleMapping(roleModel);
roles.add(ModelToRepresentation.toRepresentation(roleModel));
}
@@ -267,7 +267,7 @@ public class RoleMapperResource {
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException("Role not found");
}
- checkMapRolePermission(roleModel);
+ auth.roles().requireMapRole(roleModel);
try {
roleMapper.deleteRoleMapping(roleModel);
} catch (ModelException me) {
@@ -283,12 +283,6 @@ public class RoleMapperResource {
}
- private void checkMapRolePermission(RoleModel roleModel) {
- if (!canMapRole(roleModel)) {
- throw new ForbiddenException();
- }
- }
-
private boolean canMapRole(RoleModel roleModel) {
return auth.roles().canMapRole(roleModel);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index cdd9cd7..0161ee6 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -67,7 +67,7 @@ public abstract class RoleResource {
if (composite == null) {
throw new NotFoundException("Could not find composite role");
}
- auth.roles().requireManage(composite);
+ auth.roles().requireMapComposite(composite);
role.addCompositeRole(composite);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserResource.java
index ca9d536..bf3b236 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserResource.java
@@ -534,7 +534,7 @@ public class UserResource {
@Path("role-mappings")
public RoleMapperResource getRoleMappings() {
- AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.users().requireManage(user);
+ AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.users().requireMapRoles(user);
AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.users().requireView(user);
RoleMapperResource resource = new RoleMapperResource(realm, auth, user, adminEvent, manageCheck, viewCheck);
ResteasyProviderFactory.getInstance().injectProperties(resource);
@@ -756,13 +756,13 @@ public class UserResource {
@Path("groups/{groupId}")
@NoCache
public void removeMembership(@PathParam("groupId") String groupId) {
- auth.users().requireManage(user);
+ auth.users().requireManageGroupMembership(user);
GroupModel group = session.realms().getGroupById(groupId, realm);
if (group == null) {
throw new NotFoundException("Group not found");
}
- auth.groups().requireManageMembers(group);
+ auth.groups().requireManageMembership(group);
try {
if (user.isMemberOf(group)){
@@ -780,12 +780,12 @@ public class UserResource {
@Path("groups/{groupId}")
@NoCache
public void joinGroup(@PathParam("groupId") String groupId) {
- auth.users().requireManage(user);
+ auth.users().requireManageGroupMembership(user);
GroupModel group = session.realms().getGroupById(groupId, realm);
if (group == null) {
throw new NotFoundException("Group not found");
}
- //auth.groups().requireManageMembers(group);
+ auth.groups().requireManageMembership(group);
if (!user.isMemberOf(group)){
user.joinGroup(group);
adminEvent.operation(OperationType.CREATE).resource(ResourceType.GROUP_MEMBERSHIP).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java
index d32ad79..37d3a96 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java
@@ -66,6 +66,43 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
testRealmRep.setEnabled(true);
testRealms.add(testRealmRep);
}
+ public static void setupDemo(KeycloakSession session) {
+ RealmModel realm = session.realms().getRealmByName(TEST);
+ ClientModel client = realm.addClient("sales-pipeline-application");
+ RoleModel clientAdmin = client.addRole("admin");
+ client.addRole("leader-creator");
+ client.addRole("viewLeads");
+ ClientModel client2 = realm.addClient("market-analysis-application");
+ RoleModel client2Admin = client2.addRole("admin");
+ client2.addRole("market-manager");
+ client2.addRole("viewMarkets");
+ GroupModel sales = realm.createGroup("sales");
+ RoleModel salesAppsAdminRole = realm.addRole("sales-apps-admin");
+ salesAppsAdminRole.addCompositeRole(clientAdmin);
+ salesAppsAdminRole.addCompositeRole(client2Admin);
+
+
+ UserModel admin = session.users().addUser(realm, "salesManager");
+ admin.setEnabled(true);
+ session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
+ admin = session.users().addUser(realm, "sales-group-admin");
+ admin.setEnabled(true);
+ session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
+ admin = session.users().addUser(realm, "sales-it");
+ admin.setEnabled(true);
+ session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
+ admin = session.users().addUser(realm, "sales-pipeline-admin");
+ admin.setEnabled(true);
+ session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
+
+ UserModel user = session.users().addUser(realm, "salesman");
+ user.setEnabled(true);
+ user.joinGroup(sales);
+
+ user = session.users().addUser(realm, "saleswoman");
+ user.setEnabled(true);
+
+ }
public static void setupPolices(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName(TEST);
@@ -304,9 +341,14 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
protected boolean isImportAfterEachMethod() {
return true;
}
+ //@Test
+ public void testDemo() throws Exception {
+ testingClient.server().run(FineGrainAdminUnitTest::setupDemo);
+ Thread.sleep(1000000000);
+ }
- @Test
+ //@Test
public void testUI() throws Exception {
testingClient.server().run(FineGrainAdminUnitTest::setupPolices);
testingClient.server().run(FineGrainAdminUnitTest::setupUsers);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
index 4b0de12..16b0804 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
@@ -717,7 +717,7 @@ public class PermissionsTest extends AbstractKeycloakTest {
public void invoke(RealmResource realm) {
realm.clientTemplates().findAll();
}
- }, Resource.CLIENT, false);
+ }, Resource.CLIENT, false, true);
invoke(new InvocationWithResponse() {
public void invoke(RealmResource realm, AtomicReference<Response> response) {
ClientTemplateRepresentation template = new ClientTemplateRepresentation();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties b/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties
index 9c9bfc2..5fbec89 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties
@@ -29,7 +29,7 @@ log4j.appender.testsuite.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%C{1}]
keycloak.logging.level=info
log4j.logger.org.keycloak=${keycloak.logging.level}
-log4j.logger.org.jboss.resteasy.resteasy_jaxrs.i18n=off
+#log4j.logger.org.jboss.resteasy.resteasy_jaxrs.i18n=off
#log4j.logger.org.keycloak.keys.DefaultKeyManager=trace
#log4j.logger.org.keycloak.services.managers.AuthenticationManager=trace
@@ -62,7 +62,7 @@ log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=de
log4j.logger.org.xnio=off
log4j.logger.org.hibernate=off
-log4j.logger.org.jboss.resteasy=warn
+log4j.logger.org.jboss.resteasy=info
log4j.logger.org.apache.directory.api=warn
log4j.logger.org.apache.directory.server.core=warn
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
index 37b4984..6834ac8 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
@@ -2394,6 +2394,7 @@ module.controller('ClientRolePermissionsCtrl', function($scope, $http, $route, $
$scope.permissions = data;
});
$scope.setEnabled = function() {
+ console.log('perssions enabled: ' + $scope.permissions.enabled);
var param = { enabled: $scope.permissions.enabled};
$scope.permissions = RoleManagementPermissions.update({realm: realm.realm, role:role.id}, param);
};
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/group-attributes.html b/themes/src/main/resources/theme/base/admin/resources/partials/group-attributes.html
index c3962c5..e12c553 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/group-attributes.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/group-attributes.html
@@ -6,7 +6,7 @@
<kc-tabs-group></kc-tabs-group>
- <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageUsers">
+ <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!group.access.manage">
<table class="table table-striped table-bordered">
<thead>
<tr>
@@ -29,7 +29,7 @@
</tbody>
</table>
- <div class="form-group" data-ng-show="access.manageUsers">
+ <div class="form-group" data-ng-show="group.access.manage">
<div class="col-md-12">
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/group-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/group-detail.html
index 677ea32..8fd6461 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/group-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/group-detail.html
@@ -16,7 +16,7 @@
</div>
</fieldset>
- <div class="form-group" data-ng-show="access.manageUsers">
+ <div class="form-group" data-ng-show="group.access.manage">
<div class="col-md-10 col-md-offset-2">
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
<button kc-reset data-ng-disabled="!changed" data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/group-role-mappings.html b/themes/src/main/resources/theme/base/admin/resources/partials/group-role-mappings.html
index 9a1c5b8..62aa7d4 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/group-role-mappings.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/group-role-mappings.html
@@ -7,7 +7,7 @@
<kc-tabs-group></kc-tabs-group>
<form class="form-horizontal" name="realmForm" novalidate>
- <div class="form-group" kc-read-only="!access.manageUsers">
+ <div class="form-group" kc-read-only="!group.access.manage">
<label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label>
<div class="col-md-10">
@@ -54,7 +54,7 @@
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
- <div class="col-md-10" kc-read-only="!access.manageUsers">
+ <div class="col-md-10" kc-read-only="!group.access.manage">
<div class="row" data-ng-hide="targetClient">
<div class="col-md-4"><span class="text-muted">{{:: 'select-client-to-view-roles' | translate}}</span></div>
</div>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html b/themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html
index b57b1d2..013dae7 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html
@@ -7,7 +7,7 @@
<kc-tabs-user></kc-tabs-user>
<form class="form-horizontal" name="realmForm" novalidate>
- <div class="form-group" kc-read-only="!access.manageUsers">
+ <div class="form-group" kc-read-only="!user.access.mapRoles">
<label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label>
<div class="col-md-10">
@@ -54,7 +54,7 @@
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
- <div class="col-md-10" kc-read-only="!access.manageUsers">
+ <div class="col-md-10" kc-read-only="!user.access.mapRoles">
<div class="row" data-ng-hide="targetClient">
<div class="col-md-4"><span class="text-muted">{{:: 'select-client-to-view-roles' | translate}}</span></div>
</div>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html
index d7259fd..88e66e7 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html
@@ -138,7 +138,7 @@
<button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
</div>
- <div class="col-md-10 col-md-offset-2" data-ng-show="!create && !user.access.manage">
+ <div class="col-md-10 col-md-offset-2" data-ng-show="!create && user.access.manage">
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
</div>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/user-group-membership.html b/themes/src/main/resources/theme/base/admin/resources/partials/user-group-membership.html
index a9c0e6d..f7bf04e 100755
--- a/themes/src/main/resources/theme/base/admin/resources/partials/user-group-membership.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/user-group-membership.html
@@ -7,7 +7,7 @@
<kc-tabs-user></kc-tabs-user>
<form class="form-horizontal" name="realmForm" novalidate>
- <div class="form-group" kc-read-only="!access.manageUsers">
+ <div class="form-group" kc-read-only="!user.access.manageGroupMembership">
<label class="col-md-1 control-label" class="control-label"></label>
<div class="col-md-8" >
@@ -21,7 +21,7 @@
<label class="control-label">{{:: 'group-membership' | translate}}</label>
<kc-tooltip>{{:: 'group-membership.tooltip' | translate}}</kc-tooltip>
- <div class="pull-right" data-ng-show="access.manageUsers">
+ <div class="pull-right" data-ng-show="user.access.manageGroupMembership">
<button id="leaveGroups" class="btn btn-default" ng-click="leaveGroup()">{{:: 'leave' | translate}}</button>
</div>
</div>
@@ -53,7 +53,7 @@
<label class="control-label">{{:: 'available-groups' | translate}}</label>
<kc-tooltip>{{:: 'membership.available-groups.tooltip' | translate}}</kc-tooltip>
- <div class="pull-right" data-ng-show="access.manageUsers">
+ <div class="pull-right" data-ng-show="user.access.manageGroupMembership">
<button id="joinGroup" class="btn btn-default" ng-click="joinGroup()">{{:: 'join' | translate}}</button>
</div>
</div>