feat: add new fields when role has action permission

This commit is contained in:
Chareice 2022-02-11 21:47:26 +08:00 committed by chenos
parent ac7abedbb8
commit e92a21f072
3 changed files with 117 additions and 12 deletions

View File

@ -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();
});
});

View File

@ -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,

View File

@ -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) => {