From a2037d90c9c9a3f564a50482ca5031145c42fbee Mon Sep 17 00:00:00 2001 From: Chareice Date: Fri, 11 Feb 2022 22:00:11 +0800 Subject: [PATCH] feat: revokeResource when roleResource deleted --- packages/plugin-acl/src/__tests__/acl.test.ts | 63 +++++++++++++++++++ packages/plugin-acl/src/server.ts | 15 +++++ 2 files changed, 78 insertions(+) diff --git a/packages/plugin-acl/src/__tests__/acl.test.ts b/packages/plugin-acl/src/__tests__/acl.test.ts index 346c2ff31..5358d141a 100644 --- a/packages/plugin-acl/src/__tests__/acl.test.ts +++ b/packages/plugin-acl/src/__tests__/acl.test.ts @@ -207,6 +207,69 @@ describe('acl', () => { ).toBeNull(); }); + it('should revoke resource when collection destroy', 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'], + }, + ], + }, + }); + + expect( + acl.can({ + role: 'admin', + resource: 'posts', + action: 'view', + }), + ).not.toBeNull(); + + await db.getRepository('collections').destroy({ + filter: { + name: 'posts', + }, + }); + + expect( + acl.can({ + role: 'admin', + resource: 'posts', + action: 'view', + }), + ).toBeNull(); + }); + it('should revoke actions when not using actions config', async () => { await db.getRepository('roles').create({ values: { diff --git a/packages/plugin-acl/src/server.ts b/packages/plugin-acl/src/server.ts index 43acbcd17..d9077fc68 100644 --- a/packages/plugin-acl/src/server.ts +++ b/packages/plugin-acl/src/server.ts @@ -169,6 +169,21 @@ export class PluginACL extends Plugin { await this.writeResourceToACL(resource, transaction); }); + this.app.db.on('rolesResources.afterDestroy', async (model, options) => { + const role = this.acl.getRole(model.get('roleName')); + role.revokeResource(model.get('name')); + }); + + this.app.db.on('collections.afterDestroy', async (model, options) => { + const { transaction } = options; + await this.app.db.getRepository('rolesResources').destroy({ + filter: { + name: model.get('name'), + }, + transaction, + }); + }); + this.app.db.on('fields.afterCreate', async (model, options) => { const { transaction } = options;