http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/node/NodeAuthorizedUserFilter.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/node/NodeAuthorizedUserFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/node/NodeAuthorizedUserFilter.java
deleted file mode 100644
index 8451c7c..0000000
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/node/NodeAuthorizedUserFilter.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.security.node;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.security.cert.X509Certificate;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.nifi.authorization.user.NiFiUserDetails;
-import org.apache.nifi.controller.FlowController;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authentication.AuthenticationResponse;
-import org.apache.nifi.authorization.user.NiFiUser;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.web.security.token.NiFiAuthenticationToken;
-import org.apache.nifi.web.security.x509.X509CertificateExtractor;
-import org.apache.nifi.web.security.x509.X509IdentityProvider;
-import org.apache.nifi.web.util.WebUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.web.context.support.WebApplicationContextUtils;
-import org.springframework.web.filter.GenericFilterBean;
-
-/**
- * Custom filter to extract a user's authorities from the request where the 
user was authenticated by the cluster manager and populate the threadlocal with 
the authorized user. If the request contains
- * the appropriate header with authorities and the application instance is a 
node connected to the cluster, then the authentication/authorization steps 
remaining in the filter chain are skipped.
- *
- * Checking if the application instance is a connected node is important 
because it prevents external clients from faking the request headers and 
bypassing the authentication processing chain.
- */
-public class NodeAuthorizedUserFilter extends GenericFilterBean {
-
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(NodeAuthorizedUserFilter.class);
-
-    public static final String PROXY_USER_DETAILS = 
"X-ProxiedEntityUserDetails";
-
-    private NiFiProperties properties;
-    private X509CertificateExtractor certificateExtractor;
-    private X509IdentityProvider certificateIdentityProvider;
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
-        final HttpServletRequest httpServletRequest = (HttpServletRequest) 
request;
-
-        // get the proxied user's authorities
-        final String hexEncodedUserDetails = 
httpServletRequest.getHeader(PROXY_USER_DETAILS);
-
-        // check if the request has the necessary header information and this 
instance is configured as a node
-        if (StringUtils.isNotBlank(hexEncodedUserDetails) && 
properties.isNode()) {
-
-            // get the flow controller from the Spring context
-            final ApplicationContext ctx = 
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
-            final FlowController flowController = 
ctx.getBean("flowController", FlowController.class);
-
-            // check that we are connected to the cluster
-            if (flowController.getNodeId() != null) {
-                try {
-                    // attempt to extract the client certificate
-                    final X509Certificate[] certificate = 
certificateExtractor.extractClientCertificate(httpServletRequest);
-                    if (certificate != null) {
-                        // authenticate the certificate
-                        final AuthenticationResponse authenticationResponse = 
certificateIdentityProvider.authenticate(certificate);
-
-                        // only consider the pre-authorized user when the 
request came directly from the NCM according to the DN in the certificate
-                        final String clusterManagerIdentity = 
flowController.getClusterManagerDN();
-                        if (clusterManagerIdentity != null && 
clusterManagerIdentity.equals(authenticationResponse.getIdentity())) {
-                            // deserialize hex encoded object
-                            final Serializable userDetailsObj = 
WebUtils.deserializeHexToObject(hexEncodedUserDetails);
-
-                            // if we have a valid object, set the 
authentication token and bypass the remaining authentication processing chain
-                            if (userDetailsObj instanceof NiFiUserDetails) {
-                                final NiFiUserDetails userDetails = 
(NiFiUserDetails) userDetailsObj;
-                                final NiFiUser user = 
userDetails.getNiFiUser();
-
-                                // log the request attempt - response details 
will be logged later
-                                logger.info(String.format("Attempting request 
for (%s) %s %s (source ip: %s)", user.getIdentity(), 
httpServletRequest.getMethod(),
-                                        
httpServletRequest.getRequestURL().toString(), request.getRemoteAddr()));
-
-                                // create the authorized nifi token
-                                final NiFiAuthenticationToken token = new 
NiFiAuthenticationToken(userDetails);
-                                
SecurityContextHolder.getContext().setAuthentication(token);
-                            }
-                        }
-                    }
-                } catch (final ClassNotFoundException cnfe) {
-                    LOGGER.warn("Classpath issue detected because failed to 
deserialize authorized user in request header due to: " + cnfe, cnfe);
-                } catch (final IllegalArgumentException iae) {
-                    // unable to authenticate a serialized user from the 
incoming request
-                }
-            }
-        }
-
-        chain.doFilter(request, response);
-    }
-
-    public void setProperties(NiFiProperties properties) {
-        this.properties = properties;
-    }
-
-    public void setCertificateIdentityProvider(X509IdentityProvider 
certificateIdentityProvider) {
-        this.certificateIdentityProvider = certificateIdentityProvider;
-    }
-
-    public void setCertificateExtractor(X509CertificateExtractor 
certificateExtractor) {
-        this.certificateExtractor = certificateExtractor;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
index b72d5e1..92e690c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
@@ -65,7 +65,7 @@ public class X509AuthenticationProvider implements 
AuthenticationProvider {
         }
 
         if (StringUtils.isBlank(request.getProxiedEntitiesChain())) {
-            return new NiFiAuthenticationToken(new NiFiUserDetails(new 
StandardNiFiUser(authenticationResponse.getIdentity(), 
authenticationResponse.getUsername(), null)));
+            return new NiFiAuthenticationToken(new NiFiUserDetails(new 
StandardNiFiUser(authenticationResponse.getIdentity())));
         } else {
             // build the entire proxy chain if applicable - 
<end-user><proxy1><proxy2>
             final List<String> proxyChain = new 
ArrayList<>(ProxiedEntitiesUtils.tokenizeProxiedEntitiesChain(request.getProxiedEntitiesChain()));

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
index 77ee3f3..39fdffd 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
@@ -49,6 +49,7 @@
         <script type="text/javascript" 
src="js/jquery/jquery.ellipsis.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.each.js"></script>
         <script type="text/javascript" src="js/jquery/jquery.tab.js"></script>
+        <script type="text/javascript" 
src="js/jquery/jquery.form.min.js"></script>
         <script type="text/javascript" 
src="js/jquery/tabbs/jquery.tabbs.js?${project.version}"></script>
         <script type="text/javascript" 
src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
         <script type="text/javascript" 
src="js/jquery/propertytable/jquery.propertytable.js?${project.version}"></script>
@@ -103,6 +104,7 @@
         <jsp:include 
page="/WEB-INF/partials/canvas/new-process-group-dialog.jsp"/>
         <jsp:include 
page="/WEB-INF/partials/canvas/new-remote-process-group-dialog.jsp"/>
         <jsp:include page="/WEB-INF/partials/canvas/new-template-dialog.jsp"/>
+        <jsp:include 
page="/WEB-INF/partials/canvas/upload-template-dialog.jsp"/>
         <jsp:include 
page="/WEB-INF/partials/canvas/instantiate-template-dialog.jsp"/>
         <jsp:include page="/WEB-INF/partials/canvas/fill-color-dialog.jsp"/>
         <jsp:include page="/WEB-INF/partials/canvas/connections-dialog.jsp"/>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/templates.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/templates.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/templates.jsp
index 91409e7..0803d22 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/templates.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/templates.jsp
@@ -35,7 +35,6 @@
         <script type="text/javascript" 
src="js/jquery/jquery-2.1.1.min.js"></script>
         <script type="text/javascript" 
src="js/jquery/jquery.base64.js"></script>
         <script type="text/javascript" 
src="js/jquery/jquery.center.js"></script>
-        <script type="text/javascript" 
src="js/jquery/jquery.form.min.js"></script>
         <script type="text/javascript" 
src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
         <script type="text/javascript" 
src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
         <script type="text/javascript" 
src="js/jquery/jquery.ellipsis.js"></script>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp
index 0f3a434..050b25e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp
@@ -97,7 +97,8 @@
                     </md-menu-item>
                     <md-menu-item layout-align="space-around center">
                         <a id="counters-link"
-                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.counters.shell.launch();">
+                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.counters.shell.launch();"
+                           ng-class="{disabled: 
!appCtrl.nf.Common.canAccessCounters()}">
                             <i class="icon icon-counter"></i>Counters
                         </a>
                     </md-menu-item>
@@ -109,24 +110,26 @@
                     </md-menu-item>
                     <md-menu-divider></md-menu-divider>
                     <md-menu-item
-                            
ng-if="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.dataProvenance.enabled();"
                             layout-align="space-around center">
                         <a id="provenance-link"
-                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.dataProvenance.shell.launch();">
+                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.dataProvenance.shell.launch();"
+                           ng-class="{disabled: 
!appCtrl.nf.Common.canAccessProvenance()}">
                             <i class="icon icon-provenance"></i>Data Provenance
                         </a>
                     </md-menu-item>
                     <md-menu-divider></md-menu-divider>
                     <md-menu-item layout-align="space-around center">
                         <a id="flow-settings-link"
-                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.controllerSettings.shell.launch();">
+                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.controllerSettings.shell.launch();"
+                           ng-class="{disabled: 
!appCtrl.nf.Common.canAccessController()}">
                             <i class="fa fa-wrench"></i>Controller Settings
                         </a>
                     </md-menu-item>
