Repository: nifi
Updated Branches:
  refs/heads/master 2a9274704 -> 7d8dd2702


NIFI-2554: - Requiring READ permissions on the referenced controller service 
when creating/updating processors, controller services, and reporting tasks.
- Preventing client side selection of unauthorized controller services unless 
they were the previously configured value.

This closes #860.

Signed-off-by: Bryan Bende <[email protected]>


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

Branch: refs/heads/master
Commit: 7d8dd27027b42134d4825f3d5a5da6aedb962b1a
Parents: 2a92747
Author: Matt Gilman <[email protected]>
Authored: Mon Aug 15 11:49:05 2016 -0400
Committer: Bryan Bende <[email protected]>
Committed: Mon Aug 15 16:46:58 2016 -0400

----------------------------------------------------------------------
 .../nifi/authorization/AuthorizableLookup.java  |  36 ++++-
 .../AuthorizeControllerServiceReference.java    |  74 ++++++++++
 ...ServiceReferencingComponentAuthorizable.java |  48 +++++++
 .../StandardAuthorizableLookup.java             | 144 +++++++++++++++++--
 .../nifi/web/StandardNiFiServiceFacade.java     |  16 +--
 .../StandardNiFiWebConfigurationContext.java    |  38 +++--
 .../nifi/web/api/ApplicationResource.java       |   4 +-
 .../apache/nifi/web/api/ControllerResource.java |  46 ++++--
 .../nifi/web/api/ControllerServiceResource.java |  25 ++--
 .../nifi/web/api/ProcessGroupResource.java      |  56 +++++---
 .../apache/nifi/web/api/ProcessorResource.java  |  27 ++--
 .../nifi/web/api/ReportingTaskResource.java     |  23 +--
 .../nifi/web/controller/ControllerFacade.java   |  35 +++++
 .../webapp/js/jquery/combo/jquery.combo.css     |   4 +
 .../main/webapp/js/jquery/combo/jquery.combo.js |  26 +---
 .../propertytable/jquery.propertytable.js       |   1 +
 16 files changed, 489 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java
