Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 1c220966

Přidáno uživatelem Hung Hoang před téměř 6 roky(ů)

Re#7531 Components are guarded against invalid users

Zobrazit rozdíly:

webapp/src/app/app-routing.module.ts
1
import { NgModule } from '@angular/core';
2
import { Routes, RouterModule } from '@angular/router';
1
import {NgModule} from '@angular/core';
2
import {RouterModule, Routes} from '@angular/router';
3 3
import {EmployeesListComponent} from './employees/employees-list.component';
4 4
import {DashboardComponent} from './dashboard/dashboard.component';
5 5
import {PageNotFoundComponent} from './page-not-found/page-not-found.component';
6
import {EmployeeComponentGuard} from './auth/employee-component.guard';
7
import {DashboardComponentGuard} from './auth/dashboard-component.guard';
6 8

  
7 9
const routes: Routes = [
8
  { path: 'employees', component: EmployeesListComponent },
9
  { path: 'dashboard', component: DashboardComponent },
10
  { path: 'employees', component: EmployeesListComponent, canActivate: [EmployeeComponentGuard] },
11
  { path: 'dashboard', component: DashboardComponent, canActivate: [DashboardComponentGuard] },
10 12
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
11 13
  { path: '**', component: PageNotFoundComponent }
12 14
];
webapp/src/app/auth/base-guard.ts
1
import {Router} from '@angular/router';
2

  
3
/**
4
 * Base class for all guards, provides navigating users to
5
 * components
6
 */
7
export class BaseGuard {
8
  constructor(protected router: Router) {
9

  
10
  }
11

  
12
  protected navigateUserToLogin(): boolean {
13
    console.log('Navigating user to login');
14
    this.router.navigate(['/login']);
15

  
16
    return false;
17
  }
18

  
19
  protected navigateUserToDashboard(): boolean {
20
    console.log('Navigating user to dashboard');
21
    this.router.navigate(['/dashboard']);
22

  
23
    return false;
24
  }
25

  
26
  protected navigateUserTo(component: string): boolean {
27
    this.router.navigate([component]);
28

  
29
    return false;
30
  }
31
}
webapp/src/app/auth/dashboard-component.guard.ts
1
import {Injectable} from '@angular/core';
2
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
3
import {Observable} from 'rxjs';
4
import {ProfileService} from '../services/util/profile.service';
5
import {BaseGuard} from './base-guard';
6

  
7
@Injectable({
8
  providedIn: 'root'
9
})
10
export class DashboardComponentGuard extends BaseGuard implements CanActivate {
11

  
12
  constructor(private profileService: ProfileService, protected router: Router) {
13
    super(router);
14
  }
15

  
16
  /**
17
   * All logged users can navigate to dashboard component
18
   * other users are navigate to login page
19
   * @param route activated route snapshot
20
   * @param state router state snapshot
21
   */
22
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
23
    return new Observable<boolean>((obs) => {
24
      this.profileService.getLoggedUser()
25
        .subscribe(() => {
26
            obs.next(true);
27
            obs.complete();
28
          },
29
          () => {
30
            obs.next(this.navigateUserToLogin());
31
            obs.complete();
32
          }
33
        );
34
    });
35
  }
36
}
webapp/src/app/auth/employee-component.guard.ts
1
import {Injectable} from '@angular/core';
2
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
3
import {ProfileService} from '../services/util/profile.service';
4
import {UserProfile} from '../models/user.model';
5
import {UserType} from '../enums/common.enum';
6
import {Observable} from 'rxjs';
7
import {BaseGuard} from './base-guard';
8

  
9
@Injectable({
10
  providedIn: 'root'
11
})
12
export class EmployeeComponentGuard extends BaseGuard implements CanActivate {
13

  
14
  constructor(private profileService: ProfileService, protected router: Router) {
15
    super(router);
16
  }
17

  
18
  /**
19
   * Logged user with access rights as employer can navigate to employee component
20
   * Logged user with access rights as employee is navigated to dashboard
21
   * User that is not logged is navigated to login page
22
   * @param route activated route snapshot
23
   * @param state router state snapshot
24
   */
25
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
26
    return new Observable<boolean>((obs) => {
27
      this.profileService.getLoggedUser()
28
        .subscribe((userProfile: UserProfile) => {
29
            if (userProfile.role === UserType.EMPLOYER) {
30
              console.log('User can navigate to the page');
31
              obs.next(true);
32
            }
33

  
34
            obs.next(this.navigateUserToDashboard());
35
            obs.complete();
36
          },
37
          () => {
38
            obs.next(this.navigateUserToLogin());
39
            obs.complete();
40
          }
41
        );
42
    });
43
  }
44

  
45
}
webapp/src/app/employees/employees-list.component.html
37 37
    </thead>
38 38
    <tbody>
39 39
    <tr *ngFor="let user of _users">
