Repository: nifi-registry
Updated Branches:
  refs/heads/master 287cc41fb -> 580f77549


http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
index 605965a..228f9dd 100644
--- 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
@@ -27,9 +27,8 @@ var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
 var NfRegistryAddUser = 
require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
-var NfRegistryUserDetails = 
require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = 
require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
-var NfRegistryUserGroupPermissions = 
require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
+var NfRegistryManageUser = 
require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
+var NfRegistryManageGroup = 
require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
 var NfRegistryBucketPermissions = 
require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = 
require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js');
@@ -41,6 +40,8 @@ var ngCommonHttp = require('@angular/common/http');
 var NfRegistryTokenInterceptor = 
require('nifi-registry/services/nf-registry.token.interceptor.js');
 var NfRegistryAuthService = 
require('nifi-registry/services/nf-registry.auth.service.js');
 var NfStorage = require('nifi-registry/services/nf-storage.service.js');
+var NfLoginComponent = 
require('nifi-registry/components/login/nf-registry-login.js');
+var NfUserLoginComponent = 
require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
 
 describe('NfRegistryExplorer Component', function () {
     var comp;
@@ -61,16 +62,17 @@ describe('NfRegistryExplorer Component', function () {
                 NfRegistryExplorer,
                 NfRegistryAdministration,
                 NfRegistryUsersAdministration,
-                NfRegistryUserDetails,
-                NfRegistryUserPermissions,
-                NfRegistryUserGroupPermissions,
+                NfRegistryManageUser,
+                NfRegistryManageGroup,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
                 NfRegistryGridListViewer,
                 NfRegistryBucketGridListViewer,
                 NfRegistryDropletGridListViewer,
-                NfPageNotFoundComponent
+                NfPageNotFoundComponent,
+                NfLoginComponent,
+                NfUserLoginComponent
             ],
             providers: [
                 NfRegistryService,

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.html
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.html
 
b/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.html
new file mode 100644
index 0000000..5fc9c6c
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.html
@@ -0,0 +1,45 @@
+<!--
+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.
+-->
+
+<div id="nifi-registry-user-login-dialog">
+    <div class="pad-bottom-md" fxLayout="row" fxLayoutAlign="space-between 
center">
+        <span class="md-card-title">Log In</span>
+    </div>
+    <div fxLayout="column" fxLayoutAlign="space-between start" 
class="pad-bottom-md">
+        <div class="pad-bottom-md fill-available-width">
+            <mat-input-container floatPlaceholder="always" fxFlex>
+                <input #usernameInput matInput floatPlaceholder="always" 
placeholder="Username" focused="true">
+            </mat-input-container>
+        </div>
+        <div class="pad-bottom-md fill-available-width">
+            <mat-input-container floatPlaceholder="always" fxFlex>
+                <input #passwordInput type="password" matInput 
floatPlaceholder="always" placeholder="Password">
+            </mat-input-container>
+        </div>
+    </div>
+    <div fxLayout="row">
+        <span fxFlex></span>
+        <button (click)="usernameInput.value='';passwordInput.value=''" 
color="fds-regular" mat-raised-button
+                i18n="Clear log in form|A button for clearing the login 
form.@@nf-clear-user-login-button">
+            Clear
+        </button>
+        <button [disabled]="usernameInput.value.length === 0 || 
passwordInput.value.length === 0" class="push-left-sm" 
(click)="login(usernameInput, passwordInput)" color="fds-primary" 
mat-raised-button
+                i18n="Log in|A button for attempting to authenticate with the 
registry.@@nf-user-login-button">
+            Log In
+        </button>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.js
 
b/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.js
new file mode 100644
index 0000000..77fb7e2
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/login/dialogs/nf-registry-user-login.js
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+var ngCore = require('@angular/core');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var ngMaterial = require('@angular/material');
+
+/**
+ * NfRegistryUserLogin constructor.
+ *
+ * @param nfRegistryApi         The api service.
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param matDialogRef          The angular material dialog ref.
+ * @constructor
+ */
+function NfRegistryUserLogin(nfRegistryApi, nfRegistryService, matDialogRef) {
+    this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
+    this.dialogRef = matDialogRef;
+};
+
+NfRegistryUserLogin.prototype = {
+    constructor: NfRegistryUserLogin,
+
+    /**
+     * Submit login form.
+     *
+     * @param username  The user name.
+     * @param password  The password.
+     */
+    login: function (username, password) {
+        var self = this;
+        this.nfRegistryApi.postToLogin(username.value, 
password.value).subscribe(function(response){
+            if(!response.status || response.status === 200) {
+                //successful login
+                
self.nfRegistryService.router.navigateByUrl(self.nfRegistryService.redirectUrl);
+            }
+        });
+    }
+};
+
+NfRegistryUserLogin.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-user-login.html!text')
+    })
+];
+
+NfRegistryUserLogin.parameters = [
+    NfRegistryApi,
+    NfRegistryService,
+    ngMaterial.MatDialogRef
+];
+
+module.exports = NfRegistryUserLogin;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.html
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.html 
b/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.html
new file mode 100644
index 0000000..93d0efc
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.html
@@ -0,0 +1,19 @@
+<!--
+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.
+-->
+
+<div id="nifi-registry-login-perspective"></div>
+<router-outlet></router-outlet>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.js 
b/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.js
new file mode 100644
index 0000000..e81cc47
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/login/nf-registry-login.js
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+var ngCore = require('@angular/core');
+var ngMaterial = require('@angular/material');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
+var NfUserLoginComponent = 
require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
+
+/**
+ * NfLoginComponent constructor.
+ *
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param matDialog             The angular material dialog module.
+ */
+function NfLoginComponent(nfRegistryService, matDialog) {
+    // Services
+    this.nfRegistryService = nfRegistryService;
+    this.dialog = matDialog;
+};
+
+NfLoginComponent.prototype = {
+    constructor: NfLoginComponent,
+
+    /**
+     * Initialize the component
+     */
+    ngOnInit: function () {
+        this.nfRegistryService.perspective = 'login';
+        this.dialog.open(NfUserLoginComponent, {
+            disableClose: true
+        });
+    }
+};
+
+NfLoginComponent.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-login.html!text'),
+        animations: [nfRegistryAnimations.slideInLeftAnimation],
+        host: {
+            '[@routeAnimation]': 'routeAnimation'
+        }
+    })
+];
+
+NfLoginComponent.parameters = [
+    NfRegistryService,
+    ngMaterial.MatDialog
+];
+
+module.exports = NfLoginComponent;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.html
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.html
 
b/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.html
new file mode 100644
index 0000000..00c9582
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.html
@@ -0,0 +1,19 @@
+<!--
+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.
+-->
+
+<div id="nifi-registry-not-found-perspective"></div>
+<router-outlet></router-outlet>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.js
 
b/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.js
index 26c676b..28c1447 100644
--- 
a/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.js
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/page-not-found/nf-registry-page-not-found.js
@@ -15,22 +15,57 @@
  * limitations under the License.
  */
 var ngCore = require('@angular/core');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
+var fdsDialogsModule = require('@fluid-design-system/dialogs');
 
 /**
- * NfPageNotFoundComponent constructor.
+ * NfLoginComponent constructor.
+ *
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param fdsDialogService      The FDS dialog service.
  */
