You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2016/07/12 21:00:06 UTC

[3/9] nifi git commit: NIFI-2095: - Adding a page for managing users and groups. - Adding a page for managing access policies. - Renaming accessPolicy in entity to permissions to avoid confusion with the accessPolicy model. - Adding an Authorizable for a

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-dialog.jsp
new file mode 100644
index 0000000..1d206b4
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/user-dialog.jsp
@@ -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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<div id="user-dialog" class="hidden">
+    <div class="dialog-content">
+        <div class="setting">
+            <div class="setting-field">
+                <input id="individual-radio-button" type="radio" name="userOrGroup" value="individual" checked="checked"/> Individual
+                <input id="group-radio-button" type="radio" name="userOrGroup" value="group" style="margin-left: 20px;"/> Group
+            </div>
+            <div class="clear"></div>
+        </div>
+        <div class="setting">
+            <div class="setting-name">Identity</div>
+            <div class="setting-field">
+                <span id="user-id-edit-dialog" class="hidden"></span>
+                <input type="text" id="user-identity-edit-dialog"/>
+            </div>
+            <div class="clear"></div>
+        </div>
+        <div id="user-groups" class="setting">
+            <div class="setting-name">Member of</div>
+            <div class="setting-field">
+                <ul id="available-groups" class="usersGroupsList"></ul>
+            </div>
+            <div class="clear"></div>
+        </div>
+        <div id="group-members" class="setting hidden">
+            <div class="setting-name">Members</div>
+            <div class="setting-field">
+                <ul id="available-users" class="usersGroupsList"></ul>
+            </div>
+            <div class="clear"></div>
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/users-content.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/users-content.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/users-content.jsp
new file mode 100644
index 0000000..75872f4
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/users/users-content.jsp
@@ -0,0 +1,41 @@
+<%--
+ 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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<div id="users">
+    <div id="users-header-and-filter">
+        <div id="users-header-text">NiFi Users</div>
+    </div>
+    <div id="users-filter-controls">
+        <div id="users-filter-status" class="filter-status">
+            Displaying&nbsp;<span id="displayed-users"></span>&nbsp;of&nbsp;<span id="total-users"></span>
+        </div>
+        <div id="users-filter-container" class="filter-container">
+            <input type="text" placeholder="Filter" id="users-filter" class="filter"/>
+            <div id="users-filter-type" class="filter-type"></div>
+        </div>
+        <button id="new-user-button" class="fa fa-user-plus"></button>
+        <div class="clear"></div>
+    </div>
+    <div id="users-table"></div>
+</div>
+<div id="users-refresh-container">
+    <button id="user-refresh-button" class="refresh-button pointer fa fa-refresh" title="Refresh"></button>
+    <div id="users-last-refreshed-container" class="last-refreshed-container">
+        Last updated:&nbsp;<span id="users-last-refreshed" class="value-color"></span>
+    </div>
+    <div id="users-loading-container" class="loading-container"></div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
index f7ddc84..db9f4ce 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css
@@ -18,7 +18,7 @@
 @import url(processor-configuration.css);
 @import url(processor-details.css);
 @import url(process-group-configuration.css);
-@import url(process-group-details.css);
+@import url(policy-management.css);
 @import url(queue-listing.css);
 @import url(remote-process-group-configuration.css);
 @import url(controller-service.css);

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
index 681673a..c742c2f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
@@ -202,13 +202,4 @@ md-toolbar.md-small .md-toolbar-tools {
     font-size: 12px;
     color: #262626;
     padding-right: 5px;
-}
-
-#has-pending-accounts {
-    background-image: url(../images/starburst.png);
-    width: 9px;
-    height: 9px;
-    margin-top: 3px;
-    margin-left: 5px;
-    background-color: transparent;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
index 5486357..2a0eadd 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/main.css
@@ -297,7 +297,7 @@ input::placeholder {
     color: #728e9b; /*base-color*/
 }
 
