From f597066d168ea40536987fe618be54832c07c3c3 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Fri, 8 Nov 2024 13:38:10 +0000 Subject: [PATCH 1/6] test(user): write tests for authorizedFlows --- packages/backend/src/models/user.test.js | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/packages/backend/src/models/user.test.js b/packages/backend/src/models/user.test.js index 1ce70f8e..e02473d3 100644 --- a/packages/backend/src/models/user.test.js +++ b/packages/backend/src/models/user.test.js @@ -13,6 +13,9 @@ import Subscription from './subscription.ee.js'; import UsageData from './usage-data.ee.js'; import User from './user.js'; import { createUser } from '../../test/factories/user.js'; +import { createRole } from '../../test/factories/role.js'; +import { createPermission } from '../../test/factories/permission.js'; +import { createFlow } from '../../test/factories/flow.js'; describe('User model', () => { it('tableName should return correct name', () => { @@ -245,4 +248,61 @@ describe('User model', () => { expect(token).toBe(undefined); }); }); + + describe('authorizedFlows', () => { + it('should return user flows with isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Flow', + action: 'read', + conditions: ['isCreator'], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userFlow = await createFlow({ userId: user.id }); + await createFlow(); + + expect(await userWithRoleAndPermissions.authorizedFlows).toStrictEqual([ + userFlow, + ]); + }); + + it('should return all flows without isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Flow', + action: 'read', + conditions: [], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userFlow = await createFlow({ userId: user.id }); + const anotherUserFlow = await createFlow(); + + expect(await userWithRoleAndPermissions.authorizedFlows).toStrictEqual([ + userFlow, + anotherUserFlow, + ]); + }); + + it('should throw an authorization error without Flow read permission', async () => { + const user = new User(); + + expect(() => user.authorizedFlows).toThrowError('NotAuthorized'); + }); + }); }); From da81ecf915dfc52c41a227ec251009b16fc7bfc8 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Fri, 8 Nov 2024 13:46:40 +0000 Subject: [PATCH 2/6] feat(user): add not authorized error message in permission check --- packages/backend/src/models/user.js | 2 +- packages/backend/src/models/user.test.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/models/user.js b/packages/backend/src/models/user.js index 38960fbd..bfe7da5c 100644 --- a/packages/backend/src/models/user.js +++ b/packages/backend/src/models/user.js @@ -642,7 +642,7 @@ class User extends Base { can(action, subject) { const can = this.ability.can(action, subject); - if (!can) throw new NotAuthorizedError(); + if (!can) throw new NotAuthorizedError(`The user is not authorized!`); const relevantRule = this.ability.relevantRuleFor(action, subject); diff --git a/packages/backend/src/models/user.test.js b/packages/backend/src/models/user.test.js index e02473d3..0c2aa655 100644 --- a/packages/backend/src/models/user.test.js +++ b/packages/backend/src/models/user.test.js @@ -302,7 +302,9 @@ describe('User model', () => { it('should throw an authorization error without Flow read permission', async () => { const user = new User(); - expect(() => user.authorizedFlows).toThrowError('NotAuthorized'); + expect(() => user.authorizedFlows).toThrowError( + 'The user is not authorized!' + ); }); }); }); From b5310afb9082ace6746055db192357433daed83b Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Mon, 11 Nov 2024 17:49:17 +0100 Subject: [PATCH 3/6] refactor: Use single quote for user can method error --- packages/backend/src/models/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/models/user.js b/packages/backend/src/models/user.js index bfe7da5c..5f165273 100644 --- a/packages/backend/src/models/user.js +++ b/packages/backend/src/models/user.js @@ -642,7 +642,7 @@ class User extends Base { can(action, subject) { const can = this.ability.can(action, subject); - if (!can) throw new NotAuthorizedError(`The user is not authorized!`); + if (!can) throw new NotAuthorizedError('The user is not authorized!'); const relevantRule = this.ability.relevantRuleFor(action, subject); From 3e28af670caeed43fe3221f93ddcf0ec48a26a7c Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Fri, 8 Nov 2024 14:27:49 +0000 Subject: [PATCH 4/6] test(user): write tests for authorizedSteps --- packages/backend/src/models/user.test.js | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/packages/backend/src/models/user.test.js b/packages/backend/src/models/user.test.js index 0c2aa655..50a5d2a7 100644 --- a/packages/backend/src/models/user.test.js +++ b/packages/backend/src/models/user.test.js @@ -16,6 +16,7 @@ import { createUser } from '../../test/factories/user.js'; import { createRole } from '../../test/factories/role.js'; import { createPermission } from '../../test/factories/permission.js'; import { createFlow } from '../../test/factories/flow.js'; +import { createStep } from '../../test/factories/step.js'; describe('User model', () => { it('tableName should return correct name', () => { @@ -307,4 +308,69 @@ describe('User model', () => { ); }); }); + + describe('authorizedSteps', () => { + it('should return user steps with isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Flow', + action: 'read', + conditions: ['isCreator'], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userFlow = await createFlow({ userId: user.id }); + const userFlowStep = await createStep({ flowId: userFlow.id }); + const anotherUserFlow = await createFlow(); + await createStep({ flowId: anotherUserFlow.id }); + + expect(await userWithRoleAndPermissions.authorizedSteps).toStrictEqual([ + userFlowStep, + ]); + }); + + it('should return all steps without isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Flow', + action: 'read', + conditions: [], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userFlow = await createFlow({ userId: user.id }); + const userFlowStep = await createStep({ flowId: userFlow.id }); + const anotherUserFlow = await createFlow(); + const anotherUserFlowStep = await createStep({ + flowId: anotherUserFlow.id, + }); + + expect(await userWithRoleAndPermissions.authorizedSteps).toStrictEqual([ + userFlowStep, + anotherUserFlowStep, + ]); + }); + + it('should throw an authorization error without Flow read permission', async () => { + const user = new User(); + + expect(() => user.authorizedSteps).toThrowError( + 'The user is not authorized!' + ); + }); + }); }); From a949fda1fc915b69686b18966208fb99d4f0058a Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Mon, 11 Nov 2024 10:04:42 +0000 Subject: [PATCH 5/6] test(user): write tests for authorizedConnections --- packages/backend/src/models/user.test.js | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/packages/backend/src/models/user.test.js b/packages/backend/src/models/user.test.js index 50a5d2a7..91efe1e6 100644 --- a/packages/backend/src/models/user.test.js +++ b/packages/backend/src/models/user.test.js @@ -13,6 +13,7 @@ import Subscription from './subscription.ee.js'; import UsageData from './usage-data.ee.js'; import User from './user.js'; import { createUser } from '../../test/factories/user.js'; +import { createConnection } from '../../test/factories/connection.js'; import { createRole } from '../../test/factories/role.js'; import { createPermission } from '../../test/factories/permission.js'; import { createFlow } from '../../test/factories/flow.js'; @@ -373,4 +374,62 @@ describe('User model', () => { ); }); }); + + describe('authorizedConnections', () => { + it('should return user connections with isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Connection', + action: 'read', + conditions: ['isCreator'], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userConnection = await createConnection({ userId: user.id }); + await createConnection(); + + expect( + await userWithRoleAndPermissions.authorizedConnections + ).toStrictEqual([userConnection]); + }); + + it('should return all connections without isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Connection', + action: 'read', + conditions: [], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userConnection = await createConnection({ userId: user.id }); + const anotherUserConnection = await createConnection(); + + expect( + await userWithRoleAndPermissions.authorizedConnections + ).toStrictEqual([userConnection, anotherUserConnection]); + }); + + it('should throw an authorization error without Connection read permission', async () => { + const user = new User(); + + expect(() => user.authorizedConnections).toThrowError( + 'The user is not authorized!' + ); + }); + }); }); From de480b491c840dd9014646ab9275cf73ed63be39 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Mon, 11 Nov 2024 10:16:48 +0000 Subject: [PATCH 6/6] test(user): write tests for authorizedExecutions --- packages/backend/src/models/user.test.js | 61 ++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/packages/backend/src/models/user.test.js b/packages/backend/src/models/user.test.js index 91efe1e6..b7183ffb 100644 --- a/packages/backend/src/models/user.test.js +++ b/packages/backend/src/models/user.test.js @@ -18,6 +18,7 @@ import { createRole } from '../../test/factories/role.js'; import { createPermission } from '../../test/factories/permission.js'; import { createFlow } from '../../test/factories/flow.js'; import { createStep } from '../../test/factories/step.js'; +import { createExecution } from '../../test/factories/execution.js'; describe('User model', () => { it('tableName should return correct name', () => { @@ -432,4 +433,64 @@ describe('User model', () => { ); }); }); + + describe('authorizedExecutions', () => { + it('should return user executions with isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Execution', + action: 'read', + conditions: ['isCreator'], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userFlow = await createFlow({ userId: user.id }); + const userFlowExecution = await createExecution({ flowId: userFlow.id }); + await createExecution(); + + expect( + await userWithRoleAndPermissions.authorizedExecutions + ).toStrictEqual([userFlowExecution]); + }); + + it('should return all executions without isCreator condition', async () => { + const userRole = await createRole({ name: 'User' }); + + await createPermission({ + roleId: userRole.id, + subject: 'Execution', + action: 'read', + conditions: [], + }); + + const user = await createUser({ roleId: userRole.id }); + + const userWithRoleAndPermissions = await user + .$query() + .withGraphFetched({ role: true, permissions: true }); + + const userFlow = await createFlow({ userId: user.id }); + const userFlowExecution = await createExecution({ flowId: userFlow.id }); + const anotherUserFlowExecution = await createExecution(); + + expect( + await userWithRoleAndPermissions.authorizedExecutions + ).toStrictEqual([userFlowExecution, anotherUserFlowExecution]); + }); + + it('should throw an authorization error without Execution read permission', async () => { + const user = new User(); + + expect(() => user.authorizedExecutions).toThrowError( + 'The user is not authorized!' + ); + }); + }); });