diff --git a/apps/nestjs-backend/src/features/auth/guard/permission.guard.ts b/apps/nestjs-backend/src/features/auth/guard/permission.guard.ts index c7b365ec2..bced59af3 100644 --- a/apps/nestjs-backend/src/features/auth/guard/permission.guard.ts +++ b/apps/nestjs-backend/src/features/auth/guard/permission.guard.ts @@ -48,8 +48,18 @@ export class PermissionGuard { return true; } + private async permissionBaseReadAll() { + const accessTokenId = this.cls.get('accessTokenId'); + if (accessTokenId) { + const { scopes } = await this.permissionService.getAccessToken(accessTokenId); + return scopes.includes('base|read_all'); + } + return true; + } + protected async resourcePermission(resourceId: string | undefined, permissions: Action[]) { if (!resourceId) { + console.log('permissions', permissions); throw new ForbiddenException('permission check ID does not exist'); } const accessTokenId = this.cls.get('accessTokenId'); @@ -106,10 +116,13 @@ export class PermissionGuard { if (permissions?.includes('instance|read')) { return this.instancePermissionChecker('instance|read'); } - // space create permission check if (permissions?.includes('space|create')) { return await this.permissionCreateSpace(); } + if (permissions?.includes('base|read_all')) { + return await this.permissionBaseReadAll(); + } + // resource permission check return await this.resourcePermission(this.getResourceId(context), permissions); } diff --git a/apps/nestjs-backend/test/access-token.e2e-spec.ts b/apps/nestjs-backend/test/access-token.e2e-spec.ts index d5b5daeca..fe5413efd 100644 --- a/apps/nestjs-backend/test/access-token.e2e-spec.ts +++ b/apps/nestjs-backend/test/access-token.e2e-spec.ts @@ -30,6 +30,7 @@ import { deleteSpace, deleteBase, getAccessToken, + GET_BASE_ALL, } from '@teable/openapi'; import dayjs from 'dayjs'; import { createNewUserAxios } from './utils/axios-instance/new-user'; @@ -149,6 +150,7 @@ describe('OpenAPI AccessTokenController (e2e)', () => { describe('validate accessToken permission', () => { let tableReadToken: string; let recordReadToken: string; + let baseReadAllToken: string; const axios = createAxios(); beforeAll(async () => { @@ -164,6 +166,12 @@ describe('OpenAPI AccessTokenController (e2e)', () => { scopes: ['record|read'], }); recordReadToken = recordReadTokenData.token; + const { data: baseReadAllTokenData } = await createAccessToken({ + ...defaultCreateRo, + name: 'base read all token', + scopes: ['base|read_all'], + }); + baseReadAllToken = baseReadAllTokenData.token; axios.defaults.baseURL = defaultAxios.defaults.baseURL; }); @@ -187,6 +195,26 @@ describe('OpenAPI AccessTokenController (e2e)', () => { expect(error?.status).toEqual(403); }); + it('get base list has not base|read_all permission', async () => { + const error = await getError(() => + axios.get(urlBuilder(GET_BASE_ALL), { + headers: { + Authorization: `Bearer ${tableReadToken}`, + }, + }) + ); + expect(error?.status).toEqual(403); + }); + + it('get base list has base|read_all permission', async () => { + const res = await axios.get(urlBuilder(GET_BASE_ALL), { + headers: { + Authorization: `Bearer ${baseReadAllToken}`, + }, + }); + expect(res.status).toEqual(200); + }); + it('get record list has record|read permission', async () => { const res = await axios.get(urlBuilder(GET_RECORDS_URL, { tableId: table.id }), { headers: {