-input, input[type=text], input[type=password], textarea {
+input[type=text], input[type=password], textarea {
     background-color: #eaeef0;
     border: 1px solid #eaeef0;
     font-family: Roboto, sans-serif;
@@ -569,6 +569,7 @@ input.filter {
 button.fa {
     color: #004849;
     font-size: 16px;
+    cursor: pointer;
 }
 
 button.icon {

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
new file mode 100644
index 0000000..e414934
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+#policy-management {
+    display: none;
+    position: absolute;
+    top: 0px;
+    bottom: 0px;
+    left: 20px;
+    right: 20px;
+    overflow: auto;
+}
+
+#policy-management-header-text {
+    font-size: 18px;
+    font-weight: bold;
+    color: #728E9B;
+    font-family: Roboto Slab;
+    margin-bottom: 24px;
+}
+
+#new-policy-user-button {
+    margin-right: 5px;
+}
+
+button.policy-button {
+    float: right;
+    margin-top: 4px;
+}
+
+button.policy-button:disabled {
+    color: #CCDADB;
+    cursor: not-allowed;
+    border: 1px solid #CCDADB;
+}
+
+/*
+    policy message
+*/
+
+#policy-message-container {
+    height: 18px;
+    color: #775351;
+    font-family: Roboto;
+    font-size: 13px;
+    font-weight: 500;
+}
+
+#policy-message {
+    float: left;
+    margin-right: 4px;
+}
+
+#new-policy-message {
+    float: left;
+}
+
+#override-policy-message {
+    float: left;
+}
+
+/*
+    policy selection
+*/
+
+div.policy-controls {
+    float: left;
+}
+
+#policy-type-list {
+    float: left;
+    width: 190px;
+    margin-right: 3px;
+    border-left: 1px solid transparent;
+    border-right: 1px solid transparent;
+}
+
+#component-policy-target {
+    float: left;
+    width: 200px;
+    margin-right: 3px;
+    border-left: 1px solid transparent;
+    border-right: 1px solid transparent;
+}
+
+#controller-policy-target {
+    float: left;
+    width: 160px;
+    margin-right: 3px;
+    border-left: 1px solid transparent;
+    border-right: 1px solid transparent;
+}
+
+div.policy-selected-component-container {
+    float: left;
+    margin-right: 20px;
+}
+
+div.policy-selected-component-details-container {
+    float: left;
+    padding-left: 10px;
+}
+
+div.policy-selected-component-type-icon {
+    float: left;
+}
+
+div.policy-selected-component-type-icon i.icon {
+    font-size: 28px;
+    font-family: flowfont;
+    color: #ad9897;
+}
+
+div.policy-selected-component-name {
+    height: 14px;
+    font-size: 15px;
+    font-family: Roboto;
+    color: #262626;
+    max-width: 300px;
+    text-overflow: ellipsis;
+    overflow-x: hidden;
+    white-space: nowrap;
+}
+
+div.policy-selected-component-type {
+    font-size: 12px;
+    font-family: Roboto;
+    color: #728e9b;
+    margin-top: 3px;
+}
+
+/*
+    policy table
+*/
+
+#policy-table {
+    position: absolute;
+    top: 92px;
+    left: 0px;
+    bottom: 0px;
+    right: 0px;
+    overflow: hidden;
+    background-color: #fff;
+}
+
+#policy-refresh-container {
+    position: absolute;
+    bottom: 20px;
+    left: 0px;
+    height: 32px;
+}
+
+#policy-refresh-button {
+    float: left;
+}
+
+#policy-loading-container {
+    float: left;
+    width: 16px;
+    height: 16px;
+    background-color: transparent;
+    margin-top: 4px;
+    margin-left: 3px;
+}
+
+#policy-last-refreshed {
+    font-weight: bold;
+}
+
+/*
+    search users dialog
+*/
+
+#search-users-dialog {
+    width: 450px;
+    height: 250px;
+}
+
+#search-users-results .ui-autocomplete {
+    max-height: 300px;
+    overflow: auto;
+    border: 1px solid #aaaaaa;
+    z-index: 1351;
+    border-radius: 0;
+}
+
+#search-users-results .ui-menu .ui-menu-item a.ui-state-focus {
+    background: #D4E0E5 !important;
+    border: 1px solid #999999;
+    border-radius: 0;
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-details.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-details.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-details.css
deleted file mode 100644
index a19791a..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/process-group-details.css
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#process-group-details {
-    z-index: 1301;
-    display: none;
-    width: 400px;
-    height: 290px;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
new file mode 100644
index 0000000..1810e50
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/users.css
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+/*
+    Users Styles
+*/
+
+#users {
+    position: absolute;
+    top: 0px;
+    bottom: 0px;
+    left: 20px;
+    right: 20px;
+    overflow: auto;
+}
+
+#users-header-and-filter {
+    height: 32px;
+}
+
+#users-header-text {
+    font-size: 18px;
+    font-weight: bold;
+    color: #728E9B;
+    font-family: Roboto Slab;
+    margin-bottom: 30px;
+}
+
+#users-refresh-container {
+    position: absolute;
+    left: 20px;
+    bottom: 0px;
+}
+
+#users-loading-container {
+    float: left;
+    width: 16px;
+    height: 16px;
+    background-color: transparent;
+    margin-top: 4px;
+    margin-left: 3px;
+}
+
+#users-last-refreshed {
+    font-weight: bold;
+}
+
+#users-header {
+    padding-top: 10px;
+}
+
+#new-user-button {
+    float: right;
+    margin-top: 4px;
+}
+
+/* users table */
+
+#users-table {
+    position: absolute;
+    top: 92px;
+    left: 0px;
+    bottom: 0px;
+    right: 0px;
+    overflow: hidden;
+    background-color: #fff;
+}
+
+/* users dialog */
+
+#user-dialog {
+    width: 450px;
+    height: 500px;
+}
+
+#user-identity {
+    width: 410px;
+}
+
+/* user delete dialog */
+
+#user-delete-dialog {
+    width: 450px;
+    height: 165px;
+}
+
+/* users/groups list */
+
+ul.usersGroupsList li {
+    height: 24px;
+    line-height: 24px;
+    border-bottom: 1px solid #c7d2d7;
+    width: 100%;
+    display: inline-flex;
+}
+
+ul.usersGroupsList li.even {
+    background-color: #f4f6f7;
+}
+
+ul.usersGroupsList li div.nf-checkbox {
+    margin: 0 10px;
+    margin-top: 6px;
+    min-width: 12px;
+    max-width: 12px;
+}
+
+div.available-identities {
+    margin-left: 5px;
+    margin-right: 10px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/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 036f17e..232fe20 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,6 +118,30 @@
 
     };
 
