[ADF-3181] Auth Guard - redirect by string url (#3474)

* redirect by string url

* auth guard tests fix

* revise
This commit is contained in:
Cilibiu Bogdan 2018-06-14 12:19:34 +03:00 committed by Eugenio Romano
parent 0cf2a35983
commit c0de0d5087
12 changed files with 55 additions and 111 deletions

View File

@ -113,12 +113,12 @@ describe('LoginComponent', () => {
spyOn(authService, 'login').and.returnValue(Observable.of({ type: 'type', ticket: 'ticket' })); spyOn(authService, 'login').and.returnValue(Observable.of({ type: 'type', ticket: 'ticket' }));
const redirect = '/home'; const redirect = '/home';
component.successRoute = redirect; component.successRoute = redirect;
authService.setRedirect({ provider: 'ECM', navigation: ['some-route'] }); authService.setRedirect({ provider: 'ECM', url: 'some-route' });
spyOn(router, 'navigate'); spyOn(router, 'navigateByUrl');
loginWithCredentials('fake-username', 'fake-password'); loginWithCredentials('fake-username', 'fake-password');
expect(router.navigate).toHaveBeenCalledWith(['some-route']); expect(router.navigateByUrl).toHaveBeenCalledWith('some-route');
}); });
it('should update user preferences upon login', async(() => { it('should update user preferences upon login', async(() => {

View File

@ -219,16 +219,16 @@ export class LoginComponent implements OnInit {
this.authService.login(values.username, values.password, this.rememberMe) this.authService.login(values.username, values.password, this.rememberMe)
.subscribe( .subscribe(
(token: any) => { (token: any) => {
const redirect = this.authService.getRedirect(this.providers); const redirectUrl = this.authService.getRedirect(this.providers);
this.actualLoginStep = LoginSteps.Welcome; this.actualLoginStep = LoginSteps.Welcome;
this.userPreferences.setStoragePrefix(values.username); this.userPreferences.setStoragePrefix(values.username);
values.password = null; values.password = null;
this.success.emit(new LoginSuccessEvent(token, values.username, null)); this.success.emit(new LoginSuccessEvent(token, values.username, null));
if (redirect) { if (redirectUrl) {
this.authService.setRedirect(null); this.authService.setRedirect(null);
this.router.navigate(redirect); this.router.navigateByUrl(redirectUrl);
} else if (this.successRoute) { } else if (this.successRoute) {
this.router.navigate([this.successRoute]); this.router.navigate([this.successRoute]);
} }

View File

@ -21,14 +21,14 @@ import { RedirectionModel } from '../models/redirection.model';
// TODO: should be extending AuthenticationService // TODO: should be extending AuthenticationService
export class AuthenticationMock /*extends AuthenticationService*/ { export class AuthenticationMock /*extends AuthenticationService*/ {
private redirect: RedirectionModel = null; private redirectUrl: RedirectionModel = null;
setRedirectUrl(url: RedirectionModel) { setRedirectUrl(url: RedirectionModel) {
this.redirect = url; this.redirectUrl = url;
} }
getRedirectUrl(): any[] { getRedirectUrl(): string|null {
return this.redirect ? this.redirect.navigation : null; return this.redirectUrl ? this.redirectUrl.url : null;
} }
// TODO: real auth service returns Observable<string> // TODO: real auth service returns Observable<string>

View File

@ -21,12 +21,12 @@
export class RedirectionModel { export class RedirectionModel {
provider: string; provider: string;
navigation?: any[]; url?: string;
constructor(obj?: any) { constructor(obj?: any) {
if (obj) { if (obj) {
this.provider = obj.provider; this.provider = obj.provider;
this.navigation = obj.navigation || null; this.url = obj.url || null;
} }
} }

View File

@ -68,7 +68,7 @@ describe('AuthGuardService BPM', () => {
expect(routerService.navigate).toHaveBeenCalledWith(['/login']); expect(routerService.navigate).toHaveBeenCalledWith(['/login']);
})); }));
it('should set redirect navigation commands', async(() => { it('should set redirect url', async(() => {
spyOn(authService, 'setRedirect').and.callThrough(); spyOn(authService, 'setRedirect').and.callThrough();
spyOn(routerService, 'navigate').and.stub(); spyOn(routerService, 'navigate').and.stub();
const router: RouterStateSnapshot = <RouterStateSnapshot> { url: 'some-url' }; const router: RouterStateSnapshot = <RouterStateSnapshot> { url: 'some-url' };
@ -76,9 +76,9 @@ describe('AuthGuardService BPM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'BPM', navigation: ['some-url', {}] provider: 'BPM', url: 'some-url'
}); });
expect(authService.getRedirect('BPM')).toEqual(['some-url', {}]); expect(authService.getRedirect('BPM')).toEqual('some-url');
})); }));
it('should set redirect navigation commands with query params', async(() => { it('should set redirect navigation commands with query params', async(() => {
@ -89,9 +89,9 @@ describe('AuthGuardService BPM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'BPM', navigation: ['some-url', {q: '123'}] provider: 'BPM', url: 'some-url;q=123'
}); });
expect(authService.getRedirect('BPM')).toEqual(['some-url', { q: '123' }]); expect(authService.getRedirect('BPM')).toEqual('some-url;q=123');
})); }));
it('should set redirect navigation commands with query params', async(() => { it('should set redirect navigation commands with query params', async(() => {
@ -102,9 +102,9 @@ describe('AuthGuardService BPM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'BPM', navigation: ['/'] provider: 'BPM', url: '/'
}); });
expect(authService.getRedirect('BPM')).toEqual(['/']); expect(authService.getRedirect('BPM')).toEqual('/');
})); }));
it('should get redirect url from config if there is one configured', async(() => { it('should get redirect url from config if there is one configured', async(() => {
@ -116,7 +116,7 @@ describe('AuthGuardService BPM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'BPM', navigation: ['some-url', {}] provider: 'BPM', url: 'some-url'
}); });
expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']); expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']);
})); }));

