nifi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bbe...@apache.org
Subject nifi-registry git commit: NIFIREG-64 Updates Policy Authorization Behavior
Date Tue, 12 Dec 2017 20:34:02 GMT
Repository: nifi-registry
Updated Branches:
  refs/heads/master 31fe8434c -> a8786a807


NIFIREG-64 Updates Policy Authorization Behavior

- Changes authorization to /policies to be based on /polices resource
- Changes per-bucket policies to inherit from base /buckets policy
- Cleans up framework classes related to Authorization

This closes #52.

Signed-off-by: Bryan Bende <bbende@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/nifi-registry/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi-registry/commit/a8786a80
Tree: http://git-wip-us.apache.org/repos/asf/nifi-registry/tree/a8786a80
Diff: http://git-wip-us.apache.org/repos/asf/nifi-registry/diff/a8786a80

Branch: refs/heads/master
Commit: a8786a807c0c015f60242c627509e818f87b4f9a
Parents: 31fe843
Author: Kevin Doran <kdoran.apache@gmail.com>
Authored: Mon Dec 11 12:02:23 2017 -0500
Committer: Bryan Bende <bbende@apache.org>
Committed: Tue Dec 12 15:33:46 2017 -0500

----------------------------------------------------------------------
 .../authorization/AuthorizableLookup.java       |   8 --
 .../StandardAuthorizableLookup.java             |  91 ++++----------
 .../resource/AccessPolicyAuthorizable.java      | 122 -------------------
 ...rcePolicyPermissionsThroughBaseResource.java |  36 ------
 .../resource/InheritingAuthorizable.java        |  85 +++++++++++++
 .../authorization/resource/ResourceFactory.java |   6 -
 .../registry/service/AuthorizationService.java  |   2 +-
 .../registry/web/api/AccessPolicyResource.java  |  25 +---
 .../nifi/registry/web/api/BucketResource.java   |  12 +-
 .../nifi/registry/web/api/SecureLdapIT.java     |  14 +++
 10 files changed, 141 insertions(+), 260 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizableLookup.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizableLookup.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizableLookup.java