-function NfPageNotFoundComponent() {
-    this.title = "Page Not Found!!!!";
+function NfPageNotFoundComponent(nfRegistryService, fdsDialogService) {
+    // Services
+    this.nfRegistryService = nfRegistryService;
+    this.dialogService = fdsDialogService;
 };
 
 NfPageNotFoundComponent.prototype = {
-    constructor: NfPageNotFoundComponent
+    constructor: NfPageNotFoundComponent,
+
+    /**
+     * Initialize the component
+     */
+    ngOnInit: function () {
+        var self = this;
+        this.nfRegistryService.perspective = 'not-found';
+        this.dialogService.openConfirm({
+            title: 'Page Not Found',
+            acceptButton: 'Home',
+            acceptButtonColor: 'fds-warn'
+        }).afterClosed().subscribe(
+            function (accept) {
+                if (accept) {
+                    
self.nfRegistryService.router.navigateByUrl(self.nfRegistryService.redirectUrl);
+                }
+            });
+    }
 };
 
 NfPageNotFoundComponent.annotations = [
     new ngCore.Component({
-        template: '<h1>Hello {{title}}!</h1>'
+        template: require('./nf-registry-page-not-found.html!text'),
+        animations: [nfRegistryAnimations.slideInLeftAnimation],
+        host: {
+            '[@routeAnimation]': 'routeAnimation'
+        }
     })
 ];
 
+NfPageNotFoundComponent.parameters = [
+    NfRegistryService,
+    fdsDialogsModule.FdsDialogService,
+];
+
 module.exports = NfPageNotFoundComponent;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/nf-registry.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.html 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.html
index b175233..21eaffa 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.html
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.html
@@ -23,7 +23,7 @@ limitations under the License.
     <div id="nf-registry-app-container">
         <mat-toolbar id="nifi-registry-toolbar">
             <img id="nifi-registry-logo" 
src="nifi-registry/images/registry-logo-web-app.svg">
-            <div fxFlex="1 1 auto" class="pad-left-xl" 
[@flyInOut]="nfRegistryService.breadCrumbState">
+            <div *ngIf="nfRegistryService.perspective !== 'login' && 
nfRegistryService.perspective !== 'not-found'" fxFlex="1 1 auto" 
class="pad-left-xl" [@flyInOut]="nfRegistryService.breadCrumbState">
                 <span class="pointer" 
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}">{{nfRegistryService.registry.name}}</span>
                 <mat-menu #availableRegistriesMenu="matMenu" 
[overlapTrigger]="false">
                     <button mat-menu-item *ngFor="let registry of 
nfRegistryService.registries"
@@ -37,11 +37,11 @@ limitations under the License.
                         class="fa fa-caret-down pad-left-sm" 
aria-hidden="true"></i></span>
                 <span class="pointer" *ngIf="nfRegistryService.perspective === 
'explorer' && !nfRegistryService.bucket.identifier"
                       [matMenuTriggerFor]="availableBucketsMenu"> / All<i 
class="fa fa-caret-down pad-left-sm"
-                                                                         
aria-hidden="true"></i></span>
+                                                                          
aria-hidden="true"></i></span>
                 <mat-menu #availableBucketsMenu="matMenu" 
[overlapTrigger]="false">
                     <button mat-menu-item
                             
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}">
-                        <span>All buckets...</span>
+                        <span>All buckets</span>
                     </button>
                     <button mat-menu-item *ngFor="let bucket of 
nfRegistryService.buckets"
                             
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/buckets/{{bucket.identifier}}">
@@ -57,7 +57,7 @@ limitations under the License.
                 <mat-menu #availableDropletsMenu="matMenu" 
[overlapTrigger]="false">
                     <button mat-menu-item
                             
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/buckets/{{nfRegistryService.bucket.identifier}}">
-                        <span>All droplets...</span>
+                        <span>All resources</span>
                     </button>
                     <button mat-menu-item *ngFor="let droplet of 
nfRegistryService.droplets"
                             
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}/{{droplet.link.href}}">
@@ -71,15 +71,15 @@ limitations under the License.
             <button *ngIf="false" matTooltip="Alerts" mat-icon-button>
                 <i class="fa fa-bell" aria-hidden="true"></i>
             </button>
-            <div *ngIf="nfRegistryService.currentUser.identity" 
fxLayout="column" fxLayoutAlign="space-around end" class="push-right-sm">
+            <div *ngIf="nfRegistryService.currentUser.identity && 
nfRegistryService.perspective !== 'login' && nfRegistryService.perspective !== 
'not-found'" fxLayout="column" fxLayoutAlign="space-around end" 
class="push-right-sm">
                 <div id="current-user" 
matTooltip="{{nfRegistryService.currentUser.identity}}">{{nfRegistryService.currentUser.identity}}</div>
                 <a id="logout-link-container" 
*ngIf="nfRegistryService.currentUser.canLogout" class="link" 
(click)="logout()">logout</a>
             </div>
-            <button mat-ripple *ngIf="nfRegistryService.perspective === 
'explorer'" mat-icon-button
+            <button mat-ripple 
*ngIf="nfRegistryService.currentUser.resourcePermissions.anyTopLevelResource.canRead
 && nfRegistryService.perspective === 'explorer'" mat-icon-button
                     routerLink="/nifi-registry/administration/workflow">
                 <i class="fa fa-wrench" aria-hidden="true"></i>
             </button>
-            <button mat-ripple *ngIf="nfRegistryService.perspective === 
'administration'" mat-mini-fab
+            <button [matTooltip]="'Close administration.'" mat-ripple 
*ngIf="nfRegistryService.perspective === 'administration'" mat-mini-fab
                     
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}">
                 <mat-icon color="primary">close</mat-icon>
             </button>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/nf-registry.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.js
