From 069dcd9c86c1d344d190f793e6b6c36a53286949 Mon Sep 17 00:00:00 2001 From: Sinan997 Date: Fri, 27 Oct 2023 15:08:04 +0300 Subject: [PATCH] Create function guards and mark class guards as deprecated --- .../account/src/lib/account-routing.module.ts | 10 ++-- .../lib/guards/authentication-flow.guard.ts | 12 ++++ .../src/lib/guards/extensions.guard.ts | 28 ++++++++++ .../core/src/lib/abstracts/auth.guard.ts | 9 +++ .../core/src/lib/guards/permission.guard.ts | 30 +++++++++- .../src/lib/guards/extensions.guard.ts | 55 ++++++++++++++++++ .../src/lib/identity-routing.module.ts | 10 ++-- .../oauth/src/lib/guards/oauth.guard.ts | 24 +++++++- .../packages/oauth/src/lib/oauth.module.ts | 8 +-- .../lib/setting-management-routing.module.ts | 6 +- .../src/lib/guards/extensions.guard.ts | 56 +++++++++++++++++++ .../lib/tenant-management-routing.module.ts | 10 ++-- 12 files changed, 234 insertions(+), 24 deletions(-) diff --git a/npm/ng-packs/packages/account/src/lib/account-routing.module.ts b/npm/ng-packs/packages/account/src/lib/account-routing.module.ts index 0b188f3751..6e651f5baa 100644 --- a/npm/ng-packs/packages/account/src/lib/account-routing.module.ts +++ b/npm/ng-packs/packages/account/src/lib/account-routing.module.ts @@ -1,8 +1,8 @@ import { NgModule } from '@angular/core'; -import { RouterModule, Routes, mapToCanActivate } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; import { - AuthGuard, + AuthGuardFn, ReplaceableComponents, ReplaceableRouteContainerComponent, RouterOutletComponent, @@ -14,9 +14,9 @@ import { ManageProfileComponent } from './components/manage-profile/manage-profi import { RegisterComponent } from './components/register/register.component'; import { ResetPasswordComponent } from './components/reset-password/reset-password.component'; import { eAccountComponents } from './enums/components'; -import { AccountExtensionsGuard, AuthenticationFlowGuard } from './guards'; +import { AccountExtensionsGuardFn, AuthenticationFlowGuardFn } from './guards'; -const canActivate = mapToCanActivate([AuthenticationFlowGuard]); +const canActivate = [AuthenticationFlowGuardFn]; const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'login' }, @@ -73,7 +73,7 @@ const routes: Routes = [ { path: 'manage', component: ReplaceableRouteContainerComponent, - canActivate: mapToCanActivate([AuthGuard, AccountExtensionsGuard]), + canActivate: [AuthGuardFn, AccountExtensionsGuardFn], data: { replaceableComponent: { key: eAccountComponents.ManageProfile, diff --git a/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts b/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts index c00cee3156..c6134c8c23 100644 --- a/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts +++ b/npm/ng-packs/packages/account/src/lib/guards/authentication-flow.guard.ts @@ -1,6 +1,9 @@ import { AuthService, IAbpGuard } from '@abp/ng.core'; import { Injectable, inject } from '@angular/core'; +/** + * @deprecated Use `AuthenticationFlowGuardFn` instead. + */ @Injectable() export class AuthenticationFlowGuard implements IAbpGuard { protected readonly authService = inject(AuthService); @@ -12,3 +15,12 @@ export class AuthenticationFlowGuard implements IAbpGuard { return false; } } + +export const AuthenticationFlowGuardFn = () => { + const authService = inject(AuthService); + + if (authService.isInternalAuth) return true; + + authService.navigateToLogin(); + return false; +}; diff --git a/npm/ng-packs/packages/account/src/lib/guards/extensions.guard.ts b/npm/ng-packs/packages/account/src/lib/guards/extensions.guard.ts index 8df8aede51..185d2056f9 100644 --- a/npm/ng-packs/packages/account/src/lib/guards/extensions.guard.ts +++ b/npm/ng-packs/packages/account/src/lib/guards/extensions.guard.ts @@ -17,6 +17,9 @@ import { } from '../tokens/extensions.token'; import { eAccountComponents } from '../enums/components'; +/** + * @deprecated Use `AccountExtensionsGuardFn` instead. + */ @Injectable() export class AccountExtensionsGuard implements IAbpGuard { protected readonly configState = inject(ConfigStateService); @@ -44,3 +47,28 @@ export class AccountExtensionsGuard implements IAbpGuard { ); } } + +export const AccountExtensionsGuardFn = () => { + const configState = inject(ConfigStateService); + const extensions = inject(ExtensionsService); + + const config = { optional: true }; + + const editFormContributors = inject(ACCOUNT_EDIT_FORM_PROP_CONTRIBUTORS, config) || {}; + + return getObjectExtensionEntitiesFromStore(configState, 'Identity').pipe( + map(entities => ({ + [eAccountComponents.PersonalSettings]: entities.User, + })), + mapEntitiesToContributors(configState, 'AbpIdentity'), + tap(objectExtensionContributors => { + mergeWithDefaultProps( + extensions.editFormProps, + DEFAULT_ACCOUNT_FORM_PROPS, + objectExtensionContributors.editForm, + editFormContributors, + ); + }), + map(() => true), + ); +}; diff --git a/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts b/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts index 8fb4f4dc25..2da5d5d21a 100644 --- a/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts +++ b/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts @@ -2,7 +2,11 @@ import { Injectable } from '@angular/core'; import { UrlTree } from '@angular/router'; import { Observable } from 'rxjs'; import { IAbpGuard } from './abstract-guard'; +import { CanActivateFn } from '@angular/router'; +/** + * @deprecated Use `AuthGuardFn` instead. + */ @Injectable({ providedIn: 'root', }) @@ -12,3 +16,8 @@ export class AuthGuard implements IAbpGuard { return false; } } + +export const AuthGuardFn: CanActivateFn = () => { + console.error('You should add @abp/ng-oauth packages or create your own auth packages.'); + return false; +}; \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts b/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts index ae3fdb6e37..58293da594 100644 --- a/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts +++ b/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts @@ -1,5 +1,5 @@ import { Injectable, inject } from '@angular/core'; -import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router'; import { HttpErrorResponse } from '@angular/common/http'; import { Observable, of } from 'rxjs'; @@ -11,6 +11,9 @@ import { IAbpGuard } from '../abstracts'; import { findRoute, getRoutePath } from '../utils/route-utils'; import { RoutesService, PermissionService, HttpErrorReporterService } from '../services'; +/** + * @deprecated Use `PermissionGuardFn` instead. + */ @Injectable({ providedIn: 'root', }) @@ -40,3 +43,28 @@ export class PermissionGuard implements IAbpGuard { ); } } + +export const PermissionGuardFn: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + const router = inject(Router); + const routesService = inject(RoutesService); + const oAuthService = inject(OAuthService); + const permissionService = inject(PermissionService); + const httpErrorReporter = inject(HttpErrorReporterService); + + let { requiredPolicy } = route.data || {}; + + if (!requiredPolicy) { + const routeFound = findRoute(routesService, getRoutePath(router, state.url)); + requiredPolicy = routeFound?.requiredPolicy; + } + + if (!requiredPolicy) return of(true); + + return permissionService.getGrantedPolicy$(requiredPolicy).pipe( + tap(access => { + if (!access && oAuthService.hasValidAccessToken()) { + httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse); + } + }), + ); +} diff --git a/npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts b/npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts index 172b599f91..78916556c3 100644 --- a/npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts +++ b/npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts @@ -26,6 +26,9 @@ import { IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS, } from '../tokens/extensions.token'; +/** + * @deprecated Use `IdentityExtensionsGuardFn` instead. + */ @Injectable() export class IdentityExtensionsGuard implements IAbpGuard { protected readonly configState = inject(ConfigStateService); @@ -80,3 +83,55 @@ export class IdentityExtensionsGuard implements IAbpGuard { ); } } + +export const IdentityExtensionsGuardFn = () => { + const configState = inject(ConfigStateService); + const extensions = inject(ExtensionsService); + + const config = { optional: true }; + + const actionContributors = inject(IDENTITY_ENTITY_ACTION_CONTRIBUTORS, config) || {}; + const toolbarContributors = inject(IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS, config) || {}; + const propContributors = inject(IDENTITY_ENTITY_PROP_CONTRIBUTORS, config) || {}; + const createFormContributors = inject(IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS, config) || {}; + const editFormContributors = inject(IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS, config) || {}; + + return getObjectExtensionEntitiesFromStore(configState, 'Identity').pipe( + map(entities => ({ + [eIdentityComponents.Roles]: entities.Role, + [eIdentityComponents.Users]: entities.User, + })), + mapEntitiesToContributors(configState, 'AbpIdentity'), + tap(objectExtensionContributors => { + mergeWithDefaultActions( + extensions.entityActions, + DEFAULT_IDENTITY_ENTITY_ACTIONS, + actionContributors, + ); + mergeWithDefaultActions( + extensions.toolbarActions, + DEFAULT_IDENTITY_TOOLBAR_ACTIONS, + toolbarContributors, + ); + mergeWithDefaultProps( + extensions.entityProps, + DEFAULT_IDENTITY_ENTITY_PROPS, + objectExtensionContributors.prop, + propContributors, + ); + mergeWithDefaultProps( + extensions.createFormProps, + DEFAULT_IDENTITY_CREATE_FORM_PROPS, + objectExtensionContributors.createForm, + createFormContributors, + ); + mergeWithDefaultProps( + extensions.editFormProps, + DEFAULT_IDENTITY_EDIT_FORM_PROPS, + objectExtensionContributors.editForm, + editFormContributors, + ); + }), + map(() => true), + ); +}; diff --git a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts index 33c8f53d5a..af4dea7732 100644 --- a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts +++ b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts @@ -1,9 +1,9 @@ import { NgModule } from '@angular/core'; -import { RouterModule, Routes, mapToCanActivate } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; import { - AuthGuard, - PermissionGuard, + AuthGuardFn, + PermissionGuardFn, ReplaceableComponents, ReplaceableRouteContainerComponent, RouterOutletComponent, @@ -12,14 +12,14 @@ import { import { RolesComponent } from './components/roles/roles.component'; import { UsersComponent } from './components/users/users.component'; import { eIdentityComponents } from './enums/components'; -import { IdentityExtensionsGuard } from './guards'; +import { IdentityExtensionsGuardFn } from './guards'; const routes: Routes = [ { path: '', redirectTo: 'roles', pathMatch: 'full' }, { path: '', component: RouterOutletComponent, - canActivate: mapToCanActivate([AuthGuard, PermissionGuard, IdentityExtensionsGuard]), + canActivate: [AuthGuardFn, PermissionGuardFn, IdentityExtensionsGuardFn], children: [ { path: 'roles', diff --git a/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts b/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts index 2571a1756c..a0e0e03c09 100644 --- a/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts +++ b/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts @@ -1,11 +1,14 @@ import { Injectable, inject } from '@angular/core'; -import { UrlTree, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { UrlTree, ActivatedRouteSnapshot, RouterStateSnapshot, CanActivateFn } from '@angular/router'; import { Observable } from 'rxjs'; import { OAuthService } from 'angular-oauth2-oidc'; import { AuthService, IAbpGuard } from '@abp/ng.core'; +/** + * @deprecated Use `AbpOAuthGuardFn` instead. + */ @Injectable({ providedIn: 'root', }) @@ -27,3 +30,22 @@ export class AbpOAuthGuard implements IAbpGuard { return false; } } + + +export const AbpOAuthGuardFn: CanActivateFn = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot, +) => { + const oAuthService = inject(OAuthService); + const authService = inject(AuthService); + + const hasValidAccessToken = oAuthService.hasValidAccessToken(); + + if (hasValidAccessToken) { + return true; + } + + const params = { returnUrl: state.url }; + authService.navigateToLogin(params); + return false; +}; \ No newline at end of file diff --git a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts index ac800e7c8f..fb56c7fddd 100644 --- a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts +++ b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts @@ -4,7 +4,7 @@ import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc'; import { AbpLocalStorageService, ApiInterceptor, - AuthGuard, + AuthGuardFn, AuthService, CHECK_AUTHENTICATION_STATE_FN_KEY, noop, @@ -14,7 +14,7 @@ import { AbpOAuthService } from './services'; import { OAuthConfigurationHandler } from './handlers/oauth-configuration.handler'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { OAuthApiInterceptor } from './interceptors/api.interceptor'; -import { AbpOAuthGuard } from './guards/oauth.guard'; +import { AbpOAuthGuardFn } from './guards/oauth.guard'; import { NavigateToManageProfileProvider } from './providers'; import { checkAccessToken, pipeToLogin } from './utils'; @@ -31,8 +31,8 @@ export class AbpOAuthModule { useClass: AbpOAuthService, }, { - provide: AuthGuard, - useClass: AbpOAuthGuard, + provide: AuthGuardFn, + useValue: AbpOAuthGuardFn, }, { provide: ApiInterceptor, diff --git a/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts b/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts index 1fc5fd7c7b..f77f862fef 100644 --- a/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts +++ b/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; -import { RouterModule, Routes, mapToCanActivate } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; import { - AuthGuard, + AuthGuardFn, ReplaceableComponents, ReplaceableRouteContainerComponent, RouterOutletComponent, @@ -13,7 +13,7 @@ const routes: Routes = [ { path: '', component: RouterOutletComponent, - canActivate: mapToCanActivate([AuthGuard]), + canActivate: [AuthGuardFn], children: [ { path: '', diff --git a/npm/ng-packs/packages/tenant-management/src/lib/guards/extensions.guard.ts b/npm/ng-packs/packages/tenant-management/src/lib/guards/extensions.guard.ts index bdadb7e78a..896955cc86 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/guards/extensions.guard.ts +++ b/npm/ng-packs/packages/tenant-management/src/lib/guards/extensions.guard.ts @@ -25,7 +25,11 @@ import { TENANT_MANAGEMENT_ENTITY_PROP_CONTRIBUTORS, TENANT_MANAGEMENT_TOOLBAR_ACTION_CONTRIBUTORS, } from '../tokens/extensions.token'; +import { CanActivateFn } from '@angular/router'; +/** + * @deprecated Use `TenantManagementExtensionsGuardFn` instead. + */ @Injectable() export class TenantManagementExtensionsGuard implements IAbpGuard { protected readonly configState = inject(ConfigStateService); @@ -81,3 +85,55 @@ export class TenantManagementExtensionsGuard implements IAbpGuard { ); } } + +export const TenantManagementExtensionsGuardFn: CanActivateFn = () => { + const configState = inject(ConfigStateService); + const extensions = inject(ExtensionsService); + + const config = { optional: true }; + + const actionContributors = inject(TENANT_MANAGEMENT_ENTITY_ACTION_CONTRIBUTORS, config) || {}; + const toolbarContributors = inject(TENANT_MANAGEMENT_TOOLBAR_ACTION_CONTRIBUTORS, config) || {}; + const propContributors = inject(TENANT_MANAGEMENT_ENTITY_PROP_CONTRIBUTORS, config) || {}; + const createFormContributors = + inject(TENANT_MANAGEMENT_CREATE_FORM_PROP_CONTRIBUTORS, config) || {}; + const editFormContributors = inject(TENANT_MANAGEMENT_EDIT_FORM_PROP_CONTRIBUTORS, config) || {}; + + return getObjectExtensionEntitiesFromStore(configState, 'TenantManagement').pipe( + map(entities => ({ + [eTenantManagementComponents.Tenants]: entities.Tenant, + })), + mapEntitiesToContributors(configState, 'TenantManagement'), + tap(objectExtensionContributors => { + mergeWithDefaultActions( + extensions.entityActions, + DEFAULT_TENANT_MANAGEMENT_ENTITY_ACTIONS, + actionContributors, + ); + mergeWithDefaultActions( + extensions.toolbarActions, + DEFAULT_TENANT_MANAGEMENT_TOOLBAR_ACTIONS, + toolbarContributors, + ); + mergeWithDefaultProps( + extensions.entityProps, + DEFAULT_TENANT_MANAGEMENT_ENTITY_PROPS, + objectExtensionContributors.prop, + propContributors, + ); + mergeWithDefaultProps( + extensions.createFormProps, + DEFAULT_TENANT_MANAGEMENT_CREATE_FORM_PROPS, + objectExtensionContributors.createForm, + createFormContributors, + ); + mergeWithDefaultProps( + extensions.editFormProps, + DEFAULT_TENANT_MANAGEMENT_EDIT_FORM_PROPS, + objectExtensionContributors.editForm, + editFormContributors, + ); + }), + map(() => true), + ); +}; diff --git a/npm/ng-packs/packages/tenant-management/src/lib/tenant-management-routing.module.ts b/npm/ng-packs/packages/tenant-management/src/lib/tenant-management-routing.module.ts index 06e2f0369e..61b438b613 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/tenant-management-routing.module.ts +++ b/npm/ng-packs/packages/tenant-management/src/lib/tenant-management-routing.module.ts @@ -1,9 +1,9 @@ import { NgModule } from '@angular/core'; -import { RouterModule, Routes, mapToCanActivate } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; import { - AuthGuard, - PermissionGuard, + AuthGuardFn, + PermissionGuardFn, ReplaceableComponents, ReplaceableRouteContainerComponent, RouterOutletComponent, @@ -11,14 +11,14 @@ import { import { TenantsComponent } from './components/tenants/tenants.component'; import { eTenantManagementComponents } from './enums/components'; -import { TenantManagementExtensionsGuard } from './guards'; +import { TenantManagementExtensionsGuardFn } from './guards'; const routes: Routes = [ { path: '', redirectTo: 'tenants', pathMatch: 'full' }, { path: '', component: RouterOutletComponent, - canActivate: mapToCanActivate([AuthGuard, PermissionGuard, TenantManagementExtensionsGuard]), + canActivate: [AuthGuardFn, PermissionGuardFn, TenantManagementExtensionsGuardFn], children: [ { path: 'tenants',