View File

@ -18,7 +18,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
ActivatedRouteSnapshot, CanActivate, CanActivateChild, RouterStateSnapshot, ActivatedRouteSnapshot, CanActivate, CanActivateChild, RouterStateSnapshot,
Router, PRIMARY_OUTLET, UrlTree, UrlSegmentGroup, UrlSegment Router
} from '@angular/router'; } from '@angular/router';
import { AppConfigService } from '../app-config/app-config.service'; import { AppConfigService } from '../app-config/app-config.service';
import { AuthenticationService } from './authentication.service'; import { AuthenticationService } from './authentication.service';
@ -45,9 +45,7 @@ export class AuthGuardBpm implements CanActivate, CanActivateChild {
} }
if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin() ) { if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin() ) {
const navigation = this.getNavigationCommands(redirectUrl); this.authService.setRedirect({ provider: 'BPM', url: redirectUrl });
this.authService.setRedirect({ provider: 'BPM', navigation });
const pathToLogin = this.getRouteDestinationForLogin(); const pathToLogin = this.getRouteDestinationForLogin();
this.router.navigate(['/' + pathToLogin]); this.router.navigate(['/' + pathToLogin]);
} }
@ -64,20 +62,4 @@ export class AuthGuardBpm implements CanActivate, CanActivateChild {
this.appConfig.get<string>('loginRoute') ? this.appConfig.get<string>('loginRoute') ?
this.appConfig.get<string>('loginRoute') : 'login'; this.appConfig.get<string>('loginRoute') : 'login';
} }
private getNavigationCommands(redirectUrl: string): any[] {
const urlTree: UrlTree = this.router.parseUrl(redirectUrl);
const urlSegmentGroup: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
if (!urlSegmentGroup) {
return [redirectUrl];
}
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
return urlSegments.reduce(function(acc, item) {
acc.push(item.path, item.parameters);
return acc;
}, []);
}
} }

