keycloak-uncached
Changes
services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java 4(+2 -2)
services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java 3(+2 -1)
services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java 4(+4 -0)
services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java 12(+12 -0)
Details
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 6582ad1..087aeb1 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
@@ -182,7 +182,7 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<AuthenticationFlowRepresentation> getFlows() {
- auth.realm().requireViewRealm();
+ auth.realm().requireViewAuthenticationFlows();
List<AuthenticationFlowRepresentation> flows = new LinkedList<>();
for (AuthenticationFlowModel flow : realm.getAuthenticationFlows()) {
@@ -900,7 +900,7 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RequiredActionProviderRepresentation> getRequiredActions() {
- auth.realm().requireViewRealm();
+ auth.realm().requireViewRequiredActions();
List<RequiredActionProviderRepresentation> list = new LinkedList<>();
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
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 ae8ac33..6d45ea8 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
@@ -224,7 +224,8 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM
@Override
public boolean canList() {
- return canView() || root.hasOneAdminRole(AdminRoles.QUERY_CLIENTS);
+ // when the user is assigned with query-users role, administrators can restrict which clients the user can see when using fine-grained admin permissions
+ return canView() || root.hasOneAdminRole(AdminRoles.QUERY_CLIENTS, AdminRoles.QUERY_USERS);
}
public boolean canList(ClientModel clientModel) {
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 7020667..05499c8 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
@@ -58,4 +58,8 @@ public interface RealmPermissionEvaluator {
boolean canViewEvents();
void requireViewEvents();
+
+ void requireViewRequiredActions();
+
+ void requireViewAuthenticationFlows();
}
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 c24ac3b..891d4fb 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
@@ -183,7 +183,19 @@ class RealmPermissions implements RealmPermissionEvaluator {
}
}
+ @Override
+ public void requireViewRequiredActions() {
+ if (!(canViewRealm() || root.hasOneAdminRole(AdminRoles.QUERY_USERS))) {
+ throw new ForbiddenException();
+ }
+ }
+ @Override
+ public void requireViewAuthenticationFlows() {
+ if (!(canViewRealm() || root.hasOneAdminRole(AdminRoles.QUERY_CLIENTS))) {
+ throw new ForbiddenException();
+ }
+ }
}
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 3280d27..8c13dc0 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
@@ -453,7 +453,7 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
return root.realm().canManageRealm();
} else if (role.getContainer() instanceof ClientModel) {
ClientModel client = (ClientModel)role.getContainer();
- return root.clients().canManage(client);
+ return root.clients().canConfigure(client);
}
return false;
}
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 d7c2bf3..23dd134 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
@@ -491,12 +491,6 @@ public class PermissionsTest extends AbstractKeycloakTest {
l = clients.get(AdminRoles.VIEW_CLIENTS).realm(REALM_NAME).clients().findAll();
Assert.assertThat(l, Matchers.not(Matchers.empty()));
- // this should throw forbidden as "query-users" role isn't enough
- invoke(new Invocation() {
- public void invoke(RealmResource realm) {
- clients.get(AdminRoles.QUERY_USERS).realm(REALM_NAME).clients().findAll();
- }
- }, clients.get(AdminRoles.QUERY_USERS), false);
ClientRepresentation client = l.get(0);
invoke(new InvocationWithResponse() {
@Override
@@ -764,6 +758,12 @@ public class PermissionsTest extends AbstractKeycloakTest {
realm.clients().get(foo.getId()).roles().get("nosuch").getClientRoleComposites("nosuch");
}
}, Resource.CLIENT, false);
+ // users with query-client role should be able to query flows so the client detail page can be rendered successfully when fine-grained permissions are enabled.
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ realm.flows().getFlows();
+ }
+ }, clients.get(AdminRoles.QUERY_CLIENTS), true);
}
@Test
@@ -1603,6 +1603,19 @@ public class PermissionsTest extends AbstractKeycloakTest {
realm.users().get(user.getId()).update(user);
}
}, clients.get(AdminRoles.QUERY_CLIENTS), false);
+ // users with query-user role should be able to query required actions so the user detail page can be rendered successfully when fine-grained permissions are enabled.
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ realm.flows().getRequiredActions();
+ }
+ }, clients.get(AdminRoles.QUERY_USERS), true);
+ // users with query-user role should be able to query clients so the user detail page can be rendered successfully when fine-grained permissions are enabled.
+ // if the admin wants to restrict the clients that an user can see he can define permissions for these clients
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ clients.get(AdminRoles.QUERY_USERS).realm(REALM_NAME).clients().findAll();
+ }
+ }, clients.get(AdminRoles.QUERY_USERS), true);
}
@Test