mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
AAE-25392 Convert route guards to functional - part one (#10113)
* AAE-25392 Convert route guards to functional - part one * AAE-25392 Code improvement
This commit is contained in:
parent
aeee07d82a
commit
c876058c51
@ -16,23 +16,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { ActivatedRouteSnapshot, Router } from '@angular/router';
|
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
import { AuthGuardSsoRoleService } from './auth-guard-sso-role.service';
|
import { AuthGuardSsoRoleService } from './auth-guard-sso-role.service';
|
||||||
import { JwtHelperService } from '../services/jwt-helper.service';
|
import { JwtHelperService } from '../services/jwt-helper.service';
|
||||||
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||||
import { NoopTranslateModule } from '@alfresco/adf-core';
|
import { NoopTranslateModule } from '@alfresco/adf-core';
|
||||||
|
|
||||||
describe('Auth Guard SSO role service', () => {
|
describe('Auth Guard SSO role service', () => {
|
||||||
let authGuard: AuthGuardSsoRoleService;
|
|
||||||
let jwtHelperService: JwtHelperService;
|
let jwtHelperService: JwtHelperService;
|
||||||
let routerService: Router;
|
let routerService: Router;
|
||||||
|
const state: RouterStateSnapshot = {} as RouterStateSnapshot;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopTranslateModule, MatDialogModule]
|
imports: [NoopTranslateModule, MatDialogModule]
|
||||||
});
|
});
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
authGuard = TestBed.inject(AuthGuardSsoRoleService);
|
|
||||||
jwtHelperService = TestBed.inject(JwtHelperService);
|
jwtHelperService = TestBed.inject(JwtHelperService);
|
||||||
routerService = TestBed.inject(Router);
|
routerService = TestBed.inject(Router);
|
||||||
});
|
});
|
||||||
@ -53,54 +52,65 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
|
|
||||||
it('Should canActivate be true if the Role is present int the JWT token', async () => {
|
it('Should canActivate be true if the Role is present int the JWT token', async () => {
|
||||||
spyUserAccess(['MOCK_USER_ROLE'], {});
|
spyUserAccess(['MOCK_USER_ROLE'], {});
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeTruthy();
|
expect(authGuard).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be true if case of empty roles to check', async () => {
|
it('Should canActivate be true if case of empty roles to check', async () => {
|
||||||
spyUserAccess([], {});
|
spyUserAccess([], {});
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: [] };
|
route.data = { roles: [] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeTruthy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be false if the Role is not present int the JWT token', async () => {
|
it('Should canActivate be false if the Role is not present int the JWT token', async () => {
|
||||||
spyUserAccess(['MOCK_ROOT_USER_ROLE'], {});
|
spyUserAccess(['MOCK_ROOT_USER_ROLE'], {});
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should not redirect if canActivate is', async () => {
|
it('Should not redirect if canActivate is', async () => {
|
||||||
spyUserAccess(['MOCK_USER_ROLE'], {});
|
spyUserAccess(['MOCK_USER_ROLE'], {});
|
||||||
spyOn(routerService, 'navigate').and.stub();
|
spyOn(routerService, 'navigate').and.stub();
|
||||||
|
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeTruthy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeTruthy();
|
||||||
expect(routerService.navigate).not.toHaveBeenCalled();
|
expect(routerService.navigate).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate return false if the data Role to check is empty', async () => {
|
it('Should canActivate return false if the data Role to check is empty', async () => {
|
||||||
spyUserAccess(['MOCK_USER_ROLE', 'MOCK_ROOT_USER_ROLE'], {});
|
spyUserAccess(['MOCK_USER_ROLE', 'MOCK_ROOT_USER_ROLE'], {});
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should redirect to the redirectURL if canActivate is false and redirectUrl is in data', async () => {
|
it('Should redirect to the redirectURL if canActivate is false and redirectUrl is in data', async () => {
|
||||||
spyUserAccess([], {});
|
spyUserAccess([], {});
|
||||||
spyOn(routerService, 'navigate').and.stub();
|
spyOn(routerService, 'navigate').and.stub();
|
||||||
|
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], redirectUrl: 'no-role-url' };
|
route.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], redirectUrl: 'no-role-url' };
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
expect(routerService.navigate).toHaveBeenCalledWith(['/no-role-url']);
|
expect(routerService.navigate).toHaveBeenCalledWith(['/no-role-url']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,10 +118,12 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
spyUserAccess([], {});
|
spyUserAccess([], {});
|
||||||
spyOn(routerService, 'navigate').and.stub();
|
spyOn(routerService, 'navigate').and.stub();
|
||||||
|
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
expect(routerService.navigate).not.toHaveBeenCalled();
|
expect(routerService.navigate).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -122,7 +134,9 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
route.params = { appName: 'mockApp' };
|
route.params = { appName: 'mockApp' };
|
||||||
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(route)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be false if hasRealm is false and hasClientRole is true', async () => {
|
it('Should canActivate be false if hasRealm is false and hasClientRole is true', async () => {
|
||||||
@ -132,7 +146,9 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
route.params = { appName: 'mockApp' };
|
route.params = { appName: 'mockApp' };
|
||||||
route.data = { clientRoles: ['mockApp'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { clientRoles: ['mockApp'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(route)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be true if both Real Role and Client Role are present int the JWT token', async () => {
|
it('Should canActivate be true if both Real Role and Client Role are present int the JWT token', async () => {
|
||||||
@ -142,7 +158,9 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
route.params = { appName: 'mockApp' };
|
route.params = { appName: 'mockApp' };
|
||||||
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(route)).toBeTruthy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be false if the Client Role is not present int the JWT token with the correct role', async () => {
|
it('Should canActivate be false if the Client Role is not present int the JWT token with the correct role', async () => {
|
||||||
@ -152,7 +170,9 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
route.params = { appName: 'mockApp' };
|
route.params = { appName: 'mockApp' };
|
||||||
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(route)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be false hasRealm is true and hasClientRole is false', async () => {
|
it('Should canActivate be false hasRealm is true and hasClientRole is false', async () => {
|
||||||
@ -166,7 +186,9 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
route.params = { appName: 'mockApp' };
|
route.params = { appName: 'mockApp' };
|
||||||
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(route)).toBeFalsy();
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeFalsy();
|
||||||
expect(materialDialog.closeAll).toHaveBeenCalled();
|
expect(materialDialog.closeAll).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -174,18 +196,23 @@ describe('Auth Guard SSO role service', () => {
|
|||||||
it('Should canActivate be false when the user has one of the excluded roles', async () => {
|
it('Should canActivate be false when the user has one of the excluded roles', async () => {
|
||||||
spyUserAccess(['MOCK_USER_ROLE'], {});
|
spyUserAccess(['MOCK_USER_ROLE'], {});
|
||||||
|
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_ANOTHER_ROLE'], excludedRoles: ['MOCK_USER_ROLE'] };
|
route.data = { roles: ['MOCK_ANOTHER_ROLE'], excludedRoles: ['MOCK_USER_ROLE'] };
|
||||||
|
|
||||||
expect(authGuard.canActivate(router)).toBe(false);
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should canActivate be true when the user has none of the excluded roles', async () => {
|
it('Should canActivate be true when the user has none of the excluded roles', async () => {
|
||||||
spyUserAccess(['MOCK_ADMIN_ROLE'], {});
|
spyUserAccess(['MOCK_ADMIN_ROLE'], {});
|
||||||
|
|
||||||
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
|
||||||
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], excludedRoles: ['MOCK_ROOT_USER_ROLE'] };
|
route.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], excludedRoles: ['MOCK_ROOT_USER_ROLE'] };
|
||||||
expect(authGuard.canActivate(router)).toBeTruthy();
|
|
||||||
|
const authGuard = TestBed.runInInjectionContext(() => AuthGuardSsoRoleService(route, state));
|
||||||
|
|
||||||
|
expect(authGuard).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -15,22 +15,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
import { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { UserAccessService } from '../services/user-access.service';
|
import { UserAccessService } from '../services/user-access.service';
|
||||||
|
|
||||||
@Injectable({
|
export const AuthGuardSsoRoleService: CanActivateFn = (route: ActivatedRouteSnapshot): boolean => {
|
||||||
providedIn: 'root'
|
const userAccessService = inject(UserAccessService);
|
||||||
})
|
userAccessService.fetchUserAccess();
|
||||||
export class AuthGuardSsoRoleService implements CanActivate {
|
|
||||||
constructor(private userAccessService: UserAccessService,
|
|
||||||
private router: Router,
|
|
||||||
private dialog: MatDialog) {
|
|
||||||
}
|
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot): boolean {
|
|
||||||
this.userAccessService.fetchUserAccess();
|
|
||||||
let hasRealmRole = false;
|
let hasRealmRole = false;
|
||||||
let hasClientRole = true;
|
let hasClientRole = true;
|
||||||
if (route.data) {
|
if (route.data) {
|
||||||
@ -40,38 +33,30 @@ export class AuthGuardSsoRoleService implements CanActivate {
|
|||||||
hasRealmRole = true;
|
hasRealmRole = true;
|
||||||
} else {
|
} else {
|
||||||
const excludedRoles = route.data['excludedRoles'] || [];
|
const excludedRoles = route.data['excludedRoles'] || [];
|
||||||
hasRealmRole = this.validateRoles(rolesToCheck, excludedRoles);
|
if (excludedRoles?.length > 0) {
|
||||||
|
hasRealmRole = userAccessService.hasGlobalAccess(rolesToCheck) && !userAccessService.hasGlobalAccess(excludedRoles);
|
||||||
|
}
|
||||||
|
hasRealmRole = userAccessService.hasGlobalAccess(rolesToCheck);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route.data['clientRoles']) {
|
if (route.data['clientRoles']) {
|
||||||
const clientRoleName = route.params[route.data['clientRoles']];
|
const clientRoleName = route.params[route.data['clientRoles']];
|
||||||
const rolesToCheck = route.data['roles'];
|
const rolesToCheck = route.data['roles'];
|
||||||
hasClientRole = this.userAccessService.hasApplicationAccess(clientRoleName, rolesToCheck);
|
hasClientRole = userAccessService.hasApplicationAccess(clientRoleName, rolesToCheck);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const hasRole = hasRealmRole && hasClientRole;
|
const hasRole = hasRealmRole && hasClientRole;
|
||||||
|
|
||||||
if (!hasRole && route?.data && route.data['redirectUrl']) {
|
if (!hasRole && route?.data && route.data['redirectUrl']) {
|
||||||
this.router.navigate(['/' + route.data['redirectUrl']]);
|
const router = inject(Router);
|
||||||
|
router.navigate(['/' + route.data['redirectUrl']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasRole) {
|
if (!hasRole) {
|
||||||
this.dialog.closeAll();
|
const dialog = inject(MatDialog);
|
||||||
|
dialog.closeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasRole;
|
return hasRole;
|
||||||
}
|
};
|
||||||
|
|
||||||
private validateRoles(rolesToCheck: string[], excludedRoles?: string[]): boolean {
|
|
||||||
if (excludedRoles?.length > 0) {
|
|
||||||
return this.hasRoles(rolesToCheck) && !this.hasRoles(excludedRoles);
|
|
||||||
}
|
|
||||||
return this.hasRoles(rolesToCheck);
|
|
||||||
}
|
|
||||||
|
|
||||||
private hasRoles(roles: string[] = []): boolean {
|
|
||||||
return this.userAccessService.hasGlobalAccess(roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user