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