-                    <md-menu-item 
ng-if="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.cluster.enabled();"
+                    <md-menu-item 
ng-if="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.cluster.visible();"
                                   layout-align="space-around center">
                         <a id="cluster-link"
-                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.cluster.shell.launch();">
+                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.cluster.shell.launch();"
+                           ng-class="{disabled: 
!appCtrl.nf.Common.canAccessController()}">
                             <i class="fa fa-cubes"></i>Cluster
                         </a>
                     </md-menu-item>
@@ -136,10 +139,10 @@
                             <i class="fa fa-history"></i>Flow Configuration 
History
                         </a>
                     </md-menu-item>
-                    <md-menu-item 
ng-if="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.users.enabled();"
-                                  layout-align="space-around center">
+                    <md-menu-item layout-align="space-around center">
                         <a id="users-link" layout="row"
-                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.users.shell.launch();;">
+                           
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.users.shell.launch();"
+                           ng-class="{disabled: 
!appCtrl.nf.Common.canAccessTenants()}">
                             <i class="fa fa-users"></i>Users
                             <div id="has-pending-accounts" 
class="hidden"></div>
                         </a>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
index 59d2a45..b2b2606 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
@@ -127,7 +127,13 @@
                     <div id="operate-template" class="action-button" 
title="Create Template">
                         <button 
ng-click="appCtrl.nf.Actions['template'](appCtrl.nf.CanvasUtils.getSelection());"
                                 ng-disabled="!(appCtrl.nf.Canvas.canWrite() && 
(appCtrl.nf.CanvasUtils.getSelection().empty() || 
appCtrl.nf.CanvasUtils.canRead(appCtrl.nf.CanvasUtils.getSelection())));">
-                            <div class="graph-control-action-icon icon 
icon-template"></div></button>
+                            <div class="graph-control-action-icon icon 
icon-template-save"></div></button>
+                    </div>
+                    <div class="button-spacer-small">&nbsp;</div>
+                    <div id="operate-template-upload" class="action-button" 
title="Upload Template">
+                        <button 
ng-click="appCtrl.nf.Actions['uploadTemplate']();"
+                                ng-disabled="!(appCtrl.nf.Canvas.canWrite() && 
appCtrl.nf.CanvasUtils.getSelection().empty());">
+                            <div class="graph-control-action-icon icon 
icon-template-import"></div></button>
                     </div>
                     <div class="clear"></div>
                 </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/upload-template-dialog.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/upload-template-dialog.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/upload-template-dialog.jsp
new file mode 100644
index 0000000..3c63209
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/upload-template-dialog.jsp
@@ -0,0 +1,35 @@
+<%--
+ 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="upload-template-dialog" class="hidden small-dialog">
+    <div class="dialog-content">
+        <div id="select-template-container">
+            <div id="template-browse-container">
+                <span id="select-template-label">Select Template</span>
+                <button id="select-template-button" class="fa fa-search">
+                    <form id="template-upload-form" 
enctype="multipart/form-data" method="post">
+                        <input type="file" name="template" 
id="template-file-field"/>
+                    </form>
+                </button>
+            </div>
+        </div>
+        <div id="submit-template-container">
+            <div id="selected-template-name"></div>
+        </div>
+        <div id="upload-template-status" class="import-status"></div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/templates/templates-content.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/templates/templates-content.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/templates/templates-content.jsp
index 8ec0a59..00b4e5e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/templates/templates-content.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/templates/templates-content.jsp
@@ -29,25 +29,6 @@
                 <div id="templates-filter-type" class="filter-type"></div>
             </div>
         </div>
-        <div id="upload-template-container" class="hidden">
-            <div id="select-template-container">
-                <div id="template-browse-container">
-                    <button id="select-template-button" class="fa fa-plus">
-                        <form id="template-upload-form" 
enctype="multipart/form-data" method="post">
-                            <input type="file" name="template" 
id="template-file-field"/>
-                        </form>
-                    </button>
-                    <div id="upload-template-status" 
class="import-status"></div>
-                </div>
-            </div>
-            <div id="submit-template-container">
-                <button><div id="upload-template-button" title="Upload 
template" class="icon icon-template-import"></div></button>
-                <button id="cancel-upload-template-button" title="Cancel" 
class="fa fa-undo"></button>
-                <div id="selected-template-name"></div>
-            </div>
-            <div id="template-upload-form-container">
-            </div>
-        </div>
     </div>
     <div id="templates-table"></div>
 </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 72a34fa..caf4003 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
