Merge pull request #18005 from abpframework/create-function-guards

Create function guards and mark class guards as deprecated
update-doc
Mahmut Gundogdu 2 years ago committed by GitHub
commit 8e557d895f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,8 +1,8 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes, mapToCanActivate } from '@angular/router';
import { RouterModule, Routes } from '@angular/router';
import {
AuthGuard,
authGuard,
ReplaceableComponents,
ReplaceableRouteContainerComponent,
RouterOutletComponent,
@ -14,9 +14,10 @@ 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 { authenticationFlowGuard } from './guards';
import { accountExtensionsResolver } from './resolvers';
const canActivate = mapToCanActivate([AuthenticationFlowGuard]);
const canActivate = [authenticationFlowGuard];
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'login' },
@ -73,7 +74,8 @@ const routes: Routes = [
{
path: 'manage',
component: ReplaceableRouteContainerComponent,
canActivate: mapToCanActivate([AuthGuard, AccountExtensionsGuard]),
canActivate: [authGuard],
resolve: [accountExtensionsResolver],
data: {
replaceableComponent: {
key: eAccountComponents.ManageProfile,

@ -1,6 +1,10 @@
import { AuthService, IAbpGuard } from '@abp/ng.core';
import { Injectable, inject } from '@angular/core';
import { CanActivateFn } from '@angular/router';
/**
* @deprecated Use `authenticationFlowGuard` *function* instead.
*/
@Injectable()
export class AuthenticationFlowGuard implements IAbpGuard {
protected readonly authService = inject(AuthService);
@ -12,3 +16,12 @@ export class AuthenticationFlowGuard implements IAbpGuard {
return false;
}
}
export const authenticationFlowGuard: CanActivateFn = () => {
const authService = inject(AuthService);
if (authService.isInternalAuth) return true;
authService.navigateToLogin();
return false;
};

@ -17,6 +17,9 @@ import {
} from '../tokens/extensions.token';
import { eAccountComponents } from '../enums/components';
/**
* @deprecated Use `accountExtensionsResolver` *function* instead.
*/
@Injectable()
export class AccountExtensionsGuard implements IAbpGuard {
protected readonly configState = inject(ConfigStateService);

@ -0,0 +1,36 @@
import { inject } from '@angular/core';
import { ConfigStateService } from '@abp/ng.core';
import { map, tap } from 'rxjs';
import {
ExtensionsService,
getObjectExtensionEntitiesFromStore,
mapEntitiesToContributors,
mergeWithDefaultProps,
} from '@abp/ng.theme.shared/extensions';
import { eAccountComponents } from '../enums';
import { ACCOUNT_EDIT_FORM_PROP_CONTRIBUTORS, DEFAULT_ACCOUNT_FORM_PROPS } from '../tokens';
import { ResolveFn } from '@angular/router';
export const accountExtensionsResolver: ResolveFn<any> = () => {
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,
);
}),
);
};

@ -0,0 +1 @@
export * from './extensions.resolver'

@ -6,3 +6,4 @@ export * from './lib/models';
export * from './lib/services';
export * from './lib/tokens';
export * from './lib/utils';
export * from './lib/resolvers';

@ -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 `authGuard` *function* instead.
*/
@Injectable({
providedIn: 'root',
})
@ -12,3 +16,8 @@ export class AuthGuard implements IAbpGuard {
return false;
}
}
export const authGuard: CanActivateFn = () => {
console.error('You should add @abp/ng-oauth packages or create your own auth packages.');
return false;
};

@ -1,5 +1,10 @@
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';
import { tap } from 'rxjs/operators';
@ -7,6 +12,9 @@ import { AuthService, IAbpGuard } from '../abstracts';
import { findRoute, getRoutePath } from '../utils/route-utils';
import { RoutesService, PermissionService, HttpErrorReporterService } from '../services';
/**
* @deprecated Use `permissionGuard` *function* instead.
*/
@Injectable({
providedIn: 'root',
})
@ -36,3 +44,31 @@ export class PermissionGuard implements IAbpGuard {
);
}
}
export const permissionGuard: 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);
}
}),
);
};