index df344f7..edf840c 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.js
@@ -68,7 +68,8 @@ NfRegistry.prototype = {
      * Invalidate old tokens and route to login page
      */
     logout: function() {
-        this.nfRegistryService.currentUser = {};
+        delete this.nfRegistryService.currentUser.identity;
+        delete this.nfRegistryService.currentUser.anonymous;
         this.nfStorage.removeItem('jwt');
         this.router.navigateByUrl('/nifi-registry/login');
     }

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
index c862dab..b250d13 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
@@ -23,15 +23,17 @@ var NfRegistry = require('nifi-registry/nf-registry.js');
 var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
 var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
 var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
+var NfLoginComponent = 
require('nifi-registry/components/login/nf-registry-login.js');
+var NfUserLoginComponent = 
require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
 var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
 var NfRegistryAddUser = 
require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
 var NfRegistryCreateNewGroup = 
require('nifi-registry/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js');
-var NfRegistryAddSelectedToGroup = 
require('nifi-registry/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js');
-var NfRegistryUserDetails = 
require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = 
require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
-var NfRegistryUserGroupPermissions = 
require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
+var NfRegistryAddUserToGroups = 
require('nifi-registry/components/administration/users/dialogs/add-user-to-groups/nf-registry-add-user-to-groups.js');
+var NfRegistryAddUsersToGroup = 
require('nifi-registry/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js');
+var NfRegistryManageUser = 
require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
+var NfRegistryManageGroup = 
require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
 var NfRegistryBucketPermissions = 
require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = 
require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryCreateBucket = 
require('nifi-registry/components/administration/workflow/dialogs/nf-registry-create-bucket.js');
@@ -42,6 +44,7 @@ var fdsCore = require('@fluid-design-system/core');
 var ngCommonHttp = require('@angular/common/http');
 var NfRegistryTokenInterceptor = 
require('nifi-registry/services/nf-registry.token.interceptor.js');
 var NfRegistryAuthService = 
require('nifi-registry/services/nf-registry.auth.service.js');
+var nfRegistryAuthGuardService = 
require('nifi-registry/services/nf-registry.auth-guard.service.js');
 var NfStorage = require('nifi-registry/services/nf-storage.service.js');
 
 function NfRegistryModule() {
@@ -65,29 +68,37 @@ NfRegistryModule.annotations = [
             NfRegistryExplorer,
             NfRegistryAdministration,
             NfRegistryUsersAdministration,
-            NfRegistryUserDetails,
-            NfRegistryUserPermissions,
-            NfRegistryUserGroupPermissions,
+            NfRegistryManageUser,
+            NfRegistryManageGroup,
             NfRegistryBucketPermissions,
             NfRegistryWorkflowAdministration,
             NfRegistryAddUser,
             NfRegistryCreateBucket,
             NfRegistryCreateNewGroup,
-            NfRegistryAddSelectedToGroup,
+            NfRegistryAddUserToGroups,
+            NfRegistryAddUsersToGroup,
             NfRegistryGridListViewer,
             NfRegistryBucketGridListViewer,
             NfRegistryDropletGridListViewer,
-            NfPageNotFoundComponent
+            NfPageNotFoundComponent,
+            NfLoginComponent,
+            NfUserLoginComponent
         ],
         entryComponents: [
             NfRegistryAddUser,
             NfRegistryCreateBucket,
             NfRegistryCreateNewGroup,
-            NfRegistryAddSelectedToGroup
+            NfRegistryAddUserToGroups,
+            NfRegistryAddUsersToGroup,
+            NfUserLoginComponent
         ],
         providers: [
             NfRegistryService,
             NfRegistryAuthService,
+            nfRegistryAuthGuardService.NfRegistryUsersAdministrationAuthGuard,
+            
nfRegistryAuthGuardService.NfRegistryWorkflowsAdministrationAuthGuard,
+            nfRegistryAuthGuardService.NfRegistryLoginAuthGuard,
+            nfRegistryAuthGuardService.NfRegistryResourcesAuthGuard,
             NfRegistryApi,
             NfStorage,
             {

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
index 4cf5f60..9413777 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
@@ -18,17 +18,18 @@
 var ngRouter = require('@angular/router');
 var FdsDemo = 
require('nifi-registry/components/fluid-design-system/fds-demo.js');
 var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
+var NfLoginComponent = 
require('nifi-registry/components/login/nf-registry-login.js');
 var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
-var NfRegistryUserDetails = 
require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = 
require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
-var NfRegistryUserGroupPermissions = 
require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
+var NfRegistryManageUser = 
require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
+var NfRegistryManageGroup = 
require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
 var NfRegistryBucketPermissions = 
require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = 
require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js');
 var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
 var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
+var nfRegistryAuthGuardService = 
require('nifi-registry/services/nf-registry.auth-guard.service.js');
 
 var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
     path: 'nifi-registry/explorer',
@@ -36,17 +37,23 @@ var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
     children: [
         {
             path: 'grid-list',
-            component: NfRegistryGridListViewer
+            component: NfRegistryGridListViewer,
+            canActivate: 
[nfRegistryAuthGuardService.NfRegistryResourcesAuthGuard]
         }, {
             path: 'grid-list/buckets/:bucketId',
-            component: NfRegistryBucketGridListViewer
+            component: NfRegistryBucketGridListViewer,
+            canActivate: 
[nfRegistryAuthGuardService.NfRegistryResourcesAuthGuard]
         },
         {
             path: 'grid-list/buckets/:bucketId/:dropletType/:dropletId',
-            component: NfRegistryDropletGridListViewer
+            component: NfRegistryDropletGridListViewer,
+            canActivate: 
[nfRegistryAuthGuardService.NfRegistryResourcesAuthGuard]
         }
-        ]
-    // canActivate: [AuthGuard] //TODO: 
https://angular.io/api/router/CanActivate 
https://scotch.io/tutorials/routing-angular-2-single-page-apps-with-the-component-router
+    ]
+}, {
+    path: 'nifi-registry/login',
+    component: NfLoginComponent,
+    canActivate: [nfRegistryAuthGuardService.NfRegistryLoginAuthGuard]
 }, {
     path: 'nifi-registry/fluid-design-system',
     component: FdsDemo
@@ -55,14 +62,16 @@ var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
     component: NfRegistryAdministration,
     children: [{
         path: '',
-        redirectTo: 'users',
+        redirectTo: 'workflow',
         pathMatch: 'full'
     }, {
         path: 'users',
-        component: NfRegistryUsersAdministration
+        component: NfRegistryUsersAdministration,
+        canActivate: 
[nfRegistryAuthGuardService.NfRegistryUsersAdministrationAuthGuard]
     }, {
         path: 'workflow',
-        component: NfRegistryWorkflowAdministration
+        component: NfRegistryWorkflowAdministration,
+        canActivate: 
[nfRegistryAuthGuardService.NfRegistryWorkflowsAdministrationAuthGuard]
     }]
 }, {
     path: 'nifi-registry/explorer/grid-list/buckets',
@@ -80,20 +89,19 @@ var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
     path: '**',
     component: NfPageNotFoundComponent
 }, {
-    path: 'user/details/:userId',
-    component: NfRegistryUserDetails,
-    outlet: 'sidenav'
-}, {
-    path: 'user/permissions/:userId',
-    component: NfRegistryUserPermissions,
+    path: 'manage/user/:userId',
+    component: NfRegistryManageUser,
+    canActivate: 
[nfRegistryAuthGuardService.NfRegistryUsersAdministrationAuthGuard],
     outlet: 'sidenav'
 }, {
-    path: 'group/permissions/:groupId',
-    component: NfRegistryUserGroupPermissions,
+    path: 'manage/group/:groupId',
+    component: NfRegistryManageGroup,
+    canActivate: 
[nfRegistryAuthGuardService.NfRegistryUsersAdministrationAuthGuard],
     outlet: 'sidenav'
 }, {
     path: 'bucket/permissions/:bucketId',
     component: NfRegistryBucketPermissions,
+    canActivate: 
[nfRegistryAuthGuardService.NfRegistryWorkflowsAdministrationAuthGuard],
     outlet: 'sidenav'
 }]);
 

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/nf-registry.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.spec.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.spec.js
index 98ba0d4..09632be 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.spec.js
@@ -27,9 +27,8 @@ var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
 var NfRegistryAddUser = 
require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
-var NfRegistryUserGroupPermissions = 
require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
-var NfRegistryUserDetails = 
require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = 
require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
+var NfRegistryManageGroup = 
require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
+var NfRegistryManageUser = 
require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
 var NfRegistryBucketPermissions = 
require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = 
require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js');
@@ -42,6 +41,8 @@ var ngCommonHttp = require('@angular/common/http');
 var NfRegistryTokenInterceptor = 
require('nifi-registry/services/nf-registry.token.interceptor.js');
 var NfRegistryAuthService = 
require('nifi-registry/services/nf-registry.auth.service.js');
 var NfStorage = require('nifi-registry/services/nf-storage.service.js');