View File

@ -76,9 +76,9 @@ describe('AuthGuardService ECM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ECM', navigation: ['some-url', {}] provider: 'ECM', url: 'some-url'
}); });
expect(authService.getRedirect('ECM')).toEqual(['some-url', {}]); expect(authService.getRedirect('ECM')).toEqual('some-url');
})); }));
it('should set redirect navigation commands with query params', async(() => { it('should set redirect navigation commands with query params', async(() => {
@ -89,9 +89,9 @@ describe('AuthGuardService ECM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ECM', navigation: ['some-url', {q: '123'}] provider: 'ECM', url: 'some-url;q=123'
}); });
expect(authService.getRedirect('ECM')).toEqual(['some-url', { q: '123' }]); expect(authService.getRedirect('ECM')).toEqual('some-url;q=123');
})); }));
it('should set redirect navigation commands with query params', async(() => { it('should set redirect navigation commands with query params', async(() => {
@ -102,9 +102,9 @@ describe('AuthGuardService ECM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ECM', navigation: ['/'] provider: 'ECM', url: '/'
}); });
expect(authService.getRedirect('ECM')).toEqual(['/']); expect(authService.getRedirect('ECM')).toEqual('/');
})); }));
it('should get redirect url from config if there is one configured', async(() => { it('should get redirect url from config if there is one configured', async(() => {
@ -116,7 +116,7 @@ describe('AuthGuardService ECM', () => {
authGuard.canActivate(null, router); authGuard.canActivate(null, router);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ECM', navigation: ['some-url', {}] provider: 'ECM', url: 'some-url'
}); });
expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']); expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']);
})); }));

View File

@ -17,8 +17,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router, ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router
PRIMARY_OUTLET, UrlTree, UrlSegmentGroup, UrlSegment
} from '@angular/router'; } from '@angular/router';
import { AuthenticationService } from './authentication.service'; import { AuthenticationService } from './authentication.service';
import { AppConfigService } from '../app-config/app-config.service'; import { AppConfigService } from '../app-config/app-config.service';
@ -44,9 +43,7 @@ export class AuthGuardEcm implements CanActivate {
return true; return true;
} }
const navigation = this.getNavigationCommands(redirectUrl); this.authService.setRedirect({ provider: 'ECM', url: redirectUrl });
this.authService.setRedirect({ provider: 'ECM', navigation });
const pathToLogin = this.getRouteDestinationForLogin(); const pathToLogin = this.getRouteDestinationForLogin();
this.router.navigate(['/' + pathToLogin]); this.router.navigate(['/' + pathToLogin]);
@ -58,20 +55,4 @@ export class AuthGuardEcm implements CanActivate {
this.appConfig.get<string>('loginRoute') ? this.appConfig.get<string>('loginRoute') ?
this.appConfig.get<string>('loginRoute') : 'login'; this.appConfig.get<string>('loginRoute') : 'login';
} }
private getNavigationCommands(redirectUrl: string): any[] {
const urlTree: UrlTree = this.router.parseUrl(redirectUrl);
const urlSegmentGroup: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
if (!urlSegmentGroup) {
return [redirectUrl];
}
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
return urlSegments.reduce(function(acc, item) {
acc.push(item.path, item.parameters);
return acc;
}, []);
}
} }

View File

