mirror of https://github.com/abpframework/abp.git
committed by
GitHub
33 changed files with 223 additions and 111 deletions
@ -1,27 +1,26 @@ |
|||
import { eLayoutType, RoutesService } from '@abp/ng.core'; |
|||
import { eThemeSharedRouteNames } from '@abp/ng.theme.shared'; |
|||
import { APP_INITIALIZER } from '@angular/core'; |
|||
import { eCmsKitRouteNames } from '../enums/route-names'; |
|||
|
|||
export const MY_PROJECT_NAME_ROUTE_PROVIDERS = [ |
|||
{ |
|||
provide: APP_INITIALIZER, |
|||
useFactory: configureRoutes, |
|||
deps: [RoutesService], |
|||
multi: true, |
|||
}, |
|||
{ |
|||
provide: APP_INITIALIZER, |
|||
useFactory: configureRoutes, |
|||
deps: [RoutesService], |
|||
multi: true, |
|||
}, |
|||
]; |
|||
|
|||
export function configureRoutes(routes: RoutesService) { |
|||
return () => { |
|||
routes.add([ |
|||
{ |
|||
path: '/cms-kit', |
|||
name: eCmsKitRouteNames.CmsKit, |
|||
iconClass: 'fas fa-book', |
|||
layout: eLayoutType.application, |
|||
order: 3, |
|||
}, |
|||
]); |
|||
}; |
|||
export function configureRoutes(routesService: RoutesService) { |
|||
return () => { |
|||
routesService.add([ |
|||
{ |
|||
path: '/cms-kit', |
|||
name: eCmsKitRouteNames.CmsKit, |
|||
iconClass: 'fas fa-book', |
|||
layout: eLayoutType.application, |
|||
order: 3, |
|||
}, |
|||
]); |
|||
}; |
|||
} |
|||
|
|||
@ -1,10 +1,10 @@ |
|||
export * from './autofocus.directive'; |
|||
export * from './debounce.directive'; |
|||
export * from './ellipsis.directive'; |
|||
export * from './for.directive'; |
|||
export * from './form-submit.directive'; |
|||
export * from './init.directive'; |
|||
export * from './permission.directive'; |
|||
export * from './replaceable-template.directive'; |
|||
export * from './visibility.directive'; |
|||
export * from './debounce.directive'; |
|||
export * from './stop-propagation.directive'; |
|||
export * from './visibility.directive'; |
|||
|
|||
@ -0,0 +1,60 @@ |
|||
import { ConfigState } from '../states'; |
|||
import { Store } from '@ngxs/store'; |
|||
import { map } from 'rxjs/operators'; |
|||
import { ApplicationConfiguration } from '../models/application-configuration'; |
|||
import snq from 'snq'; |
|||
import { Injectable } from '@angular/core'; |
|||
|
|||
@Injectable({ providedIn: 'root' }) |
|||
export class PermissionService { |
|||
constructor(private store: Store) {} |
|||
|
|||
getGrantedPolicy$(key: string) { |
|||
return this.getStream().pipe(map(policies => this.isPolicyGranted(key, policies))); |
|||
} |
|||
|
|||
getGrantedPolicy(key: string) { |
|||
const policies = this.getSnapshot(); |
|||
return this.isPolicyGranted(key, policies); |
|||
} |
|||
|
|||
private isPolicyGranted(key: string, policies: ApplicationConfiguration.Policy) { |
|||
if (!key) return true; |
|||
|
|||
const orRegexp = /\|\|/g; |
|||
const andRegexp = /&&/g; |
|||
|
|||
// TODO: Allow combination of ANDs & ORs
|
|||
if (orRegexp.test(key)) { |
|||
const keys = key.split('||').filter(Boolean); |
|||
|
|||
if (keys.length < 2) return false; |
|||
|
|||
return keys.some(k => this.getPolicy(k.trim(), policies)); |
|||
} else if (andRegexp.test(key)) { |
|||
const keys = key.split('&&').filter(Boolean); |
|||
|
|||
if (keys.length < 2) return false; |
|||
|
|||
return keys.every(k => this.getPolicy(k.trim(), policies)); |
|||
} |
|||
|
|||
return this.getPolicy(key, policies); |
|||
} |
|||
|
|||
private getStream() { |
|||
return this.store.select(ConfigState).pipe(map(this.mapToPolicies)); |
|||
} |
|||
|
|||
private getSnapshot() { |
|||
return this.mapToPolicies(this.store.selectSnapshot(ConfigState)); |
|||
} |
|||
|
|||
private mapToPolicies(applicationConfiguration: ApplicationConfiguration.Response) { |
|||
return snq(() => applicationConfiguration.auth.grantedPolicies); |
|||
} |
|||
|
|||
private getPolicy(policy: string, policies: ApplicationConfiguration.Policy) { |
|||
return snq(() => policies[policy], false); |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
import { Observable, of, Subject } from 'rxjs'; |
|||
import { Store } from '@ngxs/store'; |
|||
import { AbstractType, InjectFlags, InjectionToken, Injector, Type } from '@angular/core'; |
|||
|
|||
export const mockActions = new Subject(); |
|||
export const mockStore = ({ |
|||
selectSnapshot() { |
|||
return true; |
|||
}, |
|||
select(): Observable<any> { |
|||
return of(null); |
|||
}, |
|||
} as unknown) as Store; |
|||
|
|||
export class DummyInjector extends Injector { |
|||
constructor(public payload: { [key: string]: any }) { |
|||
super(); |
|||
} |
|||
get<T>( |
|||
token: Type<T> | InjectionToken<T> | AbstractType<T>, |
|||
notFoundValue?: T, |
|||
flags?: InjectFlags, |
|||
): T; |
|||
get(token: any, notFoundValue?: any): any; |
|||
get(token, notFoundValue?, flags?: InjectFlags): any { |
|||
return this.payload[token.name || token]; |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
export * from './routes-service.spec.utils'; |
|||
@ -0,0 +1,7 @@ |
|||
import { PermissionService } from '../../services'; |
|||
import { Subject } from 'rxjs'; |
|||
|
|||
export const mockPermissionService = (args = {} as Partial<PermissionService>) => { |
|||
const permissionService = { getGrantedPolicy$: new Subject(), getGrantedPolicy: arg => true }; |
|||
return Object.assign({}, permissionService, args); |
|||
}; |
|||
@ -0,0 +1,12 @@ |
|||
import { RoutesService } from '../../services'; |
|||
import { mockPermissionService } from './permission-service.spec.utils'; |
|||
import { DummyInjector, mockActions } from './common.utils'; |
|||
|
|||
export const mockRoutesService = (injectorPayload = {} as { [key: string]: any }) => { |
|||
const injector = new DummyInjector({ |
|||
PermissionService: mockPermissionService(), |
|||
Actions: mockActions, |
|||
...injectorPayload, |
|||
}); |
|||
return new RoutesService(injector); |
|||
}; |
|||
Loading…
Reference in new issue