+var NfLoginComponent = 
require('nifi-registry/components/login/nf-registry-login.js');
+var NfUserLoginComponent = 
require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
 
 describe('NfRegistry Component', function () {
     var comp;
@@ -64,16 +65,17 @@ describe('NfRegistry Component', function () {
                 NfRegistryExplorer,
                 NfRegistryAdministration,
                 NfRegistryUsersAdministration,
-                NfRegistryUserDetails,
-                NfRegistryUserPermissions,
-                NfRegistryUserGroupPermissions,
+                NfRegistryManageUser,
+                NfRegistryManageGroup,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
                 NfRegistryGridListViewer,
                 NfRegistryBucketGridListViewer,
                 NfRegistryDropletGridListViewer,
-                NfPageNotFoundComponent
+                NfPageNotFoundComponent,
+                NfLoginComponent,
+                NfUserLoginComponent
             ],
             providers: [
                 NfRegistryService,

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
index 5491c25..08bec02 100644
--- a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
+++ b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
@@ -264,10 +264,15 @@ NfRegistryApi.prototype = {
             });
     },
 
-    //TODO: REST call to API to get user by id.
+    /**
+     * Get user by id.
+     *
+     * @param userId
+     * @returns {*}
+     */
     getUser: function (userId) {
         var self = this;
-        return this.http.get('/nifi-registry-api/users/' + userId)
+        return this.http.get('/nifi-registry-api/tenants/users/' + userId)
             .map(function (response) {
                 return response;
             })
@@ -285,15 +290,40 @@ NfRegistryApi.prototype = {
     /**
      * Creates a user.
      *
-     * @param {string} identifier   The identifier of the user.
      * @param {string} identity     The identity of the user.
      * @returns {*}
      */
-    addUser: function (identifier, identity) {
+    addUser: function (identity) {
         var self = this;
         return this.http.post('/nifi-registry-api/tenants/users', {
-            'identifier': identifier,
-            'identity': identity
+            identity: identity,
+            resourcePermissions: {
+                anyTopLevelResource: {
+                    canRead: false,
+                    canWrite: false,
+                    canDelete: false
+                },
+                buckets: {
+                    canRead: false,
+                    canWrite: false,
+                    canDelete: false
+                },
+                tenants: {
+                    canRead: false,
+                    canWrite: false,
+                    canDelete: false
+                },
+                policies: {
+                    canRead: false,
+                    canWrite: false,
+                    canDelete: false
+                },
+                proxy: {
+                    canRead: false,
+                    canWrite: false,
+                    canDelete: false
+                }
+            }
         }, headers)
             .map(function (response) {
                 return response;
@@ -310,6 +340,27 @@ NfRegistryApi.prototype = {
     },
 
     /**
+     * Updates a user.
+     *
+     * @param {string} identifier   The identifier of the user.
+     * @param {string} identity     The identity of the user.
+     * @returns {*}
+     */
+    updateUser: function (identifier, identity) {
+        var self = this;
+        return this.http.put('/nifi-registry-api/tenants/users/' + identifier, 
{
+            'identifier': identifier,
+            'identity': identity
+        }, headers)
+            .map(function (response) {
+                return response;
+            })
+            .catch(function (error) {
+                return rxjs.Observable.of(error);
+            });
+    },
+
+    /**
      * Gets all users.
      *
      * @returns {*}
@@ -470,6 +521,48 @@ NfRegistryApi.prototype = {
                 return response;
             })
             .catch(function (error) {
+                return rxjs.Observable.of(error);
+            });
+    },
+
+    /**
+     * Get policy action resource.
+     *
+     * @param {string} action   The name of the resource action (e.g. 
READ/WRITE/DELETE).
+     * @param {string} resource   The name of the resource action (e.g. 
READ/WRITE/DELETE).
+     * @returns {*}
+     */
+    getPolicyActionResource: function (action, resource) {
+        var self = this;
+        return this.http.get('/nifi-registry-api/policies/' + action + 
resource)
+            .map(function (response) {
+                return response;
+            });
+    },
+
+    /**
+     * Update policy action resource.
+     *
+     * @param {string} identifier   The identifier of the group.
+     * @param {string} action       The name of the resource action (e.g. 
READ/WRITE/DELETE).
+     * @param {string} resource     The name of the resource.
+     * @param {string} users        The users with resource privileges.
+     * @param {string} userGroups   The user groups with resource privileges.
+     * @returns {*}
+     */
+    putPolicyActionResource: function (identifier, action, resource, users, 
userGroups) {
+        var self = this;
+        return this.http.put('/nifi-registry-api/policies/' + identifier, {
+            'identifier': identifier,
+            'resource': resource,
+            'action': action,
+            'users': users,
+            'userGroups': userGroups
+        }, headers)
+            .map(function (response) {
+                return response;
+            })
+            .catch(function (error) {
                 self.dialogService.openConfirm({
                     title: 'Error',
                     message: error.message,
@@ -481,6 +574,64 @@ NfRegistryApi.prototype = {
     },
 
     /**
+     * Creates a policy action resource.
+     *
+     * @param {string} action       The name of the resource action (e.g. 
READ/WRITE/DELETE).
+     * @param {string} resource     The name of the resource.
+     * @param {string} users        The users with resource privileges.
+     * @param {string} userGroups   The user groups with resource privileges.
+     * @returns {*}
+     */
+    postPolicyActionResource: function (action, resource, users, userGroups) {
+        var self = this;
+        return this.http.post('/nifi-registry-api/policies', {
+            'resource': resource,
+            'action': action,
+            'users': users,
+            'userGroups': userGroups
+        }, headers)
+            .map(function (response) {
+                return response;
+            })
+            .catch(function (error) {
+                self.dialogService.openConfirm({
+                    title: 'Error',
+                    message: error.message,
+                    acceptButton: 'Ok',
+                    acceptButtonColor: 'fds-warn'
+                });
+                return rxjs.Observable.of(error);
+            });
+    },
+
+    /**
+     * Authenticate a user.
+     *
+     * @param {string} username     The name of the user to authenticate.
+     * @param {string} password     The user password.
+     * @returns {*}
+     */
+    postToLogin: function (username, password) {
+        var self = this;
+        return this.http.post('/nifi-registry-api/access/token/login', {
+            'username': username,
+            'password': password
+        }, headers)
+            .map(function (response) {
+                return response;
+            })
+            .catch(function (error) {
+                self.dialogService.openConfirm({
+                    title: 'Error',
+                    message: 'Please contact your System Administrator.',
+                    acceptButton: 'Ok',
+                    acceptButtonColor: 'fds-warn'
+                });
+                return rxjs.Observable.of(error);
+            });
+    },
+
+    /**
      * Kerberos ticket exchange.
      *
      * @returns {*}
@@ -494,7 +645,7 @@ NfRegistryApi.prototype = {
                 .map(function (jwt) {
                     // get the payload and store the token with the 
appropriate expiration
                     var token = self.nfStorage.getJwtPayload(jwt);
-                    if(token) {
+                    if (token) {
                         var expiration = parseInt(token['exp'], 10) * 
MILLIS_PER_SECOND;
                         self.nfStorage.setItem('jwt', jwt, expiration);
                     }
@@ -523,7 +674,35 @@ NfRegistryApi.prototype = {
                 if (error.status === 401) {
                     self.router.navigateByUrl('/nifi-registry/login');
                 }
-                return rxjs.Observable.of({});
+                return rxjs.Observable.of({
+                    resourcePermissions: {
+                        anyTopLevelResource: {
+                            canRead: false,
+                            canWrite: false,
+                            canDelete: false
+                        },
+                        buckets: {
+                            canRead: false,
+                            canWrite: false,
+                            canDelete: false
+                        },
+                        tenants: {
+                            canRead: false,
+                            canWrite: false,
+                            canDelete: false
+                        },
+                        policies: {
+                            canRead: false,
+                            canWrite: false,
+                            canDelete: false
+                        },
+                        proxy: {
+                            canRead: false,
+                            canWrite: false,
+                            canDelete: false
+                        }
+                    }
+                });
             });
     }
 };
@@ -535,4 +714,4 @@ NfRegistryApi.parameters = [
     ngRouter.Router
 ];
 
-module.exports = NfRegistryApi;
\ No newline at end of file
+module.exports = NfRegistryApi;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
index b1a6609..3c9b6d6 100644
--- a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
@@ -28,9 +28,8 @@ var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
 var NfRegistryAddUser = 
require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
-var NfRegistryUserDetails = 
require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = 
require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
-var NfRegistryUserGroupPermissions = 
require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
+var NfRegistryManageUser = 
require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
+var NfRegistryManageGroup = 
require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
 var NfRegistryBucketPermissions = 
require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = 
require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js');
@@ -43,6 +42,8 @@ var ngCommonHttp = require('@angular/common/http');
 var NfRegistryTokenInterceptor = 
require('nifi-registry/services/nf-registry.token.interceptor.js');
 var NfRegistryAuthService = 
require('nifi-registry/services/nf-registry.auth.service.js');
 var NfStorage = require('nifi-registry/services/nf-storage.service.js');
+var NfLoginComponent = 
require('nifi-registry/components/login/nf-registry-login.js');
+var NfUserLoginComponent = 
require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
 
 xdescribe('NfRegistry API w/ Angular testing utils', function () {
     var nfRegistryApi;
@@ -62,16 +63,17 @@ xdescribe('NfRegistry API w/ Angular testing utils', 
function () {
                 NfRegistryExplorer,
                 NfRegistryAdministration,
                 NfRegistryUsersAdministration,
-                NfRegistryUserDetails,
-                NfRegistryUserPermissions,
-                NfRegistryUserGroupPermissions,
+                NfRegistryManageUser,
+                NfRegistryManageGroup,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
                 NfRegistryGridListViewer,
                 NfRegistryBucketGridListViewer,
                 NfRegistryDropletGridListViewer,
-                NfPageNotFoundComponent
+                NfPageNotFoundComponent,
+                NfLoginComponent,
+                NfUserLoginComponent
             ],
             providers: [
                 NfRegistryService,
@@ -1037,11 +1039,6 @@ xdescribe('NfRegistry API w/ Angular testing utils', 
function () {
             identity: 'User #1',
             identifier: '9999'
         }]).subscribe(function (response) {
-            var dialogServiceCall = 
nfRegistryApi.dialogService.openConfirm.calls.first();
-            expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure 
response for /nifi-registry-api/tenants/user-groups/123: 401 PUT user groups 
mock error');
-            expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
-            
expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
new file mode 100644
index 0000000..71580a2
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+
+/**
+ * NfRegistryUsersAdministrationAuthGuard constructor.
+ *
+ * @param nfRegistryService                 The nfRegistryService module.
+ * @constructor
+ */
+function NfRegistryUsersAdministrationAuthGuard(nfRegistryService) {
+    this.nfRegistryService = nfRegistryService;
+};
+
+NfRegistryUsersAdministrationAuthGuard.prototype = {
+    constructor: NfRegistryUsersAdministrationAuthGuard,
+
+    /**
+     * Can activate guard.
+     * @returns {*}
+     */
+    canActivate: function (route, state) {
+        var url = state.url;
+
+        return this.checkLogin(url);
+    },
+
+    checkLogin: function (url) {
+        var self = this;
+        if 
(this.nfRegistryService.currentUser.resourcePermissions.tenants.canRead) { 
return true; }
+
+        // Store the attempted URL for redirecting
+        this.nfRegistryService.redirectUrl = url;
+
+        // attempt kerberos authentication
+        this.nfRegistryService.api.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.api.loadCurrentUser().subscribe(function 
(currentUser) {
+                self.nfRegistryService.currentUser = currentUser;
+                // if the user is logged, we want to determine if they were 
logged in using a certificate
+                if (currentUser.anonymous === false) {
+                    // render the logout button if there is a token locally
+                    if (self.nfRegistryService.nfStorage.getItem('jwt') !== 
null) {
+                        self.nfRegistryService.currentUser.canLogout = true;
+                    }
+
+                    // redirect to explorer perspective if not admin
+                    if 
(!currentUser.resourcePermissions.anyTopLevelResource.canRead) {
+                        
self.nfRegistryService.router.navigateByUrl('/nifi-registry/explorer');
+                    } else {
+                        self.nfRegistryService.router.navigateByUrl(url);
+                    }
+                } else {
+                    // navigate to the login page
+                    
self.nfRegistryService.router.navigateByUrl('/nifi-registry/login');
+                }
+            });
+        });
+
+        return false;
+    }
+};
+
+NfRegistryUsersAdministrationAuthGuard.parameters = [
+    NfRegistryService
+];
+
+/**
+ * NfRegistryWorkflowsAdministrationAuthGuard constructor.
+ *
+ * @param nfRegistryService                 The nfRegistryService module.
+ * @constructor
+ */
+function NfRegistryWorkflowsAdministrationAuthGuard(nfRegistryService) {
+    this.nfRegistryService = nfRegistryService;
+};
+
+NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
+    constructor: NfRegistryWorkflowsAdministrationAuthGuard,
+
+    /**
+     * Can activate guard.
+     * @returns {*}
+     */
+    canActivate: function (route, state) {
+        var url = state.url;
+
+        return this.checkLogin(url);
+    },
+
+    checkLogin: function (url) {
+        var self = this;
+        if 
(this.nfRegistryService.currentUser.resourcePermissions.buckets.canRead || 
this.nfRegistryService.currentUser.anonymous) { return true; }
+
+        // Store the attempted URL for redirecting
+        this.nfRegistryService.redirectUrl = url;
+
+        // attempt kerberos authentication
+        this.nfRegistryService.api.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.api.loadCurrentUser().subscribe(function 
(currentUser) {
+                self.nfRegistryService.currentUser = currentUser;
+                // if the user is logged, we want to determine if they were 
logged in using a certificate
+                if (currentUser.anonymous === false) {
+                    // render the logout button if there is a token locally
+                    if (self.nfRegistryService.nfStorage.getItem('jwt') !== 
null) {
+                        self.nfRegistryService.currentUser.canLogout = true;
+                    }
+
+                    // redirect to explorer perspective if not admin
+                    if 
(!currentUser.resourcePermissions.anyTopLevelResource.canRead) {
+                        
self.nfRegistryService.router.navigateByUrl('/nifi-registry/explorer');
+                    } else {
+                        if (currentUser.resourcePermissions.buckets) {
+                            self.nfRegistryService.router.navigateByUrl(url);
+                        } else {
+                            
self.nfRegistryService.router.navigateByUrl('/nifi-registry/administration/users');
+                        }
+                    }
+                } else {
+                    // Navigate to the login page
+                    self.nfRegistryService.router.navigateByUrl(url);
+                }
+            });
+        });
+
+        return false;
+    }
+};
+
+NfRegistryWorkflowsAdministrationAuthGuard.parameters = [
+    NfRegistryService
+];
+
+/**
+ * NfRegistryLoginAuthGuard constructor.
+ *
+ * @param nfRegistryService                 The nfRegistryService module.
+ * @constructor
+ */
+function NfRegistryLoginAuthGuard(nfRegistryService) {
+    this.nfRegistryService = nfRegistryService;
+};
+
+NfRegistryLoginAuthGuard.prototype = {
+    constructor: NfRegistryLoginAuthGuard,
+
+    /**
+     * Can activate guard.
+     * @returns {*}
+     */
+    canActivate: function (route, state) {
+        var url = state.url;
+
+        return this.checkLogin(url);
+    },
+
+    checkLogin: function (url) {
+        var self = this;
+        if (this.nfRegistryService.currentUser.anonymous) { return true; }
+        // attempt kerberos authentication
+        this.nfRegistryService.api.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.api.loadCurrentUser().subscribe(function 
(currentUser) {
+                self.nfRegistryService.currentUser = currentUser;
+                // if the user is logged, we want to determine if they were 
logged in using a certificate
+                if (currentUser.anonymous === false) {
+                    // render the logout button if there is a token locally
+                    if (self.nfRegistryService.nfStorage.getItem('jwt') !== 
null) {
+                        self.nfRegistryService.currentUser.canLogout = true;
+                    }
+                    
self.nfRegistryService.router.navigateByUrl(self.nfRegistryService.redirectUrl);
+                } else {
+                    
self.nfRegistryService.router.navigateByUrl('/nifi-registry/login');
+                }
+            });
+        });
+
+        return false;
+    }
+};
+
+NfRegistryLoginAuthGuard.parameters = [
+    NfRegistryService
+];
+
+/**
+ * NfRegistryResourcesAuthGuard constructor.
+ *
+ * @param nfRegistryService                 The nfRegistryService module.
+ * @constructor
+ */
+function NfRegistryResourcesAuthGuard(nfRegistryService) {
+    this.nfRegistryService = nfRegistryService;
+};
+
+NfRegistryResourcesAuthGuard.prototype = {
+    constructor: NfRegistryResourcesAuthGuard,
+
+    /**
+     * Can activate guard.
+     * @returns {*}
+     */
+    canActivate: function (route, state) {
+        var url = state.url;
+
+        return this.checkLogin(url);
+    },
+
+    checkLogin: function (url) {
+        var self = this;
+        if 
(this.nfRegistryService.currentUser.resourcePermissions.buckets.canRead) { 
return true; }
+
+        // Store the attempted URL for redirecting
+        this.nfRegistryService.redirectUrl = url;
+
+        // attempt kerberos authentication
+        this.nfRegistryService.api.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.api.loadCurrentUser().subscribe(function 
(currentUser) {
+                self.nfRegistryService.currentUser = currentUser;
+                // if the user is logged, we want to determine if they were 
logged in using a certificate
+                if (currentUser.anonymous === false) {
+                    // render the logout button if there is a token locally
+                    if (self.nfRegistryService.nfStorage.getItem('jwt') !== 
null) {
+                        self.nfRegistryService.currentUser.canLogout = true;
+                    }
+                }
+                self.nfRegistryService.router.navigateByUrl(url);
+            });
+        });
+
+        return false;
+    }
+};
+
+NfRegistryResourcesAuthGuard.parameters = [
+    NfRegistryService
+];
+
+module.exports = {
+    NfRegistryUsersAdministrationAuthGuard: 
NfRegistryUsersAdministrationAuthGuard,
+    NfRegistryWorkflowsAdministrationAuthGuard: 
NfRegistryWorkflowsAdministrationAuthGuard,
+    NfRegistryLoginAuthGuard: NfRegistryLoginAuthGuard,
+    NfRegistryResourcesAuthGuard: NfRegistryResourcesAuthGuard
+};

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth.service.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth.service.js 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth.service.js
index 789988d..f2f143d 100644
--- a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth.service.js
+++ b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth.service.js
@@ -34,7 +34,7 @@ NfRegistryAuth.prototype = {
      * Gets the jwt token.
      * @returns {*}
      */
-    getToken: function() {
+    getToken: function () {
         return this.nfStorage.getItem('jwt');
     }
 };

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
index d63277f..9964ffd 100644
--- a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
+++ b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
@@ -38,6 +38,7 @@ function NfRegistryService(nfRegistryApi, nfStorage, 
tdDataTableService, router,
     this.registry = {
         name: "Nifi Registry"
     };
+    this.redirectUrl = '/nifi-registry/explorer/grid-list';
 
     // Services
     this.router = router;
@@ -47,37 +48,47 @@ function NfRegistryService(nfRegistryApi, nfStorage, 
tdDataTableService, router,
     this.snackBarService = fdsSnackBarService;
     this.dataTableService = tdDataTableService;
 
-    //<editor-fold desc="application state objects">
-
-    // General
-    this.bucket = {};
-    this.buckets = [];
-    this.droplet = {};
-    this.droplets = [];
-    this.currentUser = {};
-    this.user = {};
-    this.group = {};
-    this.users = [];
-    this.groups = [];
-    this.alerts = [];
-    this.explorerViewType = '';
-    this.perspective = '';
-    this.breadCrumbState = 'out';
-
-    // Droplets
-    this.filteredDroplets = [];
-    this.dropletActions = [
+    // data table column definitions
+    this.userColumns = [
         {
-            name: 'Delete',
-            icon: 'fa fa-trash',
-            tooltip: 'Delete'
+            name: 'identity',
+            label: 'Display Name',
+            sortable: true,
+            tooltip: 'User name.',
+            width: 100
+        }
+    ];
+    this.userGroupsColumns = [
+        {
+            name: 'identity',
+            label: 'Display Name',
+            sortable: true,
+            tooltip: 'Group name.',
+            width: 100
+        }
+    ];
+    this.userPoliciesColumns = [
+        {
+            name: 'identity',
+            label: 'Bucket Name',
+            sortable: true,
+            tooltip: 'Bucket name.',
+            width: 100
+        },
+        {
+            name: 'identity',
+            label: 'Bucket Name',
+            sortable: true,
+            tooltip: 'Bucket name.',
+            width: 100
         }
     ];
     this.dropletColumns = [
         {
             name: 'name',
             label: 'Name',
-            sortable: true
+            sortable: true,
+            active: true
         },
         {
             name: 'modifiedTimestamp',
@@ -85,11 +96,6 @@ function NfRegistryService(nfRegistryApi, nfStorage, 
tdDataTableService, router,
             sortable: true
         }
     ];
-    this.autoCompleteDroplets = [];
-    this.dropletsSearchTerms = [];
-
-    // Buckets
-    this.filteredBuckets = [];
     this.bucketColumns = [
         {
             name: 'name',
@@ -98,6 +104,183 @@ function NfRegistryService(nfRegistryApi, nfStorage, 
tdDataTableService, router,
             tooltip: 'Sort Buckets by name.'
         }
     ];
+
+    // data table available row action definitions
+    this.bucketActions = [
+        {
+            'name': 'permissions',
+            'icon': 'fa fa-pencil',
+            'tooltip': 'Manage Bucket Policies',
+            'type': 'sidenav'
+        }, {
+            'name': 'Delete',
+            'icon': 'fa fa-trash',
+            'tooltip': 'Delete Bucket'
+        }
+    ];
+    this.dropletActions = [
+        {
+            name: 'delete',
+            icon: 'fa fa-trash',
+            tooltip: 'Delete'
+        }
+    ];
+    this.usersActions = [
+        {
+            name: 'manage',
+            icon: 'fa fa-pencil',
+            tooltip: 'Manage User Policies',
+            type: 'sidenav',
+            tooltip: 'Manage User'
+        }, {
+            name: 'delete',
+            icon: 'fa fa-trash',
+            tooltip: 'Delete User'
+        }
+    ];
+    this.userGroupsActions = [
+        {
+            name: 'manage',
+            icon: 'fa fa-pencil',
+            tooltip: 'Manage User Group Policies',
+            type: 'sidenav'
+        }, {
+            name: 'delete',
+            icon: 'fa fa-trash',
+            tooltip: 'Delete User Group'
+        }
+    ];
+
+    // model for buckets privileges
+    this.BUCKETS_PRIVS = {
+        '/buckets': ['read', 'write', 'delete']
+    };
+
+    // model for tenants privileges
+    this.TENANTS_PRIVS = {
+        '/tenants': ['read', 'write', 'delete']
+    };
+
+    // model for policies privileges
+    this.POLICIES_PRIVS = {
+        '/policies': ['read', 'write', 'delete']
+    };
+
+    // model for proxy privileges
+    this.PROXY_PRIVS = {
+        '/proxy': ['write']
+    };
+
+    //<editor-fold desc="application state objects">
+
+    // General
+    this.alerts = [];
+    this.inProgress = false;
+    this.perspective = '';
+    this.breadCrumbState = 'out';
+    this.explorerViewType = '';
+    this.currentUser = {
+        resourcePermissions: {
+            anyTopLevelResource: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            buckets: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            tenants: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            policies: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            proxy: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            }
+        }
+    };
+    this.bucket = {};
+    this.buckets = [];
+    this.droplet = {};
+    this.droplets = [];
+    this.user = {
+        resourcePermissions: {
+            anyTopLevelResource: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            buckets: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            tenants: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            policies: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            proxy: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            }
+        }
+    };
+    this.users = [];
+    this.group = {
+        resourcePermissions: {
+            anyTopLevelResource: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            buckets: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            tenants: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            policies: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            },
+            proxy: {
+                canRead: false,
+                canWrite: false,
+                canDelete: false
+            }
+        }
+    };
+    this.groups = [];
+
+    // Droplets
+    this.filteredDroplets = [];
+    this.activeDropletColumn = this.dropletColumns[0];
+    this.autoCompleteDroplets = [];
+    this.dropletsSearchTerms = [];
+
+    // Buckets
+    this.filteredBuckets = [];
     this.allBucketsSelected = false;
     this.autoCompleteBuckets = [];
     this.bucketsSearchTerms = [];
@@ -106,20 +289,10 @@ function NfRegistryService(nfRegistryApi, nfStorage, 
tdDataTableService, router,
     // Users and Groups
     this.filteredUsers = [];
     this.filteredUserGroups = [];
-    this.userColumns = [
-        {
-            name: 'identity',
-            label: 'Display Name',
-            sortable: true,
-            tooltip: 'User name.',
-            width: 100
-        }
-    ];
     this.allUsersAndGroupsSelected = false;
     this.autoCompleteUsersAndGroups = [];
     this.usersSearchTerms = [];
 
-    this.inProgress = false;
     //</editor-fold>
 };
 
@@ -347,6 +520,7 @@ NfRegistryService.prototype = {
                                 });
                                 self.bucket = {};
                                 self.filterBuckets();
+                                self.determineAllBucketsSelectedState();
                             });
                         }
                     });
@@ -604,7 +778,7 @@ NfRegistryService.prototype = {
         // get the current user
         return 
rxjs.Observable.of(this.api.loadCurrentUser().subscribe(function (currentUser) {
             // if the user is logged, we want to determine if they were logged 
in using a certificate
-            if (currentUser.status !== "UNKNOWN") {
+            if (currentUser.anonymous === false) {
                 // render the users name
                 self.currentUser = currentUser;
 
@@ -798,9 +972,10 @@ NfRegistryService.prototype = {
      */
     executeUserAction: function (action, user) {
         var self = this;
+        this.user = user;
         switch (action.name.toLowerCase()) {
             case 'delete':
-                this.dialogService.openConfirm({
+                return this.dialogService.openConfirm({
                     title: 'Delete User',
                     message: 'This user will lose all access to the registry.',
                     cancelButton: 'Cancel',
@@ -823,12 +998,13 @@ NfRegistryService.prototype = {
                                     duration: 3000
                                 });
                                 self.filterUsersAndGroups();
+                                self.determineAllUsersAndGroupsSelectedState();
                             });
                         }
                     });
                 break;
-            case 'permissions':
-                
this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type 
+ ':user/' + action.name + '/' + user.identifier + ')');
+            case 'manage':
+                
this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type 
+ ':' + action.name + '/user/' + user.identifier + ')');
                 break;
         }
     },
@@ -867,12 +1043,13 @@ NfRegistryService.prototype = {
                                     duration: 3000
                                 });
                                 self.filterUsersAndGroups();
+                                self.determineAllUsersAndGroupsSelectedState();
                             });
                         }
                     });
                 break;
