diff --git a/apps/meteor/app/api/server/v1/integrations.ts b/apps/meteor/app/api/server/v1/integrations.ts index f7eb9e5a14675..5306e7fbbea39 100644 --- a/apps/meteor/app/api/server/v1/integrations.ts +++ b/apps/meteor/app/api/server/v1/integrations.ts @@ -11,7 +11,6 @@ import { Match, check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; import type { Filter } from 'mongodb'; -import { hasAtLeastOnePermissionAsync } from '../../../authorization/server/functions/hasPermission'; import { mountIntegrationHistoryQueryBasedOnPermissions, mountIntegrationQueryBasedOnPermissions, @@ -43,15 +42,17 @@ API.v1.addRoute( API.v1.addRoute( 'integrations.history', - { authRequired: true, validateParams: isIntegrationsHistoryProps }, + { + authRequired: true, + validateParams: isIntegrationsHistoryProps, + permissionsRequired: { + GET: { permissions: ['manage-outgoing-integrations', 'manage-own-outgoing-integrations'], operation: 'hasAny' }, + }, + }, { async get() { const { userId, queryParams } = this; - if (!(await hasAtLeastOnePermissionAsync(userId, ['manage-outgoing-integrations', 'manage-own-outgoing-integrations']))) { - return API.v1.unauthorized(); - } - if (!queryParams.id || queryParams.id.trim() === '') { return API.v1.failure('Invalid integration id.'); } @@ -83,20 +84,22 @@ API.v1.addRoute( API.v1.addRoute( 'integrations.list', - { authRequired: true }, { - async get() { - if ( - !(await hasAtLeastOnePermissionAsync(this.userId, [ + authRequired: true, + permissionsRequired: { + GET: { + permissions: [ 'manage-outgoing-integrations', 'manage-own-outgoing-integrations', 'manage-incoming-integrations', 'manage-own-incoming-integrations', - ])) - ) { - return API.v1.unauthorized(); - } - + ], + operation: 'hasAny', + }, + }, + }, + { + async get() { const { offset, count } = await getPaginationItems(this.queryParams); const { sort, fields: projection, query } = await this.parseJsonQuery(); @@ -124,20 +127,23 @@ API.v1.addRoute( API.v1.addRoute( 'integrations.remove', - { authRequired: true, validateParams: isIntegrationsRemoveProps }, { - async post() { - if ( - !(await hasAtLeastOnePermissionAsync(this.userId, [ + authRequired: true, + validateParams: isIntegrationsRemoveProps, + permissionsRequired: { + POST: { + permissions: [ 'manage-outgoing-integrations', 'manage-own-outgoing-integrations', 'manage-incoming-integrations', 'manage-own-incoming-integrations', - ])) - ) { - return API.v1.unauthorized(); - } - + ], + operation: 'hasAny', + }, + }, + }, + { + async post() { const { bodyParams } = this; let integration: IIntegration | null = null; diff --git a/apps/meteor/tests/end-to-end/api/incoming-integrations.ts b/apps/meteor/tests/end-to-end/api/incoming-integrations.ts index ff475945a9ac6..814f246623bb4 100644 --- a/apps/meteor/tests/end-to-end/api/incoming-integrations.ts +++ b/apps/meteor/tests/end-to-end/api/incoming-integrations.ts @@ -308,7 +308,7 @@ describe('[Incoming Integrations]', () => { }); describe('[/integrations.history]', () => { - it('should return an error when trying to get history of incoming integrations', (done) => { + it('should return an error when trying to get history of incoming integrations if user does NOT have enough permissions', (done) => { void request .get(api('integrations.history')) .set(credentials) @@ -319,7 +319,7 @@ describe('[Incoming Integrations]', () => { .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }) .end(done); }); @@ -397,25 +397,22 @@ describe('[Incoming Integrations]', () => { }); }); - it('should return unauthorized error when the user does not have any integrations permissions', (done) => { - void updatePermission('manage-incoming-integrations', []).then(() => { - void updatePermission('manage-own-incoming-integrations', []).then(() => { - void updatePermission('manage-outgoing-integrations', []).then(() => { - void updatePermission('manage-outgoing-integrations', []).then(() => { - void request - .get(api('integrations.list')) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(403) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); - }) - .end(done); - }); - }); + it('should return unauthorized error when the user does not have any integrations permissions', async () => { + await Promise.all([ + updatePermission('manage-incoming-integrations', []), + updatePermission('manage-own-incoming-integrations', []), + updatePermission('manage-outgoing-integrations', []), + updatePermission('manage-outgoing-integrations', []), + ]); + await request + .get(api('integrations.list')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }); - }); }); }); @@ -578,7 +575,7 @@ describe('[Incoming Integrations]', () => { .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }) .end(done); }); @@ -597,7 +594,7 @@ describe('[Incoming Integrations]', () => { .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }) .end(done); }); diff --git a/apps/meteor/tests/end-to-end/api/outgoing-integrations.ts b/apps/meteor/tests/end-to-end/api/outgoing-integrations.ts index 5ed7f8604db11..76a67c8b330da 100644 --- a/apps/meteor/tests/end-to-end/api/outgoing-integrations.ts +++ b/apps/meteor/tests/end-to-end/api/outgoing-integrations.ts @@ -289,47 +289,42 @@ describe('[Outgoing Integrations]', () => { }); }); - it('should return unauthorized error when the user does not have any integrations permissions', (done) => { - void updatePermission('manage-incoming-integrations', []).then(() => { - void updatePermission('manage-own-incoming-integrations', []).then(() => { - void updatePermission('manage-outgoing-integrations', []).then(() => { - void updatePermission('manage-outgoing-integrations', []).then(() => { - void request - .get(api('integrations.list')) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(403) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); - }) - .end(done); - }); - }); + it('should return unauthorized error when the user does not have any integrations permissions', async () => { + await Promise.all([ + updatePermission('manage-incoming-integrations', []), + updatePermission('manage-own-incoming-integrations', []), + updatePermission('manage-outgoing-integrations', []), + updatePermission('manage-outgoing-integrations', []), + ]); + + await request + .get(api('integrations.list')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }); - }); }); }); describe('[/integrations.history]', () => { - it('should return an error when the user DOES NOT the necessary permission', (done) => { - void updatePermission('manage-outgoing-integrations', []).then(() => { - void updatePermission('manage-own-outgoing-integrations', []).then(() => { - void request - .get(api('integrations.history')) - .set(credentials) - .query({ - id: integration._id, - }) - .expect('Content-Type', 'application/json') - .expect(403) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); - }) - .end(done); + it('should return an error when the user DOES NOT the necessary permission', async () => { + await updatePermission('manage-outgoing-integrations', []); + await updatePermission('manage-own-outgoing-integrations', []); + await request + .get(api('integrations.history')) + .set(credentials) + .query({ + id: integration._id, + }) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }); - }); }); it('should return the history of outgoing integrations', (done) => { @@ -467,7 +462,7 @@ describe('[Outgoing Integrations]', () => { .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }) .end(done); }); @@ -486,7 +481,7 @@ describe('[Outgoing Integrations]', () => { .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error', 'unauthorized'); + expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }) .end(done); });