From f6341e31a097bb82a98739789600dfa2c7fabf3b Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 6 Mar 2019 13:14:23 +0000 Subject: [PATCH] [ADF-4183] improved auth redirection (#4399) * base auth guard implementation * remove code duplication * unit test fixes --- lib/core/login/components/login.component.ts | 19 +++- lib/core/services/auth-guard-base.ts | 94 +++++++++++++++++++ .../services/auth-guard-bpm.service.spec.ts | 52 +++++----- lib/core/services/auth-guard-bpm.service.ts | 43 +++------ .../services/auth-guard-ecm.service.spec.ts | 52 +++++----- lib/core/services/auth-guard-ecm.service.ts | 47 +++------- lib/core/services/auth-guard.service.spec.ts | 30 +++--- lib/core/services/auth-guard.service.ts | 51 +++------- lib/core/services/public-api.ts | 1 + 9 files changed, 216 insertions(+), 173 deletions(-) create mode 100644 lib/core/services/auth-guard-base.ts diff --git a/lib/core/login/components/login.component.ts b/lib/core/login/components/login.component.ts index c201962627..f1ff243016 100644 --- a/lib/core/login/components/login.component.ts +++ b/lib/core/login/components/login.component.ts @@ -20,8 +20,8 @@ import { Input, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; - +import { Router, ActivatedRoute, Params } from '@angular/router'; +import { Location } from '@angular/common'; import { AuthenticationService } from '../../services/authentication.service'; import { LogService } from '../../services/log.service'; import { TranslationService } from '../../services/translation.service'; @@ -140,7 +140,9 @@ export class LoginComponent implements OnInit { private logService: LogService, private router: Router, private appConfig: AppConfigService, - private userPreferences: UserPreferencesService + private userPreferences: UserPreferencesService, + private location: Location, + private route: ActivatedRoute ) { this.initFormError(); this.initFormFieldsMessages(); @@ -154,6 +156,17 @@ export class LoginComponent implements OnInit { } } + if (this.authService.isEcmLoggedIn() || this.authService.isBpmLoggedIn()) { + this.location.forward(); + } else { + this.route.queryParams.subscribe((params: Params) => { + const url = params['redirectUrl']; + const provider = this.appConfig.get(AppConfigValues.PROVIDERS); + + this.authService.setRedirect({ provider, url }); + }); + } + if (this.hasCustomFieldsValidation()) { this.form = this._fb.group(this.fieldsValidation); } else { diff --git a/lib/core/services/auth-guard-base.ts b/lib/core/services/auth-guard-base.ts new file mode 100644 index 0000000000..bf307eaf69 --- /dev/null +++ b/lib/core/services/auth-guard-base.ts @@ -0,0 +1,94 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Router, + CanActivate, + ActivatedRouteSnapshot, + RouterStateSnapshot, + CanActivateChild +} from '@angular/router'; +import { Observable } from 'rxjs'; +import { AuthenticationService } from './authentication.service'; +import { + AppConfigService, + AppConfigValues +} from '../app-config/app-config.service'; +import { OauthConfigModel } from '../models/oauth-config.model'; + +export abstract class AuthGuardBase implements CanActivate, CanActivateChild { + abstract checkLogin( + activeRoute: ActivatedRouteSnapshot, + redirectUrl: string + ): Observable | Promise | boolean; + + protected get withCredentials(): boolean { + return this.appConfigService.get( + 'auth.withCredentials', + false + ); + } + + constructor( + protected authenticationService: AuthenticationService, + protected router: Router, + protected appConfigService: AppConfigService + ) {} + + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable | Promise | boolean { + return this.checkLogin(route, state.url); + } + + canActivateChild( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable | Promise | boolean { + return this.canActivate(route, state); + } + + protected redirectToUrl(provider: string, url: string) { + this.authenticationService.setRedirect({ provider, url }); + + const pathToLogin = this.getLoginRoute(); + const urlToRedirect = `/${pathToLogin}?redirectUrl=${url}`; + + this.router.navigateByUrl(urlToRedirect); + } + + protected getLoginRoute(): string { + return ( + this.appConfigService && + this.appConfigService.get( + AppConfigValues.LOGIN_ROUTE, + 'login' + ) + ); + } + + protected isOAuthWithoutSilentLogin() { + const oauth = this.appConfigService.get( + AppConfigValues.OAUTHCONFIG, + null + ); + return ( + this.authenticationService.isOauth() && oauth.silentLogin === false + ); + } +} diff --git a/lib/core/services/auth-guard-bpm.service.spec.ts b/lib/core/services/auth-guard-bpm.service.spec.ts index 312cda77e7..dc84da5391 100644 --- a/lib/core/services/auth-guard-bpm.service.spec.ts +++ b/lib/core/services/auth-guard-bpm.service.spec.ts @@ -27,7 +27,7 @@ describe('AuthGuardService BPM', () => { let authGuard: AuthGuardBpm; let authService: AuthenticationService; - let routerService: Router; + let router: Router; let appConfigService: AppConfigService; setupTestBed({ @@ -38,7 +38,7 @@ describe('AuthGuardService BPM', () => { localStorage.clear(); authService = TestBed.get(AuthenticationService); authGuard = TestBed.get(AuthGuardBpm); - routerService = TestBed.get(Router); + router = TestBed.get(Router); appConfigService = TestBed.get(AppConfigService); appConfigService.config.providers = 'BPM'; @@ -47,45 +47,45 @@ describe('AuthGuardService BPM', () => { it('if the alfresco js api is logged in should canActivate be true', async(() => { spyOn(authService, 'isBpmLoggedIn').and.returnValue(true); - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeTruthy(); + expect(authGuard.canActivate(null, route)).toBeTruthy(); })); it('if the alfresco js api is configured with withCredentials true should canActivate be true', async(() => { spyOn(authService, 'isBpmLoggedIn').and.returnValue(true); appConfigService.config.auth.withCredentials = true; - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeTruthy(); + expect(authGuard.canActivate(null, route)).toBeTruthy(); })); it('if the alfresco js api is NOT logged in should canActivate be false', async(() => { spyOn(authService, 'isBpmLoggedIn').and.returnValue(false); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url' }; - expect(authGuard.canActivate(null, router)).toBeFalsy(); + expect(authGuard.canActivate(null, route)).toBeFalsy(); })); it('if the alfresco js api is NOT logged in should trigger a redirect event', async(() => { appConfigService.config.loginRoute = 'login'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'isBpmLoggedIn').and.returnValue(false); - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeFalsy(); - expect(routerService.navigate).toHaveBeenCalledWith(['/login']); + expect(authGuard.canActivate(null, route)).toBeFalsy(); + expect(router.navigateByUrl).toHaveBeenCalledWith('/login?redirectUrl=some-url'); })); it('should set redirect url', async(() => { spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'BPM', url: 'some-url' @@ -95,10 +95,10 @@ describe('AuthGuardService BPM', () => { it('should set redirect navigation commands with query params', async(() => { spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url;q=123' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url;q=123' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'BPM', url: 'some-url;q=123' @@ -108,10 +108,10 @@ describe('AuthGuardService BPM', () => { it('should set redirect navigation commands with query params', async(() => { spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: '/' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: '/' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'BPM', url: '/' @@ -122,15 +122,15 @@ describe('AuthGuardService BPM', () => { it('should get redirect url from config if there is one configured', async(() => { appConfigService.config.loginRoute = 'fakeLoginRoute'; spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'BPM', url: 'some-url' }); - expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']); + expect(router.navigateByUrl).toHaveBeenCalledWith('/fakeLoginRoute?redirectUrl=some-url'); })); }); diff --git a/lib/core/services/auth-guard-bpm.service.ts b/lib/core/services/auth-guard-bpm.service.ts index d1492f7518..9d0021e2cf 100644 --- a/lib/core/services/auth-guard-bpm.service.ts +++ b/lib/core/services/auth-guard-bpm.service.ts @@ -16,49 +16,32 @@ */ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, RouterStateSnapshot, Router } from '@angular/router'; -import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; +import { ActivatedRouteSnapshot, Router } from '@angular/router'; +import { AppConfigService } from '../app-config/app-config.service'; import { AuthenticationService } from './authentication.service'; -import { OauthConfigModel } from '../models/oauth-config.model'; +import { AuthGuardBase } from './auth-guard-base'; +import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) -export class AuthGuardBpm implements CanActivate, CanActivateChild { +export class AuthGuardBpm extends AuthGuardBase { - constructor(private authService: AuthenticationService, private router: Router, private appConfigService: AppConfigService) { + constructor(authenticationService: AuthenticationService, + router: Router, + appConfigService: AppConfigService) { + super(authenticationService, router, appConfigService); } - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - return this.checkLogin(state.url); - } - - canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - return this.canActivate(route, state); - } - - checkLogin(redirectUrl: string): boolean { - let withCredentialsMode = this.appConfigService.get('auth.withCredentials', false); - - if (this.authService.isBpmLoggedIn() || withCredentialsMode) { + checkLogin(activeRoute: ActivatedRouteSnapshot, redirectUrl: string): Observable | Promise | boolean { + if (this.authenticationService.isBpmLoggedIn() || this.withCredentials) { return true; } - if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin()) { - this.authService.setRedirect({ provider: 'BPM', url: redirectUrl }); - const pathToLogin = this.getRouteDestinationForLogin(); - this.router.navigate(['/' + pathToLogin]); + if (!this.authenticationService.isOauth() || this.isOAuthWithoutSilentLogin()) { + this.redirectToUrl('BPM', redirectUrl); } return false; } - - isOAuthWithoutSilentLogin() { - let oauth: OauthConfigModel = this.appConfigService.get(AppConfigValues.OAUTHCONFIG, null); - return this.authService.isOauth() && oauth.silentLogin === false; - } - - private getRouteDestinationForLogin(): string { - return this.appConfigService && this.appConfigService.get(AppConfigValues.LOGIN_ROUTE) ? this.appConfigService.get(AppConfigValues.LOGIN_ROUTE) : 'login'; - } } diff --git a/lib/core/services/auth-guard-ecm.service.spec.ts b/lib/core/services/auth-guard-ecm.service.spec.ts index 1e2da3360c..9a0534eec2 100644 --- a/lib/core/services/auth-guard-ecm.service.spec.ts +++ b/lib/core/services/auth-guard-ecm.service.spec.ts @@ -27,7 +27,7 @@ describe('AuthGuardService ECM', () => { let authGuard: AuthGuardEcm; let authService: AuthenticationService; - let routerService: Router; + let router: Router; let appConfigService: AppConfigService; setupTestBed({ @@ -38,7 +38,7 @@ describe('AuthGuardService ECM', () => { localStorage.clear(); authService = TestBed.get(AuthenticationService); authGuard = TestBed.get(AuthGuardEcm); - routerService = TestBed.get(Router); + router = TestBed.get(Router); appConfigService = TestBed.get(AppConfigService); appConfigService.config.providers = 'ECM'; @@ -47,45 +47,45 @@ describe('AuthGuardService ECM', () => { it('if the alfresco js api is logged in should canActivate be true', async(() => { spyOn(authService, 'isEcmLoggedIn').and.returnValue(true); - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeTruthy(); + expect(authGuard.canActivate(null, route)).toBeTruthy(); })); it('if the alfresco js api is configured with withCredentials true should canActivate be true', async(() => { spyOn(authService, 'isBpmLoggedIn').and.returnValue(true); appConfigService.config.auth.withCredentials = true; - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeTruthy(); + expect(authGuard.canActivate(null, route)).toBeTruthy(); })); it('if the alfresco js api is NOT logged in should canActivate be false', async(() => { spyOn(authService, 'isEcmLoggedIn').and.returnValue(false); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url' }; - expect(authGuard.canActivate(null, router)).toBeFalsy(); + expect(authGuard.canActivate(null, route)).toBeFalsy(); })); it('if the alfresco js api is NOT logged in should trigger a redirect event', async(() => { appConfigService.config.loginRoute = 'login'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'isEcmLoggedIn').and.returnValue(false); - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeFalsy(); - expect(routerService.navigate).toHaveBeenCalledWith(['/login']); + expect(authGuard.canActivate(null, route)).toBeFalsy(); + expect(router.navigateByUrl).toHaveBeenCalledWith('/login?redirectUrl=some-url'); })); it('should set redirect navigation commands', async(() => { spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ECM', url: 'some-url' @@ -95,10 +95,10 @@ describe('AuthGuardService ECM', () => { it('should set redirect navigation commands with query params', async(() => { spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url;q=123' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url;q=123' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ECM', url: 'some-url;q=123' @@ -108,10 +108,10 @@ describe('AuthGuardService ECM', () => { it('should set redirect navigation commands with query params', async(() => { spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: '/' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: '/' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ECM', url: '/' @@ -122,15 +122,15 @@ describe('AuthGuardService ECM', () => { it('should get redirect url from config if there is one configured', async(() => { appConfigService.config.loginRoute = 'fakeLoginRoute'; spyOn(authService, 'setRedirect').and.callThrough(); - spyOn(routerService, 'navigate').and.stub(); - const router: RouterStateSnapshot = { url: 'some-url' }; + spyOn(router, 'navigateByUrl').and.stub(); + const route: RouterStateSnapshot = { url: 'some-url' }; - authGuard.canActivate(null, router); + authGuard.canActivate(null, route); expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ECM', url: 'some-url' }); - expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']); + expect(router.navigateByUrl).toHaveBeenCalledWith('/fakeLoginRoute?redirectUrl=some-url'); })); }); diff --git a/lib/core/services/auth-guard-ecm.service.ts b/lib/core/services/auth-guard-ecm.service.ts index 2063e85dd9..467e8851bb 100644 --- a/lib/core/services/auth-guard-ecm.service.ts +++ b/lib/core/services/auth-guard-ecm.service.ts @@ -17,54 +17,33 @@ import { Injectable } from '@angular/core'; import { - ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router + ActivatedRouteSnapshot, Router } from '@angular/router'; import { AuthenticationService } from './authentication.service'; -import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; -import { OauthConfigModel } from '../models/oauth-config.model'; +import { AppConfigService } from '../app-config/app-config.service'; +import { AuthGuardBase } from './auth-guard-base'; +import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) -export class AuthGuardEcm implements CanActivate { +export class AuthGuardEcm extends AuthGuardBase { - constructor(private authService: AuthenticationService, - private router: Router, - private appConfigService: AppConfigService) { + constructor(authenticationService: AuthenticationService, + router: Router, + appConfigService: AppConfigService) { + super(authenticationService, router, appConfigService); } - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - return this.checkLogin(state.url); - } - - canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - return this.canActivate(route, state); - } - - checkLogin(redirectUrl: string): boolean { - let withCredentialsMode = this.appConfigService.get('auth.withCredentials', false); - - if (this.authService.isEcmLoggedIn() || withCredentialsMode) { + checkLogin(activeRoute: ActivatedRouteSnapshot, redirectUrl: string): Observable | Promise | boolean { + if (this.authenticationService.isEcmLoggedIn() || this.withCredentials) { return true; } - if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin()) { - this.authService.setRedirect({ provider: 'ECM', url: redirectUrl }); - const pathToLogin = this.getRouteDestinationForLogin(); - this.router.navigate(['/' + pathToLogin]); + if (!this.authenticationService.isOauth() || this.isOAuthWithoutSilentLogin()) { + this.redirectToUrl('ECM', redirectUrl); } return false; } - - isOAuthWithoutSilentLogin() { - let oauth: OauthConfigModel = this.appConfigService.get(AppConfigValues.OAUTHCONFIG, null); - return this.authService.isOauth() && oauth.silentLogin === false; - } - - private getRouteDestinationForLogin(): string { - return this.appConfigService && - this.appConfigService.get(AppConfigValues.LOGIN_ROUTE) ? - this.appConfigService.get(AppConfigValues.LOGIN_ROUTE) : 'login'; - } } diff --git a/lib/core/services/auth-guard.service.spec.ts b/lib/core/services/auth-guard.service.spec.ts index ba3b2433bb..8d1edcbab8 100644 --- a/lib/core/services/auth-guard.service.spec.ts +++ b/lib/core/services/auth-guard.service.spec.ts @@ -26,7 +26,7 @@ import { CoreTestingModule } from '../testing/core.testing.module'; describe('AuthGuardService', () => { let state; let authService: AuthenticationService; - let routerService: Router; + let router: Router; let authGuard: AuthGuard; let appConfigService: AppConfigService; @@ -38,7 +38,7 @@ describe('AuthGuardService', () => { localStorage.clear(); state = { url: '' }; authService = TestBed.get(AuthenticationService); - routerService = TestBed.get(Router); + router = TestBed.get(Router); authGuard = TestBed.get(AuthGuard); appConfigService = TestBed.get(AppConfigService); @@ -46,36 +46,36 @@ describe('AuthGuardService', () => { }); it('if the alfresco js api is logged in should canActivate be true', async(() => { - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'isLoggedIn').and.returnValue(true); expect(authGuard.canActivate(null, state)).toBeTruthy(); - expect(routerService.navigate).not.toHaveBeenCalled(); + expect(router.navigateByUrl).not.toHaveBeenCalled(); })); it('if the alfresco js api is NOT logged in should canActivate be false', async(() => { state.url = 'some-url'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'isLoggedIn').and.returnValue(false); expect(authGuard.canActivate(null, state)).toBeFalsy(); - expect(routerService.navigate).toHaveBeenCalled(); + expect(router.navigateByUrl).toHaveBeenCalled(); })); it('if the alfresco js api is configured with withCredentials true should canActivate be true', async(() => { spyOn(authService, 'isBpmLoggedIn').and.returnValue(true); appConfigService.config.auth.withCredentials = true; - const router: RouterStateSnapshot = {url : 'some-url'}; + const route: RouterStateSnapshot = {url : 'some-url'}; - expect(authGuard.canActivate(null, router)).toBeTruthy(); + expect(authGuard.canActivate(null, route)).toBeTruthy(); })); it('should set redirect url', async(() => { state.url = 'some-url'; appConfigService.config.loginRoute = 'login'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'setRedirect'); authGuard.canActivate(null, state); @@ -83,14 +83,14 @@ describe('AuthGuardService', () => { expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ALL', url: 'some-url' }); - expect(routerService.navigate).toHaveBeenCalledWith(['/login']); + expect(router.navigateByUrl).toHaveBeenCalledWith('/login?redirectUrl=some-url'); })); it('should set redirect url with query params', async(() => { state.url = 'some-url;q=query'; appConfigService.config.loginRoute = 'login'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'setRedirect'); authGuard.canActivate(null, state); @@ -98,14 +98,14 @@ describe('AuthGuardService', () => { expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ALL', url: 'some-url;q=query' }); - expect(routerService.navigate).toHaveBeenCalledWith(['/login']); + expect(router.navigateByUrl).toHaveBeenCalledWith('/login?redirectUrl=some-url;q=query'); })); it('should get redirect url from config if there is one configured', async(() => { state.url = 'some-url'; appConfigService.config.loginRoute = 'fakeLoginRoute'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'setRedirect'); authGuard.canActivate(null, state); @@ -113,13 +113,13 @@ describe('AuthGuardService', () => { expect(authService.setRedirect).toHaveBeenCalledWith({ provider: 'ALL', url: 'some-url' }); - expect(routerService.navigate).toHaveBeenCalledWith(['/fakeLoginRoute']); + expect(router.navigateByUrl).toHaveBeenCalledWith('/fakeLoginRoute?redirectUrl=some-url'); })); it('should pass actual redirect when no state segments exists', async(() => { state.url = '/'; - spyOn(routerService, 'navigate'); + spyOn(router, 'navigateByUrl'); spyOn(authService, 'setRedirect'); authGuard.canActivate(null, state); diff --git a/lib/core/services/auth-guard.service.ts b/lib/core/services/auth-guard.service.ts index c4f421d52d..f526d86c65 100644 --- a/lib/core/services/auth-guard.service.ts +++ b/lib/core/services/auth-guard.service.ts @@ -16,57 +16,30 @@ */ import { Injectable } from '@angular/core'; -import { - ActivatedRouteSnapshot, CanActivate, - CanActivateChild, RouterStateSnapshot, Router -} from '@angular/router'; +import { ActivatedRouteSnapshot, Router } from '@angular/router'; import { AuthenticationService } from './authentication.service'; import { Observable } from 'rxjs'; -import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; -import { OauthConfigModel } from '../models/oauth-config.model'; +import { AppConfigService } from '../app-config/app-config.service'; +import { AuthGuardBase } from './auth-guard-base'; @Injectable({ providedIn: 'root' }) -export class AuthGuard implements CanActivate, CanActivateChild { - constructor(private authService: AuthenticationService, - private router: Router, - private appConfigService: AppConfigService) { +export class AuthGuard extends AuthGuardBase { + constructor(authenticationService: AuthenticationService, + router: Router, + appConfigService: AppConfigService) { + super(authenticationService, router, appConfigService); } - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean { - const redirectUrl = state.url; - return this.checkLogin(redirectUrl); - } - - canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean { - return this.canActivate(route, state); - } - - checkLogin(redirectUrl: string): boolean { - let withCredentialsMode = this.appConfigService.get('auth.withCredentials', false); - - if (this.authService.isLoggedIn() || withCredentialsMode) { + checkLogin(activeRoute: ActivatedRouteSnapshot, redirectUrl: string): Observable | Promise | boolean { + if (this.authenticationService.isLoggedIn() || this.withCredentials) { return true; } - if (!this.authService.isOauth() || this.isOAuthWithoutSilentLogin()) { - this.authService.setRedirect({ provider: 'ALL', url: redirectUrl }); - - const pathToLogin = this.getRouteDestinationForLogin(); - this.router.navigate(['/' + pathToLogin]); + if (!this.authenticationService.isOauth() || this.isOAuthWithoutSilentLogin()) { + this.redirectToUrl('ALL', redirectUrl); } return false; } - - isOAuthWithoutSilentLogin() { - let oauth: OauthConfigModel = this.appConfigService.get(AppConfigValues.OAUTHCONFIG, null); - return this.authService.isOauth() && oauth.silentLogin === false; - } - - public getRouteDestinationForLogin(): string { - return this.appConfigService && - this.appConfigService.get(AppConfigValues.LOGIN_ROUTE) ? - this.appConfigService.get(AppConfigValues.LOGIN_ROUTE) : 'login'; - } } diff --git a/lib/core/services/public-api.ts b/lib/core/services/public-api.ts index bd1621a25d..a9b659c75e 100644 --- a/lib/core/services/public-api.ts +++ b/lib/core/services/public-api.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +export * from './auth-guard-base'; export * from './authentication.service'; export * from './alfresco-api.service'; export * from './content.service';