-            case 'permissions':
-                
this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type 
+ ':group/' + action.name + '/' + group.identifier + ')');
+            case 'manage':
+                
this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type 
+ ':' + action.name + '/group/' + group.identifier + ')');
                 break;
         }
     },

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js 
b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
index 6668b60..e3d3164 100644
--- a/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
@@ -28,9 +28,8 @@ var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
 var NfRegistryAddUser = 
require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
-var NfRegistryUserDetails = 
require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = 
require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
-var NfRegistryUserGroupPermissions = 
require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
+var NfRegistryManageUser = 
require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
+var NfRegistryManageGroup = 
require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
 var NfRegistryBucketPermissions = 
require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = 
require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js');
@@ -45,6 +44,8 @@ var ngCommonHttp = require('@angular/common/http');
 var NfRegistryTokenInterceptor = 
require('nifi-registry/services/nf-registry.token.interceptor.js');
 var NfRegistryAuthService = 
require('nifi-registry/services/nf-registry.auth.service.js');
 var NfStorage = require('nifi-registry/services/nf-storage.service.js');
+var NfLoginComponent = 
require('nifi-registry/components/login/nf-registry-login.js');
+var NfUserLoginComponent = 
require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
 
 describe('NfRegistry Service isolated unit tests', function () {
     var nfRegistryService;
@@ -86,6 +87,7 @@ describe('NfRegistry Service isolated unit tests', function 
() {
 
     it('should get the `Oldest (update)` sort by label', function () {
         //Setup the nfRegistryService state for this test
+        nfRegistryService.dropletColumns[0].active = false;
         nfRegistryService.dropletColumns[1].active = true;
 
         // The function to test
@@ -97,6 +99,7 @@ describe('NfRegistry Service isolated unit tests', function 
() {
 
     it('should get the `Newest (update)` sort by label', function () {
         //Setup the nfRegistryService state for this test
+        nfRegistryService.dropletColumns[0].active = false;
         nfRegistryService.dropletColumns[1].active = true;
         nfRegistryService.dropletColumns[1].sortOrder = 'ASC';
 
@@ -688,16 +691,17 @@ describe('NfRegistry Service w/ Angular testing utils', 
function () {
                 NfRegistryExplorer,
                 NfRegistryAdministration,
                 NfRegistryUsersAdministration,
-                NfRegistryUserDetails,
-                NfRegistryUserPermissions,
-                NfRegistryUserGroupPermissions,
+                NfRegistryManageUser,
+                NfRegistryManageGroup,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
                 NfRegistryGridListViewer,
                 NfRegistryBucketGridListViewer,
                 NfRegistryDropletGridListViewer,
-                NfPageNotFoundComponent
+                NfPageNotFoundComponent,
+                NfLoginComponent,
+                NfUserLoginComponent
             ],
             providers: [
                 NfRegistryService,
@@ -963,7 +967,7 @@ describe('NfRegistry Service w/ Angular testing utils', 
function () {
         expect(nfRegistryService.users[0].identifier).toBe(1);
     });
 
-    it('should execute a `permissions` action on a user.', function () {
+    it('should execute a `manage` action on a user.', function () {
         // from the root injector
         var router = ngCoreTesting.TestBed.get(ngRouter.Router);
 
@@ -975,11 +979,11 @@ describe('NfRegistry Service w/ Angular testing utils', 
function () {
         var user = {identifier: '999'};
 
         // The function to test
-        nfRegistryService.executeUserAction({name: 'permissions', type: 
'sidenav'}, user);
+        nfRegistryService.executeUserAction({name: 'manage', type: 'sidenav'}, 
user);
 
         //assertions
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        
expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users(sidenav:user/permissions/999)');
+        
expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users(sidenav:manage/user/999)');
     });
 
     it('should execute a `delete` action on a group.', function () {
@@ -1015,7 +1019,7 @@ describe('NfRegistry Service w/ Angular testing utils', 
function () {
         expect(nfRegistryService.groups[0].identifier).toBe(1);
     });
 
-    it('should execute a `permissions` action on a group.', function () {
+    it('should execute a `manage` action on a group.', function () {
         // from the root injector
         var router = ngCoreTesting.TestBed.get(ngRouter.Router);
 
@@ -1027,11 +1031,11 @@ describe('NfRegistry Service w/ Angular testing utils', 
function () {
         var group = {identifier: '999'};
 
         // The function to test
-        nfRegistryService.executeGroupAction({name: 'permissions', type: 
'sidenav'}, group);
+        nfRegistryService.executeGroupAction({name: 'manage', type: 
'sidenav'}, group);
 
         //assertions
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        
expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users(sidenav:group/permissions/999)');
+        
expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users(sidenav:manage/group/999)');
     });
 
     it('should filter buckets by name.', function () {

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/systemjs.builder.config.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/systemjs.builder.config.js 
b/nifi-registry-web-ui/src/main/webapp/systemjs.builder.config.js
index 8d3073d..a66d70d 100644
--- a/nifi-registry-web-ui/src/main/webapp/systemjs.builder.config.js
+++ b/nifi-registry-web-ui/src/main/webapp/systemjs.builder.config.js
@@ -100,17 +100,20 @@
             'nifi-registry/services/nf-registry.service.js': 
'services/nf-registry.service.js',
             'nifi-registry/services/nf-storage.service.js': 
'services/nf-storage.service.js',
             'nifi-registry/services/nf-registry.auth.service.js': 
'services/nf-registry.auth.service.js',
+            'nifi-registry/services/nf-registry.auth-guard.service.js': 
'services/nf-registry.auth-guard.service.js',
             'nifi-registry/services/nf-registry.token.interceptor.js': 
'services/nf-registry.token.interceptor.js',
             
'nifi-registry/components/page-not-found/nf-registry-page-not-found.js': 
'components/page-not-found/nf-registry-page-not-found.js',
+            'nifi-registry/components/login/nf-registry-login.js': 
'components/login/nf-registry-login.js',
+            
'nifi-registry/components/login/dialogs/nf-registry-user-login.js': 
'components/login/dialogs/nf-registry-user-login.js',
             'nifi-registry/components/explorer/nf-registry-explorer.js': 
'components/explorer/nf-registry-explorer.js',
             
'nifi-registry/components/administration/nf-registry-administration.js': 
'components/administration/nf-registry-administration.js',
             
'nifi-registry/components/administration/users/nf-registry-users-administration.js':
 'components/administration/users/nf-registry-users-administration.js',
             
'nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js':
 'components/administration/users/dialogs/add-user/nf-registry-add-user.js',
             
'nifi-registry/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js':
 
'components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js',
-            
'nifi-registry/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js':
 
'components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js',
-            
'nifi-registry/components/administration/users/details/nf-registry-user-details.js':
 'components/administration/users/details/nf-registry-user-details.js',
-            
'nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js':
 'components/administration/users/permissions/nf-registry-user-permissions.js',
-            
'nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js':
 
'components/administration/user-group/permissions/nf-registry-user-group-permissions.js',
+            
'nifi-registry/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js':
 
'components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js',
+            
'nifi-registry/components/administration/users/dialogs/add-user-to-groups/nf-registry-add-user-to-groups.js':
 
'components/administration/users/dialogs/add-user-to-groups/nf-registry-add-user-to-groups.js',
+            
'nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js':
 
'components/administration/users/sidenav/manage-user/nf-registry-manage-user.js',
+            
'nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js':
 
'components/administration/users/sidenav/manage-group/nf-registry-manage-group.js',
             
'nifi-registry/components/administration/workflow/dialogs/nf-registry-create-bucket.js':
 'components/administration/workflow/dialogs/nf-registry-create-bucket.js',
             
'nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js':
 
'components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js',
             
'nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js':
 'components/administration/workflow/nf-registry-workflow-administration.js',

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss 
b/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
index 5de1870..3e8fa40 100644
--- a/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
+++ b/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
@@ -16,10 +16,30 @@
  */
 
 body {
-    background: $grey5 url('/nifi-registry/images/registry-logo-web-app.svg') 
no-repeat center center;
+    background: $grey12 url('/nifi-registry/images/registry-logo-web-app.svg') 
no-repeat center center;
     background-size: 40%;
 }
 
+#nifi-registry-login-perspective {
+    background: $grey12 url('/nifi-registry/images/registry-logo-web-app.svg') 
no-repeat center center;
+    background-size: 40%;
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+}
+
+#nifi-registry-not-found-perspective {
+    background: $grey12 url('/nifi-registry/images/registry-logo-web-app.svg') 
no-repeat center center;
+    background-size: 40%;
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+}
+
 #nf-registry-app-container {
     margin: 0;
     width: 100%;
@@ -48,7 +68,7 @@ body {
     background-color: #FFFFFF;
     position: absolute;
     z-index: 1000;
-    background: $grey1;
+    background: $grey11;
 }
 
 #nifi-registry-toolbar .mat-icon-button {
@@ -74,7 +94,7 @@ body {
     min-height: 370px;
     min-width: 1045px;
     overflow: auto;
-    background: $grey5;
+    background: $grey12;
     background-size: 40%;
 }
 

Reply via email to