@ -26,6 +26,9 @@ import {
IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS,
} from '../tokens/extensions.token';
/**
* @deprecated Use `identityExtensionsResolver` *function* instead.
*/
@Injectable()
export class IdentityExtensionsGuard implements IAbpGuard {
protected readonly configState = inject(ConfigStateService);

@ -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,
authGuard,
permissionGuard,
ReplaceableComponents,
ReplaceableRouteContainerComponent,
RouterOutletComponent,
@ -12,14 +12,15 @@ 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 { identityExtensionsResolver } from './resolvers';
const routes: Routes = [
{ path: '', redirectTo: 'roles', pathMatch: 'full' },
{
path: '',
component: RouterOutletComponent,
canActivate: mapToCanActivate([AuthGuard, PermissionGuard, IdentityExtensionsGuard]),
canActivate: [authGuard, permissionGuard],
resolve: [identityExtensionsResolver],
children: [
{
path: 'roles',

@ -0,0 +1,75 @@
import { inject } from '@angular/core';
import { map, tap } from 'rxjs';
import { ConfigStateService } from '@abp/ng.core';
import {
ExtensionsService,
getObjectExtensionEntitiesFromStore,
mapEntitiesToContributors,
mergeWithDefaultActions,
mergeWithDefaultProps,
} from '@abp/ng.theme.shared/extensions';
import { eIdentityComponents } from '../enums';
import {
IDENTITY_ENTITY_ACTION_CONTRIBUTORS,
IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS,
IDENTITY_ENTITY_PROP_CONTRIBUTORS,
IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS,
IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS,
DEFAULT_IDENTITY_ENTITY_ACTIONS,
DEFAULT_IDENTITY_TOOLBAR_ACTIONS,
DEFAULT_IDENTITY_ENTITY_PROPS,
DEFAULT_IDENTITY_CREATE_FORM_PROPS,
DEFAULT_IDENTITY_EDIT_FORM_PROPS,
} from '../tokens';
import { ResolveFn } from '@angular/router';
export const identityExtensionsResolver: ResolveFn<any> = () => {
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,
);
}),
);
};

@ -0,0 +1 @@
export * from './extensions.resolver'

@ -4,3 +4,4 @@ export * from './lib/guards';
export * from './lib/identity.module';
export * from './lib/models';
export * from './lib/tokens';
export * from './lib/resolvers';

@ -1,11 +1,19 @@
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 `abpOAuthGuard` *function* instead.
*/
@Injectable({
providedIn: 'root',
})
@ -27,3 +35,21 @@ export class AbpOAuthGuard implements IAbpGuard {
return false;
}
}
export const abpOAuthGuard: 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;
};

@ -4,7 +4,7 @@ import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import {
AbpLocalStorageService,
ApiInterceptor,
AuthGuard,
authGuard,
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 { abpOAuthGuard } 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: authGuard,
useValue: abpOAuthGuard,
},
{
provide: ApiInterceptor,

@ -1,7 +1,7 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes, mapToCanActivate } from '@angular/router';
import { RouterModule, Routes } from '@angular/router';
import {
AuthGuard,
authGuard,
ReplaceableComponents,
ReplaceableRouteContainerComponent,
RouterOutletComponent,
@ -13,7 +13,7 @@ const routes: Routes = [
{
path: '',
component: RouterOutletComponent,
canActivate: mapToCanActivate([AuthGuard]),
canActivate: [authGuard],
children: [
{
path: '',

@ -26,6 +26,9 @@ import {
TENANT_MANAGEMENT_TOOLBAR_ACTION_CONTRIBUTORS,
} from '../tokens/extensions.token';
/**
* @deprecated Use `tenantManagementExtensionsResolver` *function* instead.
*/
@Injectable()
export class TenantManagementExtensionsGuard implements IAbpGuard {
protected readonly configState = inject(ConfigStateService);
@ -81,3 +84,5 @@ export class TenantManagementExtensionsGuard implements IAbpGuard {
);
}
}

@ -0,0 +1,75 @@
import { inject } from '@angular/core';
import { map, tap } from 'rxjs';
import { ConfigStateService } from '@abp/ng.core';
import {
ExtensionsService,
getObjectExtensionEntitiesFromStore,
mapEntitiesToContributors,
mergeWithDefaultActions,
mergeWithDefaultProps,
} from '@abp/ng.theme.shared/extensions';
import { eTenantManagementComponents } from '../enums';
import {
TENANT_MANAGEMENT_ENTITY_ACTION_CONTRIBUTORS,
TENANT_MANAGEMENT_TOOLBAR_ACTION_CONTRIBUTORS,
TENANT_MANAGEMENT_ENTITY_PROP_CONTRIBUTORS,
TENANT_MANAGEMENT_CREATE_FORM_PROP_CONTRIBUTORS,
TENANT_MANAGEMENT_EDIT_FORM_PROP_CONTRIBUTORS,
DEFAULT_TENANT_MANAGEMENT_ENTITY_ACTIONS,
DEFAULT_TENANT_MANAGEMENT_TOOLBAR_ACTIONS,
DEFAULT_TENANT_MANAGEMENT_ENTITY_PROPS,
DEFAULT_TENANT_MANAGEMENT_CREATE_FORM_PROPS,
DEFAULT_TENANT_MANAGEMENT_EDIT_FORM_PROPS,
} from '../tokens';
import { ResolveFn } from '@angular/router';
export const tenantManagementExtensionsResolver: ResolveFn<any> = () => {
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,
);
}),
);
};

@ -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,
authGuard,
permissionGuard,
ReplaceableComponents,
ReplaceableRouteContainerComponent,
RouterOutletComponent,
@ -11,14 +11,15 @@ import {
import { TenantsComponent } from './components/tenants/tenants.component';
import { eTenantManagementComponents } from './enums/components';
import { TenantManagementExtensionsGuard } from './guards';
import { tenantManagementExtensionsResolver } from './resolvers';
const routes: Routes = [
{ path: '', redirectTo: 'tenants', pathMatch: 'full' },
{
path: '',
component: RouterOutletComponent,
canActivate: mapToCanActivate([AuthGuard, PermissionGuard, TenantManagementExtensionsGuard]),
canActivate: [authGuard, permissionGuard],
resolve: [tenantManagementExtensionsResolver],
children: [
{
path: 'tenants',

@ -4,3 +4,4 @@ export * from './lib/guards';
export * from './lib/models';
export * from './lib/tenant-management.module';
export * from './lib/tokens';
export * from './lib/resolvers';

Loading…
Cancel
Save