You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2017/11/28 19:34:45 UTC

[3/4] nifi-registry git commit: NIFIREG-30 - GET users/groups, delete user/group, delete users/groups, create group, introduce group side nav - Add selected users to selected groups - Update JS unit tests - Add kerberos support

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.spec.js b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.spec.js
index bada058..82bc02b 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.spec.js
@@ -28,9 +28,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -41,6 +42,10 @@ var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var rxjs = require('rxjs/Rx');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistryCreateBucket Component', function () {
     var comp;
@@ -48,19 +53,19 @@ describe('NfRegistryCreateBucket Component', function () {
     var de;
     var el;
     var nfRegistryService;
+    var nfRegistryApi;
 
     beforeEach(function () {
-        nfRegistryService = new NfRegistryService({}, {
-            createBucket: function() {}
-        }, {}, {});
-        comp = new NfRegistryCreateBucket(nfRegistryService, {
+        nfRegistryService = new NfRegistryService();
+        nfRegistryApi = new NfRegistryApi();
+        comp = new NfRegistryCreateBucket(nfRegistryApi, nfRegistryService, {
             close: function() {}
         })
     });
 
     it('should create a new bucket and close the dialog', function () {
         // Spy
-        spyOn(nfRegistryService.api, 'createBucket').and.callFake(function () {
+        spyOn(nfRegistryApi, 'createBucket').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of({name: 'NewBucket'}));
         spyOn(nfRegistryService, 'filterBuckets');
         spyOn(comp.dialogRef, 'close');
@@ -78,7 +83,7 @@ describe('NfRegistryCreateBucket Component', function () {
 
     it('should create a new bucket and keep the dialog open', function () {
         // Spy
-        spyOn(nfRegistryService.api, 'createBucket').and.callFake(function () {
+        spyOn(nfRegistryApi, 'createBucket').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of({name: 'NewBucket'}));
         spyOn(nfRegistryService, 'filterBuckets');
         spyOn(comp.dialogRef, 'close');

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.html b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.html
index 666f549..5ff3247 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.html
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.html
@@ -24,7 +24,7 @@ limitations under the License.
             <button class="push-top-sm push-right-sm" color="fds-secondary" mat-raised-button (click)="createBucket()">
                 New Bucket
             </button>
-            <button class="push-top-sm" [disabled]="nfRegistryService.disableMultiBucketActions" color="fds-primary" mat-raised-button [matMenuTriggerFor]="bucketActionMenu">
+            <button class="push-top-sm" [disabled]="nfRegistryService.isMultiBucketActionsDisabled" color="fds-primary" mat-raised-button [matMenuTriggerFor]="bucketActionMenu">
                 Actions<i class="fa fa-caret-down" aria-hidden="true"></i>
             </button>
         </div>
@@ -48,8 +48,8 @@ limitations under the License.
             <div class="td-data-table-column">
                 <div fxLayout="row" fxLayoutAlign="end center">
                     <mat-checkbox class="pad-left-sm" [(ngModel)]="nfRegistryService.allBucketsSelected"
-                                 (checked)="nfRegistryService.allBucketsSelected"
-                                 (change)="nfRegistryService.toggleBucketsSelectAll()"></mat-checkbox>
+                                  (checked)="nfRegistryService.allBucketsSelected"
+                                  (change)="nfRegistryService.toggleBucketsSelectAll()"></mat-checkbox>
                 </div>
             </div>
         </div>
@@ -59,7 +59,7 @@ limitations under the License.
                  (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()">
                 <div class="td-data-table-cell" *ngFor="let column of nfRegistryService.bucketColumns"
                      fxFlex="{{column.width}}">
-                    <div>
+                    <div matTooltip="{{column.format ? column.format(row[column.name]) : row[column.name]}}">
                         {{column.format ? column.format(row[column.name]) : row[column.name]}}
                     </div>
                 </div>
@@ -73,8 +73,8 @@ limitations under the License.
                                 <i class="{{action.icon}}" aria-hidden="true"></i>
                             </button>
                             <mat-checkbox class="pad-left-sm" [(ngModel)]="row.checked" [checked]="row.checked"
-                                         (change)="nfRegistryService.determineAllBucketsSelectedState()"
-                                         (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()"></mat-checkbox>
+                                          (change)="nfRegistryService.determineAllBucketsSelectedState()"
+                                          (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()"></mat-checkbox>
                         </div>
                         <div *ngIf="bucketActions.length > 4" fxLayout="row" fxLayoutAlign="end center">
                             <button (click)="row.checked = !row.checked" matTooltip="Actions" mat-icon-button
@@ -91,19 +91,19 @@ limitations under the License.
                                 </button>
                             </mat-menu>
                             <mat-checkbox [(ngModel)]="row.checked" [checked]="row.checked"
-                                         (change)="nfRegistryService.determineAllBucketsSelectedState()"
-                                         (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()"></mat-checkbox>
+                                          (change)="nfRegistryService.determineAllBucketsSelectedState()"
+                                          (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()"></mat-checkbox>
                         </div>
                     </div>
                     <div *ngIf="!bucketActions" fxLayout="row" fxLayoutAlign="end center">
                         <mat-checkbox [(ngModel)]="row.checked" [checked]="row.checked"
-                                     (change)="nfRegistryService.determineAllBucketsSelectedState(row)"
-                                     (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()"></mat-checkbox>
+                                      (change)="nfRegistryService.determineAllBucketsSelectedState(row)"
+                                      (click)="row.checked = !row.checked;nfRegistryService.determineAllBucketsSelectedState()"></mat-checkbox>
                     </div>
                 </div>
             </div>
         </div>
-        <div class="mat-padding" *ngIf="!nfRegistryService.filteredBuckets.length > 0" layout="row"
+        <div class="mat-padding" *ngIf="nfRegistryService.filteredBuckets.length === 0" layout="row"
              layout-align="center center">
             <h3>No results to display.</h3>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.js b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.js
index 528a7f2..85a6b97 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.js
@@ -16,6 +16,8 @@
  */
 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 NfStorage = require('nifi-registry/services/nf-storage.service.js');
 var NfRegistryCreateBucket = require('nifi-registry/components/administration/workflow/dialogs/nf-registry-create-bucket.js');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
 var ngRouter = require('@angular/router');
@@ -24,14 +26,18 @@ var ngMaterial = require('@angular/material');
 /**
  * NfRegistryWorkflowAdministration constructor.
  *
+ * @param nfRegistryApi         The api service.
+ * @param nfStorage             A wrapper for the browser's local storage.
  * @param nfRegistryService     The nf-registry.service module.
- * @param ActivatedRoute        The angular activated route module.
- * @param matDialogRef          The angular material dialog ref.
+ * @param activatedRoute        The angular activated route module.
+ * @param matDialog             The angular material dialog module.
  * @constructor
  */
-function NfRegistryWorkflowAdministration(nfRegistryService, ActivatedRoute, matDialog) {
-    this.route = ActivatedRoute;
+function NfRegistryWorkflowAdministration(nfRegistryApi, nfStorage, nfRegistryService, activatedRoute, matDialog) {
+    this.route = activatedRoute;
+    this.nfStorage = nfStorage;
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
     this.dialog = matDialog;
     this.bucketActions = [{
         'name': 'permissions',
@@ -53,16 +59,20 @@ NfRegistryWorkflowAdministration.prototype = {
      */
     ngOnInit: function () {
         var self = this;
-        this.route.params
-            .switchMap(function (params) {
-                self.nfRegistryService.adminPerspective = 'workflow';
-                return self.nfRegistryService.api.getBuckets();
-            })
-            .subscribe(function (buckets) {
-                self.nfRegistryService.buckets = buckets;
-                self.nfRegistryService.filterBuckets();
+        // attempt kerberos authentication
+        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.loadCurrentUser().subscribe(function (currentUser) {
+                self.route.params
+                    .switchMap(function (params) {
+                        self.nfRegistryService.adminPerspective = 'workflow';
+                        return self.nfRegistryApi.getBuckets();
+                    })
+                    .subscribe(function (buckets) {
+                        self.nfRegistryService.buckets = buckets;
+                        self.nfRegistryService.filterBuckets();
+                    });
             });
-
+        });
     },
 
     /**
@@ -93,6 +103,8 @@ NfRegistryWorkflowAdministration.annotations = [
 ];
 
 NfRegistryWorkflowAdministration.parameters = [
+    NfRegistryApi,
+    NfStorage,
     NfRegistryService,
     ngRouter.ActivatedRoute,
     ngMaterial.MatDialog

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.spec.js b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.spec.js
index 7508530..2eac9e8 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/nf-registry-workflow-administration.spec.js
@@ -28,9 +28,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -41,6 +42,10 @@ var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var rxjs = require('rxjs/Rx');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistryWorkflowAdministration Component', function () {
     var comp;
@@ -56,6 +61,7 @@ describe('NfRegistryWorkflowAdministration Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -67,6 +73,7 @@ describe('NfRegistryWorkflowAdministration Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -81,7 +88,14 @@ describe('NfRegistryWorkflowAdministration Component', function () {
             ],
             providers: [
                 NfRegistryService,
+                NfRegistryAuthService,
                 NfRegistryApi,
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
                 {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'
@@ -106,6 +120,8 @@ describe('NfRegistryWorkflowAdministration Component', function () {
         el = de.nativeElement;
 
         // Spy
+        spyOn(nfRegistryApi, 'ticketExchange').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
+        spyOn(nfRegistryService, 'loadCurrentUser').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
         spyOn(nfRegistryService.api, 'getDroplets').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of([{
             "identifier": "2e04b4fb-9513-47bb-aa74-1ae34616bfdc",

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
index 7656c6f..d106d41 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
@@ -17,19 +17,25 @@
 var ngCore = require('@angular/core');
 var rxjs = require('rxjs/Rx');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfStorage = require('nifi-registry/services/nf-storage.service.js');
 var ngRouter = require('@angular/router');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
 
 /**
  * NfRegistryBucketGridListViewer constructor.
  *
+ * @param nfRegistryApi         The api service.
+ * @param nfStorage             A wrapper for the browser's local storage.
  * @param nfRegistryService     The nf-registry.service module.
  * @param ActivatedRoute        The angular activated route module.
  * @constructor
  */
-function NfRegistryBucketGridListViewer(nfRegistryService, ActivatedRoute) {
+function NfRegistryBucketGridListViewer(nfRegistryApi, nfStorage, nfRegistryService, ActivatedRoute) {
     this.route = ActivatedRoute;
+    this.nfStorage = nfStorage;
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
 };
 
 NfRegistryBucketGridListViewer.prototype = {
@@ -42,24 +48,30 @@ NfRegistryBucketGridListViewer.prototype = {
         var self = this;
         this.nfRegistryService.explorerViewType = 'grid-list';
         this.nfRegistryService.droplet = {};
-        this.route.params
-            .switchMap(function (params) {
-                return new rxjs.Observable.forkJoin(
-                    self.nfRegistryService.api.getBuckets(),
-                    self.nfRegistryService.api.getDroplets(params['bucketId']),
-                    self.nfRegistryService.api.getBucket(params['bucketId'])
-                );
-            })
-            .subscribe(function (response) {
-                var buckets = response[0];
-                var droplets = response[1];
-                var bucket = response[2];
-                self.nfRegistryService.bucket = bucket;
-                self.nfRegistryService.buckets = buckets;
-                self.nfRegistryService.droplets = droplets;
-                self.nfRegistryService.filterDroplets();
-                self.nfRegistryService.setBreadcrumbState('in');
+        // attempt kerberos authentication
+        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.loadCurrentUser().subscribe(function (currentUser) {
+                self.route.params
+                    .switchMap(function (params) {
+                        return new rxjs.Observable.forkJoin(
+                            self.nfRegistryApi.getBuckets(),
+                            self.nfRegistryApi.getDroplets(params['bucketId']),
+                            self.nfRegistryApi.getBucket(params['bucketId'])
+                        );
+                    })
+                    .subscribe(function (response) {
+                        var buckets = response[0];
+                        var droplets = response[1];
+                        var bucket = response[2];
+                        self.nfRegistryService.bucket = bucket;
+                        self.nfRegistryService.buckets = buckets;
+                        self.nfRegistryService.droplets = droplets;
+                        self.nfRegistryService.filterDroplets();
+                        self.nfRegistryService.setBreadcrumbState('in');
+                    });
             });
+        });
+
     },
 
     /**
@@ -79,6 +91,8 @@ NfRegistryBucketGridListViewer.annotations = [
 ];
 
 NfRegistryBucketGridListViewer.parameters = [
+    NfRegistryApi,
+    NfStorage,
     NfRegistryService,
     ngRouter.ActivatedRoute
 ];

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
index 172ae74..62f583d 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
@@ -28,9 +28,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -40,6 +41,10 @@ var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var rxjs = require('rxjs/Rx');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistryBucketGridListViewer Component', function () {
     var comp;
@@ -54,6 +59,7 @@ describe('NfRegistryBucketGridListViewer Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -65,6 +71,7 @@ describe('NfRegistryBucketGridListViewer Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -74,8 +81,15 @@ describe('NfRegistryBucketGridListViewer Component', function () {
                 NfPageNotFoundComponent
             ],
             providers: [
-                NfRegistryApi,
                 NfRegistryService,
+                NfRegistryAuthService,
+                NfRegistryApi,
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
                 {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'
@@ -106,6 +120,8 @@ describe('NfRegistryBucketGridListViewer Component', function () {
         nfRegistryService.explorerViewType = 'grid-list';
 
         //Spy
+        spyOn(nfRegistryApi, 'ticketExchange').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
+        spyOn(nfRegistryService, 'loadCurrentUser').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
         spyOn(ngHttpService, 'get').and.callThrough();
         spyOn(nfRegistryApi, 'getBuckets').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of([{

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
index 8f42aa5..97d2a0c 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
@@ -17,19 +17,25 @@
 var ngCore = require('@angular/core');
 var rxjs = require('rxjs/Rx');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfStorage = require('nifi-registry/services/nf-storage.service.js');
 var ngRouter = require('@angular/router');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
 
 /**
  * NfRegistryDropletGridListViewer constructor.
  *
+ * @param nfRegistryApi         The api service.
+ * @param nfStorage             A wrapper for the browser's local storage.
  * @param nfRegistryService     The nf-registry.service module.
- * @param ActivatedRoute        The angular activated route module.
+ * @param activatedRoute        The angular activated route module.
  * @constructor
  */
-function NfRegistryDropletGridListViewer(nfRegistryService, ActivatedRoute) {
-    this.route = ActivatedRoute;
+function NfRegistryDropletGridListViewer(nfRegistryApi, nfStorage, nfRegistryService, activatedRoute) {
+    this.route = activatedRoute;
+    this.nfStorage = nfStorage;
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
 };
 
 NfRegistryDropletGridListViewer.prototype = {
@@ -41,27 +47,32 @@ NfRegistryDropletGridListViewer.prototype = {
     ngOnInit: function () {
         var self = this;
         this.nfRegistryService.explorerViewType = 'grid-list';
-        this.route.params
-            .switchMap(function (params) {
-                return new rxjs.Observable.forkJoin(
-                    self.nfRegistryService.api.getDroplet(params['bucketId'], params['dropletType'], params['dropletId']),
-                    self.nfRegistryService.api.getBucket(params['bucketId']),
-                    self.nfRegistryService.api.getBuckets(),
-                    self.nfRegistryService.api.getDroplets(params['bucketId'])
-                );
-            })
-            .subscribe(function (response) {
-                var droplet = response[0];
-                var bucket = response[1];
-                var buckets = response[2];
-                var droplets = response[3];
-                self.nfRegistryService.bucket = bucket;
-                self.nfRegistryService.buckets = buckets;
-                self.nfRegistryService.droplet = droplet;
-                self.nfRegistryService.droplets = droplets;
-                self.nfRegistryService.filterDroplets();
-                self.nfRegistryService.setBreadcrumbState('in');
+        // attempt kerberos authentication
+        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.loadCurrentUser().subscribe(function (currentUser) {
+                self.route.params
+                    .switchMap(function (params) {
+                        return new rxjs.Observable.forkJoin(
+                            self.nfRegistryApi.getDroplet(params['bucketId'], params['dropletType'], params['dropletId']),
+                            self.nfRegistryApi.getBucket(params['bucketId']),
+                            self.nfRegistryApi.getBuckets(),
+                            self.nfRegistryApi.getDroplets(params['bucketId'])
+                        );
+                    })
+                    .subscribe(function (response) {
+                        var droplet = response[0];
+                        var bucket = response[1];
+                        var buckets = response[2];
+                        var droplets = response[3];
+                        self.nfRegistryService.bucket = bucket;
+                        self.nfRegistryService.buckets = buckets;
+                        self.nfRegistryService.droplet = droplet;
+                        self.nfRegistryService.droplets = droplets;
+                        self.nfRegistryService.filterDroplets();
+                        self.nfRegistryService.setBreadcrumbState('in');
+                    });
             });
+        });
     },
 
     /**
@@ -81,6 +92,8 @@ NfRegistryDropletGridListViewer.annotations = [
 ];
 
 NfRegistryDropletGridListViewer.parameters = [
+    NfRegistryApi,
+    NfStorage,
     NfRegistryService,
     ngRouter.ActivatedRoute
 ];

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
index 467dc3e..30b37f7 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
@@ -28,9 +28,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -40,6 +41,10 @@ var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var rxjs = require('rxjs/Rx');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistryDropletGridListViewer Component', function () {
     var comp;
@@ -54,6 +59,7 @@ describe('NfRegistryDropletGridListViewer Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -65,6 +71,7 @@ describe('NfRegistryDropletGridListViewer Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -74,8 +81,15 @@ describe('NfRegistryDropletGridListViewer Component', function () {
                 NfPageNotFoundComponent
             ],
             providers: [
-                NfRegistryApi,
                 NfRegistryService,
+                NfRegistryAuthService,
+                NfRegistryApi,
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
                 {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'
@@ -111,6 +125,8 @@ describe('NfRegistryDropletGridListViewer Component', function () {
         nfRegistryService.explorerViewType = 'grid-list';
 
         //Spy
+        spyOn(nfRegistryApi, 'ticketExchange').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
+        spyOn(nfRegistryService, 'loadCurrentUser').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
         spyOn(ngHttpService, 'get').and.callThrough();
         spyOn(nfRegistryApi, 'getDroplet').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of({

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
index 6b10b77..eb0bb99 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
@@ -108,7 +108,7 @@ limitations under the License.
         <div class="pad-bottom-sm"></div>
     </div>
 </div>
-<div class="pad-right-xxl pad-left-xxl" *ngIf="nfRegistryService.filteredDroplets.length <= 0">
+<div class="pad-right-xxl pad-left-xxl" *ngIf="nfRegistryService.filteredDroplets.length === 0">
     <p class="text-center">No results match this query.</p>
 </div>
 <router-outlet></router-outlet>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
index 3419ebc..a71f661 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
@@ -17,6 +17,8 @@
 var ngCore = require('@angular/core');
 var rxjs = require('rxjs/Rx');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfStorage = require('nifi-registry/services/nf-storage.service.js');
 var ngRouter = require('@angular/router');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
 
@@ -24,12 +26,16 @@ var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
  * NfRegistryGridListViewer constructor.
  *
  * @param nfRegistryService     The nf-registry.service module.
- * @param ActivatedRoute        The angular activated route module.
+ * @param nfRegistryApi         The api service.
+ * @param activatedRoute        The angular activated route module.
+ * @param nfStorage             A wrapper for the browser's local storage.
  * @constructor
  */
-function NfRegistryGridListViewer(nfRegistryService, ActivatedRoute) {
-    this.route = ActivatedRoute;
+function NfRegistryGridListViewer(nfRegistryService, nfRegistryApi, activatedRoute, nfStorage) {
+    this.route = activatedRoute;
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
+    this.nfStorage = nfStorage;
 };
 
 NfRegistryGridListViewer.prototype = {
@@ -42,19 +48,24 @@ NfRegistryGridListViewer.prototype = {
         var self = this;
         this.nfRegistryService.explorerViewType = 'grid-list';
         this.nfRegistryService.bucket = {};
-        this.route.params
-            .switchMap(function (params) {
-                return new rxjs.Observable.forkJoin(self.nfRegistryService.api.getDroplets(),
-                    self.nfRegistryService.api.getBuckets());
-            })
-            .subscribe(function (response) {
-                var droplets = response[0];
-                var buckets = response[1];
-                self.nfRegistryService.buckets = buckets;
-                self.nfRegistryService.droplets = droplets;
-                self.nfRegistryService.filterDroplets();
-                self.nfRegistryService.setBreadcrumbState('in');
+        // attempt kerberos authentication
+        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+            self.nfRegistryService.loadCurrentUser().subscribe(function (currentUser) {
+                self.route.params
+                    .switchMap(function (params) {
+                        return new rxjs.Observable.forkJoin(self.nfRegistryApi.getDroplets(),
+                            self.nfRegistryApi.getBuckets());
+                    })
+                    .subscribe(function (response) {
+                        var droplets = response[0];
+                        var buckets = response[1];
+                        self.nfRegistryService.buckets = buckets;
+                        self.nfRegistryService.droplets = droplets;
+                        self.nfRegistryService.filterDroplets();
+                        self.nfRegistryService.setBreadcrumbState('in');
+                    });
             });
+        });
     },
 
     /**
@@ -75,7 +86,9 @@ NfRegistryGridListViewer.annotations = [
 
 NfRegistryGridListViewer.parameters = [
     NfRegistryService,
-    ngRouter.ActivatedRoute
+    NfRegistryApi,
+    ngRouter.ActivatedRoute,
+    NfStorage
 ];
 
 module.exports = NfRegistryGridListViewer;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
index 15f0d08..f1d99fd 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
@@ -27,9 +27,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -39,6 +40,10 @@ var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var rxjs = require('rxjs/Rx');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistryGridListViewer Component', function () {
     var comp;
@@ -52,6 +57,7 @@ describe('NfRegistryGridListViewer Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -63,6 +69,7 @@ describe('NfRegistryGridListViewer Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -72,8 +79,16 @@ describe('NfRegistryGridListViewer Component', function () {
                 NfPageNotFoundComponent
             ],
             providers: [
+                NfRegistryService,
+                NfRegistryAuthService,
                 NfRegistryApi,
-                NfRegistryService, {
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
+                {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'
                 }, {
@@ -98,6 +113,8 @@ describe('NfRegistryGridListViewer Component', function () {
         nfRegistryService.perspective = 'explorer';
 
         // Spy
+        spyOn(nfRegistryApi, 'ticketExchange').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
+        spyOn(nfRegistryService, 'loadCurrentUser').and.callFake(function () {}).and.returnValue(rxjs.Observable.of({}));
         spyOn(nfRegistryApi, 'getBuckets').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of([{
             identifier: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 64c75ad..c60a230 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
@@ -26,9 +26,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -37,6 +38,10 @@ var NfRegistryDropletGridListViewer = require('nifi-registry/components/explorer
 var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistryExplorer Component', function () {
     var comp;
@@ -49,6 +54,7 @@ describe('NfRegistryExplorer Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -60,6 +66,7 @@ describe('NfRegistryExplorer Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -70,7 +77,14 @@ describe('NfRegistryExplorer Component', function () {
             ],
             providers: [
                 NfRegistryService,
+                NfRegistryAuthService,
                 NfRegistryApi,
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
                 {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 9803b82..332a692 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.html
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.html
@@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 -->
 
+<mat-progress-spinner id="loading-spinner" mode="indeterminate"></mat-progress-spinner>
 <mat-sidenav-container>
     <mat-sidenav #sidenav mode="over" align="end" opened="false" disableClose="true">
         <router-outlet name="sidenav"></router-outlet>
@@ -70,11 +71,15 @@ limitations under the License.
             <button *ngIf="false" matTooltip="Alerts" mat-icon-button>
                 <i class="fa fa-bell" aria-hidden="true"></i>
             </button>
-            <button mat-ripple [@flyInOut] *ngIf="nfRegistryService.perspective === 'explorer'" mat-icon-button
+            <div *ngIf="nfRegistryService.currentUser.identity" 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
                     routerLink="/nifi-registry/administration/users">
                 <i class="fa fa-wrench" aria-hidden="true"></i>
             </button>
-            <button mat-ripple [@flyInOut] *ngIf="nfRegistryService.perspective === 'administration'" mat-mini-fab
+            <button 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/247985ad/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 2e2a1c2..91b1909 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.js
@@ -16,26 +16,86 @@
  */
 
 var ngCore = require('@angular/core');
+var ngCommonHttp = require('@angular/common/http');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfStorage = require('nifi-registry/services/nf-storage.service.js');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var ngRouter = require('@angular/router');
+var MILLIS_PER_SECOND = 1000;
 
-function NfRegistry(nfRegistryService, changeDetectorRef) {
+/**
+ * NfRegistry constructor.
+ *
+ * @param http                  The angular http module.
+ * @param nfStorage             A wrapper for the browser's local storage.
+ * @param nfRegistryService     The registry service.
+ * @param nfRegistryApi     The api service.
+ * @param changeDetectorRef     The change detector ref.
+ * @param router                The angular router module.
+ * @constructor
+ */
+function NfRegistry(http, nfStorage, nfRegistryService, nfRegistryApi, changeDetectorRef, router) {
+    this.http = http;
+    this.nfStorage = nfStorage;
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
     this.cd = changeDetectorRef;
+    this.router = router;
 };
 
 NfRegistry.prototype = {
     constructor: NfRegistry,
 
+    /**
+     * Initialize the component
+     */
     ngOnInit: function () {
+        var self = this;
         this.nfRegistryService.sidenav = this.sidenav; //ngCore.ViewChild
+        //
+        // // attempt kerberos authentication
+        // return this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+        //     // get the payload and store the token with the appropriate expiration
+        //     var token = self.nfStorage.getJwtPayload(jwt);
+        //     if(token) {
+        //         var expiration = parseInt(token['exp'], 10) * MILLIS_PER_SECOND;
+        //         self.nfStorage.setItem('jwt', jwt, expiration);
+        //     }
+        //     self.nfRegistryApi.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") {
+        //             // render the users name
+        //             self.nfRegistryService.currentUser = currentUser;
+        //
+        //             // render the logout button if there is a token locally
+        //             if (self.nfStorage.getItem('jwt') !== null) {
+        //                 self.nfRegistryService.currentUser.canLogout = true;
+        //             }
+        //         } else {
+        //             // set the anonymous user label
+        //             self.nfRegistryService.currentUser.identity = 'Anonymous';
+        //         }
+        //     });
+        // });
     },
 
+    /**
+     * since the child views are updating the nfRegistryService values that are used to display
+     * the breadcrumbs in this component's view we need to manually detect changes at the correct
+     * point in the lifecycle.
+     */
     ngAfterViewChecked: function () {
-        // since the child views are updating the nfRegistryService values that are used to display
-        // the breadcrumbs in this component's view we need to manually detect changes at the correct
-        // point in the lifecycle.
         this.cd.detectChanges();
+    },
+
+    /**
+     * Invalidate old tokens and route to login page
+     */
+    logout: function() {
+        this.nfRegistryService.currentUser = {};
+        this.nfStorage.removeItem('jwt');
+        this.router.navigateByUrl('/nifi-registry/login');
     }
 };
 
@@ -51,8 +111,12 @@ NfRegistry.annotations = [
 ];
 
 NfRegistry.parameters = [
+    ngCommonHttp.HttpClient,
+    NfStorage,
     NfRegistryService,
-    ngCore.ChangeDetectorRef
+    NfRegistryApi,
+    ngCore.ChangeDetectorRef,
+    ngRouter.Router
 ];
 
 module.exports = NfRegistry;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 a44f7b8..455574e 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
@@ -26,9 +26,12 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 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');
@@ -37,6 +40,10 @@ var NfRegistryBucketGridListViewer = require('nifi-registry/components/explorer/
 var NfRegistryDropletGridListViewer = require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
 var fdsCore = require('@fluid-design-system/core');
 var ngHttp = require('@angular/http');
+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');
 
 function NfRegistryModule() {
 };
@@ -52,6 +59,7 @@ NfRegistryModule.annotations = [
             fdsCore,
             ngHttp.HttpModule,
             ngHttp.JsonpModule,
+            ngCommonHttp.HttpClientModule,
             NfRegistryRoutes
         ],
         declarations: [
@@ -62,21 +70,34 @@ NfRegistryModule.annotations = [
             NfRegistryUsersAdministration,
             NfRegistryUserDetails,
             NfRegistryUserPermissions,
+            NfRegistryUserGroupPermissions,
             NfRegistryBucketPermissions,
-            NfRegistryAddUser,
             NfRegistryWorkflowAdministration,
+            NfRegistryAddUser,
             NfRegistryCreateBucket,
+            NfRegistryCreateNewGroup,
+            NfRegistryAddSelectedToGroup,
             NfRegistryGridListViewer,
             NfRegistryBucketGridListViewer,
             NfRegistryDropletGridListViewer,
             NfPageNotFoundComponent
         ],
         entryComponents: [
-            NfRegistryCreateBucket
+            NfRegistryAddUser,
+            NfRegistryCreateBucket,
+            NfRegistryCreateNewGroup,
+            NfRegistryAddSelectedToGroup
         ],
         providers: [
             NfRegistryService,
-            NfRegistryApi
+            NfRegistryAuthService,
+            NfRegistryApi,
+            NfStorage,
+            {
+                provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                useClass: NfRegistryTokenInterceptor,
+                multi: true
+            }
         ],
         bootstrap: [NfRegistry]
     })

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 d1ed18f..4cf5f60 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
@@ -21,9 +21,9 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/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 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');
@@ -88,8 +88,8 @@ var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
     component: NfRegistryUserPermissions,
     outlet: 'sidenav'
 }, {
-    path: 'user/add',
-    component: NfRegistryAddUser,
+    path: 'group/permissions/:groupId',
+    component: NfRegistryUserGroupPermissions,
     outlet: 'sidenav'
 }, {
     path: 'bucket/permissions/:bucketId',

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 8b381c9..ca8097a 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
@@ -26,7 +26,8 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 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/add/nf-registry-add-user.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 NfRegistryBucketPermissions = require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
@@ -37,6 +38,10 @@ var NfRegistryDropletGridListViewer = require('nifi-registry/components/explorer
 var fdsCore = require('@fluid-design-system/core');
 var ngMoment = require('angular2-moment');
 var ngHttp = require('@angular/http');
+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');
 
 describe('NfRegistry Component', function () {
     var comp;
@@ -48,6 +53,7 @@ describe('NfRegistry Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -59,6 +65,7 @@ describe('NfRegistry Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -69,7 +76,14 @@ describe('NfRegistry Component', function () {
             ],
             providers: [
                 NfRegistryService,
+                NfRegistryAuthService,
                 NfRegistryApi,
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
                 {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'