mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 14:16:26 +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', () => {
|
describe('acl', () => {
|
||||||
let acl: ACL;
|
let acl: ACL;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
acl = new ACL();
|
acl = new ACL();
|
||||||
});
|
});
|
||||||
@ -25,7 +26,11 @@ describe('acl', () => {
|
|||||||
strategy: 's1',
|
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', () => {
|
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 () {
|
it('should grant action', function () {
|
||||||
acl.setAvailableAction('create', {
|
acl.setAvailableAction('create', {
|
||||||
displayName: 'create',
|
displayName: 'create',
|
||||||
@ -101,7 +111,11 @@ describe('acl', () => {
|
|||||||
|
|
||||||
role.grantAction('posts:create', {});
|
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', () => {
|
it('should works with alias action', () => {
|
||||||
@ -121,8 +135,16 @@ describe('acl', () => {
|
|||||||
strategy: 's1',
|
strategy: 's1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'get' })).not.toBeNull();
|
expect(acl.can({ role: 'admin', resource: 'posts', action: 'get' })).toMatchObject({
|
||||||
expect(acl.can({ role: 'admin', resource: 'posts', action: 'list' })).not.toBeNull();
|
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', () => {
|
it('should return action params when check permission', () => {
|
||||||
@ -210,7 +232,11 @@ describe('acl', () => {
|
|||||||
|
|
||||||
role.grantAction('posts:create', {});
|
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');
|
role.revokeAction('posts:create');
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import lodash from 'lodash';
|
import lodash from 'lodash';
|
||||||
|
import { ACL } from './acl';
|
||||||
type StrategyValue = false | '*' | string | string[];
|
type StrategyValue = false | '*' | string | string[];
|
||||||
|
|
||||||
export interface AvailableStrategyOptions {
|
export interface AvailableStrategyOptions {
|
||||||
|
acl: ACL;
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
actions: false | string | string[];
|
actions: false | string | string[];
|
||||||
resource?: '*';
|
resource?: '*';
|
||||||
@ -35,6 +37,6 @@ export class ACLAvailableStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
allow(resourceName: string, actionName: string) {
|
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) {
|
getAction(name: string) {
|
||||||
return this.actions.get(name);
|
return this.actions.get(this.acl.resolveActionAlias(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
setAction(name: string, params: RoleActionParams) {
|
setAction(name: string, params: RoleActionParams) {
|
||||||
|
@ -75,8 +75,14 @@ export class ACL extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAvailableStrategy(name: string, options: AvailableStrategyOptions) {
|
setAvailableStrategy(name: string, options: Omit<AvailableStrategyOptions, 'acl'>) {
|
||||||
this.availableStrategy.set(name, new ACLAvailableStrategy(options));
|
this.availableStrategy.set(
|
||||||
|
name,
|
||||||
|
new ACLAvailableStrategy({
|
||||||
|
...options,
|
||||||
|
acl: this,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeGrantAction(path: string, listener?: Listener) {
|
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 {
|
can({ role, resource, action }: { role: string; resource: string; action: string }): CanResult | null {
|
||||||
action = this.resolveActionAlias(action);
|
|
||||||
|
|
||||||
if (!this.isAvailableAction(action)) {
|
if (!this.isAvailableAction(action)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -94,15 +98,15 @@ export class ACL extends EventEmitter {
|
|||||||
const aclResource = aclRole.getResource(resource);
|
const aclResource = aclRole.getResource(resource);
|
||||||
|
|
||||||
if (aclResource) {
|
if (aclResource) {
|
||||||
const aclActionConfig = aclResource.actions.get(this.resolveActionAlias(action));
|
const actionParams = aclResource.getAction(action);
|
||||||
|
|
||||||
if (aclActionConfig) {
|
if (actionParams) {
|
||||||
// handle single action config
|
// handle single action config
|
||||||
return {
|
return {
|
||||||
role,
|
role,
|
||||||
resource,
|
resource,
|
||||||
action,
|
action,
|
||||||
params: aclActionConfig,
|
params: actionParams,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +119,7 @@ export class ACL extends EventEmitter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roleStrategy.allow(resource, action)) {
|
if (roleStrategy.allow(resource, this.resolveActionAlias(action))) {
|
||||||
return { role, resource, action };
|
return { role, resource, action };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +127,10 @@ export class ACL extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected isAvailableAction(actionName: string) {
|
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;
|
return this.actionAlias.get(action) ? this.actionAlias.get(action) : action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user