keycloak-aplcache

Merge pull request #3085 from pedroigor/master [KEYCLOAK-3376]

8/1/2016 4:09:55 AM

Details

diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
index 6712a9d..67ae7d4 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
@@ -87,16 +87,17 @@ public class PolicyEvaluationService {
     @Consumes("application/json")
     @Produces("application/json")
     public void evaluate(PolicyEvaluationRequest evaluationRequest, @Suspended AsyncResponse asyncResponse) {
-        EvaluationContext evaluationContext = createEvaluationContext(evaluationRequest);
-        authorization.evaluators().from(createPermissions(evaluationRequest, evaluationContext, authorization), evaluationContext).evaluate(createDecisionCollector(evaluationRequest, authorization, asyncResponse));
+        KeycloakIdentity identity = createIdentity(evaluationRequest);
+        EvaluationContext evaluationContext = createEvaluationContext(evaluationRequest, identity);
+        authorization.evaluators().from(createPermissions(evaluationRequest, evaluationContext, authorization), evaluationContext).evaluate(createDecisionCollector(evaluationRequest, authorization, identity, asyncResponse));
     }
 
-    private DecisionResultCollector createDecisionCollector(PolicyEvaluationRequest evaluationRequest, AuthorizationProvider authorization, AsyncResponse asyncResponse) {
+    private DecisionResultCollector createDecisionCollector(PolicyEvaluationRequest evaluationRequest, AuthorizationProvider authorization, KeycloakIdentity identity, AsyncResponse asyncResponse) {
         return new DecisionResultCollector() {
             @Override
             protected void onComplete(List<Result> results) {
                 try {
-                    asyncResponse.resume(Response.ok(PolicyEvaluationResponse.build(evaluationRequest,  results, resourceServer,  authorization)).build());
+                    asyncResponse.resume(Response.ok(PolicyEvaluationResponse.build(evaluationRequest,  results, resourceServer,  authorization, identity)).build());
                 } catch (Throwable cause) {
                     asyncResponse.resume(cause);
                 }
@@ -109,8 +110,8 @@ public class PolicyEvaluationService {
         };
     }
 
-    private EvaluationContext createEvaluationContext(PolicyEvaluationRequest representation) {
-        return new KeycloakEvaluationContext(createIdentity(representation), this.authorization.getKeycloakSession()) {
+    private EvaluationContext createEvaluationContext(PolicyEvaluationRequest representation, KeycloakIdentity identity) {
+        return new KeycloakEvaluationContext(identity, this.authorization.getKeycloakSession()) {
             @Override
             public Attributes getAttributes() {
                 Map<String, Collection<String>> attributes = new HashMap<>(super.getAttributes().toMap());
@@ -137,17 +138,6 @@ public class PolicyEvaluationService {
 
     private List<ResourcePermission> createPermissions(PolicyEvaluationRequest representation, EvaluationContext evaluationContext, AuthorizationProvider authorization) {
         List<PolicyEvaluationRequest.Resource> resources = representation.getResources();
-
-        for (PolicyEvaluationRequest.Resource resource : new ArrayList<>(resources)) {
-            if (resource.getId() == null && (resource.getScopes() == null || resource.getScopes().isEmpty())) {
-                resources.remove(resource);
-            }
-        }
-
-        if (representation.isEntitlements() || resources.isEmpty()) {
-            return Permissions.all(this.resourceServer, evaluationContext.getIdentity(), authorization);
-        }
-
         return resources.stream().flatMap((Function<PolicyEvaluationRequest.Resource, Stream<ResourcePermission>>) resource -> {
             Set<String> givenScopes = resource.getScopes();
 
diff --git a/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponse.java b/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponse.java
index 9a3c9b3..cccb38f 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponse.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponse.java
@@ -21,10 +21,15 @@ package org.keycloak.authorization.admin.representation;
 import org.keycloak.authorization.AuthorizationProvider;
 import org.keycloak.authorization.Decision.Effect;
 import org.keycloak.authorization.admin.util.Models;
+import org.keycloak.authorization.common.KeycloakIdentity;
 import org.keycloak.authorization.model.ResourceServer;
 import org.keycloak.authorization.model.Scope;
 import org.keycloak.authorization.policy.evaluation.Result;
 import org.keycloak.authorization.policy.evaluation.Result.PolicyResult;
+import org.keycloak.authorization.util.Permissions;
+import org.keycloak.protocol.oidc.TokenManager;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.idm.authorization.Permission;
 import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
@@ -42,14 +47,22 @@ public class PolicyEvaluationResponse {
     private List<EvaluationResultRepresentation> results;
     private boolean entitlements;
     private Effect status;
+    private AccessToken rpt;
 
     private PolicyEvaluationResponse() {
 
     }
 
-    public static PolicyEvaluationResponse build(PolicyEvaluationRequest evaluationRequest, List<Result> results, ResourceServer resourceServer, AuthorizationProvider authorization) {
+    public static PolicyEvaluationResponse build(PolicyEvaluationRequest evaluationRequest, List<Result> results, ResourceServer resourceServer, AuthorizationProvider authorization, KeycloakIdentity identity) {
         PolicyEvaluationResponse response = new PolicyEvaluationResponse();
         List<EvaluationResultRepresentation> resultsRep = new ArrayList<>();
+        AccessToken accessToken = identity.getAccessToken();
+        AccessToken.Authorization authorizationData = new AccessToken.Authorization();
+
+        authorizationData.setPermissions(Permissions.allPermits(results));
+        accessToken.setAuthorization(authorizationData);
+
+        response.rpt = accessToken;
 
         if (results.stream().anyMatch(evaluationResult -> evaluationResult.getEffect().equals(Effect.DENY))) {
             response.status = Effect.DENY;
@@ -124,6 +137,10 @@ public class PolicyEvaluationResponse {
         return entitlements;
     }
 
+    public AccessToken getRpt() {
+        return rpt;
+    }
+
     public static class EvaluationResultRepresentation {
 
         private ResourceRepresentation resource;
diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index 50d5919..1f39b06 100644
--- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
+++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -1076,10 +1076,11 @@ authz-permission-scope-scope.tooltip=Specifies that this permission must be appl
 # Authz Evaluation
 authz-evaluation-identity-information=Identity Information
 authz-evaluation-identity-information.tooltip=The available options to configure the identity information that will be used when evaluating policies.
-authz-evaluation-client.tooltip=Select the client making this authorization request.
+authz-evaluation-client.tooltip=Select the client making this authorization request. If not provided, authorization requests would be done based on the client you are in.
 authz-evaluation-user.tooltip=Select an user whose identity is going to be used to query permissions from the server.
 authz-evaluation-role.tooltip=Select the roles you want to associate with the selected user.
 authz-evaluation-new=New Evaluation
+authz-evaluation-re-evaluate=Re-Evaluate
 authz-evaluation-previous=Previous Evaluation
 authz-evaluation-contextual-info=Contextual Information
 authz-evaluation-contextual-info.tooltip=The available options to configure any contextual information that will be used when evaluating policies.
@@ -1093,3 +1094,6 @@ authz-evaluation-no-policies-resource=No policies were found for this resource.
 authz-evaluation-result.tooltip=The overall result for this permission request.
 authz-evaluation-scopes.tooltip=The requested scopes.
 authz-evaluation-policies.tooltip=Details about which policies were evaluated and their decisions.
+authz-evaluation-authorization-data=Response
+authz-evaluation-authorization-data.tooltip=Represents a token carrying authorization data as a result of the processing of an authorization request. This representation is basically what Keycloak issues to clients asking for permissions. Check the 'authorization' claim for the permissions that were granted based on the current authorization request.
+authz-show-authorization-data=Show Authorization Data
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 bbe0fd0..d772f92 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
@@ -1329,6 +1329,18 @@ module.controller('PolicyEvaluateCtrl', function($scope, $http, $route, $locatio
         }
     }
 
+    $scope.reevaluate = function() {
+        if ($scope.authzRequest.entitlements) {
+            $scope.entitlements();
+        } else {
+            $scope.save();
+        }
+    }
+
+    $scope.showAuthzData = function() {
+        $scope.showRpt = true;
+    }
+
     $scope.save = function() {
         $scope.authzRequest.entitlements = false;
         if ($scope.applyResourceType) {
@@ -1356,10 +1368,12 @@ module.controller('PolicyEvaluateCtrl', function($scope, $http, $route, $locatio
 
     $scope.showResultTab = function() {
         $scope.showResult = true;
+        $scope.showRpt = false;
     }
 
     $scope.showRequestTab = function() {
         $scope.showResult = false;
+        $scope.showRpt = false;
     }
 
     User.query({realm: $route.current.params.realm}, function(data) {
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html
index ce62c33..d875e86 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html
@@ -12,6 +12,10 @@
     <div data-ng-show="showResult">
         <br>
         <a href="" data-ng-click="showRequestTab()">{{:: 'authz-evaluation-new' | translate}}</a>
+        |
+        <a href="" data-ng-click="reevaluate()">{{:: 'authz-evaluation-re-evaluate' | translate}}</a>
+        |
+        <a href="" data-ng-click="showAuthzData()">{{:: 'authz-show-authorization-data' | translate}}</a>
     </div>
 
     <div data-ng-show="evaluationResult && !showResult">
@@ -19,6 +23,16 @@
         <a href="" data-ng-click="showResultTab()">{{:: 'authz-evaluation-previous' | translate}}</a>
     </div>
 
+    <div data-ng-show="showRpt">
+        <div class="form-group">
+            <label class="col-sm-1 control-label" for="rpt">{{:: 'authz-evaluation-authorization-data' | translate}}</label>
+            <div class="col-md-6">
+                <textarea id="rpt" class="form-control" rows="20">{{evaluationResult.rpt | json}}</textarea>
+            </div>
+            <kc-tooltip>{{:: 'authz-evaluation-authorization-data.tooltip' | translate}}</kc-tooltip>
+        </div>
+    </div>
+
     <div data-ng-hide="showResult">
         <form class="form-horizontal" name="clientForm" novalidate>
             <fieldset>
@@ -56,12 +70,6 @@
                         <kc-tooltip>{{:: 'authz-evaluation-user.tooltip' | translate}}</kc-tooltip>
                     </div>
 
-                    <div class="form-group">
-                        <div class="col-md-10 col-md-offset-2">
-                            <button class="btn btn-primary" data-ng-click="entitlements()" data-ng-disabled="authzRequest.userId == null || authzRequest.clientId == null">{{:: 'authz-entitlements' | translate}}</button>
-                        </div>
-                    </div>
-
                     <div class="form-group clearfix">
                         <label class="col-md-2 control-label" for="reqActions">{{:: 'roles' | translate}} <span class="required"
                                                                                            data-ng-show="!authzRequest.userId || authzRequest.userId == null">*</span></label>
@@ -268,7 +276,7 @@
             </fieldset>
         </form>
     </div>
-    <div data-ng-include="resultUrl" data-ng-show="showResult"/>
+    <div data-ng-include="resultUrl" data-ng-show="showResult && !showRpt"/>
 </div>
 
 <kc-menu></kc-menu>
\ No newline at end of file