Skip to content
Snippets Groups Projects
search-auth.guard.ts 3.97 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * This file is part of Anis Client.
     *
     * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */
    
    import { Injectable } from '@angular/core';
    import { CanActivate, Router } from '@angular/router';
    
    import { Store, select } from '@ngrx/store';
    
    import { combineLatest, Observable } from 'rxjs';
    
    import { switchMap, map, skipWhile } from 'rxjs/operators';
    
    import * as datasetSelector from 'src/app/metamodel/selectors/dataset.selector';
    import * as datasetActions from 'src/app/metamodel/actions/dataset.actions';
    import * as datasetGroupSelector from 'src/app/metamodel/selectors/dataset-group.selector';
    import * as datasetGroupActions from 'src/app/metamodel/actions/dataset-group.actions';
    import * as authSelector from 'src/app/auth/auth.selector';
    import { AppConfigService } from 'src/app/app-config.service';
    import { isAdmin } from 'src/app/shared/utils';
    
    @Injectable({
        providedIn: 'root',
    })
    export class SearchAuthGuard implements CanActivate {
        constructor(
            protected readonly router: Router,
            private store: Store<{ }>,
            private config: AppConfigService
        ) { }
    
        canActivate(): Observable<boolean> {
            return combineLatest([
                this.store.pipe(select(datasetSelector.selectDatasetListIsLoaded)),
                this.store.pipe(select(datasetGroupSelector.selectDatasetGroupListIsLoaded))
            ]).pipe(
                map(([datasetListIsLoaded, datasetGroupListIsLoaded]) => {
                    if (!datasetListIsLoaded) {
                        this.store.dispatch(datasetActions.loadDatasetList());
                    }
                    if (!datasetGroupListIsLoaded) {
                        this.store.dispatch(datasetGroupActions.loadDatasetGroupList());
                    }
                    return [datasetListIsLoaded, datasetGroupListIsLoaded];
                }),
                skipWhile(([datasetListIsLoaded, datasetGroupListIsLoaded]) => !datasetListIsLoaded || !datasetGroupListIsLoaded),
                switchMap(() => {
                    return combineLatest([
                        this.store.pipe(select(datasetSelector.selectDatasetByRouteName)),
                        this.store.pipe(select(authSelector.selectUserRoles)),
                        this.store.pipe(select(authSelector.selectIsAuthenticated)),
                        this.store.pipe(select(datasetGroupSelector.selectAllDatasetGroups))
                    ]).pipe(
                        map(([dataset, userRoles, isAuthenticated, datasetGroupList]) => {
                            // No authorization required to continue
                            if (!this.config.authenticationEnabled 
                                || dataset.public
                                || (isAuthenticated && isAdmin(this.config.adminRoles, userRoles))) {
                                return true;
                            }
    
                            
                            // If user is authenticated and authorized so accessible changes to true
                            let accessible = false
    
                            if (isAuthenticated) {
    
                                accessible = datasetGroupList
                                    .filter(datasetGroup => datasetGroup.datasets.includes(dataset.name))
                                    .filter(datasetGroup => userRoles.includes(datasetGroup.role))
                                    .length > 0;
    
                            // If user is not authorized to continue go to unauthorized page
    
                            if (!accessible) {
    
                                sessionStorage.setItem('redirect_uri', window.location.toString());
    
                                this.router.navigateByUrl('/unauthorized');
                                return false;
                            }
            
                            // Let "Router" allow user entering the page
                            return true;
                        })
                    );
                })
            );
        }
    }