keycloak-aplcache

Details

diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/js/app.js b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/js/app.js
index 691e01a..ecdbf0b 100755
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/js/app.js
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/js/app.js
@@ -34,7 +34,7 @@ module.config(function ($httpProvider, $routeProvider) {
         controller: 'AdminAlbumCtrl',
     }).when('/profile', {
         templateUrl: 'partials/profile.html',
-        controller: 'ProfileCtrl',
+        controller: 'ProfileCtrl'
     });
 });
 
@@ -50,6 +50,16 @@ module.controller('GlobalCtrl', function ($scope, $http, $route, $location, Albu
             $route.reload();
         });
     }
+
+    $scope.requestPathWithAnyProtectedScope = function() {
+        $http.get(apiUrl + '/scope-any').success(function (data) {
+        });
+    }
+
+    $scope.requestPathWithAllProtectedScope = function() {
+        $http.get(apiUrl + '/scope-all').success(function (data) {
+        });
+    }
 });
 
 module.controller('TokenCtrl', function ($scope, Identity) {
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/home.html b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/home.html
index e144d1b..788763b 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/home.html
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/src/main/webapp/partials/home.html
@@ -3,7 +3,7 @@
 <hr/>
 <br/>
 <div data-ng-show="!Identity.isAdmin()">
-<a href="#/album/create" id="create-album">Create Album</a> | <a href="#/profile">My Profile</a>
+<a href="#/album/create" id="create-album">Create Album</a> | <a href="#/profile">My Profile</a> | <a href="#" id="requestPathWithAnyProtectedScope" ng-click="requestPathWithAnyProtectedScope()">Any Scope Access</a> | <a href="#" id="requestPathWithAllProtectedScope" ng-click="requestPathWithAllProtectedScope()">All Scope Access</a>
 <br/>
 <br/>
 <span data-ng-show="albums.length == 0" id="resource-list-empty">You don't have any albums, yet.</span>
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json
index 5b41d26..f3db78d 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/src/main/webapp/WEB-INF/keycloak.json
@@ -51,6 +51,28 @@
       {
         "name" : "Admin Resources",
         "path" : "/admin/*"
+      },
+      {
+        "name" : "Scope Protected Resource",
+        "path" : "/scope-any",
+        "methods": [
+          {
+            "method": "GET",
+            "scopes": ["scope-a", "scope-b"],
+            "scopes-enforcement-mode": "ANY"
+          }
+        ]
+      },
+      {
+        "name" : "Scope Protected Resource",
+        "path" : "/scope-all",
+        "methods": [
+          {
+            "method": "GET",
+            "scopes": ["scope-a", "scope-b"],
+            "scopes-enforcement-mode": "ALL"
+          }
+        ]
       }
     ]
   }
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json
index ba44208..0b621f5 100644
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api-authz-service.json
@@ -37,6 +37,18 @@
           "name": "urn:photoz.com:scopes:album:admin:manage"
         }
       ]
+    },
+    {
+      "name": "Scope Protected Resource",
+      "uri": "/scope-any",
+      "scopes": [
+        {
+          "name": "scope-a"
+        },
+        {
+          "name": "scope-b"
+        }
+      ]
     }
   ],
   "policies": [
@@ -166,6 +178,37 @@
         "applyPolicies": "[\"Only Owner and Administrators Policy\"]",
         "scopes": "[\"urn:photoz.com:scopes:album:delete\"]"
       }
+    },
+    {
+      "name": "Deny Policy",
+      "type": "js",
+      "logic": "POSITIVE",
+      "decisionStrategy": "UNANIMOUS",
+      "config": {
+        "code": "// by default, grants any permission associated with this policy\n$evaluation.deny();"
+      }
+    },
+    {
+      "name": "Protected Scope A Permission",
+      "type": "scope",
+      "logic": "POSITIVE",
+      "decisionStrategy": "UNANIMOUS",
+      "config": {
+        "resources": "[\"Scope Protected Resource\"]",
+        "scopes": "[\"scope-a\"]",
+        "applyPolicies": "[\"Any User Policy\"]"
+      }
+    },
+    {
+      "name": "Protected Scope B Permission",
+      "type": "scope",
+      "logic": "POSITIVE",
+      "decisionStrategy": "UNANIMOUS",
+      "config": {
+        "resources": "[\"Scope Protected Resource\"]",
+        "scopes": "[\"scope-b\"]",
+        "applyPolicies": "[\"Deny Policy\"]"
+      }
     }
   ],
   "scopes": [
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
index 32cc58f..27df535 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
@@ -160,6 +160,18 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
         pause(WAIT_AFTER_OPERATION);
     }
 
+    public void requestResourceProtectedAnyScope() throws InterruptedException {
+        navigateTo();
+        this.driver.findElement(By.id("requestPathWithAnyProtectedScope")).click();
+        pause(WAIT_AFTER_OPERATION);
+    }
+
+    public void requestResourceProtectedAllScope() throws InterruptedException {
+        navigateTo();
+        this.driver.findElement(By.id("requestPathWithAllProtectedScope")).click();
+        pause(WAIT_AFTER_OPERATION);
+    }
+
     public WebElement getOutput() {
         return output;
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
index 7223b2a..edd264c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
@@ -642,6 +642,20 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         }
     }
 
+    @Test
+    public void testResourceProtectedWithAnyScope() throws Exception {
+        try {
+            this.deployer.deploy(RESOURCE_SERVER_ID);
+            loginToClientPage("alice", "alice");
+            this.clientPage.requestResourceProtectedAllScope();
+            assertTrue(this.clientPage.wasDenied());
+            this.clientPage.requestResourceProtectedAnyScope();
+            assertFalse(this.clientPage.wasDenied());
+        } finally {
+            this.deployer.undeploy(RESOURCE_SERVER_ID);
+        }
+    }
+
     private void importResourceServerSettings() throws FileNotFoundException {
         ResourceServerRepresentation authSettings = loadJson(new FileInputStream(new File(TEST_APPS_HOME_DIR + "/photoz/photoz-restful-api-authz-service.json")), ResourceServerRepresentation.class);