mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 10:06:22 +00:00
feat: add new fields when role has action permission
This commit is contained in:
parent
ac7abedbb8
commit
e92a21f072
@ -313,4 +313,69 @@ describe('acl', () => {
|
||||
action: 'create',
|
||||
});
|
||||
});
|
||||
|
||||
it('should add fields when field created', async () => {
|
||||
const role = await db.getRepository('roles').create({
|
||||
values: {
|
||||
name: 'admin',
|
||||
title: 'Admin User',
|
||||
allowConfigure: true,
|
||||
},
|
||||
});
|
||||
|
||||
await db.getRepository('collections').create({
|
||||
values: {
|
||||
name: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
await db.getRepository('fields').create({
|
||||
values: {
|
||||
collectionName: 'posts',
|
||||
type: 'string',
|
||||
name: 'title',
|
||||
},
|
||||
});
|
||||
|
||||
await app
|
||||
.agent()
|
||||
.resource('roles.resources')
|
||||
.create({
|
||||
associatedIndex: role.get('name') as string,
|
||||
values: {
|
||||
name: 'posts',
|
||||
usingActionsConfig: true,
|
||||
actions: [
|
||||
{
|
||||
name: 'view',
|
||||
fields: ['title'],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const allowFields = acl.can({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'view',
|
||||
})['params']['fields'];
|
||||
|
||||
expect(allowFields.includes('title')).toBeTruthy();
|
||||
|
||||
await db.getRepository('fields').create({
|
||||
values: {
|
||||
collectionName: 'posts',
|
||||
type: 'string',
|
||||
name: 'description',
|
||||
},
|
||||
});
|
||||
|
||||
const newAllowFields = acl.can({
|
||||
role: 'admin',
|
||||
resource: 'posts',
|
||||
action: 'view',
|
||||
})['params']['fields'];
|
||||
|
||||
expect(newAllowFields.includes('description')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -17,6 +17,7 @@ export class RoleResourceActionModel extends Model {
|
||||
const actionName = this.get('name') as string;
|
||||
|
||||
const fields = this.get('fields') as any;
|
||||
|
||||
const actionPath = `${resourceName}:${actionName}`;
|
||||
const actionParams = {
|
||||
fields,
|
||||
|
@ -82,6 +82,27 @@ export class PluginACL extends Plugin {
|
||||
});
|
||||
}
|
||||
|
||||
async writeResourceToACL(resourceModel: RoleResourceModel, transaction) {
|
||||
await resourceModel.writeToACL({
|
||||
acl: this.acl,
|
||||
associationFieldsActions: this.associationFieldsActions,
|
||||
transaction: transaction,
|
||||
grantHelper: this.grantHelper,
|
||||
});
|
||||
}
|
||||
|
||||
async writeActionToACL(actionModel: RoleResourceActionModel, transaction) {
|
||||
const resource = actionModel.get('resource') as RoleResourceModel;
|
||||
const role = this.acl.getRole(resource.get('roleName') as string);
|
||||
await actionModel.writeToACL({
|
||||
acl: this.acl,
|
||||
role,
|
||||
resourceName: resource.get('name') as string,
|
||||
associationFieldsActions: this.associationFieldsActions,
|
||||
grantHelper: this.grantHelper,
|
||||
});
|
||||
}
|
||||
|
||||
async beforeLoad() {
|
||||
const acl = createACL();
|
||||
this.acl = acl;
|
||||
@ -136,12 +157,7 @@ export class PluginACL extends Plugin {
|
||||
});
|
||||
|
||||
this.app.db.on('rolesResources.afterSaveWithAssociations', async (model: RoleResourceModel, options) => {
|
||||
await model.writeToACL({
|
||||
acl: this.acl,
|
||||
associationFieldsActions: this.associationFieldsActions,
|
||||
transaction: options.transaction,
|
||||
grantHelper: this.grantHelper,
|
||||
});
|
||||
await this.writeResourceToACL(model, options.transaction);
|
||||
});
|
||||
|
||||
this.app.db.on('rolesResourcesActions.afterUpdateWithAssociations', async (model, options) => {
|
||||
@ -150,12 +166,35 @@ export class PluginACL extends Plugin {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await resource.writeToACL({
|
||||
acl: this.acl,
|
||||
associationFieldsActions: this.associationFieldsActions,
|
||||
transaction: options.transaction,
|
||||
grantHelper: this.grantHelper,
|
||||
await this.writeResourceToACL(resource, transaction);
|
||||
});
|
||||
|
||||
this.app.db.on('fields.afterCreate', async (model, options) => {
|
||||
const { transaction } = options;
|
||||
|
||||
const collectionName = model.get('collectionName');
|
||||
const fieldName = model.get('name');
|
||||
|
||||
const resourceActions = (await this.app.db.getRepository('rolesResourcesActions').find({
|
||||
filter: {
|
||||
'resource.name': collectionName,
|
||||
},
|
||||
transaction,
|
||||
appends: ['resource'],
|
||||
})) as RoleResourceActionModel[];
|
||||
|
||||
for (const resourceAction of resourceActions) {
|
||||
const fields = resourceAction.get('fields') as string[];
|
||||
const newFields = [...fields, fieldName];
|
||||
|
||||
await this.app.db.getRepository('rolesResourcesActions').update({
|
||||
filterByTk: resourceAction.get('id') as number,
|
||||
values: {
|
||||
fields: newFields,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.app.db.on('fields.afterDestroy', async (model, options) => {
|
||||
|
Loading…
Reference in New Issue
Block a user