]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | import { HttpClient } from '@angular/common/http'; |
2 | import { Injectable } from '@angular/core'; | |
3 | import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router'; | |
4 | ||
5 | import { of as observableOf } from 'rxjs'; | |
6 | import { catchError, map } from 'rxjs/operators'; | |
7 | ||
8 | import { ServicesModule } from './services.module'; | |
9 | ||
10 | /** | |
11 | * This service checks if a route can be activated by executing a | |
12 | * REST API call to '/api/<apiPath>/status'. If the returned response | |
13 | * states that the module is not available, then the user is redirected | |
14 | * to the specified <redirectTo> URL path. | |
15 | * | |
16 | * A controller implementing this endpoint should return an object of | |
17 | * the following form: | |
18 | * {'available': true|false, 'message': null|string}. | |
19 | * | |
20 | * The configuration of this guard should look like this: | |
21 | * const routes: Routes = [ | |
22 | * { | |
23 | * path: 'rgw/bucket', | |
24 | * component: RgwBucketListComponent, | |
25 | * canActivate: [AuthGuardService, ModuleStatusGuardService], | |
26 | * data: { | |
27 | * moduleStatusGuardConfig: { | |
28 | * apiPath: 'rgw', | |
29 | * redirectTo: 'rgw/501' | |
30 | * } | |
31 | * } | |
32 | * }, | |
33 | * ... | |
34 | */ | |
35 | @Injectable({ | |
36 | providedIn: ServicesModule | |
37 | }) | |
38 | export class ModuleStatusGuardService implements CanActivate, CanActivateChild { | |
39 | // TODO: Hotfix - remove WHITELIST'ing when a generic ErrorComponent is implemented | |
40 | static readonly WHITELIST: string[] = ['501']; | |
41 | ||
42 | constructor(private http: HttpClient, private router: Router) {} | |
43 | ||
44 | canActivate(route: ActivatedRouteSnapshot) { | |
45 | return this.doCheck(route); | |
46 | } | |
47 | ||
48 | canActivateChild(childRoute: ActivatedRouteSnapshot) { | |
49 | return this.doCheck(childRoute); | |
50 | } | |
51 | ||
52 | private doCheck(route: ActivatedRouteSnapshot) { | |
53 | if (route.url.length > 0 && ModuleStatusGuardService.WHITELIST.includes(route.url[0].path)) { | |
54 | return observableOf(true); | |
55 | } | |
56 | const config = route.data['moduleStatusGuardConfig']; | |
57 | return this.http.get(`/api/${config.apiPath}/status`).pipe( | |
58 | map((resp: any) => { | |
59 | if (!resp.available) { | |
60 | this.router.navigate([config.redirectTo, resp.message || '']); | |
61 | } | |
62 | return resp.available; | |
63 | }), | |
64 | catchError(() => { | |
65 | this.router.navigate([config.redirectTo]); | |
66 | return observableOf(false); | |
67 | }) | |
68 | ); | |
69 | } | |
70 | } |