mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 11:56:29 +00:00
Acl (#162)
* feat: getRepository * getRepository return type * export action * add: acl * feat: setResourceAction * feat: action alias * chore: code struct * feat: removeResourceAction * chore: file name * ignorecase * remove ACL * feat: ACL * feat: role toJSON * using emit * chore: test Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
fd32705954
commit
43f33044ea
@ -2,6 +2,7 @@ import { ACL } from '..';
|
||||
|
||||
describe('acl', () => {
|
||||
let acl: ACL;
|
||||
|
||||
beforeEach(() => {
|
||||
acl = new ACL();
|
||||
});
|
||||
@ -25,7 +26,11 @@ describe('acl', () => {
|
||||
strategy: 's1',
|
||||
});
|
||||
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).not.toBeNull();
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).toMatchObject({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'create',
|
||||
});
|
||||
});
|
||||
|
||||
it('should deny all', () => {
|
||||
@ -79,8 +84,13 @@ describe('acl', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).not.toBeNull();
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).toMatchObject({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'create',
|
||||
});
|
||||
});
|
||||
|
||||
it('should grant action', function () {
|
||||
acl.setAvailableAction('create', {
|
||||
displayName: 'create',
|
||||
@ -101,7 +111,11 @@ describe('acl', () => {
|
||||
|
||||
role.grantAction('posts:create', {});
|
||||
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).not.toBeNull();
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).toMatchObject({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'create',
|
||||
});
|
||||
});
|
||||
|
||||
it('should works with alias action', () => {
|
||||
@ -121,8 +135,16 @@ describe('acl', () => {
|
||||
strategy: 's1',
|
||||
});
|
||||
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'get' })).not.toBeNull();
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'list' })).not.toBeNull();
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'get' })).toMatchObject({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'get',
|
||||
});
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'list' })).toMatchObject({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'list',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return action params when check permission', () => {
|
||||
@ -210,7 +232,11 @@ describe('acl', () => {
|
||||
|
||||
role.grantAction('posts:create', {});
|
||||
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).not.toBeNull();
|
||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'create' })).toMatchObject({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'create',
|
||||
});
|
||||
|
||||
role.revokeAction('posts:create');
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import lodash from 'lodash';
|
||||
import { ACL } from './acl';
|
||||
type StrategyValue = false | '*' | string | string[];
|
||||
|
||||
export interface AvailableStrategyOptions {
|
||||
acl: ACL;
|
||||
displayName?: string;
|
||||
actions: false | string | string[];
|
||||
resource?: '*';
|
||||
@ -35,6 +37,6 @@ export class ACLAvailableStrategy {
|
||||
}
|
||||
|
||||
allow(resourceName: string, actionName: string) {
|
||||
return this.matchAction(actionName);
|
||||
return this.matchAction(this.options.acl.resolveActionAlias(actionName));
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export class ACLResource {
|
||||
}
|
||||
|
||||
getAction(name: string) {
|
||||
return this.actions.get(name);
|
||||
return this.actions.get(this.acl.resolveActionAlias(name));
|
||||
}
|
||||
|
||||
setAction(name: string, params: RoleActionParams) {
|
||||
|
@ -75,8 +75,14 @@ export class ACL extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
setAvailableStrategy(name: string, options: AvailableStrategyOptions) {
|
||||
this.availableStrategy.set(name, new ACLAvailableStrategy(options));
|
||||
setAvailableStrategy(name: string, options: Omit<AvailableStrategyOptions, 'acl'>) {
|
||||
this.availableStrategy.set(
|
||||
name,
|
||||
new ACLAvailableStrategy({
|
||||
...options,
|
||||
acl: this,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
beforeGrantAction(path: string, listener?: Listener) {
|
||||
@ -84,8 +90,6 @@ export class ACL extends EventEmitter {
|
||||
}
|
||||
|
||||
can({ role, resource, action }: { role: string; resource: string; action: string }): CanResult | null {
|
||||
action = this.resolveActionAlias(action);
|
||||
|
||||
if (!this.isAvailableAction(action)) {
|
||||
return null;
|
||||
}
|
||||
@ -94,15 +98,15 @@ export class ACL extends EventEmitter {
|
||||
const aclResource = aclRole.getResource(resource);
|
||||
|
||||
if (aclResource) {
|
||||
const aclActionConfig = aclResource.actions.get(this.resolveActionAlias(action));
|
||||
const actionParams = aclResource.getAction(action);
|
||||
|
||||
if (aclActionConfig) {
|
||||
if (actionParams) {
|
||||
// handle single action config
|
||||
return {
|
||||
role,
|
||||
resource,
|
||||
action,
|
||||
params: aclActionConfig,
|
||||
params: actionParams,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -115,7 +119,7 @@ export class ACL extends EventEmitter {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (roleStrategy.allow(resource, action)) {
|
||||
if (roleStrategy.allow(resource, this.resolveActionAlias(action))) {
|
||||
return { role, resource, action };
|
||||
}
|
||||
|
||||
@ -123,10 +127,10 @@ export class ACL extends EventEmitter {
|
||||
}
|
||||
|
||||
protected isAvailableAction(actionName: string) {
|
||||
return this.availableActions.has(actionName);
|
||||
return this.availableActions.has(this.resolveActionAlias(actionName));
|
||||
}
|
||||
|
||||
protected resolveActionAlias(action: string) {
|
||||
public resolveActionAlias(action: string) {
|
||||
return this.actionAlias.get(action) ? this.actionAlias.get(action) : action;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user