You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jw...@apache.org on 2017/01/24 21:28:18 UTC

nifi git commit: NIFI-3251: Delete requires WRITE perms on parent - Requiring WRITE permissions to the parent resource when attempting to remove a component. - Updating expired certificates in the REST API integration tests.

Repository: nifi
Updated Branches:
  refs/heads/master ddda60262 -> 7340078de


NIFI-3251: Delete requires WRITE perms on parent
- Requiring WRITE permissions to the parent resource when attempting to remove a component.
- Updating expired certificates in the REST API integration tests.

This closes #1399.

Signed-off-by: James Wing <jv...@gmail.com>


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

Branch: refs/heads/master
Commit: 7340078de2229a4fc094cd2185117a7772389ec0
Parents: ddda602
Author: Matt Gilman <ma...@gmail.com>
Authored: Thu Jan 5 16:21:50 2017 -0500
Committer: James Wing <jv...@gmail.com>
Committed: Tue Jan 24 13:24:29 2017 -0800

----------------------------------------------------------------------
 .../nifi/connectable/StandardConnection.java    |   2 +-
 .../nifi/authorization/SnippetAuthorizable.java |   7 ++++
 .../StandardAuthorizableLookup.java             |   5 +++
 .../nifi/web/api/AccessPolicyResource.java      |   8 ++++-
 .../apache/nifi/web/api/ConnectionResource.java |   6 ++++
 .../nifi/web/api/ControllerServiceResource.java |   7 ++++
 .../org/apache/nifi/web/api/FunnelResource.java |   8 ++++-
 .../apache/nifi/web/api/InputPortResource.java  |   8 ++++-
 .../org/apache/nifi/web/api/LabelResource.java  |   8 ++++-
 .../apache/nifi/web/api/OutputPortResource.java |   8 ++++-
 .../nifi/web/api/ProcessGroupResource.java      |  10 +++++-
 .../apache/nifi/web/api/ProcessorResource.java  |   6 ++++
 .../web/api/RemoteProcessGroupResource.java     |   8 ++++-
 .../nifi/web/api/ReportingTaskResource.java     |   6 ++++
 .../apache/nifi/web/api/SnippetResource.java    |   6 +++-
 .../apache/nifi/web/api/TemplateResource.java   |   8 ++++-
 .../util/NiFiFlowTestAuthorizer.java            |   2 +-
 .../integration/util/NiFiTestAuthorizer.java    |   2 +-
 .../resources/access-control/localhost-ks.jks   | Bin 3512 -> 3052 bytes
 .../resources/access-control/localhost-ts.jks   | Bin 1816 -> 911 bytes
 .../main/webapp/js/nf/canvas/nf-canvas-utils.js |   5 +++
 .../js/nf/canvas/nf-controller-services.js      |  34 +++++++++++++++++--
 .../src/main/webapp/js/nf/canvas/nf-settings.js |   2 +-
 23 files changed, 141 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