index 69104db..0cd0548 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java
@@ -34,7 +34,17 @@ public interface AuthorizableLookup {
      * @param id processor id
      * @return authorizable
      */
-    Authorizable getProcessor(String id);
+    ControllerServiceReferencingComponentAuthorizable getProcessor(String id);
+
+    /**
+     * Get the authorizable for this Processor. This will create a dummy 
instance of the
+     * processor. The intent of this method is to provide access to the 
PropertyDescriptors
+     * prior to the component being created.
+     *
+     * @param type processor type
+     * @return authorizable
+     */
+    ControllerServiceReferencingComponentAuthorizable 
getProcessorByType(String type);
 
     /**
      * Get the authorizable for querying Provenance.
@@ -130,7 +140,17 @@ public interface AuthorizableLookup {
      * @param id controller service id
      * @return authorizable
      */
-    Authorizable getControllerService(String id);
+    ControllerServiceReferencingComponentAuthorizable 
getControllerService(String id);
+
+    /**
+     * Get the authorizable for this Controller Service. This will create a 
dummy instance of the
+     * controller service. The intent of this method is to provide access to 
the PropertyDescriptors
+     * prior to the component being created.
+     *
+     * @param type processor type
+     * @return authorizable
+     */
+    ControllerServiceReferencingComponentAuthorizable 
getControllerServiceByType(String type);
 
     /**
      * Get the authorizable referencing component.
@@ -147,7 +167,17 @@ public interface AuthorizableLookup {
      * @param id reporting task id
      * @return authorizable
      */
-    Authorizable getReportingTask(String id);
+    ControllerServiceReferencingComponentAuthorizable getReportingTask(String 
id);
+
+    /**
+     * Get the authorizable for this Reporting Task. This will create a dummy 
instance of the
+     * reporting task. The intent of this method is to provide access to the 
PropertyDescriptors
+     * prior to the component being created.
+     *
+     * @param type processor type
+     * @return authorizable
+     */
+    ControllerServiceReferencingComponentAuthorizable 
getReportingTaskByType(String type);
 
     /**
      * Get the authorizable Template.

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeControllerServiceReference.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeControllerServiceReference.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeControllerServiceReference.java
new file mode 100644
index 0000000..8617135
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeControllerServiceReference.java
@@ -0,0 +1,74 @@
+/*
+ * 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.authorization;
+
+import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.authorization.user.NiFiUserUtils;
+import org.apache.nifi.components.PropertyDescriptor;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Authorizes references to Controller Services. Utilizes when Processors, 
Controller Services, and Reporting Tasks are created and updated.
+ */
+public final class AuthorizeControllerServiceReference {
+
+    /**
+     * Authorizes the proposed properties for the specified authorizable.
+     *
+     * @param proposedProperties proposed properties
+     * @param authorizable authorizable that may reference a controller service
+     * @param authorizer authorizer
+     * @param lookup lookup
+     */
+    public static void authorizeControllerServiceReferences(final Map<String, 
String> proposedProperties, final 
ControllerServiceReferencingComponentAuthorizable authorizable,
+                                                            final Authorizer 
authorizer, final AuthorizableLookup lookup) {
+
+        // only attempt to authorize if properties are changing
+        if (proposedProperties != null) {
+            final NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+            for (final Map.Entry<String, String> entry : 
proposedProperties.entrySet()) {
+                final String propertyName = entry.getKey();
+                final PropertyDescriptor propertyDescriptor = 
authorizable.getPropertyDescriptor(propertyName);
+
+                // if this descriptor identifies a controller service
+                if (propertyDescriptor.getControllerServiceDefinition() != 
null) {
+                    final String currentValue = 
authorizable.getValue(propertyDescriptor);
+                    final String proposedValue = entry.getValue();
+
+                    // if the value is changing
+                    if (!Objects.equals(currentValue, proposedValue)) {
+                        // ensure access to the old service
+                        if (currentValue != null) {
+                            final Authorizable currentServiceAuthorizable = 
lookup.getControllerService(currentValue).getAuthorizable();
+                            currentServiceAuthorizable.authorize(authorizer, 
RequestAction.READ, user);
+                        }
+
+                        // ensure access to the new service
+                        if (proposedValue != null) {
+                            final Authorizable newServiceAuthorizable = 
lookup.getControllerService(proposedValue).getAuthorizable();
+                            newServiceAuthorizable.authorize(authorizer, 
RequestAction.READ, user);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ControllerServiceReferencingComponentAuthorizable.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ControllerServiceReferencingComponentAuthorizable.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ControllerServiceReferencingComponentAuthorizable.java
new file mode 100644
index 0000000..abffc94
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ControllerServiceReferencingComponentAuthorizable.java
@@ -0,0 +1,48 @@
+/*
+ * 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.authorization;
+
+import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.components.PropertyDescriptor;
+
+/**
+ * Authorizable for a component that references a ControllerService.
+ */
+public interface ControllerServiceReferencingComponentAuthorizable {
+    /**
+     * Returns the base authorizable for this ControllerServiceReference. Non 
null
+     *
+     * @return authorizable
+     */
+    Authorizable getAuthorizable();
+
+    /**
+     * Returns the property descriptor for the specified property.
+     *
+     * @param propertyName property name
+     * @return property descriptor
+     */
+    PropertyDescriptor getPropertyDescriptor(String propertyName);
+
+    /**
+     * Returns the current value of the specified property.
+     *
+     * @param propertyDescriptor property descriptor
+     * @return value
+     */
+    String getValue(PropertyDescriptor propertyDescriptor);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/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 58e7966..5880808 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
@@ -24,9 +24,12 @@ import 
org.apache.nifi.authorization.resource.DataTransferAuthorizable;
 import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.resource.ResourceType;
 import org.apache.nifi.authorization.resource.TenantAuthorizable;
+import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.connectable.Connectable;
 import org.apache.nifi.connectable.Connection;
 import org.apache.nifi.controller.ConfiguredComponent;
+import org.apache.nifi.controller.ProcessorNode;
+import org.apache.nifi.controller.ReportingTaskNode;
 import org.apache.nifi.controller.Snippet;
 import org.apache.nifi.controller.service.ControllerServiceNode;
 import org.apache.nifi.controller.service.ControllerServiceReference;
@@ -115,8 +118,49 @@ class StandardAuthorizableLookup implements 
AuthorizableLookup {
     }
 
     @Override
-    public Authorizable getProcessor(final String id) {
-        return processorDAO.getProcessor(id);
+    public ControllerServiceReferencingComponentAuthorizable 
getProcessor(final String id) {
+        final ProcessorNode processorNode = processorDAO.getProcessor(id);
+        return new ControllerServiceReferencingComponentAuthorizable() {
+            @Override
+            public Authorizable getAuthorizable() {
+                return processorNode;
+            }
+
+            @Override
+            public String getValue(PropertyDescriptor propertyDescriptor) {
+                return processorNode.getProperty(propertyDescriptor);
+            }
+
+            @Override
+            public PropertyDescriptor getPropertyDescriptor(String 
propertyName) {
+                return processorNode.getPropertyDescriptor(propertyName);
+            }
+        };
+    }
+
+    @Override
+    public ControllerServiceReferencingComponentAuthorizable 
getProcessorByType(String type) {
+        try {
+            final ProcessorNode processorNode = 
controllerFacade.createTemporaryProcessor(type);
+            return new ControllerServiceReferencingComponentAuthorizable() {
+                @Override
+                public Authorizable getAuthorizable() {
+                    return processorNode;
+                }
+
+                @Override
+                public String getValue(PropertyDescriptor propertyDescriptor) {
+                    return processorNode.getProperty(propertyDescriptor);
+                }
+
+                @Override
+                public PropertyDescriptor getPropertyDescriptor(String 
propertyName) {
+                    return processorNode.getPropertyDescriptor(propertyName);
+                }
+            };
+        } catch (final Exception e) {
+            throw new AccessDeniedException("Unable to create processor to 
verify if it references any Controller Services.");
+        }
     }
 
     @Override
@@ -212,8 +256,49 @@ class StandardAuthorizableLookup implements 
AuthorizableLookup {
     }
 
     @Override
-    public Authorizable getControllerService(final String id) {
-        return controllerServiceDAO.getControllerService(id);
+    public ControllerServiceReferencingComponentAuthorizable 
getControllerService(final String id) {
+        final ControllerServiceNode controllerService = 
controllerServiceDAO.getControllerService(id);
+        return new ControllerServiceReferencingComponentAuthorizable() {
+            @Override
+            public Authorizable getAuthorizable() {
+                return controllerService;
+            }
+
+            @Override
+            public String getValue(PropertyDescriptor propertyDescriptor) {
+                return controllerService.getProperty(propertyDescriptor);
+            }
+
+            @Override
+            public PropertyDescriptor getPropertyDescriptor(String 
propertyName) {
+                return 
controllerService.getControllerServiceImplementation().getPropertyDescriptor(propertyName);
+            }
+        };
+    }
+
+    @Override
+    public ControllerServiceReferencingComponentAuthorizable 
getControllerServiceByType(String type) {
+        try {
+            final ControllerServiceNode controllerService = 
controllerFacade.createTemporaryControllerService(type);
+            return new ControllerServiceReferencingComponentAuthorizable() {
+                @Override
+                public Authorizable getAuthorizable() {
+                    return controllerService;
+                }
+
+                @Override
+                public String getValue(PropertyDescriptor propertyDescriptor) {
+                    return controllerService.getProperty(propertyDescriptor);
+                }
+
+                @Override
+                public PropertyDescriptor getPropertyDescriptor(String 
propertyName) {
+                    return 
controllerService.getControllerServiceImplementation().getPropertyDescriptor(propertyName);
+                }
+            };
+        } catch (final Exception e) {
+            throw new AccessDeniedException("Unable to create controller 
service to verify if it references any Controller Services.");
+        }
     }
 
     @Override
@@ -260,8 +345,49 @@ class StandardAuthorizableLookup implements 
AuthorizableLookup {
     }
 
     @Override
-    public Authorizable getReportingTask(final String id) {
-        return reportingTaskDAO.getReportingTask(id);
+    public ControllerServiceReferencingComponentAuthorizable 
getReportingTask(final String id) {
+        final ReportingTaskNode reportingTaskNode = 
reportingTaskDAO.getReportingTask(id);
+        return new ControllerServiceReferencingComponentAuthorizable() {
+            @Override
+            public Authorizable getAuthorizable() {
+                return reportingTaskNode;
+            }
+
+            @Override
+            public String getValue(PropertyDescriptor propertyDescriptor) {
+                return reportingTaskNode.getProperty(propertyDescriptor);
+            }
+
+            @Override
+            public PropertyDescriptor getPropertyDescriptor(String 
propertyName) {
+                return 
reportingTaskNode.getReportingTask().getPropertyDescriptor(propertyName);
+            }
+        };
+    }
+
+    @Override
+    public ControllerServiceReferencingComponentAuthorizable 
getReportingTaskByType(String type) {
+        try {
+            final ReportingTaskNode reportingTask = 
controllerFacade.createTemporaryReportingTask(type);
+            return new ControllerServiceReferencingComponentAuthorizable() {
+                @Override
+                public Authorizable getAuthorizable() {
+                    return reportingTask;
+                }
+
+                @Override
+                public String getValue(PropertyDescriptor propertyDescriptor) {
+                    return reportingTask.getProperty(propertyDescriptor);
+                }
+
+                @Override
+                public PropertyDescriptor getPropertyDescriptor(String 
propertyName) {
+                    return 
reportingTask.getReportingTask().getPropertyDescriptor(propertyName);
+                }
+            };
+        } catch (final Exception e) {
+            throw new AccessDeniedException("Unable to create reporting to 
verify if it references any Controller Services.");
+        }
     }
 
     @Override
@@ -357,7 +483,7 @@ class StandardAuthorizableLookup implements 
AuthorizableLookup {
         Authorizable authorizable = null;
         switch (resourceType) {
             case ControllerService:
-                authorizable = getControllerService(componentId);
+                authorizable = 
getControllerService(componentId).getAuthorizable();
                 break;
             case Funnel:
                 authorizable = getFunnel(componentId);
@@ -372,7 +498,7 @@ class StandardAuthorizableLookup implements 
AuthorizableLookup {
                 authorizable = getOutputPort(componentId);
                 break;
             case Processor:
-                authorizable = getProcessor(componentId);
+                authorizable = getProcessor(componentId).getAuthorizable();
                 break;
             case ProcessGroup:
                 authorizable = getProcessGroup(componentId).getAuthorizable();
@@ -381,7 +507,7 @@ class StandardAuthorizableLookup implements 
AuthorizableLookup {
                 authorizable = getRemoteProcessGroup(componentId);
                 break;
             case ReportingTask:
-                authorizable = getReportingTask(componentId);
+                authorizable = getReportingTask(componentId).getAuthorizable();
                 break;
             case Template:
                 authorizable = getTemplate(componentId);

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 34890ad..d336b51 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -2275,13 +2275,13 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         try {
             switch (type) {
                 case PROCESSOR:
-                    authorizable = authorizableLookup.getProcessor(sourceId);
+                    authorizable = 
authorizableLookup.getProcessor(sourceId).getAuthorizable();
                     break;
                 case REPORTING_TASK:
-                    authorizable = 
authorizableLookup.getReportingTask(sourceId);
+                    authorizable = 
authorizableLookup.getReportingTask(sourceId).getAuthorizable();
                     break;
                 case CONTROLLER_SERVICE:
-                    authorizable = 
authorizableLookup.getControllerService(sourceId);
+                    authorizable = 
authorizableLookup.getControllerService(sourceId).getAuthorizable();
                     break;
                 case FLOW_CONTROLLER:
                     authorizable = controllerFacade;
@@ -2465,7 +2465,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final List<Bulletin> authorizedControllerServiceBulletins = new 
ArrayList<>();
         for (final Bulletin bulletin : allControllerServiceBulletins) {
             try {
-                final Authorizable controllerServiceAuthorizable = 
authorizableLookup.getControllerService(bulletin.getSourceId());
+                final Authorizable controllerServiceAuthorizable = 
authorizableLookup.getControllerService(bulletin.getSourceId()).getAuthorizable();
                 if (controllerServiceAuthorizable.isAuthorized(authorizer, 
RequestAction.READ, user)) {
                     authorizedControllerServiceBulletins.add(bulletin);
                 }
@@ -2481,7 +2481,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final List<Bulletin> authorizedReportingTaskBulletins = new 
ArrayList<>();
         for (final Bulletin bulletin : allReportingTaskBulletins) {
             try {
-                final Authorizable reportingTaskAuthorizable = 
authorizableLookup.getReportingTask(bulletin.getSourceId());
+                final Authorizable reportingTaskAuthorizable = 
authorizableLookup.getReportingTask(bulletin.getSourceId()).getAuthorizable();
                 if (reportingTaskAuthorizable.isAuthorized(authorizer, 
RequestAction.READ, user)) {
                     authorizedReportingTaskBulletins.add(bulletin);
                 }
@@ -2957,13 +2957,13 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         try {
             switch (type) {
                 case Processor:
-                    authorizable = authorizableLookup.getProcessor(sourceId);
+                    authorizable = 
authorizableLookup.getProcessor(sourceId).getAuthorizable();
                     break;
                 case ReportingTask:
-                    authorizable = 
authorizableLookup.getReportingTask(sourceId);
+                    authorizable = 
authorizableLookup.getReportingTask(sourceId).getAuthorizable();
                     break;
                 case ControllerService:
-                    authorizable = 
authorizableLookup.getControllerService(sourceId);
+                    authorizable = 
authorizableLookup.getControllerService(sourceId).getAuthorizable();
                     break;
                 case Controller:
                     authorizable = controllerFacade;

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
index 6a931f9..8269d79 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
@@ -29,7 +29,9 @@ import org.apache.nifi.authorization.AccessDeniedException;
 import org.apache.nifi.authorization.AuthorizationRequest;
 import org.apache.nifi.authorization.AuthorizationResult;
 import org.apache.nifi.authorization.AuthorizationResult.Result;
+import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
 import org.apache.nifi.authorization.Authorizer;
+import 
org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.UserContextKeys;
 import org.apache.nifi.authorization.resource.Authorizable;
@@ -145,7 +147,7 @@ public class StandardNiFiWebConfigurationContext implements 
NiFiWebConfiguration
             case ProcessorConfiguration:
                 // authorize access
                 serviceFacade.authorizeAccess(lookup -> {
-                    final Authorizable authorizable = 
lookup.getProcessor(requestContext.getId());
+                    final Authorizable authorizable = 
lookup.getProcessor(requestContext.getId()).getAuthorizable();
                     authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
                 });
 
@@ -154,7 +156,7 @@ public class StandardNiFiWebConfigurationContext implements 
NiFiWebConfiguration
             case ControllerServiceConfiguration:
                 // authorize access
                 serviceFacade.authorizeAccess(lookup -> {
-                    final Authorizable authorizable = 
lookup.getControllerService(requestContext.getId());
+                    final Authorizable authorizable = 
lookup.getControllerService(requestContext.getId()).getAuthorizable();
                     authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
                 });
 
@@ -163,7 +165,7 @@ public class StandardNiFiWebConfigurationContext implements 
NiFiWebConfiguration
             case ReportingTaskConfiguration:
                 // authorize access
                 serviceFacade.authorizeAccess(lookup -> {
-                    final Authorizable authorizable = 
lookup.getReportingTask(requestContext.getId());
+                    final Authorizable authorizable = 
lookup.getReportingTask(requestContext.getId()).getAuthorizable();
                     authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
                 });
 
@@ -336,7 +338,7 @@ public class StandardNiFiWebConfigurationContext implements 
NiFiWebConfiguration
 
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable authorizable = lookup.getProcessor(id);
+                final Authorizable authorizable = 
lookup.getProcessor(id).getAuthorizable();
                 authorizable.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
             });
 
@@ -387,8 +389,12 @@ public class StandardNiFiWebConfigurationContext 
implements NiFiWebConfiguration
 
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable authorizable = lookup.getProcessor(id);
-                authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+                // authorize the processor
+                final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getProcessor(id);
+                authorizable.getAuthorizable().authorize(authorizer, 
RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                // authorize any referenced service
+                
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties,
 authorizable, authorizer, lookup);
             });
 
             final ProcessorDTO processor;
@@ -516,7 +522,7 @@ public class StandardNiFiWebConfigurationContext implements 
NiFiWebConfiguration
 
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable authorizable = 
lookup.getControllerService(id);
+                final Authorizable authorizable = 
lookup.getControllerService(id).getAuthorizable();
                 authorizable.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
             });
 
@@ -574,8 +580,12 @@ public class StandardNiFiWebConfigurationContext 
implements NiFiWebConfiguration
 
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable authorizable = 
lookup.getControllerService(id);
-                authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+                // authorize the controller service
+                final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getControllerService(id);
+                authorizable.getAuthorizable().authorize(authorizer, 
RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                // authorize any referenced service
+                
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties,
 authorizable, authorizer, lookup);
             });
 
             final ControllerServiceDTO controllerService;
@@ -677,7 +687,7 @@ public class StandardNiFiWebConfigurationContext implements 
NiFiWebConfiguration
 
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable authorizable = lookup.getReportingTask(id);
+                final Authorizable authorizable = 
lookup.getReportingTask(id).getAuthorizable();
                 authorizable.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
             });
 
@@ -735,8 +745,12 @@ public class StandardNiFiWebConfigurationContext 
implements NiFiWebConfiguration
 
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable authorizable = lookup.getReportingTask(id);
-                authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+                // authorize the reporting task
+                final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getReportingTask(id);
+                authorizable.getAuthorizable().authorize(authorizer, 
RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                // authorize any referenced service
+                
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties,
 authorizable, authorizer, lookup);
             });
 
             final ReportingTaskDTO reportingTask;

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.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/ApplicationResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
index aeffa89..880186d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
@@ -426,7 +426,7 @@ public abstract class ApplicationResource {
             
processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(authorize);
         });
         snippet.getRemoteProcessGroups().keySet().stream().map(id -> 
lookup.getRemoteProcessGroup(id)).forEach(authorize);
-        snippet.getProcessors().keySet().stream().map(id -> 
lookup.getProcessor(id)).forEach(authorize);
+        snippet.getProcessors().keySet().stream().map(id -> 
lookup.getProcessor(id).getAuthorizable()).forEach(authorize);
         snippet.getInputPorts().keySet().stream().map(id -> 
lookup.getInputPort(id)).forEach(authorize);
         snippet.getOutputPorts().keySet().stream().map(id -> 
lookup.getOutputPort(id)).forEach(authorize);
         snippet.getConnections().keySet().stream().map(id -> 
lookup.getConnection(id)).forEach(connAuth -> 
authorize.accept(connAuth.getAuthorizable()));
@@ -451,7 +451,7 @@ public abstract class ApplicationResource {
             
processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(authorize);
         });
         snippet.getRemoteProcessGroups().keySet().stream().map(id -> 
lookup.getRemoteProcessGroup(id)).forEach(authorize);
-        snippet.getProcessors().keySet().stream().map(id -> 
lookup.getProcessor(id)).forEach(authorize);
+        snippet.getProcessors().keySet().stream().map(id -> 
lookup.getProcessor(id).getAuthorizable()).forEach(authorize);
         snippet.getInputPorts().keySet().stream().map(id -> 
lookup.getInputPort(id)).forEach(authorize);
         snippet.getOutputPorts().keySet().stream().map(id -> 
lookup.getOutputPort(id)).forEach(authorize);
         snippet.getConnections().keySet().stream().map(id -> 
lookup.getConnection(id)).forEach(connAuth -> 
authorize.accept(connAuth.getAuthorizable()));

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.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/ControllerResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
index 4063a72..8971aed 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
@@ -28,7 +28,9 @@ import org.apache.nifi.authorization.AccessDeniedException;
 import org.apache.nifi.authorization.AuthorizationRequest;
 import org.apache.nifi.authorization.AuthorizationResult;
 import org.apache.nifi.authorization.AuthorizationResult.Result;
+import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
 import org.apache.nifi.authorization.Authorizer;
+import 
org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.UserContextKeys;
 import org.apache.nifi.authorization.resource.ResourceFactory;
@@ -39,7 +41,9 @@ import 
org.apache.nifi.web.IllegalClusterResourceRequestException;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.api.dto.ClusterDTO;
+import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.NodeDTO;
+import org.apache.nifi.web.api.dto.ReportingTaskDTO;
 import org.apache.nifi.web.api.entity.ClusterEntity;
 import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
@@ -230,7 +234,8 @@ public class ControllerResource extends ApplicationResource 
{
             value = "Creates a new reporting task",
             response = ReportingTaskEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /controller", type = "")
+                    @Authorization(value = "Write - /controller", type = ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -256,11 +261,12 @@ public class ControllerResource extends 
ApplicationResource {
             throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Reporting task.");
         }
 
-        if (reportingTaskEntity.getComponent().getId() != null) {
+        final ReportingTaskDTO requestReportingTask = 
reportingTaskEntity.getComponent();
+        if (requestReportingTask.getId() != null) {
             throw new IllegalArgumentException("Reporting task ID cannot be 
specified.");
         }
 
-        if (StringUtils.isBlank(reportingTaskEntity.getComponent().getType())) 
{
+        if (StringUtils.isBlank(requestReportingTask.getType())) {
             throw new IllegalArgumentException("The type of reporting task to 
create must be specified.");
         }
 
@@ -274,6 +280,11 @@ public class ControllerResource extends 
ApplicationResource {
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
                 authorizeController(RequestAction.WRITE);
+
+                if (requestReportingTask.getProperties() != null) {
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getReportingTaskByType(requestReportingTask.getType());
+                    
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTask.getProperties(),
 authorizable, authorizer, lookup);
+                }
             });
         }
         if (validationPhase) {
@@ -281,11 +292,11 @@ public class ControllerResource extends 
ApplicationResource {
         }
 
         // set the processor id as appropriate
-        reportingTaskEntity.getComponent().setId(generateUuid());
+        requestReportingTask.setId(generateUuid());
 
         // create the reporting task and generate the json
-        final Revision revision = getRevision(reportingTaskEntity, 
reportingTaskEntity.getComponent().getId());
-        final ReportingTaskEntity entity = 
serviceFacade.createReportingTask(revision, reportingTaskEntity.getComponent());
+        final Revision revision = getRevision(reportingTaskEntity, 
requestReportingTask.getId());
+        final ReportingTaskEntity entity = 
serviceFacade.createReportingTask(revision, requestReportingTask);
         
reportingTaskResource.populateRemainingReportingTaskEntityContent(entity);
 
         // build the response
@@ -311,7 +322,8 @@ public class ControllerResource extends ApplicationResource 
{
             value = "Creates a new controller service",
             response = ControllerServiceEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /controller", type = "")
+                    @Authorization(value = "Write - /controller", type = ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -337,11 +349,16 @@ public class ControllerResource extends 
ApplicationResource {
             throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Controller service.");
         }
 
-        if (controllerServiceEntity.getComponent().getId() != null) {
+        final ControllerServiceDTO requestControllerService = 
controllerServiceEntity.getComponent();
+        if (requestControllerService.getId() != null) {
             throw new IllegalArgumentException("Controller service ID cannot 
be specified.");
         }
 
-        if 
(StringUtils.isBlank(controllerServiceEntity.getComponent().getType())) {
+        if (requestControllerService.getParentGroupId() != null) {
+            throw new IllegalArgumentException("Parent process group ID cannot 
be specified.");
+        }
+
+        if (StringUtils.isBlank(requestControllerService.getType())) {
             throw new IllegalArgumentException("The type of controller service 
to create must be specified.");
         }
 
@@ -355,6 +372,11 @@ public class ControllerResource extends 
ApplicationResource {
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
                 authorizeController(RequestAction.WRITE);
+
+                if (requestControllerService.getProperties() != null) {
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = 
lookup.getControllerServiceByType(requestControllerService.getType());
+                    
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(),
 authorizable, authorizer, lookup);
+                }
             });
         }
         if (validationPhase) {
@@ -362,11 +384,11 @@ public class ControllerResource extends 
ApplicationResource {
         }
 
         // set the processor id as appropriate
-        controllerServiceEntity.getComponent().setId(generateUuid());
+        requestControllerService.setId(generateUuid());
 
         // create the controller service and generate the json
-        final Revision revision = getRevision(controllerServiceEntity, 
controllerServiceEntity.getComponent().getId());
-        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(revision, null, 
controllerServiceEntity.getComponent());
+        final Revision revision = getRevision(controllerServiceEntity, 
requestControllerService.getId());
+        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(revision, null, requestControllerService);
         
controllerServiceResource.populateRemainingControllerServiceEntityContent(entity);
 
         // build the response

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/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 89b441f..0b9434a 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
@@ -23,7 +23,9 @@ import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
 import org.apache.nifi.authorization.Authorizer;
+import 
org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
@@ -175,7 +177,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable controllerService = 
lookup.getControllerService(id);
+            final Authorizable controllerService = 
lookup.getControllerService(id).getAuthorizable();
             controllerService.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -236,7 +238,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable controllerService = 
lookup.getControllerService(id);
+            final Authorizable controllerService = 
lookup.getControllerService(id).getAuthorizable();
             controllerService.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -290,7 +292,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable controllerService = 
lookup.getControllerService(id);
+            final Authorizable controllerService = 
lookup.getControllerService(id).getAuthorizable();
             controllerService.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -348,7 +350,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
         if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable controllerService = 
lookup.getControllerService(id);
+                final Authorizable controllerService = 
lookup.getControllerService(id).getAuthorizable();
                 controllerService.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
             });
         }
@@ -406,7 +408,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable controllerService = 
lookup.getControllerService(id);
+            final Authorizable controllerService = 
lookup.getControllerService(id).getAuthorizable();
             controllerService.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -545,7 +547,8 @@ public class ControllerServiceResource extends 
ApplicationResource {
             value = "Updates a controller service",
             response = ControllerServiceEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - 
/controller-services/{uuid}", type = "")
+                    @Authorization(value = "Write - 
/controller-services/{uuid}", type = ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -594,8 +597,12 @@ public class ControllerServiceResource extends 
ApplicationResource {
                 serviceFacade,
                 revision,
                 lookup -> {
-                    Authorizable authorizable = 
lookup.getControllerService(id);
-                    authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+                    // authorize the service
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getControllerService(id);
+                    authorizable.getAuthorizable().authorize(authorizer, 
RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // authorize any referenced services
+                    
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerServiceDTO.getProperties(),
 authorizable, authorizer, lookup);
                 },
                 () -> 
serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO),
                 () -> {
@@ -668,7 +675,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
                 serviceFacade,
                 revision,
                 lookup -> {
-                    final Authorizable controllerService = 
lookup.getControllerService(id);
+                    final Authorizable controllerService = 
lookup.getControllerService(id).getAuthorizable();
                     controllerService.authorize(authorizer, 
RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteControllerService(id),

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/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 d9055c9..00fe7d2 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
@@ -26,7 +26,9 @@ import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.authorization.AuthorizableLookup;
+import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
 import org.apache.nifi.authorization.Authorizer;
+import 
org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
 import org.apache.nifi.authorization.ProcessGroupAuthorizable;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.resource.Authorizable;
@@ -38,7 +40,10 @@ import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.ResourceNotFoundException;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.api.dto.ConnectionDTO;
+import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
+import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
+import org.apache.nifi.web.api.dto.ProcessorDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
 import org.apache.nifi.web.api.dto.TemplateDTO;
 import org.apache.nifi.web.api.dto.flow.FlowDTO;
@@ -553,7 +558,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
             value = "Creates a new processor",
             response = ProcessorEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /process-groups/{uuid}", 
type = "")
+                    @Authorization(value = "Write - /process-groups/{uuid}", 
type = ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -585,19 +591,20 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Processor.");
         }
 
-        if (processorEntity.getComponent().getId() != null) {
+        final ProcessorDTO requestProcessor = processorEntity.getComponent();
+        if (requestProcessor.getId() != null) {
             throw new IllegalArgumentException("Processor ID cannot be 
specified.");
         }
 
-        if (StringUtils.isBlank(processorEntity.getComponent().getType())) {
+        if (StringUtils.isBlank(requestProcessor.getType())) {
             throw new IllegalArgumentException("The type of processor to 
create must be specified.");
         }
 
-        if (processorEntity.getComponent().getParentGroupId() != null && 
!groupId.equals(processorEntity.getComponent().getParentGroupId())) {
+        if (requestProcessor.getParentGroupId() != null && 
!groupId.equals(requestProcessor.getParentGroupId())) {
             throw new IllegalArgumentException(String.format("If specified, 
the parent process group id %s must be the same as specified in the URI %s",
-                    processorEntity.getComponent().getParentGroupId(), 
groupId));
+                    requestProcessor.getParentGroupId(), groupId));
         }
-        processorEntity.getComponent().setParentGroupId(groupId);
+        requestProcessor.setParentGroupId(groupId);
 
         if (isReplicateRequest()) {
             return replicate(HttpMethod.POST, processorEntity);
@@ -610,6 +617,12 @@ public class ProcessGroupResource extends 
ApplicationResource {
             serviceFacade.authorizeAccess(lookup -> {
                 final Authorizable processGroup = 
lookup.getProcessGroup(groupId).getAuthorizable();
                 processGroup.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+
+                final ProcessorConfigDTO config = requestProcessor.getConfig();
+                if (config != null && config.getProperties() != null) {
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getProcessorByType(requestProcessor.getType());
+                    
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(),
 authorizable, authorizer, lookup);
+                }
             });
         }
         if (validationPhase) {
@@ -617,11 +630,11 @@ public class ProcessGroupResource extends 
ApplicationResource {
         }
 
         // set the processor id as appropriate
-        processorEntity.getComponent().setId(generateUuid());
+        requestProcessor.setId(generateUuid());
 
         // create the new processor
-        final Revision revision = getRevision(processorEntity, 
processorEntity.getComponent().getId());
-        final ProcessorEntity entity = serviceFacade.createProcessor(revision, 
groupId, processorEntity.getComponent());
+        final Revision revision = getRevision(processorEntity, 
requestProcessor.getId());
+        final ProcessorEntity entity = serviceFacade.createProcessor(revision, 
groupId, requestProcessor);
         processorResource.populateRemainingProcessorEntityContent(entity);
 
         // generate a 201 created response
@@ -2074,7 +2087,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
             value = "Creates a new controller service",
             response = ControllerServiceEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /process-groups/{uuid}", 
type = "")
+                    @Authorization(value = "Write - /process-groups/{uuid}", 
type = ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -2105,19 +2119,20 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Controller service.");
         }
 
-        if (controllerServiceEntity.getComponent().getId() != null) {
+        final ControllerServiceDTO requestControllerService = 
controllerServiceEntity.getComponent();
+        if (requestControllerService.getId() != null) {
             throw new IllegalArgumentException("Controller service ID cannot 
be specified.");
         }
 
-        if 
(StringUtils.isBlank(controllerServiceEntity.getComponent().getType())) {
+        if (StringUtils.isBlank(requestControllerService.getType())) {
             throw new IllegalArgumentException("The type of controller service 
to create must be specified.");
         }
 
-        if (controllerServiceEntity.getComponent().getParentGroupId() != null 
&& !groupId.equals(controllerServiceEntity.getComponent().getParentGroupId())) {
+        if (requestControllerService.getParentGroupId() != null && 
!groupId.equals(requestControllerService.getParentGroupId())) {
             throw new IllegalArgumentException(String.format("If specified, 
the parent process group id %s must be the same as specified in the URI %s",
-                    controllerServiceEntity.getComponent().getParentGroupId(), 
groupId));
+                    requestControllerService.getParentGroupId(), groupId));
         }
-        controllerServiceEntity.getComponent().setParentGroupId(groupId);
+        requestControllerService.setParentGroupId(groupId);
 
         if (isReplicateRequest()) {
             return replicate(HttpMethod.POST, controllerServiceEntity);
@@ -2130,6 +2145,11 @@ public class ProcessGroupResource extends 
ApplicationResource {
             serviceFacade.authorizeAccess(lookup -> {
                 final Authorizable processGroup = 
lookup.getProcessGroup(groupId).getAuthorizable();
                 processGroup.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+
+                if (requestControllerService.getProperties() != null) {
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = 
lookup.getControllerServiceByType(requestControllerService.getType());
+                    
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(),
 authorizable, authorizer, lookup);
+                }
             });
         }
         if (validationPhase) {
@@ -2137,11 +2157,11 @@ public class ProcessGroupResource extends 
ApplicationResource {
         }
 
         // set the processor id as appropriate
-        controllerServiceEntity.getComponent().setId(generateUuid());
+        requestControllerService.setId(generateUuid());
 
         // create the controller service and generate the json
-        final Revision revision = getRevision(controllerServiceEntity, 
controllerServiceEntity.getComponent().getId());
-        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(revision, groupId, 
controllerServiceEntity.getComponent());
+        final Revision revision = getRevision(controllerServiceEntity, 
requestControllerService.getId());
+        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(revision, groupId, 
requestControllerService);
         
controllerServiceResource.populateRemainingControllerServiceEntityContent(entity);
 
         // build the response

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/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 fae20aa..246ba70 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
@@ -23,9 +23,12 @@ import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
 import org.apache.nifi.authorization.Authorizer;
+import 
org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
 import org.apache.nifi.ui.extension.UiExtension;
 import org.apache.nifi.ui.extension.UiExtensionMapping;
@@ -173,7 +176,7 @@ public class ProcessorResource extends ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable processor = lookup.getProcessor(id);
+            final Authorizable processor = 
lookup.getProcessor(id).getAuthorizable();
             processor.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -241,7 +244,7 @@ public class ProcessorResource extends ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable processor = lookup.getProcessor(id);
+            final Authorizable processor = 
lookup.getProcessor(id).getAuthorizable();
             processor.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -296,7 +299,7 @@ public class ProcessorResource extends ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable processor = lookup.getProcessor(id);
+            final Authorizable processor = 
lookup.getProcessor(id).getAuthorizable();
             processor.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -355,7 +358,7 @@ public class ProcessorResource extends ApplicationResource {
         if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable processor = lookup.getProcessor(id);
+                final Authorizable processor = 
lookup.getProcessor(id).getAuthorizable();
                 processor.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
             });
         }
@@ -391,7 +394,8 @@ public class ProcessorResource extends ApplicationResource {
             value = "Updates a processor",
             response = ProcessorEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /processors/{uuid}", type 
= "")
+                    @Authorization(value = "Write - /processors/{uuid}", type 
= ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -440,8 +444,15 @@ public class ProcessorResource extends ApplicationResource 
{
                 serviceFacade,
                 revision,
                 lookup -> {
-                    Authorizable authorizable = lookup.getProcessor(id);
-                    authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+                    final NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getProcessor(id);
+                    authorizable.getAuthorizable().authorize(authorizer, 
RequestAction.WRITE, user);
+
+                    final ProcessorConfigDTO config = 
requestProcessorDTO.getConfig();
+                    if (config != null) {
+                        
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(),
 authorizable, authorizer, lookup);
+                    }
                 },
                 () -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO),
                 () -> {
@@ -511,7 +522,7 @@ public class ProcessorResource extends ApplicationResource {
                 serviceFacade,
                 revision,
                 lookup -> {
-                    final Authorizable processor = lookup.getProcessor(id);
+                    final Authorizable processor = 
lookup.getProcessor(id).getAuthorizable();
                     processor.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteProcessor(id),

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/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 0920220..0c2ad68 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
@@ -23,7 +23,9 @@ import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
 import org.apache.nifi.authorization.Authorizer;
+import 
org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
@@ -162,7 +164,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable reportingTask = lookup.getReportingTask(id);
+            final Authorizable reportingTask = 
lookup.getReportingTask(id).getAuthorizable();
             reportingTask.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -223,7 +225,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable reportingTask = lookup.getReportingTask(id);
+            final Authorizable reportingTask = 
lookup.getReportingTask(id).getAuthorizable();
             reportingTask.authorize(authorizer, RequestAction.READ, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -277,7 +279,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
 
         // authorize access
         serviceFacade.authorizeAccess(lookup -> {
-            final Authorizable reportingTask = lookup.getReportingTask(id);
+            final Authorizable reportingTask = 
lookup.getReportingTask(id).getAuthorizable();
             reportingTask.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
         });
 
@@ -335,7 +337,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
         if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable processor = lookup.getReportingTask(id);
+                final Authorizable processor = 
lookup.getReportingTask(id).getAuthorizable();
                 processor.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
             });
         }
@@ -370,7 +372,8 @@ public class ReportingTaskResource extends 
ApplicationResource {
             value = "Updates a reporting task",
             response = ReportingTaskEntity.class,
             authorizations = {
-                    @Authorization(value = "Write - /reporting-tasks/{uuid}", 
type = "")
+                    @Authorization(value = "Write - /reporting-tasks/{uuid}", 
type = ""),
+                    @Authorization(value = "Read - any referenced Controller 
Services - /controller-services/{uuid}", type = "")
             }
     )
     @ApiResponses(
@@ -419,8 +422,12 @@ public class ReportingTaskResource extends 
ApplicationResource {
                 serviceFacade,
                 revision,
                 lookup -> {
-                    Authorizable authorizable = lookup.getReportingTask(id);
-                    authorizable.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+                    // authorize reporting task
+                    final ControllerServiceReferencingComponentAuthorizable 
authorizable = lookup.getReportingTask(id);
+                    authorizable.getAuthorizable().authorize(authorizer, 
RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+
+                    // authorize any referenced services
+                    
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTaskDTO.getProperties(),
 authorizable, authorizer, lookup);
                 },
                 () -> 
serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO),
                 () -> {
@@ -493,7 +500,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
                 serviceFacade,
                 revision,
                 lookup -> {
-                    final Authorizable reportingTask = 
lookup.getReportingTask(id);
+                    final Authorizable reportingTask = 
lookup.getReportingTask(id).getAuthorizable();
                     reportingTask.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
                 },
                 () -> serviceFacade.verifyDeleteReportingTask(id),

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index d64956d..cbdc2da 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -43,9 +43,11 @@ import org.apache.nifi.controller.ProcessorNode;
 import org.apache.nifi.controller.ReportingTaskNode;
 import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.controller.Template;
+import org.apache.nifi.controller.exception.ProcessorInstantiationException;
 import org.apache.nifi.controller.label.Label;
 import org.apache.nifi.controller.queue.FlowFileQueue;
 import org.apache.nifi.controller.queue.QueueSize;
+import 
org.apache.nifi.controller.reporting.ReportingTaskInstantiationException;
 import org.apache.nifi.controller.repository.ContentNotFoundException;
 import org.apache.nifi.controller.repository.claim.ContentDirection;
 import org.apache.nifi.controller.service.ControllerServiceNode;
@@ -126,6 +128,7 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TimeZone;
 import java.util.TreeSet;
+import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
@@ -190,6 +193,38 @@ public class ControllerFacade implements Authorizable {
     }
 
     /**
+     * Create a temporary Processor used for extracting PropertyDescriptor's 
for ControllerService reference authorization.
+     *
+     * @param type type of processor
+     * @return processor
+     * @throws ProcessorInstantiationException when unable to instantiate the 
processor
+     */
+    public ProcessorNode createTemporaryProcessor(String type) throws 
ProcessorInstantiationException {
+        return flowController.createProcessor(type, 
UUID.randomUUID().toString(), false);
+    }
+
+    /**
+     * Create a temporary ReportingTask used for extracting 
PropertyDescriptor's for ControllerService reference authorization.
+     *
+     * @param type type of reporting task
+     * @return reporting task
+     * @throws ReportingTaskInstantiationException when unable to instantiate 
the reporting task
+     */
+    public ReportingTaskNode createTemporaryReportingTask(String type) throws 
ReportingTaskInstantiationException {
+        return flowController.createReportingTask(type, 
UUID.randomUUID().toString(), false);
+    }
+
+    /**
+     * Create a temporary ControllerService used for extracting 
PropertyDescriptor's for ControllerService reference authorization.
+     *
+     * @param type type of controller service
+     * @return controller service
+     */
+    public ControllerServiceNode createTemporaryControllerService(String type) 
{
+        return flowController.createControllerService(type, 
UUID.randomUUID().toString(), false);
+    }
+
+    /**
      * Sets the max timer driven thread count of this controller.
      *
      * @param maxTimerDrivenThreadCount count

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
index 67ad499..1494a16 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.css
@@ -77,6 +77,10 @@ div.selected-disabled-option {
     padding: 0px 10px;
 }
 
+.combo-options ul > li.disabled {
+    font-style: italic;
+}
+
 .combo-option-text {
     overflow: hidden;
     white-space: nowrap;

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js
index b79ea16..2bc406b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js
@@ -118,30 +118,6 @@
 
     };
 
-    var setDisabled = function (combo, optionElement, option, disabled) {
-        // reset the option element
-        optionElement.removeClass('unset').off('click');
-        
-        if (disabled === true) {
-            optionElement.addClass('unset');
-        } else {
-            optionElement.on('click', function () {
-                //remove active styles
-                $('.combo').removeClass('combo-open');
-
-                // select the option
-                selectOption(combo, option.text, option.value);
-
-                // click the glass pane which will hide the options
-                $('.combo-glass-pane').click();
-            }).hover(function () {
-                $(this).addClass('pointer').css('background', '#eaeef0');
-            }, function () {
-                $(this).removeClass('pointer').css('background', '#ffffff');
-            });
-        }
-    };
-
     var methods = {
 
         /**
@@ -212,7 +188,7 @@
 
                             // this is option is enabled register appropriate 
listeners
                             if (option.disabled === true) {
-                                optionElement.addClass('unset');
+                                optionElement.addClass('unset disabled');
                             } else {
                                 optionElement.click(function () {
                                     //remove active styles

http://git-wip-us.apache.org/repos/asf/nifi/blob/7d8dd270/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
index 67d7efc..b914482 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
@@ -530,6 +530,7 @@
                     options.push({
                         text: allowableValue.displayName,
                         value: allowableValue.value,
+                        disabled: allowableValueEntity.canRead === false && 
allowableValue.value !== args.item['previousValue'],
                         description: 
nf.Common.escapeHtml(allowableValue.description)
                     });
                 });

Reply via email to