@ -70,7 +70,7 @@ describe('AuthGuardService', () => {
service.canActivate(null, state); service.canActivate(null, state);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ALL', navigation: ['some-url', {}] provider: 'ALL', url: 'some-url'
}); });
expect(router.navigate).toHaveBeenCalledWith(['/login']); expect(router.navigate).toHaveBeenCalledWith(['/login']);
})); }));
@ -85,7 +85,7 @@ describe('AuthGuardService', () => {
service.canActivate(null, state); service.canActivate(null, state);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ALL', navigation: ['some-url', { q: 'query' } ] provider: 'ALL', url: 'some-url;q=query'
}); });
expect(router.navigate).toHaveBeenCalledWith(['/login']); expect(router.navigate).toHaveBeenCalledWith(['/login']);
})); }));
@ -100,7 +100,7 @@ describe('AuthGuardService', () => {
service.canActivate(null, state); service.canActivate(null, state);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ALL', navigation: ['some-url', {}] provider: 'ALL', url: 'some-url'
}); });
expect(router.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']); expect(router.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']);
})); }));
@ -114,7 +114,7 @@ describe('AuthGuardService', () => {
service.canActivate(null, state); service.canActivate(null, state);
expect(authService.setRedirect).toHaveBeenCalledWith({ expect(authService.setRedirect).toHaveBeenCalledWith({
provider: 'ALL', navigation: ['/'] provider: 'ALL', url: '/'
}); });
})); }));
}); });

View File

@ -18,8 +18,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
ActivatedRouteSnapshot, CanActivate, ActivatedRouteSnapshot, CanActivate,
CanActivateChild, RouterStateSnapshot, Router, CanActivateChild, RouterStateSnapshot, Router
PRIMARY_OUTLET, UrlTree, UrlSegmentGroup, UrlSegment
} from '@angular/router'; } from '@angular/router';
import { AuthenticationService } from './authentication.service'; import { AuthenticationService } from './authentication.service';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
@ -47,9 +46,7 @@ export class AuthGuard implements CanActivate, CanActivateChild {
return true; return true;
} }
if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin() ) { if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin() ) {
const navigation = this.getNavigationCommands(redirectUrl); this.authService.setRedirect({ provider: 'ALL', url: redirectUrl } );
this.authService.setRedirect({ provider: 'ALL', navigation } );
const pathToLogin = this.getRouteDestinationForLogin(); const pathToLogin = this.getRouteDestinationForLogin();
this.router.navigate(['/' + pathToLogin]); this.router.navigate(['/' + pathToLogin]);
@ -67,20 +64,4 @@ export class AuthGuard implements CanActivate, CanActivateChild {
this.appConfig.get<string>('loginRoute') ? this.appConfig.get<string>('loginRoute') ?
this.appConfig.get<string>('loginRoute') : 'login'; this.appConfig.get<string>('loginRoute') : 'login';
} }
public getNavigationCommands(redirectUrl: string): any[] {
const urlTree: UrlTree = this.router.parseUrl(redirectUrl);
const urlSegmentGroup: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
if (!urlSegmentGroup) {
return [redirectUrl];
}
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
return urlSegments.reduce(function(acc, item) {
acc.push(item.path, item.parameters);
return acc;
}, []);
}
} }

View File

