diff --git a/packages/core/acl/src/acl.ts b/packages/core/acl/src/acl.ts index c23e9b853a..1e39a5e9aa 100644 --- a/packages/core/acl/src/acl.ts +++ b/packages/core/acl/src/acl.ts @@ -453,6 +453,20 @@ export class ACL extends EventEmitter { ctx.permission.parsedParams = parsedParams; ctx.log?.debug && ctx.log.debug('acl parsedParams', parsedParams); ctx.permission.rawParams = lodash.cloneDeep(resourcerAction.params); + + if (parsedParams.appends && resourcerAction.params.fields) { + for (const queryField of resourcerAction.params.fields) { + if (parsedParams.appends.indexOf(queryField) !== -1) { + // move field to appends + if (!resourcerAction.params.appends) { + resourcerAction.params.appends = []; + } + resourcerAction.params.appends.push(queryField); + resourcerAction.params.fields = resourcerAction.params.fields.filter((f) => f !== queryField); + } + } + } + resourcerAction.mergeParams(parsedParams, { appends: (x, y) => { if (!x) { diff --git a/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts b/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts index 418bc40199..34b3979548 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts +++ b/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts @@ -16,6 +16,8 @@ describe('list action with acl', () => { let Post; + let Comment; + beforeEach(async () => { app = await prepareApp(); @@ -32,6 +34,21 @@ describe('list action with acl', () => { name: 'createdBy', target: 'users', }, + { + type: 'hasMany', + name: 'comments', + target: 'comments', + }, + ], + }); + + Comment = app.db.collection({ + name: 'comments', + fields: [ + { + type: 'string', + name: 'content', + }, ], }); @@ -42,6 +59,52 @@ describe('list action with acl', () => { await app.destroy(); }); + it('should list associations with fields filter', async () => { + const userRole = app.acl.define({ + role: 'user', + }); + + userRole.grantAction('posts:view', { + fields: ['title', 'comments'], + }); + + userRole.grantAction('comments:view', { + fields: ['content'], + }); + + await Post.repository.create({ + values: [ + { + title: 'p1', + comments: [{ content: 'c1' }, { content: 'c2' }], + }, + ], + }); + + app.resourceManager.use( + (ctx, next) => { + ctx.state.currentRole = 'user'; + return next(); + }, + { + before: 'acl', + }, + ); + + const response = await (app as any) + .agent() + .set('X-With-ACL-Meta', true) + .resource('posts') + .list({ + fields: ['title', 'comments'], + }); + + expect(response.status).toBe(200); + const { data } = response.body; + expect(data[0].title).toBeDefined(); + expect(data[0].comments[0].content).toBeDefined(); + }); + it('should list with meta permission that has difference primary key', async () => { const userRole = app.acl.define({ role: 'user',