From 5c9fa3aa7adf133b7f8fd58ec9e0cb7a5e4ffa71 Mon Sep 17 00:00:00 2001 From: Matt Raible Date: Wed, 28 Dec 2016 17:06:46 -0700 Subject: [PATCH] feat(directives): Add ifUserInGroup and ifUser directives Contributes to #30. --- demo/app.component.ts | 5 ++++- src/index.ts | 1 + src/stormpath.module.ts | 10 +++++++-- src/stormpath/stormpath.service.ts | 9 ++++++++ src/user/if-user-in-group.directive.ts | 31 ++++++++++++++++++++++++++ src/user/if-user.directive.ts | 31 ++++++++++++++++++++++++++ src/user/index.ts | 2 ++ 7 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 src/user/if-user-in-group.directive.ts create mode 100644 src/user/if-user.directive.ts create mode 100644 src/user/index.ts diff --git a/demo/app.component.ts b/demo/app.component.ts index 381b95f..8c528f5 100644 --- a/demo/app.component.ts +++ b/demo/app.component.ts @@ -27,7 +27,10 @@ import { Account } from '../src/shared/account'; - + +

Directives

+ Only show for 'admin' group
+ Only show if user logged in `, providers: [Stormpath] diff --git a/src/index.ts b/src/index.ts index df267e3..e9011fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ export * from './stormpath.module'; // all components that will be codegen'd need to be exported for AOT to work +export * from './user/index'; export * from './authport/index'; export * from './email-verification/index'; export * from './forgot-password/index'; diff --git a/src/stormpath.module.ts b/src/stormpath.module.ts index cf6d7d0..c5e15b5 100644 --- a/src/stormpath.module.ts +++ b/src/stormpath.module.ts @@ -13,6 +13,8 @@ import { httpFactory } from './stormpath/stormpath.http'; import { EmailVerificationComponent } from './email-verification/email-verification.component'; import { ResetPasswordComponent } from './reset-password/reset-password.component'; import { ResendEmailVerificationComponent } from './resend-email-verification/resend-email-verification.component'; +import { IfUserInGroupDirective } from './user/if-user-in-group.directive'; +import { IfUserDirective } from './user/if-user.directive'; @NgModule({ declarations: [ @@ -22,7 +24,9 @@ import { ResendEmailVerificationComponent } from './resend-email-verification/re RegisterComponent, EmailVerificationComponent, ResetPasswordComponent, - ResendEmailVerificationComponent + ResendEmailVerificationComponent, + IfUserDirective, + IfUserInGroupDirective ], imports: [CommonModule, FormsModule, HttpModule], exports: [ @@ -32,7 +36,9 @@ import { ResendEmailVerificationComponent } from './resend-email-verification/re RegisterComponent, EmailVerificationComponent, ResetPasswordComponent, - ResendEmailVerificationComponent + ResendEmailVerificationComponent, + IfUserDirective, + IfUserInGroupDirective, ], providers: [Stormpath, StormpathConfiguration, LoginService, { diff --git a/src/stormpath/stormpath.service.ts b/src/stormpath/stormpath.service.ts index d0d583d..af49edd 100644 --- a/src/stormpath/stormpath.service.ts +++ b/src/stormpath/stormpath.service.ts @@ -194,6 +194,15 @@ export class Stormpath { .catch(this.errorTranslator); } + isInGroup(authorities: any, groups: Array): boolean { + // if at least one authority matches, allow + return authorities.filter(authority => this.inGroup(authority, groups)).length > 0; + } + + private inGroup(groupName: string, groups: Array): boolean { + return groups.filter(group => group.name == groupName).length > 0 + }; + /** * Returns the JSON error from an HTTP response, or a generic error if the * response is not a JSON error diff --git a/src/user/if-user-in-group.directive.ts b/src/user/if-user-in-group.directive.ts new file mode 100644 index 0000000..9cf7101 --- /dev/null +++ b/src/user/if-user-in-group.directive.ts @@ -0,0 +1,31 @@ +import { Directive, ElementRef, Input, Renderer, OnInit } from '@angular/core'; +import { Stormpath } from '../stormpath/index'; +import { IfUserDirective } from './if-user.directive'; + +@Directive({ + selector: '[ifUserInGroup]' +}) +export class IfUserInGroupDirective extends IfUserDirective { + @Input() ifUserInGroup: string; + private authority: string[]; + + ngOnInit(): void { + this.authority = this.ifUserInGroup.replace(/\s+/g, '').split(','); + this.stormpath.user$.subscribe(response => this.setVisibility(response)); + } + + protected setVisibility(account: any): void { + if (account === false) { + this.setHidden(); + // use == instead of === here because triple doesn't detect undefined + } else if (account && account['groups'] == null) { + // handle the fact that /login doesn't result groups + this.stormpath.getAccount().subscribe(response => { + return this.setVisibility(response); + }); + } else { + let result = this.stormpath.isInGroup(this.authority, account['groups'].items); + super.setVisibility(result); + } + } +} diff --git a/src/user/if-user.directive.ts b/src/user/if-user.directive.ts new file mode 100644 index 0000000..cd50208 --- /dev/null +++ b/src/user/if-user.directive.ts @@ -0,0 +1,31 @@ +import { Directive, ElementRef, Renderer, OnInit } from '@angular/core'; +import { Stormpath } from '../stormpath/index'; + +@Directive({ + selector: '[ifUser]' +}) +export class IfUserDirective implements OnInit { + + constructor(protected stormpath: Stormpath, protected el: ElementRef, protected renderer: Renderer) { + } + + ngOnInit(): void { + this.stormpath.user$.subscribe(response => this.setVisibility(response)); + } + + protected setVisible(): void { + this.renderer.setElementClass(this.el.nativeElement, 'hidden', false); + } + + protected setHidden(): void { + this.renderer.setElementClass(this.el.nativeElement, 'hidden', true); + } + + protected setVisibility(result: any): void { + if (result) { + this.setVisible(); + } else { + this.setHidden(); + } + } +} diff --git a/src/user/index.ts b/src/user/index.ts new file mode 100644 index 0000000..1b3a851 --- /dev/null +++ b/src/user/index.ts @@ -0,0 +1,2 @@ +export * from './if-user.directive' +export * from './if-user-in-group.directive'