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