Skip to content

Commit

Permalink
Merge pull request #1885 from bcgov/bug/TCVP-2687
Browse files Browse the repository at this point in the history
TCVP-2687 [XL] QA - Roles issues for staff workbench, JJ workbench in TEST and PROD [PROD]
  • Loading branch information
saikrishnametpalli-nttdata authored Jun 7, 2024
2 parents d2d34a1 + e8d070b commit 77ac4b9
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 41 deletions.
4 changes: 2 additions & 2 deletions src/frontend/staff-portal/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let routes: Routes = [
{
path: AppRoutes.STAFF,
canActivate: [AuthorizationGuard],
data: { expectedRole: UserGroup.VTC_STAFF },
data: { roles: [UserGroup.VTC_STAFF, UserGroup.SUPPORT_STAFF] },
children: [
{
path: '',
Expand All @@ -28,7 +28,7 @@ let routes: Routes = [
{
path: AppRoutes.JJ,
canActivate: [AuthorizationGuard],
data: { expectedRole: UserGroup.JUDICIAL_JUSTICE },
data: { roles: [UserGroup.JUDICIAL_JUSTICE, UserGroup.ADMIN_JUDICIAL_JUSTICE, UserGroup.SUPPORT_STAFF] },
children: [
{
path: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<app-page>
<div class="container">
<br />
<h1 class="BC-Gov-32px-blue-text">You are not authorized to access Ticket Resolution Management</h1>
<h1 class="BC-Gov-32px-blue-text">You are not authorized to access the TCO - {{application}} Workbench</h1>
<hr style="opacity: 1; color: #fcba19" />
</div>
</app-page>
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
selector: 'app-unauthorized',
templateUrl: './unauthorized.component.html',
styleUrls: ['./unauthorized.component.scss']
})
export class UnauthorizedComponent {
constructor() {
export class UnauthorizedComponent implements OnInit {
application: string;
constructor(private route: ActivatedRoute) {
}

ngOnInit() {
this.application = this.route.snapshot.queryParamMap.get('application');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
<div class="content">
<mat-tab-group class="dashTabs" mat-align-tabs="start" [selectedIndex]="tabSelected.value"
(selectedIndexChange)="tabSelected.setValue($event)">
<mat-tab>
<mat-tab *ngIf="hasTicketValidationPermission">
<ng-template mat-tab-label>
<h2>Ticket Validation</h2>
</ng-template>
</mat-tab>
<mat-tab>
<mat-tab *ngIf="hasDecisionValidationPermission">
<ng-template mat-tab-label>
<h2>Decision Validation</h2>
</ng-template>
</mat-tab>
<mat-tab>
<mat-tab *ngIf="hasUpdateRequestsPermission">
<ng-template mat-tab-label>
<h2>Update Requests</h2>
</ng-template>
</mat-tab>
<mat-tab #DCF>
<mat-tab #DCF *ngIf="hasDCFPermission">
<ng-template mat-tab-label>
<h2>DCF</h2>
</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { DisputeService } from 'app/services/dispute.service';
import { UpdateRequestInboxComponent } from '../update-request-inbox/update-request-inbox.component';
import { Store } from '@ngrx/store';
import { JJDisputeStore } from 'app/store';
import { BusyService } from '@core/services/busy.service';
import { AuthService } from 'app/services/auth.service';
import { UserGroup } from '@shared/enums/user-group.enum';

@Component({
selector: 'app-staff-workbench-dashboard',
Expand All @@ -28,19 +29,31 @@ export class StaffWorkbenchDashboardComponent implements OnInit {
data$: Observable<JJDispute[]>;
jjDisputeInfo: JJDispute;

hasTicketValidationPermission: boolean = false;
hasDecisionValidationPermission: boolean = false;
hasUpdateRequestsPermission: boolean = false;
hasDCFPermission: boolean = false;

@ViewChild(DisputeDecisionInboxComponent) disputeChild: DisputeDecisionInboxComponent;
@ViewChild(TicketInboxComponent) ticketChild: TicketInboxComponent;
@ViewChild(UpdateRequestInboxComponent) updateRequestChild: UpdateRequestInboxComponent;

constructor(
private authService: AuthService,
private disputeService: DisputeService,
private busyService: BusyService,
private store: Store
) {
}

ngOnInit(): void {
// this.busyService.busy$.subscribe(i => this.busy = i);
this.authService.userProfile$.subscribe(userProfile => {
if (userProfile) {
this.hasTicketValidationPermission = this.authService.checkRoles([UserGroup.VTC_STAFF, UserGroup.SUPPORT_STAFF]);
this.hasDecisionValidationPermission = this.authService.checkRoles([UserGroup.VTC_STAFF, UserGroup.SUPPORT_STAFF]);
this.hasUpdateRequestsPermission = this.authService.checkRoles([UserGroup.VTC_STAFF, UserGroup.SUPPORT_STAFF]);
this.hasDCFPermission = this.authService.checkRoles([UserGroup.VTC_STAFF, UserGroup.SUPPORT_STAFF]);
}
});
this.data$ = this.store.select(JJDisputeStore.Selectors.JJDisputes).pipe(filter(i => !!i));
}

Expand Down
31 changes: 26 additions & 5 deletions src/frontend/staff-portal/src/app/core/guards/auth-guard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import { AppRoutes } from 'app/app.routes';
import { AuthService } from 'app/services/auth.service';
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';

Expand All @@ -17,20 +18,40 @@ export class AuthorizationGuard extends KeycloakAuthGuard {

public async isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
// Force the user to log in if currently unauthenticated.
let permission;
if (!this.authenticated) {
this.authService.login();
}


// Get the roles required from the route.
const requiredRoles = route.data.roles;

// Allow the user to to proceed if no additional roles are required to access the route.
if (!(requiredRoles instanceof Array) || requiredRoles.length === 0) {
return true;
if (!requiredRoles || requiredRoles.length === 0) {
permission = true;
} else {
if (!this.roles || this.roles.length === 0) {
permission = false;
}
// Allow the user to proceed if any of the required role(s) is/are present.
if (requiredRoles.some((role) => this.roles.indexOf(role) > -1))
{
permission = true;
} else {
permission = false;
};
}

if(!permission){
let application;
if(state.url.indexOf(AppRoutes.JJ) > -1) {
application = "JJ";
} else {
application = "Staff";
}
this.router.navigate([AppRoutes.UNAUTHORIZED], {queryParams: {application: application}});
}

// Allow the user to proceed if all the required roles are present.
return requiredRoles.some(role => this.roles.includes(role));
return permission;
}
}
51 changes: 28 additions & 23 deletions src/frontend/staff-portal/src/app/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export class AuthService {

private site: string = "staff-api";
private roles = [
{ name: UserGroup.JUDICIAL_JUSTICE, redirectUrl: AppRoutes.JJ },
{ name: UserGroup.VTC_STAFF, redirectUrl: AppRoutes.STAFF },
{ name: [UserGroup.JUDICIAL_JUSTICE, UserGroup.ADMIN_JUDICIAL_JUSTICE, UserGroup.SUPPORT_STAFF], redirectUrl: AppRoutes.JJ },
{ name: [UserGroup.VTC_STAFF, UserGroup.SUPPORT_STAFF], redirectUrl: AppRoutes.STAFF },
]

constructor(
Expand All @@ -35,8 +35,8 @@ export class AuthService {
private toastService: ToastService,
private logger: LoggerService,
private configService: ConfigService,
private lookupsService: LookupsService, // to be moved
private store: Store<AppState>, // to be moved
private lookupsService: LookupsService,
private store: Store<AppState>,
) {
this.keycloak.keycloakEvents$.subscribe({
next(event) {
Expand All @@ -56,24 +56,11 @@ export class AuthService {
.pipe(
map((response: boolean) => {
if (response) {
this.loadUserProfile().subscribe(() => { // to be moved
this.loadUserProfile().subscribe(() => {
this._isLoggedIn.next(response);
if (this.isLoggedIn && this.isInit) {
this.userProfile$.pipe(first()).subscribe(() => {
this.isInit = false;
let observables = [
this.loadUsersLists(),
this.lookupsService.init()
];

forkJoin(observables).subscribe({
next: results => {
this.store.dispatch(JJDisputeStore.Actions.Get());
},
error: err => {
this.logger.error("Landing Page Init: Initial data loading failed");
}
});
this.isInit = false;
})
}
return response;
Expand All @@ -86,6 +73,22 @@ export class AuthService {
);
}

loadLookupData(){
let observables = [
this.loadUsersLists(),
this.lookupsService.init()
];

forkJoin(observables).subscribe({
next: results => {
this.store.dispatch(JJDisputeStore.Actions.Get());
},
error: err => {
this.logger.error("Landing Page Init: Initial data loading failed");
}
});
}

get token(): string {
return this.keycloak.getKeycloakInstance().token;
}
Expand Down Expand Up @@ -176,10 +179,12 @@ export class AuthService {
getRedirectUrl(): string {
var result;
this.roles.forEach(r => {
if (this.keycloak.isUserInRole(r.name, this.site)) {
result = r.redirectUrl;
}
})
r.name.forEach(n => {
if (this.keycloak.isUserInRole(n, this.site)) {
result = r.redirectUrl;
}
});
});
if (!result) {
result = AppRoutes.UNAUTHORIZED;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { NavigationEnd, Router, Scroll } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { AppRoutes } from 'app/app.routes';
import { AppConfigService } from 'app/services/app-config.service';
import { AuthService, KeycloakProfile } from 'app/services/auth.service';
import { filter } from 'rxjs';
Expand Down Expand Up @@ -54,6 +55,9 @@ export class HeaderComponent implements OnInit {
this.authService.isLoggedIn$.subscribe(isLoggedIn => {
this.isLoggedIn = isLoggedIn;
this.fullName = this.authService.userProfile?.fullName;
if(this.router.url.indexOf(AppRoutes.UNAUTHORIZED) === -1){
this.authService.loadLookupData();
}
})
})
}
Expand Down

0 comments on commit 77ac4b9

Please sign in to comment.