@@ -104,7 +104,7 @@ md-toolbar.md-small .md-toolbar-tools {
     margin-bottom: 3px;
 }
 
-#global-menu-content a{
+#global-menu-content a {
     height: 28px;
     padding: 6px 16px;
     cursor: pointer;
@@ -112,6 +112,15 @@ md-toolbar.md-small .md-toolbar-tools {
     padding-right: 10px;
 }
 
+#global-menu-content a.disabled {
+    color: #a8a8a8;
+    cursor: not-allowed;
+}
+
+#global-menu-content a.disabled i {
+    color: #bebebe;
+}
+
 #global-menu-content a:hover{
     background-color:#C7D2D7;
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 f2a8d42..a809760 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
@@ -614,4 +614,79 @@ div.secondary-button:hover {
 
 md-progress-linear > div {
     background-color: #eaeef0 !important;
+}
+
+/* new template */
+
+#new-template-description {
+    height: 210px;
+}
+
+/* upload */
+
+#select-template-container {
+}
+
+#template-browse-container {
+    display: block;
+    height: 20px;
+}
+
+#select-template-label {
+    font-weight: bold;
+    font-size: 14px;
+    line-height: 28px;
+}
+
+#select-template-button {
+    position: absolute;
+    top: 66px;
+    left: 135px;
+    cursor: pointer;
+    overflow: hidden;
+}
+
+#template-file-field {
+    height: 28px;
+    display: inline;
+    position: absolute;
+    top: 0;
+    left: 0;
+    opacity: 0;
+    filter: alpha(opacity = 0);
+    z-index: 3000;
+    cursor: pointer;
+}
+
+#submit-template-container {
+    margin-top: 20px;
+}
+
+#selected-template-name {
+    font-weight: bold;
+    font-family: Roboto;
+    font-size: 13px;
+}
+
+#upload-template-status {
+    margin-top: 10px;
+    font-weight: bold;
+    font-family: Roboto;
+    font-size: 13px;
+    color: #ba554a;
+}
+
+#upload-template-container button {
+    float: right;
+    font-size: 16px;
+    line-height: 14px;
+    margin-left: 1px;
+}
+
+#template-file-upload {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 22px;
+    width: 300px;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/templates.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/templates.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/templates.css
index ed3d5e7..762fdf5 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/templates.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/templates.css
@@ -90,96 +90,6 @@ input.templates-filter-list {
     float: left;
 }
 
-#new-template-description {
-    height: 210px;
-}
-
-/* upload */
-
-#select-template-container {
-}
-
-#template-browse-container {
-    display: block;
-    height: 20px;
-}
-
-#template-file-field {
-    height: 22px;
-    display: inline;
-    position: absolute;
-    top: -1px;
-    right: -1px;
-    float: right;
-    opacity: 0;
-    filter: alpha(opacity = 0);
-    z-index: 3000;
-    cursor: pointer;
-}
-
-.import-status-error {
-    color: #ff0000;
-}
-
-.import-status {
-    color: #888888;
-}
-
-#upload-template-container {
-    float: right;
-    position: relative;
-    top: -28px;
-    overflow: hidden;
-}
-
-#submit-template-container {
-    display: none;
-}
-
-#selected-template-name {
-    float: right;
-    font-weight: bold;
-    margin-right: 20px;
-    margin-top: 6px;
-    font-family: Roboto;
-    font-size: 13px;
-    color: #728e9b;
-}
-
-#upload-template-status {
-    float: right;
-    font-weight: bold;
-    margin-right: 20px;
-    margin-top: 6px;
-    line-height: normal;
-    font-family: Roboto;
-    font-size: 13px;
-    color: #728e9b;
-}
-
-#upload-template-container button {
-    float: right;
-    font-size: 16px;
-    line-height: 14px;
-    margin-left: 1px;
-}
-
-#template-upload-form-container {
-    display: none;
-}
-
-#upload-template-button {
-    margin-right: 0;
-}
-
-#template-file-upload {
-    position: absolute;
-    top: 0;
-    left: 0;
-    height: 22px;
-    width: 300px;
-}
-
 /* templates table */
 
 #templates-table {

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 0823f56..0d00e27 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
@@ -62,7 +62,9 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
                  * Launch the counters shell.
                  */
                 launch: function () {
-                    nf.Shell.showPage('counters');
+                    if (nf.Common.canAccessCounters()) {
+                        nf.Shell.showPage('counters');
+                    }
                 }
             }
         };
@@ -92,15 +94,6 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
         this.dataProvenance = {
 
             /**
-             * Determines if the data provenance menu item is enabled.
-             *
-             * @returns {*|boolean}
-             */
-            enabled: function () {
-                return nf.Common.canAccessProvenance();
-            },
-
-            /**
              * The data provenance menu item's shell controller.
              */
             shell: {
@@ -109,7 +102,9 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
                  * Launch the data provenance shell.
                  */
                 launch: function () {
-                    nf.Shell.showPage('provenance');
+                    if (nf.Common.canAccessProvenance()) {
+                        nf.Shell.showPage('provenance');
+                    }
                 }
             }
         };
@@ -128,14 +123,16 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
                  * Launch the settings shell.
                  */
                 launch: function () {
-                    nf.Settings.showSettings().done(function() {
-                        
$('#settings-refresh-container').width($('#shell').width());
-                        
-                        // add a shell:resize listener
-                        $('#shell').on('shell:resize', function () {
+                    if (nf.Common.canAccessController()) {
+                        nf.Settings.showSettings().done(function() {
                             
$('#settings-refresh-container').width($('#shell').width());
+                            
+                            // add a shell:resize listener
+                            $('#shell').on('shell:resize', function () {
+                                
$('#settings-refresh-container').width($('#shell').width());
+                            });
                         });
-                    });
+                    }
                 }
             }
         };
@@ -150,7 +147,7 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
              *
              * @returns {*|boolean}
              */
-            enabled: function () {
+            visible: function () {
                 return nf.Canvas.isClustered();
             },
 
@@ -163,7 +160,9 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
                  * Launch the cluster shell.
                  */
                 launch: function () {
-                    nf.Shell.showPage('cluster');
+                    if (nf.Common.canAccessController()) {
+                        nf.Shell.showPage('cluster');
+                    }
                 }
             }
         };
