Browse Source

Add redirectUrl support to PermissionGuard

PermissionGuard now supports redirecting to a specified URL when access is denied and a redirectUrl is provided in route data. Updated guard logic to use map instead of filter/tap, and added corresponding unit tests to verify redirect behavior.
pull/24276/head
Fahri Gedik 2 months ago
parent
commit
04e5d4da59
  1. 31
      npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts
  2. 17
      npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts

31
npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts

@ -4,10 +4,11 @@ import {
CanActivateFn, CanActivateFn,
Router, Router,
RouterStateSnapshot, RouterStateSnapshot,
UrlTree,
} from '@angular/router'; } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { filter, take, tap } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { AuthService, IAbpGuard } from '../abstracts'; import { AuthService, IAbpGuard } from '../abstracts';
import { findRoute, getRoutePath } from '../utils/route-utils'; import { findRoute, getRoutePath } from '../utils/route-utils';
import { RoutesService, PermissionService, HttpErrorReporterService } from '../services'; import { RoutesService, PermissionService, HttpErrorReporterService } from '../services';
@ -25,7 +26,7 @@ export class PermissionGuard implements IAbpGuard {
protected readonly permissionService = inject(PermissionService); protected readonly permissionService = inject(PermissionService);
protected readonly httpErrorReporter = inject(HttpErrorReporterService); protected readonly httpErrorReporter = inject(HttpErrorReporterService);
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
let { requiredPolicy } = route.data || {}; let { requiredPolicy } = route.data || {};
if (!requiredPolicy) { if (!requiredPolicy) {
@ -38,12 +39,19 @@ export class PermissionGuard implements IAbpGuard {
} }
return this.permissionService.getGrantedPolicy$(requiredPolicy).pipe( return this.permissionService.getGrantedPolicy$(requiredPolicy).pipe(
filter(Boolean),
take(1), take(1),
tap(access => { map(access => {
if (!access && this.authService.isAuthenticated) { if (access) return true;
if (route.data?.['redirectUrl']) {
return this.router.parseUrl(route.data['redirectUrl']);
}
if (this.authService.isAuthenticated) {
this.httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse); this.httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse);
} }
return false;
}), }),
); );
} }
@ -77,12 +85,19 @@ export const permissionGuard: CanActivateFn = (
} }
return permissionService.getGrantedPolicy$(requiredPolicy).pipe( return permissionService.getGrantedPolicy$(requiredPolicy).pipe(
filter(Boolean),
take(1), take(1),
tap(access => { map(access => {
if (!access && authService.isAuthenticated) { if (access) return true;
if (route.data?.['redirectUrl']) {
return router.parseUrl(route.data['redirectUrl']);
}
if (authService.isAuthenticated) {
httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse); httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse);
} }
return false;
}), }),
); );
}; };

17
npm/ng-packs/packages/core/src/lib/tests/permission.guard.spec.ts

@ -39,6 +39,15 @@ describe('authGuard', () => {
component: DummyComponent, component: DummyComponent,
canActivate: [permissionGuard], canActivate: [permissionGuard],
}, },
{
path: 'redirect-test',
component: DummyComponent,
canActivate: [permissionGuard],
data: {
requiredPolicy: 'TestPolicy',
redirectUrl: '/zibzib',
},
},
]; ];
beforeEach(() => { beforeEach(() => {
@ -103,4 +112,12 @@ describe('authGuard', () => {
await RouterTestingHarness.create('/zibzib'); await RouterTestingHarness.create('/zibzib');
expect(TestBed.inject(Router).url).toEqual('/zibzib'); expect(TestBed.inject(Router).url).toEqual('/zibzib');
}); });
it('should redirect to redirectUrl when the grantedPolicy is false and redirectUrl is provided', async () => {
permissionService.getGrantedPolicy$.andReturn(of(false));
await RouterTestingHarness.create('/redirect-test');
expect(TestBed.inject(Router).url).toEqual('/zibzib');
expect(httpErrorReporter.reportError).not.toHaveBeenCalled();
});
}); });

Loading…
Cancel
Save