index ddb4523..8b81c81 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
@@ -110,7 +110,7 @@ public final class StandardConnection implements Connection {
 
     @Override
     public Authorizable getParentAuthorizable() {
-        return null;
+        return getProcessGroup();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/SnippetAuthorizable.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/SnippetAuthorizable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/SnippetAuthorizable.java
index 5503f44..e28bf74 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/SnippetAuthorizable.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/SnippetAuthorizable.java
@@ -25,6 +25,13 @@ import java.util.Set;
  */
 public interface SnippetAuthorizable {
     /**
+     * The authorizable for the parent process group of this snippet.
+     *
+     * @return authorizable for parent process group of this snippet
+     */
+    Authorizable getParentProcessGroup();
+
+    /**
      * The authorizables for selected processors. Non null
      *
      * @return processors

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
index 18af600..28092cd 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
@@ -330,6 +330,11 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
 
         return new SnippetAuthorizable() {
             @Override
+            public Authorizable getParentProcessGroup() {
+                return processGroup;
+            }
+
+            @Override
             public Set<ConfigurableComponentAuthorizable> getSelectedProcessors() {
                 return processGroup.getProcessors().stream()
                         .filter(processor -> snippet.getProcessors().containsKey(processor.getIdentifier()))

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java
index 9875df4..999c832 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java
@@ -422,7 +422,8 @@ public class AccessPolicyResource extends ApplicationResource {
             value = "Deletes an access policy",
             response = AccessPolicyEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /policies/{resource}", type = "")
+                    @Authorization(value = "Write - /policies/{resource}", type = ""),
+                    @Authorization(value = "Write - Policy of the parent resource - /policies/{resource}", type = "")
             }
     )
     @ApiResponses(
@@ -472,7 +473,12 @@ public class AccessPolicyResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final Authorizable accessPolicy = lookup.getAccessPolicyById(id);
+
+                    // ensure write permission to the access policy
                     accessPolicy.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the policy for the parent process group
+                    accessPolicy.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 null,
                 (revision, accessPolicyEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
index 4527e87..cfd6585 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
@@ -295,6 +295,7 @@ public class ConnectionResource extends ApplicationResource {
             response = ConnectionEntity.class,
             authorizations = {
                     @Authorization(value = "Write Source - /{component-type}/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = ""),
                     @Authorization(value = "Write Destination - /{component-type}/{uuid}", type = "")
             }
     )
@@ -344,7 +345,12 @@ public class ConnectionResource extends ApplicationResource {
                 lookup -> {
                     // verifies write access to the source and destination
                     final Authorizable authorizable = lookup.getConnection(id).getAuthorizable();
+
+                    // ensure write permission to the connection
                     authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    authorizable.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteConnection(id),
                 (revision, connectionEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
index 9544ff8..26ebd2b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
@@ -661,6 +661,8 @@ public class ControllerServiceResource extends ApplicationResource {
             response = ControllerServiceEntity.class,
             authorizations = {
                     @Authorization(value = "Write - /controller-services/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group if scoped by Process Group - /process-groups/{uuid}", type = ""),
+                    @Authorization(value = "Write - Controller if scoped by Controller - /controller", type = ""),
                     @Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
             }
     )
@@ -706,8 +708,13 @@ public class ControllerServiceResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final ConfigurableComponentAuthorizable controllerService = lookup.getControllerService(id);
+
+                    // ensure write permission to the controller service
                     controllerService.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
 
+                    // ensure write permission to the parent process group
+                    controllerService.getAuthorizable().getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
                     // verify any referenced services
                     AuthorizeControllerServiceReference.authorizeControllerServiceReferences(controllerService, authorizer, lookup, false);
                 },

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java
index dcb35fa..811fc61 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java
@@ -245,7 +245,8 @@ public class FunnelResource extends ApplicationResource {
             value = "Deletes a funnel",
             response = FunnelEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /funnels/{uuid}", type = "")
+                    @Authorization(value = "Write - /funnels/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -290,7 +291,12 @@ public class FunnelResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final Authorizable funnel = lookup.getFunnel(id);
+
+                    // ensure write permission to the funnel
                     funnel.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    funnel.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteFunnel(id),
                 (revision, funnelEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
index 65e871e..a5e8169 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
@@ -244,7 +244,8 @@ public class InputPortResource extends ApplicationResource {
             value = "Deletes an input port",
             response = PortEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /input-ports/{uuid}", type = "")
+                    @Authorization(value = "Write - /input-ports/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -289,7 +290,12 @@ public class InputPortResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final Authorizable inputPort = lookup.getInputPort(id);
+
+                    // ensure write permission to the input port
                     inputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    inputPort.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteInputPort(id),
                 (revision, portEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java
index 34f62f5..fa67657 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java
@@ -244,7 +244,8 @@ public class LabelResource extends ApplicationResource {
             value = "Deletes a label",
             response = LabelEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /labels/{uuid}", type = "")
+                    @Authorization(value = "Write - /labels/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -289,7 +290,12 @@ public class LabelResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final Authorizable label = lookup.getLabel(id);
+
+                    // ensure write permission to the label
                     label.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    label.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 null,
                 (revision, labelEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
index 442473c..c6cfac6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
@@ -244,7 +244,8 @@ public class OutputPortResource extends ApplicationResource {
             value = "Deletes an output port",
             response = PortEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /output-ports/{uuid}", type = "")
+                    @Authorization(value = "Write - /output-ports/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -289,7 +290,12 @@ public class OutputPortResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final Authorizable outputPort = lookup.getOutputPort(id);
+
+                    // ensure write permission to the output port
                     outputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    outputPort.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteOutputPort(id),
                 (revision, portEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index 75bdc3e..58c9e30 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -339,6 +339,8 @@ public class ProcessGroupResource extends ApplicationResource {
             response = ProcessGroupEntity.class,
             authorizations = {
                     @Authorization(value = "Write - /process-groups/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = ""),
+                    @Authorization(value = "Read - any referenced Controller Services by any encapsulated components - /controller-services/{uuid}", type = ""),
                     @Authorization(value = "Write - /{component-type}/{uuid} - For all encapsulated components", type = "")
             }
     )
@@ -384,12 +386,18 @@ public class ProcessGroupResource extends ApplicationResource {
                 requestProcessGroupEntity,
                 requestRevision,
                 lookup -> {
-                    final NiFiUser user = NiFiUserUtils.getNiFiUser();
                     final ProcessGroupAuthorizable processGroupAuthorizable = lookup.getProcessGroup(id);
 
                     // ensure write to this process group and all encapsulated components including templates and controller services. additionally, ensure
                     // read to any referenced services by encapsulated components
                     authorizeProcessGroup(processGroupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, true, true, false);
+
+                    // ensure write permission to the parent process group, if applicable... if this is the root group the
+                    // request will fail later but still need to handle authorization here
+                    final Authorizable parentAuthorizable = processGroupAuthorizable.getAuthorizable().getParentAuthorizable();
+                    if (parentAuthorizable != null) {
+                        parentAuthorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+                    }
                 },
                 () -> serviceFacade.verifyDeleteProcessGroup(id),
                 (revision, processGroupEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index d17f7ac..1238e64 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -496,6 +496,7 @@ public class ProcessorResource extends ApplicationResource {
             response = ProcessorEntity.class,
             authorizations = {
                     @Authorization(value = "Write - /processors/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = ""),
                     @Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
             }
     )
@@ -540,8 +541,13 @@ public class ProcessorResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final ConfigurableComponentAuthorizable processor = lookup.getProcessor(id);
+
+                    // ensure write permission to the processor
                     processor.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
 
+                    // ensure write permission to the parent process group
+                    processor.getAuthorizable().getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
                     // verify any referenced services
                     AuthorizeControllerServiceReference.authorizeControllerServiceReferences(processor, authorizer, lookup, false);
                 },

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
index 3aef47e..0c192d7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
@@ -159,7 +159,8 @@ public class RemoteProcessGroupResource extends ApplicationResource {
             value = "Deletes a remote process group",
             response = RemoteProcessGroupEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /remote-process-groups/{uuid}", type = "")
+                    @Authorization(value = "Write - /remote-process-groups/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -204,7 +205,12 @@ public class RemoteProcessGroupResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final Authorizable remoteProcessGroup = lookup.getRemoteProcessGroup(id);
+
+                    // ensure write permission to the remote process group
                     remoteProcessGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    remoteProcessGroup.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteRemoteProcessGroup(id),
                 (revision, remoteProcessGroupEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
index 31ceb9f..39c75f9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
@@ -465,6 +465,7 @@ public class ReportingTaskResource extends ApplicationResource {
             response = ReportingTaskEntity.class,
             authorizations = {
                     @Authorization(value = "Write - /reporting-tasks/{uuid}", type = ""),
+                    @Authorization(value = "Write - /controller", type = ""),
                     @Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
             }
     )
@@ -510,8 +511,13 @@ public class ReportingTaskResource extends ApplicationResource {
                 requestRevision,
                 lookup -> {
                     final ConfigurableComponentAuthorizable reportingTask = lookup.getReportingTask(id);
+
+                    // ensure write permission to the reporting task
                     reportingTask.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
 
+                    // ensure write permission to the parent process group
+                    reportingTask.getAuthorizable().getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
                     // verify any referenced services
                     AuthorizeControllerServiceReference.authorizeControllerServiceReferences(reportingTask, authorizer, lookup, false);
                 },

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java
index f5fc624..0be7218 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java
@@ -301,7 +301,8 @@ public class SnippetResource extends ApplicationResource {
             value = "Deletes the components in a snippet and discards the snippet",
             response = SnippetEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /{component-type}/{uuid} - For each component in the Snippet and their descendant components", type = "")
+                    @Authorization(value = "Write - /{component-type}/{uuid} - For each component in the Snippet and their descendant components", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = ""),
             }
     )
     @ApiResponses(
@@ -338,6 +339,9 @@ public class SnippetResource extends ApplicationResource {
                     // ensure write permission to every component in the snippet excluding referenced services
                     final SnippetAuthorizable snippet = lookup.getSnippet(snippetId);
                     authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE, true, false);
+
+                    // ensure write permission to the parent process group
+                    snippet.getParentProcessGroup().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteSnippet(snippetId, requestRevisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())),
                 (revisions, entity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java
index 63a37a8..515ade6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java
@@ -165,7 +165,8 @@ public class TemplateResource extends ApplicationResource {
             value = "Deletes a template",
             response = TemplateEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /templates/{uuid}", type = "")
+                    @Authorization(value = "Write - /templates/{uuid}", type = ""),
+                    @Authorization(value = "Write - Parent Process Group - /process-groups/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -197,7 +198,12 @@ public class TemplateResource extends ApplicationResource {
                 requestTemplateEntity,
                 lookup -> {
                     final Authorizable template = lookup.getTemplate(id).getAuthorizable();
+
+                    // ensure write permission to the template
                     template.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // ensure write permission to the parent process group
+                    template.getParentAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 null,
                 (templateEntity) -> {

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiFlowTestAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiFlowTestAuthorizer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiFlowTestAuthorizer.java
index 07d6906..47f70ea 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiFlowTestAuthorizer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiFlowTestAuthorizer.java
@@ -33,7 +33,7 @@ public class NiFiFlowTestAuthorizer implements Authorizer {
 
     public static final String NO_POLICY_COMPONENT_NAME = "No policies";
 
-    public static final String PROXY_DN = "CN=localhost, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
+    public static final String PROXY_DN = "CN=localhost, OU=NIFI";
 
     public static final String NONE_USER_DN = "none@nifi";
     public static final String READ_USER_DN = "read@nifi";

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
index de55b83..c72d512 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
@@ -33,7 +33,7 @@ public class NiFiTestAuthorizer implements Authorizer {
 
     public static final String NO_POLICY_COMPONENT_NAME = "No policies";
 
-    public static final String PROXY_DN = "CN=localhost, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
+    public static final String PROXY_DN = "CN=localhost, OU=NIFI";
 
     public static final String NONE_USER_DN = "none@nifi";
     public static final String READ_USER_DN = "read@nifi";

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ks.jks
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ks.jks b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ks.jks
old mode 100755
new mode 100644
index df36197..44a3537
Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ks.jks and b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ks.jks differ

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ts.jks
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ts.jks b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ts.jks
old mode 100755
new mode 100644
index 7824378..3b6d1d0
Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ts.jks and b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/access-control/localhost-ts.jks differ

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
index e743d3d..05bf2af 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
@@ -953,6 +953,11 @@ nf.CanvasUtils = (function () {
                 return false;
             }
 
+            // ensure the user has write permissions to the current process group
+            if (nf.Canvas.canWrite() === false) {
+                return false;
+            }
+
             if (nf.CanvasUtils.canModify(selection) === false) {
                 return false;
             }

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
index 5010013..942df0e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
@@ -505,7 +505,37 @@ nf.ControllerServices = (function () {
         if (nf.Common.isDefinedAndNotNull(dataContext.component.parentGroupId)) {
             return dataContext.component.parentGroupId;
         } else {
-            return 'Controller'
+            return 'Controller';
+        }
+    };
+
+    /**
+     * Determines if the user has write permissions for the parent of the specified controller service.
+     *
+     * @param dataContext
+     * @returns {boolean} whether the user has write permissions for the parent of the controller service
+     */
+    var canWriteControllerServiceParent = function (dataContext) {
+        // we know the process group for this controller service is part
+        // of the current breadcrumb trail
+        var canWriteProcessGroupParent = function (processGroupId) {
+            var breadcrumbs = nf.ng.Bridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
+
+            var isAuthorized = false;
+            $.each(breadcrumbs, function (_, breadcrumbEntity) {
+                if (breadcrumbEntity.id === processGroupId) {
+                    isAuthorized = breadcrumbEntity.permissions.canWrite;
+                    return false;
+                }
+            });
+
+            return isAuthorized;
+        };
+
+        if (nf.Common.isDefinedAndNotNull(dataContext.component.parentGroupId)) {
+            return canWriteProcessGroupParent(dataContext.component.parentGroupId);
+        } else {
+            return nf.Common.canModifyController();
         }
     };
 
@@ -650,7 +680,7 @@ nf.ControllerServices = (function () {
                 }
             }
 
-            if (dataContext.permissions.canWrite) {
+            if (dataContext.permissions.canWrite && canWriteControllerServiceParent(dataContext)) {
                 markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-right: 3px;" ></div>';
             }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/7340078d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index 65f222d..0a19a7e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -754,7 +754,7 @@ nf.Settings = (function () {
                 }
             }
 
-            if (dataContext.permissions.canWrite) {
+            if (dataContext.permissions.canWrite && nf.Common.canModifyController()) {
                 markup += '<div title="Remove" class="pointer delete-reporting-task fa fa-trash" style="margin-top: 2px; margin-right: 3px;" ></div>';
             }