keycloak-aplcache

Details

diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java
index 195835c..58f9a08 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java
@@ -25,6 +25,10 @@ import org.keycloak.authorization.model.Policy;
 import org.keycloak.authorization.model.Resource;
 import org.keycloak.authorization.permission.ResourcePermission;
 import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
+import org.keycloak.authorization.store.PolicyStore;
+import org.keycloak.authorization.store.StoreFactory;
+import org.keycloak.models.ClientModel;
+import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.authorization.DecisionStrategy;
 import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
@@ -34,6 +38,7 @@ import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -327,6 +332,93 @@ public class ResourcePermissionManagementTest extends AbstractPhotozAdminTest {
         assertEquals(0, evaluationsUserRole.size());
     }
 
+    @Test
+    public void testResourceAccessWithClientBasedPolicy() throws Exception {
+        ClientModel testClient1 = getClientByClientId("test-client-1");
+        ClientModel testClient2 = getClientByClientId("test-client-2");
+        Policy clientPolicy = createClientPolicy(Collections.singletonList(testClient1));
+
+        PolicyRepresentation newPermission = new PolicyRepresentation();
+
+        newPermission.setName("Client Permission");
+        newPermission.setType("resource");
+
+        HashedMap config = new HashedMap();
+
+        config.put("defaultResourceType", "http://photoz.com/admin");
+        config.put("applyPolicies", JsonSerialization.writeValueAsString(new String[] {clientPolicy.getId()}));
+
+        newPermission.setConfig(config);
+
+        Response response = newPermissionRequest().post(Entity.entity(newPermission, MediaType.APPLICATION_JSON_TYPE));
+
+        assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+
+        PolicyRepresentation permission = response.readEntity(PolicyRepresentation.class);
+
+        onAuthorizationSession(authorizationProvider -> {
+            Policy policyModel = authorizationProvider.getStoreFactory().getPolicyStore().findById(permission.getId());
+
+            assertNotNull(policyModel);
+            assertEquals(permission.getId(), policyModel.getId());
+            assertEquals(newPermission.getName(), policyModel.getName());
+            assertEquals(resourceServer.getId(), policyModel.getResourceServer().getId());
+        });
+
+        Map<String, DefaultEvaluation> evaluations = performEvaluation(
+                Collections.singletonList(new ResourcePermission(adminResource, Collections.emptyList(), resourceServer)),
+                createAccessTokenForClient(testClient1),
+                createClientConnection("127.0.0.1"));
+
+        assertEquals(1, evaluations.size());
+        assertTrue(evaluations.containsKey(clientPolicy.getId()));
+        assertEquals(Effect.PERMIT, evaluations.get(clientPolicy.getId()).getEffect());
+
+        Map<String, DefaultEvaluation> evaluations2 = performEvaluation(
+                Collections.singletonList(new ResourcePermission(adminResource, Collections.emptyList(), resourceServer)),
+                createAccessTokenForClient(testClient2),
+                createClientConnection("127.0.0.1"));
+
+        assertEquals(1, evaluations2.size());
+        assertTrue(evaluations2.containsKey(clientPolicy.getId()));
+        assertEquals(Effect.DENY, evaluations2.get(clientPolicy.getId()).getEffect());
+    }
+
+    private Policy createClientPolicy(List<ClientModel> allowedClients) {
+        return onAuthorizationSession(authorizationProvider -> {
+            StoreFactory storeFactory = authorizationProvider.getStoreFactory();
+            PolicyStore policyStore = storeFactory.getPolicyStore();
+            Policy policy = policyStore.create("Client-Based Policy", "client", resourceServer);
+
+            List<String> clientIds = new ArrayList<>();
+            for (ClientModel client : allowedClients) {
+                clientIds.add(client.getClientId());
+            }
+
+            String[] clients = clientIds.toArray(new String[clientIds.size()]);
+            HashedMap config = new HashedMap();
+
+            try {
+                config.put("clients", JsonSerialization.writeValueAsString(clients));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+
+            policy.setConfig(config);
+
+            return policy;
+        });
+    }
+
+    private AccessToken createAccessTokenForClient(ClientModel client) {
+        AccessToken accessToken = new AccessToken();
+
+        accessToken.setRealmAccess(new AccessToken.Access());
+        accessToken.issuedFor = client.getClientId();
+
+        return accessToken;
+    }
+
     private PolicyRepresentation createAlbumResourceTypePermission() throws Exception {
         PolicyRepresentation newPermission = new PolicyRepresentation();
 
diff --git a/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json b/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json
index 340576c..4e300e4 100644
--- a/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json
+++ b/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json
@@ -153,6 +153,26 @@
         "/confidential-no-service-account/*"
       ],
       "secret": "secret"
+    },
+    {
+      "clientId": "test-client-1",
+      "secret": "secret",
+      "enabled": true,
+      "baseUrl": "test-client-1",
+      "redirectUris": [
+        "/test-client-1/*"
+      ],
+      "webOrigins" : ["*"]
+    },
+    {
+      "clientId": "test-client-2",
+      "secret": "secret",
+      "enabled": true,
+      "baseUrl": "test-client-2",
+      "redirectUris": [
+        "/test-client-2/*"
+      ],
+      "webOrigins" : ["*"]
     }
   ]
 }
\ No newline at end of file