index f5bbd4d..2cbe1af 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizableLookup.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizableLookup.java
@@ -65,14 +65,6 @@ public interface AuthorizableLookup {
     Authorizable getBucketAuthorizable(String bucketIdentifier);
 
     /**
-     * Get the authorizable for the policy of the specified resource.
-     *
-     * @param resource resource
-     * @return authorizable
-     */
-    Authorizable getAccessPolicyByResource(String resource);
-
-    /**
      * Get the authorizable of the specified resource.
      *
      * @param resource resource

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/StandardAuthorizableLookup.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/StandardAuthorizableLookup.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/StandardAuthorizableLookup.java
index dfd9adc..3d54c62 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/StandardAuthorizableLookup.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/StandardAuthorizableLookup.java
@@ -18,8 +18,8 @@ package org.apache.nifi.registry.security.authorization;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.registry.exception.ResourceNotFoundException;
-import org.apache.nifi.registry.security.authorization.resource.AccessPolicyAuthorizable;
 import org.apache.nifi.registry.security.authorization.resource.Authorizable;
+import org.apache.nifi.registry.security.authorization.resource.InheritingAuthorizable;
 import org.apache.nifi.registry.security.authorization.resource.ResourceFactory;
 import org.apache.nifi.registry.security.authorization.resource.ResourceType;
 import org.springframework.stereotype.Component;
@@ -114,7 +114,8 @@ public class StandardAuthorizableLookup implements AuthorizableLookup
{
 
     @Override
     public Authorizable getBucketAuthorizable(String bucketIdentifier) {
-        return new Authorizable() {
+        // Note - this returns a special Authorizable type that inherits permissions from
the parent Authorizable
+        return new InheritingAuthorizable() {
 
             @Override
             public Authorizable getParentAuthorizable() {
@@ -123,24 +124,13 @@ public class StandardAuthorizableLookup implements AuthorizableLookup
{
 
             @Override
             public Resource getResource() {
-                return ResourceFactory.getBucketResource(bucketIdentifier, null);
+                return ResourceFactory.getBucketResource(bucketIdentifier, "Bucket with ID
" + bucketIdentifier);
             }
         };
     }
 
     @Override
-    public Authorizable getAccessPolicyByResource(final String resource) {
-        try {
-            return new AccessPolicyAuthorizable(getAuthorizableByResource(resource));
-        } catch (final ResourceNotFoundException e) {
-            // the underlying component has been removed or resource is invalid... require
/policies permissions
-            return POLICIES_AUTHORIZABLE;
-        }
-    }
-
-    @Override
     public Authorizable getAuthorizableByResource(String resource) {
-        // parse the resource type
         ResourceType resourceType = null;
         for (ResourceType type : ResourceType.values()) {
             if (resource.equals(type.getValue()) || resource.startsWith(type.getValue() +
"/")) {
@@ -152,53 +142,19 @@ public class StandardAuthorizableLookup implements AuthorizableLookup
{
             throw new ResourceNotFoundException("Unrecognized resource: " + resource);
         }
 
-        // if this is a policy resource, there should be another resource type
-        if (ResourceType.Policy.equals(resourceType)) {
-            final ResourceType primaryResourceType = resourceType;
-
-            // get the resource type
-            resource = StringUtils.substringAfter(resource, resourceType.getValue());
-
-            for (ResourceType type : ResourceType.values()) {
-                if (resource.equals(type.getValue()) || resource.startsWith(type.getValue()
+ "/")) {
-                    resourceType = type;
-                }
-            }
-
-            if (resourceType == null) {
-                throw new ResourceNotFoundException("Unrecognized resource: " + resource);
-            }
-
-            return new AccessPolicyAuthorizable(getAccessPolicy(resourceType, resource));
-        } else {
-            return getAccessPolicy(resourceType, resource);
-        }
+        return getAuthorizableByResource(resourceType, resource);
     }
 
-    private Authorizable getAccessPolicy(final ResourceType resourceType, final String resource)
{
-        final String slashComponentId = StringUtils.substringAfter(resource, resourceType.getValue());
-        if (slashComponentId.startsWith("/")) {
-            return getAccessPolicyByResource(resourceType, slashComponentId.substring(1));
+    private Authorizable getAuthorizableByResource(final ResourceType resourceType, final
String resource) {
+        final String childResourceId = StringUtils.substringAfter(resource, resourceType.getValue());
+        if (childResourceId.startsWith("/")) {
+            return getAuthorizableByChildResource(resourceType, childResourceId.substring(1));
         } else {
-            return getAccessPolicyByResource(resourceType);
+            return getAuthorizableByResource(resourceType);
         }
     }
 
-    private Authorizable getAccessPolicyByResource(final ResourceType resourceType, final
String childResourceId) {
-        Authorizable authorizable = null;
-        switch (resourceType) {
-            case Bucket:
-                authorizable = getBucketAuthorizable(childResourceId);
-        }
-
-        if (authorizable == null) {
-            throw new IllegalArgumentException("An unexpected type of resource in this policy
" + resourceType.getValue());
-        }
-
-        return authorizable;
-    }
-
-    private Authorizable getAccessPolicyByResource(final ResourceType resourceType) {
+    private Authorizable getAuthorizableByResource(final ResourceType resourceType) {
         Authorizable authorizable = null;
         switch (resourceType) {
 
@@ -209,17 +165,7 @@ public class StandardAuthorizableLookup implements AuthorizableLookup
{
                 authorizable = getPoliciesAuthorizable();
                 break;
             case Resource:
-                authorizable = new Authorizable() {
-                    @Override
-                    public Authorizable getParentAuthorizable() {
-                        return null;
-                    }
-
-                    @Override
-                    public Resource getResource() {
-                        return ResourceFactory.getResourceResource();
-                    }
-                };
+                authorizable = getResourcesAuthorizable();
                 break;
             case Tenant:
                 authorizable = getTenantsAuthorizable();
@@ -235,4 +181,17 @@ public class StandardAuthorizableLookup implements AuthorizableLookup
{
         return authorizable;
     }
 
+    private Authorizable getAuthorizableByChildResource(final ResourceType baseResourceType,
final String childResourceId) {
+        Authorizable authorizable;
+        switch (baseResourceType) {
+            case Bucket:
+                authorizable = getBucketAuthorizable(childResourceId);
+                break;
+            default:
+                throw new IllegalArgumentException("Unexpected lookup for child resource
authorizable for base resource type " + baseResourceType.getValue());
+        }
+
+        return authorizable;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/AccessPolicyAuthorizable.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/AccessPolicyAuthorizable.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/AccessPolicyAuthorizable.java
deleted file mode 100644
index de28565..0000000
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/AccessPolicyAuthorizable.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.nifi.registry.security.authorization.resource;
-
-import org.apache.nifi.registry.security.authorization.exception.AccessDeniedException;
-import org.apache.nifi.registry.security.authorization.AuthorizationResult;
-import org.apache.nifi.registry.security.authorization.AuthorizationResult.Result;
-import org.apache.nifi.registry.security.authorization.Authorizer;
-import org.apache.nifi.registry.security.authorization.RequestAction;
-import org.apache.nifi.registry.security.authorization.Resource;
-import org.apache.nifi.registry.security.authorization.user.NiFiUser;
-
-import java.util.Map;
-
-/**
- * Authorizable for policies of an Authorizable.
- */
-public class AccessPolicyAuthorizable implements Authorizable, EnforcePolicyPermissionsThroughBaseResource
{
-
-    private static final Authorizable POLICIES_AUTHORIZABLE = new Authorizable() {
-        @Override
-        public Authorizable getParentAuthorizable() {
-            return null;
-        }
-
-        @Override
-        public Resource getResource() {
-            return ResourceFactory.getPoliciesResource();
-        }
-    };
-
-    final Authorizable authorizable;
-
-    public AccessPolicyAuthorizable(Authorizable authorizable) {
-        this.authorizable = authorizable;
-    }
-
-    @Override
-    public Authorizable getBaseAuthorizable() {
-        return authorizable;
-    }
-
-    @Override
-    public Authorizable getParentAuthorizable() {
-        final Authorizable effectiveAuthorizable = getEffectiveAuthorizable();
-        if (effectiveAuthorizable.getParentAuthorizable() == null) {
-            return POLICIES_AUTHORIZABLE;
-        } else {
-            return new AccessPolicyAuthorizable(effectiveAuthorizable.getParentAuthorizable());
-        }
-    }
-
-    @Override
-    public Resource getResource() {
-        return ResourceFactory.getPolicyResource(getEffectiveAuthorizable().getResource());
-    }
-
-    private Authorizable getEffectiveAuthorizable() {
-        // possibly consider the base resource if the authorizable uses it to enforce policy
permissions
-        if (authorizable instanceof EnforcePolicyPermissionsThroughBaseResource) {
-            final Authorizable baseAuthorizable = ((EnforcePolicyPermissionsThroughBaseResource)
authorizable).getBaseAuthorizable();
-
-            // if the base authorizable is for a policy, we don't want to use the base otherwise
it would keep unwinding and would eventually
-            // evaluate to the policy of the component and not the policy of the policies
for the component
-            if (baseAuthorizable instanceof AccessPolicyAuthorizable) {
-                return authorizable;
-            } else {
-                return baseAuthorizable;
-            }
-        } else {
-            return authorizable;
-        }
-    }
-
-    @Override
-    public AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action,
NiFiUser user, Map<String, String> resourceContext) {
-        if (user == null) {
-            throw new AccessDeniedException("Unknown user.");
-        }
-
-        final AuthorizationResult resourceResult = Authorizable.super.checkAuthorization(authorizer,
action, user, resourceContext);
-
-        // if we're denied from the resource try inheriting
-        if (Result.Denied.equals(resourceResult.getResult())) {
-            return getParentAuthorizable().checkAuthorization(authorizer, action, user, resourceContext);
-        } else {
-            return resourceResult;
-        }
-    }
-
-    @Override
-    public void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String,
String> resourceContext) throws AccessDeniedException {
-        if (user == null) {
-            throw new AccessDeniedException("Unknown user.");
-        }
-
-        try {
-            Authorizable.super.authorize(authorizer, action, user, resourceContext);
-        } catch (final AccessDeniedException resourceDenied) {
-            // if we're denied from the resource try inheriting
-            try {
-                getParentAuthorizable().authorize(authorizer, action, user, resourceContext);
-            } catch (final AccessDeniedException policiesDenied) {
-                throw resourceDenied;
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/EnforcePolicyPermissionsThroughBaseResource.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/EnforcePolicyPermissionsThroughBaseResource.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/EnforcePolicyPermissionsThroughBaseResource.java
deleted file mode 100644
index 90fc143..0000000
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/EnforcePolicyPermissionsThroughBaseResource.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.nifi.registry.security.authorization.resource;
-
-/**
- * Defers permissions on policies to the policies of the base authorizable. Required because
we don't
- * want to change the enforcement of the policies on the authorizable. For example...
- *
- * if a user has permissions to /policies/input-ports/1234 then they have permissions to
the following
- *
- * - the policy for /buckets/1234                    -> /policies/buckets/1234
- * - the policy for /policies/buckets/1234           -> /policies/policies/buckets/1234
- */
-public interface EnforcePolicyPermissionsThroughBaseResource {
-
-    /**
-     * Returns the base authorizable. Cannot be null.
-     *
-     * @return base authorizable
-     */
-    Authorizable getBaseAuthorizable();
-}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/InheritingAuthorizable.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/InheritingAuthorizable.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/InheritingAuthorizable.java
new file mode 100644
index 0000000..b029229
--- /dev/null
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/InheritingAuthorizable.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nifi.registry.security.authorization.resource;
+
+import org.apache.nifi.registry.security.authorization.AuthorizationResult;
+import org.apache.nifi.registry.security.authorization.AuthorizationResult.Result;
+import org.apache.nifi.registry.security.authorization.Authorizer;
+import org.apache.nifi.registry.security.authorization.RequestAction;
+import org.apache.nifi.registry.security.authorization.exception.AccessDeniedException;
+import org.apache.nifi.registry.security.authorization.user.NiFiUser;
+
+import java.util.Map;
+
+public interface InheritingAuthorizable extends Authorizable {
+
+    /**
+     * Returns the result of an authorization request for the specified user for the specified
action on the specified
+     * resource. This method does not imply the user is directly attempting to access the
specified resource. If the user is
+     * attempting a direct access use Authorizable.authorize().
+     *
+     * @param authorizer authorizer
+     * @param action action
+     * @param user user
+     * @return is authorized
+     */
+    default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action,
NiFiUser user, Map<String, String> resourceContext) {
+        if (user == null) {
+            throw new AccessDeniedException("Unknown user.");
+        }
+
+        final AuthorizationResult resourceResult = Authorizable.super.checkAuthorization(authorizer,
action, user, resourceContext);
+
+        // if we're denied from the resource try inheriting
+        if (Result.Denied.equals(resourceResult.getResult()) && getParentAuthorizable()
!= null) {
+            return getParentAuthorizable().checkAuthorization(authorizer, action, user, resourceContext);
+        } else {
+            return resourceResult;
+        }
+    }
+
+    /**
+     * Authorizes the current user for the specified action on the specified resource. If
the current user is
+     * not in the access policy for the specified resource, the parent authorizable resource
will be checked, recursively
+     *
+     * @param authorizer authorizer
+     * @param action action
+     * @param user user
+     * @param resourceContext resource context
+     */
+    default void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String,
String> resourceContext) throws AccessDeniedException {
+        if (user == null) {
+            throw new AccessDeniedException("Unknown user.");
+        }
+
+        try {
+            Authorizable.super.authorize(authorizer, action, user, resourceContext);
+        } catch (final AccessDeniedException resourceDenied) {
+            // if we're denied from the resource try inheriting
+            try {
+                if (getParentAuthorizable() != null) {
+                    getParentAuthorizable().authorize(authorizer, action, user, resourceContext);
+                } else {
+                    throw resourceDenied;
+                }
+            } catch (final AccessDeniedException policiesDenied) {
+                throw resourceDenied;
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/ResourceFactory.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/ResourceFactory.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/ResourceFactory.java
index 52c91c5..7882708 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/ResourceFactory.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/resource/ResourceFactory.java
@@ -235,12 +235,6 @@ public final class ResourceFactory {
                     case Bucket:
                         safeDescription.append("Bucket");
                         break;
-                    case Policy:
-                        safeDescription.append("Policy");
-                        break;
-                    case Tenant:
-                        safeDescription.append("Tenant");
-                        break;
                     default:
                         safeDescription.append("Unknown resource type");
                         break;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
index 6c380b1..3bb29fb 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
@@ -466,7 +466,7 @@ public class AuthorizationService {
             resources.add(ResourceFactory.getBucketsResource());
             // add all buckets
             for (final Bucket bucket : registryService.getBuckets()) {
-                resources.add(ResourceFactory.getChildResource(ResourceType.Bucket, bucket.getIdentifier(),
bucket.getName()));
+                resources.add(ResourceFactory.getBucketResource(bucket.getIdentifier(), bucket.getName()));
             }
         }
 

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/AccessPolicyResource.java
----------------------------------------------------------------------
diff --git a/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/AccessPolicyResource.java
b/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/AccessPolicyResource.java
index 84cc555..2c96d70 100644
--- a/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/AccessPolicyResource.java
+++ b/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/AccessPolicyResource.java
@@ -16,7 +16,6 @@
  */
 package org.apache.nifi.registry.web.api;
 
-
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -71,8 +70,6 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
         super(authorizer, authorizationService);
     }
 
-    // TODO - Verify that access control is done by the resource the policy is for, not the
/policies resource itself.
-
     /**
      * Create a new access policy.
      *
@@ -110,7 +107,7 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
         }
         RequestAction.valueOfValue(requestAccessPolicy.getAction());
 
-        authorizeAccessToResource(RequestAction.WRITE, requestAccessPolicy.getResource());
+        authorizeAccess(RequestAction.WRITE);
 
         AccessPolicy createdPolicy = authorizationService.createAccessPolicy(requestAccessPolicy);
 
@@ -172,7 +169,7 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
         verifyAuthorizerIsManaged();
 
         final AccessPolicy accessPolicy = authorizationService.getAccessPolicy(identifier);
-        authorizeAccessToResource(RequestAction.READ, accessPolicy.getResource());
+        authorizeAccess(RequestAction.READ);
 
         return generateOkResponse(accessPolicy).build();
     }
@@ -218,7 +215,7 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
         final RequestAction requestAction = RequestAction.valueOfValue(action);
         final String resource = "/" + rawResource;
 
-        authorizeAccessToResource(RequestAction.READ, resource);
+        authorizeAccess(RequestAction.READ);
 
         AccessPolicy accessPolicy = authorizationService.getAccessPolicy(resource, requestAction);
         return generateOkResponse(accessPolicy).build();
@@ -266,7 +263,7 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
                     + "policy id of the requested resource (%s).", requestAccessPolicy.getIdentifier(),
identifier));
         }
 
-        authorizeAccessToPolicy(RequestAction.WRITE, identifier);
+        authorizeAccess(RequestAction.WRITE);
 
         AccessPolicy createdPolicy = authorizationService.updateAccessPolicy(requestAccessPolicy);
 
@@ -302,7 +299,7 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
             final String identifier) {
 
         verifyAuthorizerSupportsConfigurablePolicies();
-        authorizeAccessToPolicy(RequestAction.DELETE, identifier);
+        authorizeAccess(RequestAction.DELETE);
         AccessPolicy deletedPolicy = authorizationService.deleteAccessPolicy(identifier);
         return generateOkResponse(deletedPolicy).build();
     }
@@ -328,18 +325,6 @@ public class AccessPolicyResource extends AuthorizableApplicationResource
{
         });
     }
 
-    private void authorizeAccessToPolicy(RequestAction actionType, String accessPolicyIdentifier)
{
-        AccessPolicy accessPolicy = authorizationService.getAccessPolicy(accessPolicyIdentifier);
-        authorizeAccessToResource(actionType, accessPolicy.getResource());
-    }
-
-    private void authorizeAccessToResource(RequestAction actionType, String resource) {
-        authorizationService.authorizeAccess(lookup -> {
-            final Authorizable accessPolicy = lookup.getAccessPolicyByResource(resource);
-            accessPolicy.authorize(authorizer, actionType, NiFiUserUtils.getNiFiUser());
-        });
-    }
-
     private String generateAccessPolicyUri(final AccessPolicySummary accessPolicy) {
         return generateResourceUri("policies", accessPolicy.getIdentifier());
     }

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketResource.java
----------------------------------------------------------------------
diff --git a/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketResource.java
b/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketResource.java
index 82bb172..1ee2180 100644
--- a/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketResource.java
+++ b/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketResource.java
@@ -116,7 +116,8 @@ public class BucketResource extends AuthorizableApplicationResource {
     @Produces(MediaType.APPLICATION_JSON)
     @ApiOperation(
             value = "Gets all buckets",
-            notes = "The returned list will include only buckets for which the caller is
authorized.",
+            notes = "The returned list will include only buckets for which the user is authorized."
+
+                    "If the user is not authorized for any buckets, this returns an empty
list.",
             response = Bucket.class,
             responseContainer = "List"
     )
@@ -128,6 +129,15 @@ public class BucketResource extends AuthorizableApplicationResource {
             @ApiParam(value = SortParameter.API_PARAM_DESCRIPTION, format = "field:order",
allowMultiple = true, example = "name:ASC")
             @QueryParam("sort")
             final List<String> sortParameters) {
+
+        // Note: We don't explicitly check for access to (READ, /buckets) because
+        // a user might have access to individual buckets without top-level access.
+        // For example, a user that has (READ, /buckets/bucket-id-1) but not access
+        // to /buckets should not get a 403 error returned from this endpoint.
+        // This has the side effect that a user with no access to any buckets
+        // gets an empty array returned from this endpoint instead of 403 as one
+        // might expect.
+
         final Set<String> authorizedBucketIds = getAuthorizedBucketIds(RequestAction.READ);
 
         if (authorizedBucketIds == null || authorizedBucketIds.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/a8786a80/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
----------------------------------------------------------------------
diff --git a/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
b/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
index 7cd9138..416e50d 100644
--- a/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
+++ b/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
@@ -427,6 +427,20 @@ public class SecureLdapIT extends IntegrationTestBase {
         assertEquals(201, adminGrantsReadAccessResponse.getStatus());
 
 
+        // When: nifiadmin tries to list all buckets
+        final Bucket[] adminBuckets = client
+                .target(createURL("buckets"))
+                .request()
+                .header("Authorization", "Bearer " + adminAuthToken)
+                .get(Bucket[].class);
+
+        // Then: the full list is returned (verifies that per-bucket access policies are
additive to base /buckets policy)
+        assertNotNull(adminBuckets);
+        assertEquals(1, adminBuckets.length);
+        assertEquals(createdBucket.getIdentifier(), adminBuckets[0].getIdentifier());
+        assertEquals(new Permissions().withCanRead(true).withCanWrite(true).withCanDelete(true),
adminBuckets[0].getPermissions());
+
+
         // When: user nobel re-queries /buckets
         final Bucket[] buckets2 = client
                 .target(createURL("buckets"))


Mime
View raw message