@@ -193,15 +192,6 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
         this.users = {
 
             /**
-             * Determines if the users menu item is enabled.
-             *
-             * @returns {*|boolean}
-             */
-            enabled: function () {
-                return nf.Common.isAdmin();
-            },
-
-            /**
              * The users menu item's shell controller.
              */
             shell: {
@@ -210,7 +200,9 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
                  * Launch the users shell.
                  */
                 launch: function () {
-                    nf.Shell.showPage('users');
+                    if (nf.Common.canAccessTenants()) {
+                        nf.Shell.showPage('users');
+                    }
                 }
             }
         };

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 d14b724..cb329ba 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
@@ -89,6 +89,143 @@ nf.ng.Canvas.OperateCtrl = function () {
         };
 
         /**
+         * The canvas operator's create template component.
+         */
+        this.templateUpload = {
+
+            /**
+             * The canvas operator's create template component's modal.
+             */
+            modal: {
+
+                /**
+                 * Gets the modal element.
+                 *
+                 * @returns {*|jQuery|HTMLElement}
+                 */
+                getElement: function () {
+                    return $('#upload-template-dialog');
+                },
+
+                /**
+                 * Initialize the modal.
+                 */
+                init: function () {
+                    // initialize the form
+                    var templateForm = $('#template-upload-form').ajaxForm({
+                        url: '../nifi-api/process-groups/' + 
encodeURIComponent(nf.Canvas.getGroupId()) + '/templates/upload',
+                        dataType: 'xml',
+                        success: function (response, statusText, xhr, form) {
+                            // see if the import was successful
+                            if (response.documentElement.tagName === 
'templateEntity') {
+                                // close the dialog
+                                $('#upload-template-dialog').modal('hide');
+
+                                // close the settings dialog
+                                nf.Dialog.showOkDialog({
+                                    headerText: 'Success',
+                                    dialogContent: 'Template successfully 
imported.'
+                                });
+                            } else {
+                                // import failed
+                                var status = 'Unable to import template. 
Please check the log for errors.';
+                                if (response.documentElement.tagName === 
'errorResponse') {
+                                    // if a more specific error was given, use 
it
+                                    var errorMessage = 
response.documentElement.getAttribute('statusText');
+                                    if (!nf.Common.isBlank(errorMessage)) {
+                                        status = errorMessage;
+                                    }
+                                }
+                                $('#upload-template-status').text(status);
+                            }
+                        },
+                        error: function (xhr, statusText, error) {
+                            $('#upload-template-status').text(error);
+                        }
+                    });
+                    
+                    // configure the upload template dialog
+                    this.getElement().modal({
+                        headerText: 'Upload Template',
+                        buttons: [{
+                            buttonText: 'Upload',
+                            color: {
+                                base: '#728E9B',
+                                hover: '#004849',
+                                text: '#ffffff'
+                            },
+                            handler: {
+                                click: function () {
+                                    // submit the template
+                                    templateForm.submit();
+                                }
+                            }
+                        }, {
+                            buttonText: 'Cancel',
+                            color: {
+                                base: '#E3E8EB',
+                                hover: '#C7D2D7',
+                                text: '#004849'
+                            },
+                            handler: {
+                                click: function () {
+                                    // hide the dialog
+                                    $('#upload-template-dialog').modal('hide');
+
+                                    // reset the form to ensure that the 
change fire will fire
+                                    templateForm.resetForm();
+                                }
+                            }
+                        }],
+                        handler: {
+                            close: function () {
+                                // set the filename
+                                $('#selected-template-name').text('');
+                                $('#upload-template-status').text('');
+                            }
+                        }
+                    });
+
+                    // add a handler for the change file input chain event
+                    $('#template-file-field').on('change', function (e) {
+                        var filename = $(this).val();
+                        if (!nf.Common.isBlank(filename)) {
+                            filename = filename.replace(/^.*[\\\/]/, '');
+                        }
+
+                        // set the filename and clear any status
+                        $('#selected-template-name').text(filename);
+                        $('#upload-template-status').text('');
+                    });
+                },
+
+                /**
+                 * Updates the modal config.
+                 *
+                 * @param {string} name             The name of the property 
to update.
+                 * @param {object|array} config     The config for the `name`.
+                 */
+                update: function (name, config) {
+                    this.getElement().modal(name, config);
+                },
+
+                /**
+                 * Show the modal.
+                 */
+                show: function () {
+                    this.getElement().modal('show');
+                },
+
+                /**
+                 * Hide the modal.
+                 */
+                hide: function () {
+                    this.getElement().modal('hide');
+                }
+            }
+        };
+
+        /**
          * The canvas operator's fillcolor component.
          */
         this.fillcolor = {
@@ -275,6 +412,7 @@ nf.ng.Canvas.OperateCtrl = function () {
          */
         init: function () {
             this.template.modal.init();
+            this.templateUpload.modal.init();
             this.fillcolor.modal.init();
             this.fillcolor.modal.minicolors.init();
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-toolbox-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-toolbox-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-toolbox-controller.js
index 35a3a14..568e1be 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-toolbox-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-toolbox-controller.js
@@ -76,26 +76,13 @@ nf.ng.Canvas.ToolboxCtrl = function (processorComponent,
          * Initialize the toolbox controller.
          */
         init: function() {
-            // ensure the user can create graph components
-            if (nf.Common.isDFM()) {
-                // initialize modal dialogs
-                processorComponent.modal.init();
-                inputPortComponent.modal.init();
-                outputPortComponent.modal.init();
-                groupComponent.modal.init();
-                remoteGroupComponent.modal.init();
-                templateComponent.modal.init();
-            } else {
-                // disable components
-                processorComponent.disabled();
-                inputPortComponent.disabled();
-                outputPortComponent.disabled();
-                groupComponent.disabled();
-                remoteGroupComponent.disabled();
-                funnelComponent.disabled();
-                templateComponent.disabled();
-                labelComponent.disabled();
-            }
+            // initialize modal dialogs
+            processorComponent.modal.init();
+            inputPortComponent.modal.init();
+            outputPortComponent.modal.init();
+            groupComponent.modal.init();
+            remoteGroupComponent.modal.init();
+            templateComponent.modal.init();
         },
 
         /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 3c8a71a..b332c5b 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
@@ -161,18 +161,20 @@ nf.ng.TemplateComponent = function (serviceProvider) {
             var self = this;
             $.ajax({
                 type: 'GET',
-                url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + 
'/process-groups/' + encodeURIComponent(nf.Canvas.getGroupId()) + '/templates',
+                url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + 
'/flow/templates',
                 dataType: 'json'
             }).done(function (response) {
                 var templates = response.templates;
                 if (nf.Common.isDefinedAndNotNull(templates) && 
templates.length > 0) {
                     var options = [];
-                    $.each(templates, function (_, template) {
-                        options.push({
-                            text: template.name,
-                            value: template.id,
-                            description: 
nf.Common.escapeHtml(template.description)
-                        });
+                    $.each(templates, function (_, templateEntity) {
+                        if (templateEntity.accessPolicy.canRead === true) {
+                            options.push({
+                                text: templateEntity.template.name,
+                                value: templateEntity.id,
+                                description: 
nf.Common.escapeHtml(templateEntity.template.description)
+                            });
+                        }
                     });
 
                     // configure the templates combo

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 747be03..3cd8c55 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
@@ -1170,6 +1170,13 @@ nf.Actions = (function () {
         },
 
         /**
+         * Uploads a new template.
+         */
+        uploadTemplate: function () {
+            $('#upload-template-dialog').modal('show');
+        },
+
+        /**
          * Creates a new template based off the currently selected components. 
If no components
          * are selected, a template of the entire canvas is made.
          */

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/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 0104b36..ed9327e 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
@@ -126,8 +126,7 @@ nf.Canvas = (function () {
     var config = {
         urls: {
             api: '../nifi-api',
-            identity: '../nifi-api/flow/identity',
-            authorities: '../nifi-api/flow/authorities',
+            currentUser: '../nifi-api/flow/current-user',
             kerberos: '../nifi-api/access/kerberos',
             revision: '../nifi-api/flow/revision',
             banners: '../nifi-api/flow/banners',
@@ -168,54 +167,6 @@ nf.Canvas = (function () {
     };
 
     /**
-     * Checks the current revision against this version of the flow.
-     */
-    // var checkRevision = function () {
-    //     // get the revision
-    //     return $.ajax({
-    //         type: 'GET',
-    //         url: config.urls.revision,
-    //         dataType: 'json'
-    //     }).done(function (response) {
-    //         if (nf.Common.isDefinedAndNotNull(response.revision)) {
-    //             var revision = response.revision;
-    //             var currentRevision = nf.Client.getRevision();
-    //
-    //             // if there is a newer revision, there are outstanding
-    //             // changes that need to be updated
-    //             if (revision.version > currentRevision.version && 
revision.clientId !== currentRevision.clientId) {
-    //                 var refreshContainer = $('#refresh-required-container');
-    //                 var settingsRefreshIcon = 
$('#settings-refresh-required-icon');
-    //
-    //                 // insert the refresh needed text in the canvas - if 
necessary
-    //                 if (!refreshContainer.is(':visible')) {
-    //                     $('#stats-last-refreshed').addClass('alert');
-    //                     var refreshMessage = "This flow has been modified 
by '" + revision.lastModifier + "'. Please refresh.";
-    //
-    //                     // update the tooltip
-    //                     var refreshRequiredIcon = 
$('#refresh-required-icon');
-    //                     if (refreshRequiredIcon.data('qtip')) {
-    //                         refreshRequiredIcon.qtip('option', 
'content.text', refreshMessage);
-    //                     } else {
-    //                         refreshRequiredIcon.qtip($.extend({
-    //                             content: refreshMessage
-    //                         }, nf.CanvasUtils.config.systemTooltipConfig));
-    //                     }
-    //
-    //                     refreshContainer.show();
-    //                 }
-    //
-    //                 // insert the refresh needed text in the settings - if 
necessary
-    //                 if (!settingsRefreshIcon.is(':visible')) {
-    //                     $('#settings-last-refreshed').addClass('alert');
-    //                     settingsRefreshIcon.show();
-    //                 }
-    //             }
-    //         }
-    //     }).fail(nf.Common.handleAjaxError);
-    // };
-
-    /**
      * Initializes the canvas.
      */
     var initCanvas = function () {
@@ -563,7 +514,7 @@ nf.Canvas = (function () {
                     evt.preventDefault();
                 } else if (evt.keyCode === 67) {
                     // ctrl-c
-                    if (nf.Common.isDFM() && 
nf.CanvasUtils.isCopyable(selection)) {
+                    if (nf.Canvas.canWrite() && 
nf.CanvasUtils.isCopyable(selection)) {
                         nf.Actions.copy(selection);
 
                         // only want to prevent default if the action was 
performed, otherwise default copy would be overridden
@@ -571,7 +522,7 @@ nf.Canvas = (function () {
                     }
                 } else if (evt.keyCode === 86) {
                     // ctrl-v
-                    if (nf.Common.isDFM() && nf.CanvasUtils.isPastable()) {
+                    if (nf.Canvas.canWrite() && nf.CanvasUtils.isPastable()) {
                         nf.Actions.paste(selection);
 
                         // only want to prevent default if the action was 
performed, otherwise default paste would be overridden
@@ -581,7 +532,7 @@ nf.Canvas = (function () {
             } else {
                 if (evt.keyCode === 8 || evt.keyCode === 46) {
                     // backspace or delete
-                    if (nf.Common.isDFM() && 
nf.CanvasUtils.areDeletable(selection)) {
+                    if (nf.Canvas.canWrite() && 
nf.CanvasUtils.areDeletable(selection)) {
                         nf.Actions['delete'](selection);
                     }
 
@@ -755,36 +706,22 @@ nf.Canvas = (function () {
                 }
             }).promise();
 
-            // load the identity and authorities for the current user
+            // load the current user
             var userXhr = $.Deferred(function (deferred) {
                 ticketExchange.always(function () {
-                    // get the current user's identity
-                    var identityXhr = $.ajax({
-                        type: 'GET',
-                        url: config.urls.identity,
-                        dataType: 'json'
-                    });
-
-                    // get the current user's authorities
-                    var authoritiesXhr = $.ajax({
+                    // get the current user
+                    $.ajax({
                         type: 'GET',
-                        url: config.urls.authorities,
+                        url: config.urls.currentUser,
                         dataType: 'json'
-                    });
-
-                    $.when(authoritiesXhr, identityXhr).done(function 
(authoritiesResult, identityResult) {
-                        var authoritiesResponse = authoritiesResult[0];
-                        var identityResponse = identityResult[0];
-
-                        // set the user's authorities
-                        
nf.Common.setAuthorities(authoritiesResponse.authorities);
-
+                    }).done(function (currentUser) {
                         // at this point the user may be themselves or 
anonymous
-
+                        nf.Common.setCurrentUser(currentUser)
+                        
                         // if the user is logged, we want to determine if they 
were logged in using a certificate
-                        if (identityResponse.anonymous === false) {
-                            // rendner the users name
-                            
$('#current-user').text(identityResponse.identity).show();
+                        if (currentUser.anonymous === false) {
+                            // render the users name
+                            
$('#current-user').text(currentUser.identity).show();
 
                             // render the logout button if there is a token 
locally
                             if (nf.Storage.getItem('jwt') !== null) {
@@ -805,6 +742,7 @@ nf.Canvas = (function () {
                     });
                 });
             }).promise();
+            
             userXhr.done(function () {
                 // load the client id
                 var clientXhr = nf.Client.init();

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
index b5b1156..77258b7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
@@ -172,7 +172,7 @@ nf.ContextMenu = (function () {
      * @param {selection} selection         The selection of currently 
selected components
      */
     var isPastable = function (selection) {
-        return nf.Common.isDFM() && nf.CanvasUtils.isPastable();
+        return nf.Canvas.canWrite() && nf.CanvasUtils.isPastable();
     };
 
     /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-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-processor-configuration.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
index d7c4c35..e60699b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
@@ -580,11 +580,6 @@ nf.ProcessorConfiguration = (function () {
                     dataType: 'json'
                 }));
 
-                // get the processor state if we're a DFM
-                if (nf.Common.isDFM()) {
-                    requests.push();
-                }
-
                 // once everything is loaded, show the dialog
                 $.when.apply(window, requests).done(function (processorResult, 
historyResult) {
                     // get the updated processor'

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-remote-process-group-ports.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-remote-process-group-ports.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-remote-process-group-ports.js
index 7cd6720..9907c6c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-remote-process-group-ports.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-remote-process-group-ports.js
@@ -156,12 +156,13 @@ nf.RemoteProcessGroupPorts = (function () {
                 },
                 handler: {
                     click: function () {
-                        // if this is a DFM, the over status of this node may 
have changed
-                        if (nf.Common.isDFM()) {
-                            // get the component in question
-                            var remoteProcessGroupId = 
$('#remote-process-group-ports-id').text();
-                            var remoteProcessGroupData = d3.select('#id-' + 
remoteProcessGroupId).datum();
+                        // get the component in question
+                        var remoteProcessGroupId = 
$('#remote-process-group-ports-id').text();
+                        var remoteProcessGroup = d3.select('#id-' + 
remoteProcessGroupId);
+                        var remoteProcessGroupData = 
remoteProcessGroup.datum();
 
+                        // if can modify, the over status of this node may 
have changed
+                        if (nf.CanvasUtils.canModify(remoteProcessGroup)) {
                             // reload the remote process group
                             
nf.RemoteProcessGroup.reload(remoteProcessGroupData.component);
                         }
@@ -204,8 +205,12 @@ nf.RemoteProcessGroupPorts = (function () {
         var portContainerEditContainer = $('<div 
class="remote-port-edit-container"></div>').appendTo(portContainer);
         var portContainerDetailsContainer = $('<div 
class="remote-port-details-container"></div>').appendTo(portContainer);
 
-        // only DFMs can update the remote group port
-        if (nf.Common.isDFM()) {
+        // get the component in question
+        var remoteProcessGroupId = $('#remote-process-group-ports-id').text();
+        var remoteProcessGroup = d3.select('#id-' + remoteProcessGroupId);
+
+        // if can modify, support updating the remote group port
+        if (nf.CanvasUtils.canModify(remoteProcessGroup)) {
             // show the enabled transmission switch
             var transmissionSwitch;
             if (port.connected === true) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index 707cecf..cca62ce 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -922,6 +922,12 @@ nf.Settings = (function () {
      * Shows the process group configuration.
      */
     var showSettings = function () {
+        if (nf.Common.canModifyController()) {
+            $('#new-service-or-task').show();
+        } else {
+            $('#new-service-or-task').hide();
+        }
+
         // show the settings dialog
         nf.Shell.showContent('#settings').done(function () {
             reset();
@@ -964,18 +970,20 @@ nf.Settings = (function () {
                         $('#new-service-or-task').hide();
                         $('#settings-save').show();
                     } else {
-                        $('#new-service-or-task').show();
-
-                        // update the tooltip on the button
-                        $('#new-service-or-task').attr('title', function () {
-                            if (tab === 'Controller Services') {
-                                $('#settings-save').hide();
-                                return 'Create a new controller service';
-                            } else if (tab === 'Reporting Tasks') {
-                                $('#settings-save').hide();
-                                return 'Create a new reporting task';
-                            }
-                        });
+                        if (nf.Common.canModifyController()) {
+                            $('#new-service-or-task').show();
+
+                            // update the tooltip on the button
+                            $('#new-service-or-task').attr('title', function 
() {
+                                if (tab === 'Controller Services') {
+                                    $('#settings-save').hide();
+                                    return 'Create a new controller service';
+                                } else if (tab === 'Reporting Tasks') {
+                                    $('#settings-save').hide();
+                                    return 'Create a new reporting task';
+                                }
+                            });
+                        }
 
                         // resize the table
                         nf.Settings.resetTableSize();

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster-table.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster-table.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster-table.js
index 7aa2450..5d25e4e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster-table.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster-table.js
@@ -426,7 +426,7 @@ nf.ClusterTable = (function () {
             ];
 
             // only allow the admin to modify the cluster
-            if (nf.Common.isAdmin()) {
+            if (nf.Common.canModifyController()) {
                 // function for formatting the actions column
                 var actionFormatter = function (row, cell, value, columnDef, 
dataContext) {
                     var canDisconnect = false;
@@ -477,7 +477,7 @@ nf.ClusterTable = (function () {
 
             // initialize the sort
             sort({
-                columnId: 'userName',
+                columnId: 'node',
                 sortAsc: true
             }, clusterData);
 
@@ -487,7 +487,7 @@ nf.ClusterTable = (function () {
             clusterGrid.setSortColumn('node', true);
             clusterGrid.onSort.subscribe(function (e, args) {
                 sort({
-                    columnId: args.sortCol.field,
+                    columnId: args.sortCol.id,
                     sortAsc: args.sortAsc
                 }, clusterData);
             });

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster.js
index 383d8ce..ae672bb 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/cluster/nf-cluster.js
@@ -37,32 +37,21 @@ nf.Cluster = (function () {
         urls: {
             banners: '../nifi-api/flow/banners',
             about: '../nifi-api/flow/about',
-            authorities: '../nifi-api/flow/authorities'
+            currentUser: '../nifi-api/flow/current-user'
         }
     };
 
     /**
-     * Loads the current users authorities.
+     * Loads the current user.
      */
-    var loadAuthorities = function () {
-        return $.Deferred(function (deferred) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.authorities,
-                dataType: 'json'
-            }).done(function (response) {
-                if (nf.Common.isDefinedAndNotNull(response.authorities)) {
-                    // record the users authorities
-                    nf.Common.setAuthorities(response.authorities);
-                    deferred.resolve();
-                } else {
-                    deferred.reject();
-                }
-            }).fail(function (xhr, status, error) {
-                nf.Common.handleAjaxError(xhr, status, error);
-                deferred.reject();
-            });
-        }).promise();
+    var loadCurrentUser = function () {
+        return $.ajax({
+            type: 'GET',
+            url: config.urls.currentUser,
+            dataType: 'json'
+        }).done(function (currentUser) {
+            nf.Common.setCurrentUser(currentUser);
+        }).fail(nf.Common.handleAjaxError);
     };
 
     /**
@@ -131,8 +120,8 @@ nf.Cluster = (function () {
         init: function () {
             nf.Storage.init();
             
-            // load the users authorities
-            loadAuthorities().done(function () {
+            // load the current user
+            loadCurrentUser().done(function () {
                 // create the counters table
                 nf.ClusterTable.init();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
index 3c32a0d..81854ee 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
@@ -173,7 +173,7 @@ nf.CountersTable = (function () {
             ];
 
             // only allow dfm's to reset counters
-            if (nf.Common.isDFM()) {
+            if (nf.Common.canModifyCounters()) {
                 // function for formatting the actions column
                 var actionFormatter = function (row, cell, value, columnDef, 
dataContext) {
                     return '<div title="Connect" class="pointer reset-counter 
fa fa-undo" style="margin-top: 2px;"></div>';

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters.js
index 4b7c921..6a6b36d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters.js
@@ -31,32 +31,22 @@ nf.Counters = (function () {
         urls: {
             banners: '../nifi-api/flow/banners',
             about: '../nifi-api/flow/about',
-            authorities: '../nifi-api/flow/authorities'
+            currentUser: '../nifi-api/flow/current-user'
         }
     };
 
     /**
-     * Loads the current users authorities.
+     * Loads the current user.
      */
-    var loadAuthorities = function () {
-        return $.Deferred(function (deferred) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.authorities,
-                dataType: 'json'
-            }).done(function (response) {
-                if (nf.Common.isDefinedAndNotNull(response.authorities)) {
-                    // record the users authorities
-                    nf.Common.setAuthorities(response.authorities);
-                    deferred.resolve();
-                } else {
-                    deferred.reject();
-                }
-            }).fail(function (xhr, status, error) {
-                nf.Common.handleAjaxError(xhr, status, error);
-                deferred.reject();
-            });
-        }).promise();
+    var loadCurrentUser = function () {
+        return $.ajax({
+            type: 'GET',
+            url: config.urls.currentUser,
+            dataType: 'json'
+        }).done(function (currentUser) {
+            nf.Common.setCurrentUser(currentUser);
+
+        }).fail(nf.Common.handleAjaxError);
     };
 
     /**
@@ -125,8 +115,8 @@ nf.Counters = (function () {
         init: function () {
             nf.Storage.init();
             
-            // load the users authorities
-            loadAuthorities().done(function () {
+            // load the current user
+            loadCurrentUser().done(function () {
                 // create the counters table
                 nf.CountersTable.init();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-model.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-model.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-model.js
index d55d96b..366a275 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-model.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-model.js
@@ -149,7 +149,7 @@
                     
$('.timezone').text(nf.Common.substringAfterLast(history.lastRefreshed, ' '));
 
                     // show the filter message if applicable
-                    if (query['sourceId'] || query['userName'] || 
query['startDate'] || query['endDate']) {
+                    if (query['sourceId'] || query['userIdentity'] || 
query['startDate'] || query['endDate']) {
                         $('#history-filter-overview').css('visibility', 
'visible');
                     } else {
                         $('#history-filter-overview').css('visibility', 
'hidden');

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-table.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-table.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-table.js
index 52816f6..1892f7b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-table.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history-table.js
@@ -119,7 +119,7 @@ nf.HistoryTable = (function () {
                             if (filterType === 'by id') {
                                 filter['sourceId'] = filterText;
                             } else if (filterType === 'by user') {
-                                filter['userName'] = filterText;
+                                filter['userIdentity'] = filterText;
                             }
                         }
 
@@ -274,6 +274,11 @@ nf.HistoryTable = (function () {
             return '<div title="View Details" class="pointer 
show-action-details fa fa-info-circle" style="margin-top: 4px;"></div>';
         };
 
+        // define how general values are formatted
+        var valueFormatter = function (row, cell, value, columnDef, 
dataContext) {
+            return nf.Common.formatValue(value);
+        };
+
         // initialize the templates table
         var historyColumns = [
             {
@@ -285,11 +290,11 @@ nf.HistoryTable = (function () {
                 width: 50,
                 maxWidth: 50
             },
-            {id: 'timestamp', name: 'Date/Time', field: 'timestamp', sortable: 
true, resizable: true},
-            {id: 'sourceName', name: 'Name', field: 'sourceName', sortable: 
true, resizable: true},
-            {id: 'sourceType', name: 'Type', field: 'sourceType', sortable: 
true, resizable: true},
-            {id: 'operation', name: 'Operation', field: 'operation', sortable: 
true, resizable: true},
-            {id: 'userName', name: 'User', field: 'userName', sortable: true, 
resizable: true}
+            {id: 'timestamp', name: 'Date/Time', field: 'timestamp', sortable: 
true, resizable: true, formatter: valueFormatter},
+            {id: 'sourceName', name: 'Name', field: 'sourceName', sortable: 
true, resizable: true, formatter: valueFormatter},
+            {id: 'sourceType', name: 'Type', field: 'sourceType', sortable: 
true, resizable: true, formatter: valueFormatter},
+            {id: 'operation', name: 'Operation', field: 'operation', sortable: 
true, resizable: true, formatter: valueFormatter},
+            {id: 'userIdentity', name: 'User', field: 'userIdentity', 
sortable: true, resizable: true, formatter: valueFormatter}
         ];
         var historyOptions = {
             forceFitColumns: true,
@@ -353,7 +358,7 @@ nf.HistoryTable = (function () {
         $('#history-table').data('gridInstance', historyGrid);
 
         // add the purge button if appropriate
-        if (nf.Common.isAdmin()) {
+        if (nf.Common.canModifyController()) {
             $('#history-purge-button').on('click', function () {
                 $('#history-purge-dialog').modal('show');
             }).show();

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history.js
index 674e862..c6087bc 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/history/nf-history.js
@@ -31,33 +31,21 @@ nf.History = (function () {
         urls: {
             banners: '../nifi-api/flow/banners',
             about: '../nifi-api/flow/about',
-            authorities: '../nifi-api/flow/authorities'
+            currentUser: '../nifi-api/flow/current-user'
         }
     };
 
     /**
-     * Loads the current users authorities.
+     * Loads the current user.
      */
-    var loadAuthorities = function () {
-        // get the banners and update the page accordingly
-        return $.Deferred(function (deferred) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.authorities,
-                dataType: 'json'
-            }).done(function (response) {
-                if (nf.Common.isDefinedAndNotNull(response.authorities)) {
-                    // record the users authorities
-                    nf.Common.setAuthorities(response.authorities);
-                    deferred.resolve();
-                } else {
-                    deferred.reject();
-                }
-            }).fail(function (xhr, status, error) {
-                nf.Common.handleAjaxError(xhr, status, error);
-                deferred.reject();
-            });
-        }).promise();
+    var loadCurrentUser = function () {
+        return $.ajax({
+            type: 'GET',
+            url: config.urls.currentUser,
+            dataType: 'json'
+        }).done(function (currentUser) {
+            nf.Common.setCurrentUser(currentUser);
+        }).fail(nf.Common.handleAjaxError);
     };
 
     /**
@@ -126,8 +114,8 @@ nf.History = (function () {
         init: function () {
             nf.Storage.init();
             
-            // load the users authorities
-            loadAuthorities().done(function () {
+            // load the current user
+            loadCurrentUser().done(function () {
                 // create the history table
                 nf.HistoryTable.init();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
index a200d29..11faba5 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
@@ -25,8 +25,6 @@ nf.Login = (function () {
 
     var config = {
         urls: {
-            identity: '../nifi-api/flow/identity',
-            users: '../nifi-api/controller/users',
             token: '../nifi-api/access/token',
             accessStatus: '../nifi-api/access',
             accessConfig: '../nifi-api/access/config'

http://git-wip-us.apache.org/repos/asf/nifi/blob/ce533033/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 144f8f5..7872964 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -114,17 +114,17 @@ nf.Common = (function () {
         SUPPORTS_SVG: !!document.createElementNS && 
!!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect,
 
         /**
-         * The authorities for the current user.
+         * The current user.
          */
-        authorities: undefined,
+        currentUser: undefined,
 
         /**
-         * Sets the authorities for the current user.
+         * Sets the current user.
          * 
-         * @argument {array} roles      The current users authorities
+         * @param currentUser
          */
-        setAuthorities: function (roles) {
-            nf.Common.authorities = roles;
+        setCurrentUser: function (currentUser) {
+            nf.Common.currentUser = currentUser;
         },
 
         /**
@@ -226,48 +226,89 @@ nf.Common = (function () {
          * @returns {boolean}
          */
         canAccessProvenance: function () {
-            var canAccessProvenance = false;
-            if (nf.Common.isDefinedAndNotNull(nf.Common.authorities)) {
-                $.each(nf.Common.authorities, function (i, authority) {
-                    if (authority === 'ROLE_PROVENANCE') {
-                        canAccessProvenance = true;
-                        return false;
-                    }
-                });
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.provenancePermissions.canRead === 
true;
+            } else {
+                return false;
             }
-            return canAccessProvenance;
         },
 
         /**
-         * Returns whether or not the current user is a DFM.
+         * Determines whether the current user can access counters.
+         * 
+         * @returns {boolean}
          */
-        isDFM: function () {
-            var dfm = false;
-            if (nf.Common.isDefinedAndNotNull(nf.Common.authorities)) {
-                $.each(nf.Common.authorities, function (i, authority) {
-                    if (authority === 'ROLE_DFM') {
-                        dfm = true;
-                        return false;
-                    }
-                });
+        canAccessCounters: function () {
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.countersPermissions.canRead === 
true;
+            } else {
+                return false;
             }
-            return dfm;
         },
 
         /**
-         * Returns whether or not the current user is a DFM.
+         * Determines whether the current user can modify counters.
+         * 
+         * @returns {boolean}
          */
-        isAdmin: function () {
-            var admin = false;
-            if (nf.Common.isDefinedAndNotNull(nf.Common.authorities)) {
-                $.each(nf.Common.authorities, function (i, authority) {
-                    if (authority === 'ROLE_ADMIN') {
-                        admin = true;
-                        return false;
-                    }
-                });
+        canModifyCounters: function () {
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.countersPermissions.canRead === 
true && nf.Common.currentUser.countersPermissions.canWrite === true;
+            } else {
+                return false;
+            }
+        },
+
+        /**
+         * Determines whether the current user can access tenants.
+         *
+         * @returns {boolean}
+         */
+        canAccessTenants: function () {
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.tenantsPermissions.canRead === 
true;
+            } else {
+                return false;
+            }
+        },
+
+        /**
+         * Determines whether the current user can modify tenants.
+         *
+         * @returns {boolean}
+         */
+        canModifyTenants: function () {
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.tenantsPermissions.canRead === 
true && nf.Common.currentUser.tenantsPermissions.canWrite === true;
+            } else {
+                return false;
+            }
+        },
+
+        /**
+         * Determines whether the current user can access the controller.
+         *
+         * @returns {boolean}
+         */
+        canAccessController: function () {
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.controllerPermissions.canRead === 
true;
+            } else {
+                return false;
+            }
+        },
+
+        /**
+         * Determines whether the current user can modify the controller.
+         *
+         * @returns {boolean}
+         */
+        canModifyController: function () {
+            if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+                return nf.Common.currentUser.controllerPermissions.canRead === 
true && nf.Common.currentUser.controllerPermissions.canWrite === true;
+            } else {
+                return false;
             }
-            return admin;
         },
 
         /**
@@ -508,7 +549,7 @@ nf.Common = (function () {
                 if (!nf.Common.isEmpty(propertyHistory.previousValues)) {
                     var history = [];
                     $.each(propertyHistory.previousValues, function (_, 
previousValue) {
-                        history.push('<li>' + 
nf.Common.escapeHtml(previousValue.previousValue) + ' - ' + 
nf.Common.escapeHtml(previousValue.timestamp) + ' (' + 
nf.Common.escapeHtml(previousValue.userName) + ')</li>');
+                        history.push('<li>' + 
nf.Common.escapeHtml(previousValue.previousValue) + ' - ' + 
nf.Common.escapeHtml(previousValue.timestamp) + ' (' + 
nf.Common.escapeHtml(previousValue.userIdentity) + ')</li>');
                     });
                     tipContent.push('<b>History:</b><ul 
class="property-info">' + history.join('') + '</ul>');
                 }

Reply via email to