@ -274,13 +274,13 @@ describe('AuthenticationService', () => {
}); });
it('[ECM] should set/get redirectUrl when provider is ECM', () => { it('[ECM] should set/get redirectUrl when provider is ECM', () => {
authService.setRedirect({ provider: 'ECM', navigation: ['some-url'] }); authService.setRedirect({ provider: 'ECM', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toEqual(['some-url']); expect(authService.getRedirect(preferences.providers)).toEqual('some-url');
}); });
it('[ECM] should set/get redirectUrl when provider is BPM', () => { it('[ECM] should set/get redirectUrl when provider is BPM', () => {
authService.setRedirect({ provider: 'BPM', navigation: ['some-url'] }); authService.setRedirect({ provider: 'BPM', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toBeNull(); expect(authService.getRedirect(preferences.providers)).toBeNull();
}); });
@ -427,13 +427,13 @@ describe('AuthenticationService', () => {
}); });
it('[BPM] should set/get redirectUrl when provider is BPM', () => { it('[BPM] should set/get redirectUrl when provider is BPM', () => {
authService.setRedirect({ provider: 'BPM', navigation: ['some-url'] }); authService.setRedirect({ provider: 'BPM', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toEqual(['some-url']); expect(authService.getRedirect(preferences.providers)).toEqual('some-url');
}); });
it('[BPM] should set/get redirectUrl when provider is ECM', () => { it('[BPM] should set/get redirectUrl when provider is ECM', () => {
authService.setRedirect({ provider: 'ECM', navigation: ['some-url'] }); authService.setRedirect({ provider: 'ECM', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toBeNull(); expect(authService.getRedirect(preferences.providers)).toBeNull();
}); });
@ -544,21 +544,21 @@ describe('AuthenticationService', () => {
}); });
it('[ALL] should set/get redirectUrl when provider is ALL', () => { it('[ALL] should set/get redirectUrl when provider is ALL', () => {
authService.setRedirect({ provider: 'ALL', navigation: ['some-url'] }); authService.setRedirect({ provider: 'ALL', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toEqual(['some-url']); expect(authService.getRedirect(preferences.providers)).toEqual('some-url');
}); });
it('[ALL] should set/get redirectUrl when provider is BPM', () => { it('[ALL] should set/get redirectUrl when provider is BPM', () => {
authService.setRedirect({ provider: 'BPM', navigation: ['some-url'] }); authService.setRedirect({ provider: 'BPM', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toEqual(['some-url']); expect(authService.getRedirect(preferences.providers)).toEqual('some-url');
}); });
it('[ALL] should set/get redirectUrl when provider is ECM', () => { it('[ALL] should set/get redirectUrl when provider is ECM', () => {
authService.setRedirect({ provider: 'ECM', navigation: ['some-url'] }); authService.setRedirect({ provider: 'ECM', url: 'some-url' });
expect(authService.getRedirect(preferences.providers)).toEqual(['some-url']); expect(authService.getRedirect(preferences.providers)).toEqual('some-url');
}); });
it('[ALL] should return null as redirectUrl when redirectUrl field is not set', () => { it('[ALL] should return null as redirectUrl when redirectUrl field is not set', () => {

View File

@ -33,7 +33,7 @@ const REMEMBER_ME_UNTIL = 1000 * 60 * 60 * 24 * 30 ;
@Injectable() @Injectable()
export class AuthenticationService { export class AuthenticationService {
private redirect: RedirectionModel = null; private redirectUrl: RedirectionModel = null;
onLogin: Subject<any> = new Subject<any>(); onLogin: Subject<any> = new Subject<any>();
onLogout: Subject<any> = new Subject<any>(); onLogout: Subject<any> = new Subject<any>();
@ -249,23 +249,23 @@ export class AuthenticationService {
* @param url URL to redirect to * @param url URL to redirect to
*/ */
setRedirect(url: RedirectionModel) { setRedirect(url: RedirectionModel) {
this.redirect = url; this.redirectUrl = url;
} }
/** Gets the URL to redirect to after login. /** Gets the URL to redirect to after login.
* @param provider Service provider. Can be "ECM", "BPM" or "ALL". * @param provider Service provider. Can be "ECM", "BPM" or "ALL".
* @returns The redirect URL * @returns The redirect URL
*/ */
getRedirect(provider: string): any[] { getRedirect(provider: string): string {
return this.hasValidRedirection(provider) ? this.redirect.navigation : null; return this.hasValidRedirection(provider) ? this.redirectUrl.url : null;
} }
private hasValidRedirection(provider: string): boolean { private hasValidRedirection(provider: string): boolean {
return this.redirect && (this.redirect.provider === provider || this.hasSelectedProviderAll(provider)); return this.redirectUrl && (this.redirectUrl.provider === provider || this.hasSelectedProviderAll(provider));
} }
private hasSelectedProviderAll(provider: string): boolean { private hasSelectedProviderAll(provider: string): boolean {
return this.redirect && (this.redirect.provider === 'ALL' || provider === 'ALL'); return this.redirectUrl && (this.redirectUrl.provider === 'ALL' || provider === 'ALL');
} }
/** /**