40
      <th scope="row">
40
      <th scope="row" style="font-size: x-small">
41 41
        <img
42 42
          alt="photo"
43 43
          [src]="user.imageLink"
webapp/src/app/employees/employees-list.component.ts
12 12
import {LocalizationService} from '../localization/localization.service';
13 13
import {DateFormatterService} from '../services/util/date-formatter.service';
14 14
import {FileService} from '../services/api/file.service';
15
import {ProfileService} from '../services/util/profile.service';
15 16

  
16 17
const daysOfWeek: string[] = [
17 18
  'po',
......
42 43
    private localizationService: LocalizationService,
43 44
    private dateFormatterService: DateFormatterService,
44 45
    private fileService: FileService,
46
    private profileService: ProfileService,
45 47
    public dialog: MatDialog,
46 48
    private snackBar: MatSnackBar) {
47 49
    this.generateDays();
webapp/src/app/services/api/profile.service.ts
1
import {Injectable} from '@angular/core';
2
import {UserService} from './user.service';
3
import {Observable} from 'rxjs';
4
import {UserProfile} from '../../models/user.model';
5

  
6
@Injectable({
7
  providedIn: 'root'
8
})
9
export class ProfileService {
10
  private profile: UserProfile;
11

  
12
  constructor(
13
    private userService: UserService
14
  ) {
15
    // userService.getUserProfile(1)
16
    //   .subscribe((data: UserProfile) => this.profile = data);
17
  }
18

  
19
  getProfile(): Observable<UserProfile> {
20
    return new Observable((observer) => {
21
      if (this.profile) {
22
        observer.next(this.profile);
23
        observer.complete();
24
      } else {
25
        this.userService.getUserProfile(1) // TODO zmenit id na prihlaseneho uzivatele
26
          .subscribe((data: UserProfile) => {
27
            this.profile = data;
28
            observer.next(this.profile);
29
            observer.complete();
30
          });
31
      }
32
    });
33
  }
34

  
35
}
webapp/src/app/services/util/menu.service.ts
15 15
})
16 16
export class MenuService {
17 17

  
18
  constructor(private userService: UserService) { }
18
  constructor(private userService: UserService) {
19
  }
19 20

  
20 21
  getMenuItems() {
21 22
    const menuItems: MenuItem[] = [];
22
    menuItems.push({name: 'Dashboard', routePath: 'dashboard'});
23 23

  
24 24
    return new Observable((observer) => {
25 25
      this.userService.getLoggedUserProfile()
26 26
        .subscribe((profile: UserProfile) => {
27
          if (profile.role === UserType.EMPLOYER) {
28
            menuItems.push({name: 'Zaměstnanci', routePath: 'employees'});
29
          }
27
            menuItems.push({name: 'Dashboard', routePath: 'dashboard'});
28
            if (profile.role === UserType.EMPLOYER) {
29
              menuItems.push({name: 'Zaměstnanci', routePath: 'employees'});
30
            }
30 31

  
31
          observer.next(menuItems);
32
          observer.complete();
33
        });
32
            observer.next(menuItems);
33
            observer.complete();
34
          },
35
          () => {
36
            observer.next(menuItems);
37
            observer.complete();
38
          });
34 39
    });
35 40
  }
36 41
}
webapp/src/app/services/util/profile.service.ts
1
import {Injectable} from '@angular/core';
2
import {UserService} from '../api/user.service';
3
import {UserProfile} from '../../models/user.model';
4
import {Observable} from 'rxjs';
5

  
6
@Injectable({
7
  providedIn: 'root'
8
})
9
export class ProfileService {
10
  private profile: UserProfile;
11

  
12
  constructor(private userService: UserService) {
13

  
14
  }
15

  
16
  /**
17
   * Returns logged user profile if the server responds
18
   * with valid profile otherwise observer returns error
19
   * with message 'Cannot log in'
20
   *
21
   * The idea was to cache the logged user profile but
22
   * the changes to logged user would not be seen until
23
   * the user logged off and then logged back in
24
   */
25
  public getLoggedUser() {
26
    return new Observable<UserProfile>((obs) => {
27
      this.userService.getLoggedUserProfile()
28
        .subscribe((userProfile: UserProfile) => {
29
            this.profile = {...userProfile};
30
            obs.next(this.profile);
31
            obs.complete();
32
          },
33
          error1 => {
34
            obs.error(error1);
35
            obs.complete();
36
          });
37
    });
38
  }
39

  
40
  /**
41
   * Do not use at the start of the application
42
   * User might be logged but the service hasn't
43
   * finished the request for the user profile
44
   */
45
  public isUserLogged(): boolean {
46
    return this.profile == null;
47
  }
48

  
49
  public logUserOff(): void {
50
    this.profile = null;
51
  }
52
}

Také k dispozici: Unified diff