From 84628f48a51236b865aa765294f394dd013134ab Mon Sep 17 00:00:00 2001 From: Volker Theile Date: Wed, 17 Jul 2019 11:18:48 +0200 Subject: [PATCH] mgr/dashboard: Add SSO guard service. Signed-off-by: Volker Theile --- .../frontend/src/app/app-routing.module.ts | 2 + .../services/no-sso-guard.service.spec.ts | 51 +++++++++++++++++++ .../shared/services/no-sso-guard.service.ts | 27 ++++++++++ 3 files changed, 80 insertions(+) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts index e38235fcf29..6445054f7d4 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts @@ -31,6 +31,7 @@ import { BreadcrumbsResolver, IBreadcrumb } from './shared/models/breadcrumbs'; import { AuthGuardService } from './shared/services/auth-guard.service'; import { FeatureTogglesGuardService } from './shared/services/feature-toggles-guard.service'; import { ModuleStatusGuardService } from './shared/services/module-status-guard.service'; +import { NoSsoGuardService } from './shared/services/no-sso-guard.service'; export class PerformanceCounterBreadcrumbsResolver extends BreadcrumbsResolver { resolve(route: ActivatedRouteSnapshot) { @@ -228,6 +229,7 @@ const routes: Routes = [ { path: URLVerbs.EDIT, component: UserPasswordFormComponent, + canActivate: [NoSsoGuardService], data: { breadcrumbs: ActionLabels.EDIT } } ] diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts new file mode 100644 index 00000000000..76bbd4fe0b6 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.spec.ts @@ -0,0 +1,51 @@ +import { Component, NgZone } from '@angular/core'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { Router, Routes } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { configureTestBed } from '../../../testing/unit-test-helper'; +import { AuthStorageService } from './auth-storage.service'; +import { NoSsoGuardService } from './no-sso-guard.service'; + +describe('NoSsoGuardService', () => { + let service: NoSsoGuardService; + let authStorageService: AuthStorageService; + let ngZone: NgZone; + let router: Router; + + @Component({ selector: 'cd-404', template: '' }) + class NotFoundComponent {} + + const routes: Routes = [{ path: '404', component: NotFoundComponent }]; + + configureTestBed({ + imports: [RouterTestingModule.withRoutes(routes)], + providers: [NoSsoGuardService, AuthStorageService], + declarations: [NotFoundComponent] + }); + + beforeEach(() => { + service = TestBed.get(NoSsoGuardService); + authStorageService = TestBed.get(AuthStorageService); + ngZone = TestBed.get(NgZone); + router = TestBed.get(Router); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should allow if not logged in via SSO', () => { + spyOn(authStorageService, 'isSSO').and.returnValue(false); + expect(service.canActivate()).toBe(true); + }); + + it('should prevent if logged in via SSO', fakeAsync(() => { + spyOn(authStorageService, 'isSSO').and.returnValue(true); + ngZone.run(() => { + expect(service.canActivate()).toBe(false); + }); + tick(); + expect(router.url).toBe('/404'); + })); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts new file mode 100644 index 00000000000..79338a8541b --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/no-sso-guard.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { CanActivate, CanActivateChild, Router } from '@angular/router'; + +import { AuthStorageService } from './auth-storage.service'; + +/** + * This service checks if a route can be activated if the user has not + * been logged in via SSO. + */ +@Injectable({ + providedIn: 'root' +}) +export class NoSsoGuardService implements CanActivate, CanActivateChild { + constructor(private authStorageService: AuthStorageService, private router: Router) {} + + canActivate() { + if (!this.authStorageService.isSSO()) { + return true; + } + this.router.navigate(['404']); + return false; + } + + canActivateChild(): boolean { + return this.canActivate(); + } +} -- 2.39.5