From 48cca84f6ec438c3bf258e074e9eff31dbef7c09 Mon Sep 17 00:00:00 2001 From: Senyoret1 <34079003+Senyoret1@users.noreply.github.com> Date: Tue, 3 Nov 2020 13:17:16 -0400 Subject: [PATCH] Change how AuthGuardService works --- .../src/app/app-routing.module.ts | 3 +- .../components/pages/login/login.component.ts | 20 +++++-- .../src/app/services/auth-guard.service.ts | 60 +++++++------------ .../src/app/services/auth.service.ts | 8 +++ 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/static/skywire-manager-src/src/app/app-routing.module.ts b/static/skywire-manager-src/src/app/app-routing.module.ts index 0db61dc10e..37c0df5791 100644 --- a/static/skywire-manager-src/src/app/app-routing.module.ts +++ b/static/skywire-manager-src/src/app/app-routing.module.ts @@ -17,8 +17,7 @@ import { AllLabelsComponent } from './components/pages/settings/all-labels/all-l const routes: Routes = [ { path: 'login', - component: LoginComponent, - canActivate: [AuthGuardService] + component: LoginComponent }, { path: 'nodes', diff --git a/static/skywire-manager-src/src/app/components/pages/login/login.component.ts b/static/skywire-manager-src/src/app/components/pages/login/login.component.ts index ed6361c73a..b0ea768a37 100644 --- a/static/skywire-manager-src/src/app/components/pages/login/login.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/login/login.component.ts @@ -5,7 +5,7 @@ import { MatDialog } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { HttpErrorResponse } from '@angular/common/http'; -import { AuthService } from '../../../services/auth.service'; +import { AuthService, AuthStates } from '../../../services/auth.service'; import { SnackbarService } from '../../../services/snackbar.service'; import { InitialSetupComponent } from './initial-setup/initial-setup.component'; import { OperationError } from '../../../utils/operation-error'; @@ -23,7 +23,8 @@ export class LoginComponent implements OnInit, OnDestroy { form: FormGroup; loading = false; - private subscription: Subscription; + private verificationSubscription: Subscription; + private loginSubscription: Subscription; constructor( private authService: AuthService, @@ -33,15 +34,24 @@ export class LoginComponent implements OnInit, OnDestroy { ) { } ngOnInit() { + // Check if the user is already logged. + this.verificationSubscription = this.authService.checkLogin().subscribe(response => { + if (response !== AuthStates.NotLogged) { + this.router.navigate(['nodes'], { replaceUrl: true }); + } + }); + this.form = new FormGroup({ 'password': new FormControl('', Validators.required), }); } ngOnDestroy() { - if (this.subscription) { - this.subscription.unsubscribe(); + if (this.loginSubscription) { + this.loginSubscription.unsubscribe(); } + + this.verificationSubscription.unsubscribe(); } login() { @@ -50,7 +60,7 @@ export class LoginComponent implements OnInit, OnDestroy { } this.loading = true; - this.subscription = this.authService.login(this.form.get('password').value).subscribe( + this.loginSubscription = this.authService.login(this.form.get('password').value).subscribe( () => this.onLoginSuccess(), err => this.onLoginError(err) ); diff --git a/static/skywire-manager-src/src/app/services/auth-guard.service.ts b/static/skywire-manager-src/src/app/services/auth-guard.service.ts index f70d979991..4209be4f69 100644 --- a/static/skywire-manager-src/src/app/services/auth-guard.service.ts +++ b/static/skywire-manager-src/src/app/services/auth-guard.service.ts @@ -1,64 +1,44 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, CanActivateChild } from '@angular/router'; import { Observable, of } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; -import { MatDialog } from '@angular/material/dialog'; -import { AuthService, AuthStates } from './auth.service'; - -/** - * Redirects unauthorized users to the login page during the first load and always redirects - * authorized users from the login page to the node list. The api service is in chage of - * redirecting the unauthorized users to the login page in other cases. + /** + * Redirects the user to the login page if the forceFail property is set to true. The api + * service is in chage of redirecting the unauthorized users to the login page in other cases. + * It must be used in the canActivate and canActivateChild properties of the routing module. */ @Injectable({ providedIn: 'root' }) export class AuthGuardService implements CanActivate, CanActivateChild { - private authChecked = false; + private forceFailInternal = false; + /** + * If true, the user will be redirected to the login page. + */ + set forceFail(val: boolean) { + this.forceFailInternal = val; + } constructor( - private authService: AuthService, private router: Router, - private matDialog: MatDialog, ) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { - return this.checkIfCanActivate(route); + return this.checkIfCanActivate(); } canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { - return this.checkIfCanActivate(childRoute); + return this.checkIfCanActivate(); } - private checkIfCanActivate(route: ActivatedRouteSnapshot): Observable { - if (this.authChecked && route.routeConfig.path !== 'login') { - return of(true); - } - - return this.authService.checkLogin().pipe(catchError(e => { - return of(AuthStates.AuthDisabled); - }), map((authState: AuthStates) => { - this.authChecked = true; + private checkIfCanActivate(): Observable { + if (this.forceFailInternal) { + // Redirect the user. + this.router.navigate(['login'], { replaceUrl: true }); - // If the user is trying to access "Login" page while he is already logged in or the - // auth is disabled, redirect him to "Nodes" page - if (route.routeConfig.path === 'login' && (authState === AuthStates.Logged || authState === AuthStates.AuthDisabled)) { - this.router.navigate(['nodes'], { replaceUrl: true }); - - return false; - } - - // If the user is trying to access a protected part of the application while not logged in, - // redirect him to "Login" page - if (route.routeConfig.path !== 'login' && (authState !== AuthStates.Logged && authState !== AuthStates.AuthDisabled)) { - this.router.navigate(['login'], { replaceUrl: true }); - this.matDialog.closeAll(); - - return false; - } + return of(false); + } - return true; - })); + return of(true); } } diff --git a/static/skywire-manager-src/src/app/services/auth.service.ts b/static/skywire-manager-src/src/app/services/auth.service.ts index c4cea6fcb2..c351bdb3ca 100644 --- a/static/skywire-manager-src/src/app/services/auth.service.ts +++ b/static/skywire-manager-src/src/app/services/auth.service.ts @@ -7,6 +7,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { ApiService, ResponseTypes, RequestOptions } from './api.service'; import { OperationError } from '../utils/operation-error'; import { processServiceError } from '../utils/errors'; +import { AuthGuardService } from './auth-guard.service'; export enum AuthStates { AuthDisabled, Logged, NotLogged @@ -22,6 +23,7 @@ export class AuthService { constructor( private apiService: ApiService, private translateService: TranslateService, + private authGuardService: AuthGuardService, ) { } /** @@ -34,6 +36,8 @@ export class AuthService { if (status !== true) { throw new Error(); } + + this.authGuardService.forceFail = false; }), ); } @@ -56,6 +60,8 @@ export class AuthService { // The user is not logged. if (err.originalError && (err.originalError as HttpErrorResponse).status === 401) { + this.authGuardService.forceFail = true; + return of(AuthStates.NotLogged); } @@ -74,6 +80,8 @@ export class AuthService { if (status !== true) { throw new Error(); } + + this.authGuardService.forceFail = true; }), ); }