# All files / src/app/shared/services module-status-guard.service.ts

92.31% Statements 24/26
72.73% Branches 8/11
83.33% Functions 5/6
90.91% Lines 20/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    716x
    6x
    6x

    6x
    6x

    6x

    6x

    6x

    4x

    6x

    6x
    3x

    6x

    3x
    3x

    1x

    2x

    1x
    1x

    6x
     import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router';

    import { of as observableOf } from 'rxjs';
    import { catchError, map } from 'rxjs/operators';

    import { ServicesModule } from './services.module';

    /**
     * This service checks if a route can be activated by executing a
     * REST API call to '/api/<apiPath>/status'. If the returned response
     * states that the module is not available, then the user is redirected
     * to the specified <redirectTo> URL path.
     *
     * A controller implementing this endpoint should return an object of
     * the following form:
     * {'available': true|false, 'message': null|string}.
     *
     * The configuration of this guard should look like this:
     * const routes: Routes = [
     * {
     *   path: 'rgw/bucket',
     *   component: RgwBucketListComponent,
     *   canActivate: [AuthGuardService, ModuleStatusGuardService],
     *   data: {
     *     moduleStatusGuardConfig: {
     *       apiPath: 'rgw',
     *       redirectTo: 'rgw/501'
     *     }
     *   }
     * },
     * ...
     */
    @Injectable({
      providedIn: ServicesModule
    })
    export class ModuleStatusGuardService implements CanActivate, CanActivateChild {
      // TODO: Hotfix - remove WHITELIST'ing when a generic ErrorComponent is implemented
      static readonly WHITELIST: string[] = ['501'];

      constructor(private http: HttpClient, private router: Router) {}

      canActivate(route: ActivatedRouteSnapshot) {
        return this.doCheck(route);
      }

      canActivateChild(childRoute: ActivatedRouteSnapshot) {
        return this.doCheck(childRoute);
      }

      private doCheck(route: ActivatedRouteSnapshot) {
        if (route.url.length > 0 && ModuleStatusGuardService.WHITELIST.includes(route.url[0].path)) {
          return observableOf(true);
        }
        const config = route.data['moduleStatusGuardConfig'];
        return this.http.get(`/api/${config.apiPath}/status`).pipe(
          map((resp: any) => {
            if (!resp.available) {
              this.router.navigate([config.redirectTo, resp.message || '']);
            }
            return resp.available;
          }),
          catchError(() => {
            this.router.navigate([config.redirectTo]);
            return observableOf(false);
          })
        );
      }
    }