+    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 = {
 
         /**
@@ -146,6 +170,8 @@
                     }, function () {
                         combo.removeClass('button-over').addClass('combo-button-normal');
                     }).click(function (event) {
+                        var comboConfigOptions = combo.data('options');
+                        
                         //add active styles
                         $(this).addClass('combo-open');
 
@@ -166,8 +192,8 @@
 
                         // set the max height if necessary
                         var maxHeight = -1;
-                        if (isDefinedAndNotNull(options.maxHeight)) {
-                            maxHeight = parseInt(options.maxHeight);
+                        if (isDefinedAndNotNull(comboConfigOptions.maxHeight)) {
+                            maxHeight = parseInt(comboConfigOptions.maxHeight);
                             if (maxHeight > 0) {
                                 comboOptions.css('max-height', maxHeight + 'px');
                             }
@@ -177,7 +203,7 @@
                         var optionList = $('<ul></ul>').appendTo(comboOptions);
 
                         // process the options
-                        $.each(options.options, function (i, option) {
+                        $.each(comboConfigOptions.options, function (i, option) {
                             var optionText = $('<span class="combo-option-text"></span>').attr('title', option.text).text(option.text);
                             var optionValue = $('<span class="hidden"></span>').text(option.value);
 
@@ -298,13 +324,34 @@
         },
 
         /**
+         * Sets whether the specified option is enabled or disabled.
+         * 
+         * @param option
+         * @param enabled
+         */
+        setOptionEnabled: function (option, enabled) {
+            return this.each(function () {
+                var combo = $(this);
+                var comboConfigOptions = combo.data('options');
+
+                $.each(comboConfigOptions.options, function (i, configOption) {
+                     if (configOption.value === option.value) {
+                        configOption.disabled = !enabled;   
+                     }
+                });
+            });
+        },
+
+        /**
          * Destroy's the combo.
          */
         destroy: function () {
-            $(this).empty().unbind().removeData();
+            return this.each(function () {
+                $(this).empty().unbind().removeData();
 
-            // remove the options if open
-            $('div.combo-glass-pane').click();
+                // remove the options if open
+                $('div.combo-glass-pane').click();
+            });
         }
     };
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
index 2087034..58a73a5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
@@ -42,7 +42,7 @@ nf.ng.BreadcrumbsCtrl = function (serviceProvider, $sanitize) {
          */
         generateBreadcrumbs: function(breadcrumbEntity) {
             var label = breadcrumbEntity.id;
-            if (breadcrumbEntity.accessPolicy.canRead) {
+            if (breadcrumbEntity.permissions.canRead) {
                 label = breadcrumbEntity.breadcrumb.name;
             }
             

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
index debc1ca..c669386 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
@@ -382,13 +382,6 @@ nf.ng.Canvas.FlowStatusCtrl = function (serviceProvider, $sanitize) {
                 nf.Common.isDefinedAndNotNull(status.connectedNodes) ? $sanitize(status.connectedNodes) : '-';
 
             this.bulletins.update(status);
-
-            // handle any pending user request
-            if (status.hasPendingAccounts === true) {
-                $('#has-pending-accounts').show();
-            } else {
-                $('#has-pending-accounts').hide();
-            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js
index f086518..186b5f9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js
@@ -193,7 +193,7 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
                  * Launch the users shell.
                  */
                 launch: function () {
-                    if (nf.Common.canAccessTenants()) {
+                    if (nf.Common.canModifyTenants()) {
                         nf.Shell.showPage('users');
                     }
                 }
@@ -201,6 +201,27 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
         };
 
         /**
+         * The policies menu item controller.
+         */
+        this.policies = {
+
+            /**
+             * The policies menu item's shell controller.
+             */
+            shell: {
+
+                /**
+                 * Launch the policies shell.
+                 */
+                launch: function () {
+                    if (nf.Common.canModifyPolicies() && nf.Common.canAccessTenants()) {
+                        nf.PolicyManagement.showGlobalPolicies();
+                    }
+                }
+            }
+        };
+
+        /**
          * The templates menu item controller.
          */
         this.templates = {

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-graph-controls-controller.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-graph-controls-controller.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-graph-controls-controller.js
index 9990eae..9ee45cb 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-graph-controls-controller.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-graph-controls-controller.js
@@ -215,7 +215,7 @@ nf.ng.Canvas.GraphControlsCtrl = function (serviceProvider, navigateCtrl, operat
             } else {
                 if (selection.size() === 1) {
                     var d = selection.datum();
-                    if (d.accessPolicy.canRead) {
+                    if (d.permissions.canRead) {
                         if (nf.CanvasUtils.isLabel(selection)) {
                             if ($.trim(d.component.label) !== '') {
                                 return d.component.label;

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-operate-controller.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-operate-controller.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-operate-controller.js
index 0f03386..5d68462 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-operate-controller.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-operate-controller.js
@@ -298,7 +298,7 @@ nf.ng.Canvas.OperateCtrl = function () {
                                             }).fail(function (xhr, status, error) {
                                                 if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
                                                     nf.Dialog.showOkDialog({
-                                                        headerText: 'Malformed Request',
+                                                        headerText: 'Error',
                                                         dialogContent: nf.Common.escapeHtml(xhr.responseText)
                                                     });
                                                 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js
index 947d316..a029e79 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js
@@ -173,7 +173,7 @@ nf.ng.TemplateComponent = function (serviceProvider) {
                 if (nf.Common.isDefinedAndNotNull(templates) && templates.length > 0) {
                     var options = [];
                     $.each(templates, function (_, templateEntity) {
-                        if (templateEntity.accessPolicy.canRead === true) {
+                        if (templateEntity.permissions.canRead === true) {
                             options.push({
                                 text: templateEntity.template.name,
                                 value: templateEntity.id,

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
index 593ac3f..f0f606b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
@@ -157,7 +157,7 @@ nf.Actions = (function () {
                             // reload the group's connections
                             var connections = nf.Connection.getComponentConnections(remoteProcessGroup.id);
                             $.each(connections, function (_, connection) {
-                                if (connection.accessPolicy.canRead) {
+                                if (connection.permissions.canRead) {
                                     nf.Connection.reload(connection.component);
                                 }
                             });
@@ -702,16 +702,27 @@ nf.Actions = (function () {
             }
         },
 
+        /**
+         * Opens the policy management page for the selected component.
+         *
+         * @param selection
+         */
+        managePolicies: function(selection) {
+            if (selection.size() <= 1) {
+                nf.PolicyManagement.showComponentPolicy(selection);
+            }
+        },
+
         // Defines an action for showing component details (like configuration but read only).
         showDetails: function (selection) {
             if (selection.empty()) {
-                nf.ProcessGroupDetails.showConfiguration(nf.Canvas.getGroupId());
+                nf.ProcessGroupConfiguration.showConfiguration(nf.Canvas.getGroupId());
             } else if (selection.size() === 1) {
                 var selectionData = selection.datum();
                 if (nf.CanvasUtils.isProcessor(selection)) {
                     nf.ProcessorDetails.showDetails(nf.Canvas.getGroupId(), selectionData.id);
                 } else if (nf.CanvasUtils.isProcessGroup(selection)) {
-                    nf.ProcessGroupDetails.showConfiguration(selectionData.id);
+                    nf.ProcessGroupConfiguration.showConfiguration(selectionData.id);
                 } else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
                     nf.RemoteProcessGroupDetails.showDetails(selection);
                 } else if (nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection)) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js
index 51fb550..80aaa17 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js
@@ -151,7 +151,7 @@ nf.Birdseye = (function () {
         $.each(components.labels, function (_, d) {
             var color = nf.Label.defaultColor();
 
-            if (d.accessPolicy.canRead) {
+            if (d.permissions.canRead) {
                 // use the specified color if appropriate
                 if (nf.Common.isDefinedAndNotNull(d.component.style['background-color'])) {
                     color = d.component.style['background-color'];
@@ -189,7 +189,7 @@ nf.Birdseye = (function () {
         $.each(components.processors, function (_, d) {
             var color = '#dde4eb';
 
-            if (d.accessPolicy.canRead) {
+            if (d.permissions.canRead) {
                 // use the specified color if appropriate
                 if (nf.Common.isDefinedAndNotNull(d.component.style['background-color'])) {
                     color = d.component.style['background-color'];

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/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 31576ba..47ab0f9 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
@@ -260,7 +260,7 @@ nf.CanvasUtils = (function () {
         editable: function (selection) {
             var selectionData = selection.datum();
             
-            if (selectionData.accessPolicy.canWrite && selectionData.accessPolicy.canRead) {
+            if (selectionData.permissions.canWrite && selectionData.permissions.canRead) {
                 if (!selection.classed('connectable')) {
                     selection.call(nf.Connectable.activate);
                 }
@@ -888,7 +888,7 @@ nf.CanvasUtils = (function () {
         canModify: function (selection) {
             var selectionSize = selection.size();
             var writableSize = selection.filter(function (d) {
-                return d.accessPolicy.canWrite && d.accessPolicy.canRead;
+                return d.permissions.canWrite && d.permissions.canRead;
             }).size();
             
             return selectionSize === writableSize;
@@ -903,7 +903,7 @@ nf.CanvasUtils = (function () {
         canRead: function (selection) {
             var selectionSize = selection.size();
             var readableSize = selection.filter(function (d) {
-                return d.accessPolicy.canRead;
+                return d.permissions.canRead;
             }).size();
 
             return selectionSize === readableSize;
@@ -923,7 +923,7 @@ nf.CanvasUtils = (function () {
             var selectionData = selection.datum();
 
             // check access policies first
-            if (selectionData.accessPolicy.canRead === false || selectionData.accessPolicy.canWrite === false) {
+            if (selectionData.permissions.canRead === false || selectionData.permissions.canWrite === false) {
                 return false;
             }
 
@@ -1101,7 +1101,7 @@ nf.CanvasUtils = (function () {
                 if (source.empty() === false) {
                     var sourceData = source.datum();
 
-                    if (sourceData.accessPolicy.canRead) {
+                    if (sourceData.permissions.canRead) {
                         // update the source status if necessary
                         if (nf.CanvasUtils.isProcessor(source)) {
                             nf.Processor.reload(sourceData.component);
@@ -1119,7 +1119,7 @@ nf.CanvasUtils = (function () {
                 if (destination.empty() === false) {
                     var destinationData = destination.datum();
 
-                    if (destinationData.accessPolicy.canRead) {
+                    if (destinationData.permissions.canRead) {
                         // update the destination component accordingly
                         if (nf.CanvasUtils.isProcessor(destination)) {
                             nf.Processor.reload(destinationData.component);

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.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.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index d83c60a..d5bc4ce 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -114,7 +114,7 @@ nf.Canvas = (function () {
     var polling = false;
     var groupId = 'root';
     var groupName = null;
-    var accessPolicy = null;
+    var permissions = null;
     var parentGroupId = null;
     var clustered = false;
     var svg = null;
@@ -631,15 +631,15 @@ nf.Canvas = (function () {
 
             // get the current group name from the breadcrumb
             var breadcrumb = processGroupFlow.breadcrumb;
-            if (breadcrumb.accessPolicy.canRead) {
+            if (breadcrumb.permissions.canRead) {
                 nf.Canvas.setGroupName(breadcrumb.breadcrumb.name);
             } else {
                 nf.Canvas.setGroupName(breadcrumb.id);
             }
 
             // update the access policies
-            accessPolicy = flowResponse.accessPolicy;
-
+            permissions = flowResponse.permissions;
+            
             // update the breadcrumbs
             nf.ng.Bridge.injector.get('breadcrumbsCtrl').resetBreadcrumbs();
             nf.ng.Bridge.injector.get('breadcrumbsCtrl').generateBreadcrumbs(breadcrumb);
@@ -832,6 +832,7 @@ nf.Canvas = (function () {
                     nf.ConnectionConfiguration.init();
                     nf.ControllerService.init();
                     nf.ReportingTask.init();
+                    nf.PolicyManagement.init();
                     nf.ProcessorConfiguration.init();
                     nf.ProcessGroupConfiguration.init();
                     nf.RemoteProcessGroupConfiguration.init();
@@ -839,7 +840,6 @@ nf.Canvas = (function () {
                     nf.PortConfiguration.init();
                     nf.LabelConfiguration.init();
                     nf.ProcessorDetails.init();
-                    nf.ProcessGroupDetails.init();
                     nf.PortDetails.init();
                     nf.ConnectionDetails.init();
                     nf.RemoteProcessGroupDetails.init();
@@ -925,10 +925,10 @@ nf.Canvas = (function () {
          * @returns {boolean}   can write
          */
         canRead: function () {
-            if (accessPolicy === null) {
+            if (permissions === null) {
                 return false;
             } else {
-                return accessPolicy.canRead === true;
+                return permissions.canRead === true;
             }
         },
 
@@ -938,10 +938,10 @@ nf.Canvas = (function () {
          * @returns {boolean}   can write
          */
         canWrite: function () {
-            if (accessPolicy === null) {
+            if (permissions === null) {
                 return false;
             } else {
-                return accessPolicy.canWrite === true;
+                return permissions.canWrite === true;
             }
         },
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
index b2ca3f8..0878a54 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
@@ -281,7 +281,7 @@ nf.ConnectionConfiguration = (function () {
                 // show the output port options
                 var options = [];
                 $.each(processGroupContents.outputPorts, function (i, outputPort) {
-                    if (outputPort.accessPolicy.canRead && outputPort.accessPolicy.canWrite) {
+                    if (outputPort.permissions.canRead && outputPort.permissions.canWrite) {
                         var component = outputPort.component;
                         options.push({
                             text: component.name,
@@ -506,7 +506,7 @@ nf.ConnectionConfiguration = (function () {
                 // show the input port options
                 var options = [];
                 $.each(processGroupContents.inputPorts, function (i, inputPort) {
-                    if (inputPort.accessPolicy.canRead && inputPort.accessPolicy.canWrite) {
+                    if (inputPort.permissions.canRead && inputPort.permissions.canWrite) {
                         var component = inputPort.component;
                         options.push({
                             text: component.name,

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
index 41f08ea..f559e96 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
@@ -308,7 +308,7 @@ nf.Connection = (function () {
                 .classed('grouped', function (d) {
                     var grouped = false;
 
-                    if (d.accessPolicy.canRead) {
+                    if (d.permissions.canRead) {
                         // if there are more than one selected relationship, mark this as grouped
                         if (nf.Common.isDefinedAndNotNull(d.component.selectedRelationships) && d.component.selectedRelationships.length > 1) {
                             grouped = true;
@@ -320,7 +320,7 @@ nf.Connection = (function () {
                 .classed('ghost', function (d) {
                     var ghost = false;
 
-                    if (d.accessPolicy.canRead) {
+                    if (d.permissions.canRead) {
                         // if the connection has a relationship that is unavailable, mark it a ghost relationship
                         if (hasUnavailableRelationship(d)) {
                             ghost = true;
@@ -333,13 +333,13 @@ nf.Connection = (function () {
             // update connection path
             updated.select('path.connection-path')
                 .classed('unauthorized', function (d) {
-                    return d.accessPolicy.canRead === false;
+                    return d.permissions.canRead === false;
                 });
 
             // update connection behavior
             updated.select('path.connection-path-selectable')
                 .on('dblclick', function (d) {
-                    if (d.accessPolicy.canWrite && d.accessPolicy.canRead) {
+                    if (d.permissions.canWrite && d.permissions.canRead) {
                         var position = d3.mouse(this.parentNode);
 
                         // find where to put this bend point
@@ -466,7 +466,7 @@ nf.Connection = (function () {
                         'marker-end': function () {
                             var marker = 'normal';
 
-                            if (d.accessPolicy.canRead) {
+                            if (d.permissions.canRead) {
                                 // if the connection has a relationship that is unavailable, mark it a ghost relationship
                                 if (hasUnavailableRelationship(d)) {
                                     marker = 'ghost';
@@ -501,7 +501,7 @@ nf.Connection = (function () {
                 var endpoints = connection.selectAll('rect.endpoint');
                 var midpoints = connection.selectAll('rect.midpoint');
 
-                if (d.accessPolicy.canWrite) {
+                if (d.permissions.canWrite) {
 
                     // ------------------
                     // bends - startpoint
@@ -695,7 +695,7 @@ nf.Connection = (function () {
                     var backgrounds = [];
                     var borders = [];
 
-                    if (d.accessPolicy.canRead) {
+                    if (d.permissions.canRead) {
 
                         // -----------------------
                         // connection label - from
@@ -1087,14 +1087,14 @@ nf.Connection = (function () {
                             return (rowHeight * labelCount);
                         })
                         .classed('unauthorized', function () {
-                            return d.accessPolicy.canRead === false;
+                            return d.permissions.canRead === false;
                         });
                     connectionLabelContainer.select('rect.border')
                         .attr('height', function () {
                             return (rowHeight * labelCount);
                         })
                         .classed('unauthorized', function () {
-                            return d.accessPolicy.canRead === false;
+                            return d.permissions.canRead === false;
                         });
 
                     // update the coloring of the backgrounds
@@ -1115,7 +1115,7 @@ nf.Connection = (function () {
                         }
                     });
 
-                    if (d.accessPolicy.canRead) {
+                    if (d.permissions.canRead) {
                         // determine whether or not to show the expiration icon
                         connectionLabelContainer.select('g.expiration-icon')
                             .classed('hidden', function () {
@@ -1126,7 +1126,7 @@ nf.Connection = (function () {
                         });
                     }
 
-                    if (d.accessPolicy.canWrite) {
+                    if (d.permissions.canWrite) {
                         // only support dragging the label when appropriate
                         connectionLabelContainer.call(labelDrag);
                     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.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-service.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
index 67b4ed6..5e3899a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
@@ -179,7 +179,7 @@ nf.ControllerService = (function () {
         // reload all dependent processors if they are currently visible
         $.each(controllerService.referencingComponents, function (_, referencingComponentEntity) {
             // ensure we can read the referencing component prior to reloading
-            if (referencingComponentEntity.accessPolicy.canRead === false) {
+            if (referencingComponentEntity.permissions.canRead === false) {
                 return;
             }
 
@@ -401,7 +401,7 @@ nf.ControllerService = (function () {
         var unauthorized = $('<ul class="referencing-component-listing clear"></ul>');
         $.each(referencingComponents, function (_, referencingComponentEntity) {
             // check the access policy for this referencing component
-            if (referencingComponentEntity.accessPolicy.canRead === false || referencingComponentEntity.accessPolicy.canWrite === false) {
+            if (referencingComponentEntity.permissions.canRead === false || referencingComponentEntity.permissions.canWrite === false) {
                 var unauthorizedReferencingComponent = $('<div class="unset"></div>').text(referencingComponentEntity.id);
                 unauthorized.append(unauthorizedReferencingComponent);
             } else {
@@ -1029,7 +1029,7 @@ nf.ControllerService = (function () {
 
         var hasUnauthorized = false;
         $.each(controllerService.referencingComponents, function (_, referencingComponent) {
-            if (referencingComponent.accessPolicy.canRead === false || referencingComponent.accessPolicy.canWrite === false) {
+            if (referencingComponent.permissions.canRead === false || referencingComponent.permissions.canWrite === false) {
                 hasUnauthorized = true;
                 return false;
             }
@@ -1263,7 +1263,7 @@ nf.ControllerService = (function () {
 
         var hasUnauthorized = false;
         $.each(controllerService.referencingComponents, function (_, referencingComponent) {
-            if (referencingComponent.accessPolicy.canRead === false || referencingComponent.accessPolicy.canWrite === false) {
+            if (referencingComponent.permissions.canRead === false || referencingComponent.permissions.canWrite === false) {
                 hasUnauthorized = true;
                 return false;
             }

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/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 9a8a5e5..665cb14 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
@@ -415,7 +415,7 @@ nf.ControllerServices = (function () {
      * @returns {String}
      */
     var nameFormatter = function (row, cell, value, columnDef, dataContext) {
-        if (!dataContext.accessPolicy.canRead) {
+        if (!dataContext.permissions.canRead) {
             return '<span class="blank">' + dataContext.id + '</span>';
         }
         
@@ -433,7 +433,7 @@ nf.ControllerServices = (function () {
      * @returns {String}
      */
     var typeFormatter = function (row, cell, value, columnDef, dataContext) {
-        if (!dataContext.accessPolicy.canRead) {
+        if (!dataContext.permissions.canRead) {
             return '';
         }
         
@@ -492,24 +492,24 @@ nf.ControllerServices = (function () {
     var initControllerServices = function (serviceTable) {
         // more details formatter
         var moreControllerServiceDetails = function (row, cell, value, columnDef, dataContext) {
-            if (!dataContext.accessPolicy.canRead) {
+            if (!dataContext.permissions.canRead) {
                 return '';
             }
             
-            var markup = '<div class="pointer view-controller-service fa fa-info-circle" title="View Details" style="margin-top: 5px; float: left;" ></div>';
+            var markup = '<div class="pointer view-controller-service fa fa-info-circle" title="View Details" style="margin-top: 5px; margin-right: 3px;" ></div>';
 
             // always include a button to view the usage
-            markup += '<div title="Usage" class="pointer controller-service-usage fa fa-book" style="margin-left: 3px; margin-top: 5px; float: left;" ></div>';
+            markup += '<div title="Usage" class="pointer controller-service-usage fa fa-book" style="margin-top: 5px; margin-right: 3px;" ></div>';
 
             var hasErrors = !nf.Common.isEmpty(dataContext.component.validationErrors);
             var hasBulletins = !nf.Common.isEmpty(dataContext.bulletins);
 
             if (hasErrors) {
-                markup += '<div class="pointer has-errors fa fa-warning" style="margin-top: 4px; margin-left: 3px; float: left;" ></div>';
+                markup += '<div class="pointer has-errors fa fa-warning" style="margin-top: 4px; margin-right: 3px;" ></div>';
             }
 
             if (hasBulletins) {
-                markup += '<div class="has-bulletins fa fa-sticky-note-o" style="margin-top: 5px; margin-left: 5px; float: left;"></div>';
+                markup += '<div class="has-bulletins fa fa-sticky-note-o" style="margin-top: 5px; margin-right: 3px;"></div>';
             }
 
             if (hasErrors || hasBulletins) {
@@ -520,7 +520,7 @@ nf.ControllerServices = (function () {
         };
 
         var controllerServiceStateFormatter = function (row, cell, value, columnDef, dataContext) {
-            if (!dataContext.accessPolicy.canRead) {
+            if (!dataContext.permissions.canRead) {
                 return '';
             }
             
@@ -553,25 +553,28 @@ nf.ControllerServices = (function () {
         var controllerServiceActionFormatter = function (row, cell, value, columnDef, dataContext) {
             var markup = '';
 
-            if (dataContext.accessPolicy.canRead && dataContext.accessPolicy.canWrite) {
+            if (dataContext.permissions.canRead && dataContext.permissions.canWrite) {
                 if (dataContext.component.state === 'ENABLED' || dataContext.component.state === 'ENABLING') {
-                    markup += '<div class="pointer disable-controller-service icon icon-enable-false" title="Disable" style="margin-top: 2px;" ></div>';
+                    markup += '<div class="pointer disable-controller-service icon icon-enable-false" title="Disable" style="margin-top: 2px; margin-right: 3px;" ></div>';
                 } else if (dataContext.component.state === 'DISABLED') {
-                    markup += '<div class="pointer edit-controller-service fa fa-pencil" title="Edit" style="margin-top: 2px;" ></div>';
+                    markup += '<div class="pointer edit-controller-service fa fa-pencil" title="Edit" style="margin-top: 2px; margin-right: 3px;" ></div>';
 
                     // if there are no validation errors allow enabling
                     if (nf.Common.isEmpty(dataContext.component.validationErrors)) {
-                        markup += '<div class="pointer enable-controller-service fa fa-flash" title="Enable" style="margin-top: 2px; margin-left: 6px;"></div>';
+                        markup += '<div class="pointer enable-controller-service fa fa-flash" title="Enable" style="margin-top: 2px; margin-right: 3px;"></div>';
                     }
 
-                    markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-left: 3px;" ></div>';
+                    markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-right: 3px;" ></div>';
                 }
 
                 if (dataContext.component.persistsState === true) {
-                    markup += '<div title="View State" class="pointer view-state-controller-service fa fa-tasks" style="margin-top: 2px; margin-left: 3px;" ></div>';
+                    markup += '<div title="View State" class="pointer view-state-controller-service fa fa-tasks" style="margin-top: 2px; margin-right: 3px;" ></div>';
                 }
             }
 
+            // TODO - only if we can adminster policies
+            markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
+
             return markup;
         };
 
@@ -629,6 +632,12 @@ nf.ControllerServices = (function () {
                     nf.ControllerService.remove(serviceTable, controllerServiceEntity);
                 } else if (target.hasClass('view-state-controller-service')) {
                     nf.ComponentState.showState(controllerServiceEntity.component, controllerServiceEntity.state === 'DISABLED');
+                } else if (target.hasClass('edit-access-policies')) {
+                    // show the policies for this service
+                    nf.PolicyManagement.showControllerServicePolicy(controllerServiceEntity);
+
+                    // close the settings dialog
+                    $('#shell-close-button').click();
                 }
             } else if (controllerServicesGrid.getColumns()[args.cell].id === 'moreDetails') {
                 if (target.hasClass('view-controller-service')) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-funnel.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-funnel.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-funnel.js
index 46f8795..efda58c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-funnel.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-funnel.js
@@ -128,13 +128,13 @@ nf.Funnel = (function () {
         // funnel border authorization
         updated.select('rect.border')
             .classed('unauthorized', function (d) {
-                return d.accessPolicy.canRead === false;
+                return d.permissions.canRead === false;
             });
 
         // funnel body authorization
         updated.select('rect.body')
             .classed('unauthorized', function (d) {
-                return d.accessPolicy.canRead === false;
+                return d.permissions.canRead === false;
             });
 
         updated.each(function () {

http://git-wip-us.apache.org/repos/asf/nifi/blob/e0c96794/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label.js
index 94c7b0c..dbcb5a0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label.js
@@ -129,7 +129,7 @@ nf.Label = (function () {
                 }
             })
             .classed('unauthorized', function (d) {
-                return d.accessPolicy.canRead === false;
+                return d.permissions.canRead === false;
             });
 
         // update the body fill using the configured color
@@ -143,7 +143,7 @@ nf.Label = (function () {
                 }
             })
             .style('fill', function (d) {
-                if (!d.accessPolicy.canRead) {
+                if (!d.permissions.canRead) {
                     return null;
                 }
 
@@ -157,7 +157,7 @@ nf.Label = (function () {
                 return color;
             })
             .classed('unauthorized', function (d) {
-                return d.accessPolicy.canRead === false;
+                return d.permissions.canRead === false;
             });
 
         // go through each label being updated
@@ -170,7 +170,7 @@ nf.Label = (function () {
             // update the label
             var labelText = label.select('text.label-value');
             var labelPoint = label.selectAll('rect.labelpoint');
-            if (d.accessPolicy.canRead) {
+            if (d.permissions.canRead) {
                 // udpate the font size
                 labelText.attr('font-size', function () {
                     var fontSize = '12px';
@@ -209,7 +209,7 @@ nf.Label = (function () {
                 // labelpoints
                 // -----------
 
-                if (d.accessPolicy.canWrite) {
+                if (d.permissions.canWrite) {
                     var pointData = [
                         {x: d.dimensions.width, y: d.dimensions.height}
                     ];