Merge pull request #2422 from automatisch/aut-1515
feat(migrations): introduce manage permissions instead of create, update, delete, publish
This commit is contained in:
@@ -112,5 +112,6 @@
|
|||||||
"src/"
|
"src/"
|
||||||
],
|
],
|
||||||
"ext": "js"
|
"ext": "js"
|
||||||
}
|
},
|
||||||
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ describe('PATCH /api/v1/admin/roles/:roleId', () => {
|
|||||||
|
|
||||||
it('should return the updated role with sanitized permissions', async () => {
|
it('should return the updated role with sanitized permissions', async () => {
|
||||||
const validPermission = {
|
const validPermission = {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: role.id,
|
roleId: role.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,14 +15,7 @@ describe('DELETE /api/v1/connections/:connectionId', () => {
|
|||||||
currentUserRole = await currentUser.$relatedQuery('role');
|
currentUserRole = await currentUser.$relatedQuery('role');
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
|
||||||
roleId: currentUserRole.id,
|
|
||||||
conditions: ['isCreator'],
|
|
||||||
});
|
|
||||||
|
|
||||||
await createPermission({
|
|
||||||
action: 'update',
|
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ describe('POST /api/v1/connections/:connectionId/auth-url', () => {
|
|||||||
currentUser = await createUser();
|
currentUser = await createUser();
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe('POST /api/v1/connections/:connectionId/reset', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -68,7 +68,7 @@ describe('POST /api/v1/connections/:connectionId/reset', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -84,7 +84,7 @@ describe('POST /api/v1/connections/:connectionId/reset', () => {
|
|||||||
const notExistingConnectionUUID = Crypto.randomUUID();
|
const notExistingConnectionUUID = Crypto.randomUUID();
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -98,7 +98,7 @@ describe('POST /api/v1/connections/:connectionId/reset', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe('POST /api/v1/connections/:connectionId/test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -63,7 +63,7 @@ describe('POST /api/v1/connections/:connectionId/test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -88,7 +88,7 @@ describe('POST /api/v1/connections/:connectionId/test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -109,7 +109,7 @@ describe('POST /api/v1/connections/:connectionId/test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ describe('PATCH /api/v1/connections/:connectionId', () => {
|
|||||||
const currentUserConnection = await createConnection(connectionData);
|
const currentUserConnection = await createConnection(connectionData);
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -72,7 +72,7 @@ describe('PATCH /api/v1/connections/:connectionId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -88,7 +88,7 @@ describe('PATCH /api/v1/connections/:connectionId', () => {
|
|||||||
const notExistingConnectionUUID = Crypto.randomUUID();
|
const notExistingConnectionUUID = Crypto.randomUUID();
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -102,7 +102,7 @@ describe('PATCH /api/v1/connections/:connectionId', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ describe('POST /api/v1/connections/:connectionId/verify', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -54,7 +54,7 @@ describe('POST /api/v1/connections/:connectionId/verify', () => {
|
|||||||
const notExistingConnectionUUID = Crypto.randomUUID();
|
const notExistingConnectionUUID = Crypto.randomUUID();
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -68,7 +68,7 @@ describe('POST /api/v1/connections/:connectionId/verify', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ describe('POST /api/v1/flows', () => {
|
|||||||
|
|
||||||
it('should create an empty flow when no templateId is provided', async () => {
|
it('should create an empty flow when no templateId is provided', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -42,7 +42,7 @@ describe('POST /api/v1/flows', () => {
|
|||||||
|
|
||||||
it('should create a flow from template when templateId is provided', async () => {
|
it('should create a flow from template when templateId is provided', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ describe('POST /api/v1/flows/:flowId/steps', () => {
|
|||||||
await createPermission({
|
await createPermission({
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ describe('POST /api/v1/flows/:flowId/steps', () => {
|
|||||||
await createPermission({
|
await createPermission({
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
conditions: [],
|
conditions: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ describe('POST /api/v1/flows/:flowId/steps', () => {
|
|||||||
await createPermission({
|
await createPermission({
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ describe('POST /api/v1/flows/:flowId/steps', () => {
|
|||||||
await createPermission({
|
await createPermission({
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ describe('POST /api/v1/flows/:flowId/steps', () => {
|
|||||||
await createPermission({
|
await createPermission({
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ describe('DELETE /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -52,7 +52,7 @@ describe('DELETE /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -73,7 +73,7 @@ describe('DELETE /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -96,7 +96,7 @@ describe('DELETE /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ describe('POST /api/v1/flows/:flowId/duplicate', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -106,7 +106,7 @@ describe('POST /api/v1/flows/:flowId/duplicate', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -143,7 +143,7 @@ describe('POST /api/v1/flows/:flowId/duplicate', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -169,7 +169,7 @@ describe('POST /api/v1/flows/:flowId/duplicate', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -190,7 +190,7 @@ describe('POST /api/v1/flows/:flowId/duplicate', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ describe('POST /api/v1/flows/:flowId/export', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -113,7 +113,7 @@ describe('POST /api/v1/flows/:flowId/export', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -141,7 +141,7 @@ describe('POST /api/v1/flows/:flowId/export', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -167,7 +167,7 @@ describe('POST /api/v1/flows/:flowId/export', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -188,7 +188,7 @@ describe('POST /api/v1/flows/:flowId/export', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ describe('POST /api/v1/flows/import', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -124,7 +124,7 @@ describe('POST /api/v1/flows/import', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -206,7 +206,7 @@ describe('POST /api/v1/flows/import', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -279,7 +279,7 @@ describe('POST /api/v1/flows/import', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -330,7 +330,7 @@ describe('POST /api/v1/flows/import', () => {
|
|||||||
const currentUserFlow = await createFlow({ userId: currentUser.id });
|
const currentUserFlow = await createFlow({ userId: currentUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -77,7 +77,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
const anotherUserFlow = await createFlow({ userId: anotherUser.id });
|
const anotherUserFlow = await createFlow({ userId: anotherUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -96,7 +96,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
const anotherUserFolder = await createFolder({ userId: anotherUser.id });
|
const anotherUserFolder = await createFolder({ userId: anotherUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -111,7 +111,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing flow UUID', async () => {
|
it('should return not found response for not existing flow UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -130,7 +130,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
const flow = await createFlow({ userId: currentUser.id });
|
const flow = await createFlow({ userId: currentUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -147,7 +147,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid flow UUID', async () => {
|
it('should return bad request response for invalid flow UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
@@ -160,7 +160,7 @@ describe('PATCH /api/v1/flows/:flowId/folder', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid folder UUID', async () => {
|
it('should return bad request response for invalid folder UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ describe('PATCH /api/v1/flows/:flowId/status', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'publish',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -114,7 +114,7 @@ describe('PATCH /api/v1/flows/:flowId/status', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'publish',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -152,7 +152,7 @@ describe('PATCH /api/v1/flows/:flowId/status', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'publish',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -178,7 +178,7 @@ describe('PATCH /api/v1/flows/:flowId/status', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'publish',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -199,7 +199,7 @@ describe('PATCH /api/v1/flows/:flowId/status', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'publish',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ describe('PATCH /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -65,7 +65,7 @@ describe('PATCH /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -98,7 +98,7 @@ describe('PATCH /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -121,7 +121,7 @@ describe('PATCH /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -144,7 +144,7 @@ describe('PATCH /api/v1/flows/:flowId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ describe('POST /api/v1/folders', () => {
|
|||||||
|
|
||||||
it('should return created flow', async () => {
|
it('should return created flow', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ describe('DELETE /api/v1/folders/:folderId', () => {
|
|||||||
const currentUserFolder = await createFolder({ userId: currentUser.id });
|
const currentUserFolder = await createFolder({ userId: currentUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
@@ -34,7 +34,7 @@ describe('DELETE /api/v1/folders/:folderId', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing folder UUID', async () => {
|
it('should return not found response for not existing folder UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
@@ -49,7 +49,7 @@ describe('DELETE /api/v1/folders/:folderId', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ describe('PATCH /api/v1/folders/:folderId', () => {
|
|||||||
const currentUserFolder = await createFolder({ userId: currentUser.id });
|
const currentUserFolder = await createFolder({ userId: currentUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
@@ -47,7 +47,7 @@ describe('PATCH /api/v1/folders/:folderId', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing folder UUID', async () => {
|
it('should return not found response for not existing folder UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
@@ -62,7 +62,7 @@ describe('PATCH /api/v1/folders/:folderId', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
@@ -77,7 +77,7 @@ describe('PATCH /api/v1/folders/:folderId', () => {
|
|||||||
const currentUserFolder = await createFolder({ userId: currentUser.id });
|
const currentUserFolder = await createFolder({ userId: currentUser.id });
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-data', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -102,7 +102,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-data', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -156,7 +156,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-data', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -177,7 +177,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-data', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing step UUID', async () => {
|
it('should return not found response for not existing step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -200,7 +200,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-data', () => {
|
|||||||
|
|
||||||
it('should return not found response for existing step UUID without app key', async () => {
|
it('should return not found response for existing step UUID without app key', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -223,7 +223,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-data', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-fields', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -78,7 +78,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-fields', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -102,7 +102,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-fields', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing step UUID', async () => {
|
it('should return not found response for not existing step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -125,7 +125,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-fields', () => {
|
|||||||
|
|
||||||
it('should return not found response for existing step UUID without app key', async () => {
|
it('should return not found response for existing step UUID without app key', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -149,7 +149,7 @@ describe('POST /api/v1/steps/:stepId/dynamic-fields', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ describe('DELETE /api/v1/steps/:stepId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -76,7 +76,7 @@ describe('DELETE /api/v1/steps/:stepId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -90,7 +90,7 @@ describe('DELETE /api/v1/steps/:stepId', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing step UUID', async () => {
|
it('should return not found response for not existing step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -113,7 +113,7 @@ describe('DELETE /api/v1/steps/:stepId', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid step UUID', async () => {
|
it('should return bad request response for invalid step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ describe('GET /api/v1/steps/:stepId/previous-steps', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -108,7 +108,7 @@ describe('GET /api/v1/steps/:stepId/previous-steps', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -129,7 +129,7 @@ describe('GET /api/v1/steps/:stepId/previous-steps', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing step UUID', async () => {
|
it('should return not found response for not existing step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -152,7 +152,7 @@ describe('GET /api/v1/steps/:stepId/previous-steps', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ describe('POST /api/v1/steps/:stepId/test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -140,7 +140,7 @@ describe('POST /api/v1/steps/:stepId/test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -165,7 +165,7 @@ describe('POST /api/v1/steps/:stepId/test', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing step UUID', async () => {
|
it('should return not found response for not existing step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -188,7 +188,7 @@ describe('POST /api/v1/steps/:stepId/test', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid step UUID', async () => {
|
it('should return bad request response for invalid step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ describe('PATCH /api/v1/steps/:stepId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -96,7 +96,7 @@ describe('PATCH /api/v1/steps/:stepId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -145,7 +145,7 @@ describe('PATCH /api/v1/steps/:stepId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
conditions: ['isCreator'],
|
conditions: ['isCreator'],
|
||||||
@@ -169,7 +169,7 @@ describe('PATCH /api/v1/steps/:stepId', () => {
|
|||||||
|
|
||||||
it('should return not found response for not existing step UUID', async () => {
|
it('should return not found response for not existing step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -192,7 +192,7 @@ describe('PATCH /api/v1/steps/:stepId', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid step UUID', async () => {
|
it('should return bad request response for invalid step UUID', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUser.roleId,
|
roleId: currentUser.roleId,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ describe('GET /api/v1/templates', () => {
|
|||||||
|
|
||||||
it('should return templates when templates are enabled and user has create flow permission', async () => {
|
it('should return templates when templates are enabled and user has create flow permission', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
@@ -45,7 +45,7 @@ describe('GET /api/v1/templates', () => {
|
|||||||
|
|
||||||
it('should return 403 when templates are disabled', async () => {
|
it('should return 403 when templates are disabled', async () => {
|
||||||
await createPermission({
|
await createPermission({
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
roleId: currentUserRole.id,
|
roleId: currentUserRole.id,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
export async function up(knex) {
|
||||||
|
const roles = await knex('roles').select('id', 'name');
|
||||||
|
|
||||||
|
// Define the required actions for each subject
|
||||||
|
const subjectActionMap = {
|
||||||
|
Connection: ['create', 'delete', 'update'],
|
||||||
|
Flow: ['create', 'delete', 'publish', 'update'],
|
||||||
|
User: ['create', 'delete', 'update'],
|
||||||
|
Role: ['create', 'delete', 'update'],
|
||||||
|
SamlAuthProvider: ['create', 'delete', 'update'],
|
||||||
|
Config: ['update'],
|
||||||
|
App: ['create', 'delete', 'update'],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const role of roles) {
|
||||||
|
for (const [subject, actions] of Object.entries(subjectActionMap)) {
|
||||||
|
const rolePermissions = await knex('permissions')
|
||||||
|
.where({ role_id: role.id, subject })
|
||||||
|
.whereIn('action', actions)
|
||||||
|
.select('id', 'action', 'conditions');
|
||||||
|
|
||||||
|
const actionCounts = rolePermissions.reduce((counts, perm) => {
|
||||||
|
counts[perm.action] = (counts[perm.action] || 0) + 1;
|
||||||
|
return counts;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
let allActionsExist = true;
|
||||||
|
for (const action of actions) {
|
||||||
|
if (actionCounts[action] !== 1) {
|
||||||
|
allActionsExist = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if any of the permissions has the 'isCreator' condition
|
||||||
|
const hasIsCreatorCondition = rolePermissions.some(
|
||||||
|
(perm) => perm.conditions && perm.conditions.includes('isCreator')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Delete the existing permissions for the required actions
|
||||||
|
await knex('permissions')
|
||||||
|
.where({ role_id: role.id, subject })
|
||||||
|
.whereIn('action', actions)
|
||||||
|
.del();
|
||||||
|
|
||||||
|
// If all required actions exist, insert a new permission with the 'manage' action
|
||||||
|
if (allActionsExist) {
|
||||||
|
await knex('permissions').insert({
|
||||||
|
role_id: role.id,
|
||||||
|
subject,
|
||||||
|
action: 'manage',
|
||||||
|
conditions: JSON.stringify(
|
||||||
|
hasIsCreatorCondition ? ['isCreator'] : []
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex) {
|
||||||
|
const roles = await knex('roles').select('id', 'name');
|
||||||
|
|
||||||
|
// Define the required actions for each subject
|
||||||
|
const subjectActionMap = {
|
||||||
|
Connection: ['create', 'delete', 'update'],
|
||||||
|
Flow: ['create', 'delete', 'publish', 'update'],
|
||||||
|
User: ['create', 'delete', 'update'],
|
||||||
|
Role: ['create', 'delete', 'update'],
|
||||||
|
SamlAuthProvider: ['create', 'delete', 'update'],
|
||||||
|
Config: ['update'],
|
||||||
|
App: ['create', 'delete', 'update'],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const role of roles) {
|
||||||
|
for (const [subject, actions] of Object.entries(subjectActionMap)) {
|
||||||
|
// Find the 'manage' permission for the subject
|
||||||
|
const managePermission = await knex('permissions')
|
||||||
|
.where({ role_id: role.id, subject, action: 'manage' })
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if (managePermission) {
|
||||||
|
// Determine if the 'manage' permission has the 'isCreator' condition
|
||||||
|
const hasIsCreatorCondition =
|
||||||
|
managePermission.conditions.includes('isCreator');
|
||||||
|
|
||||||
|
// Delete the 'manage' permission
|
||||||
|
await knex('permissions')
|
||||||
|
.where({ role_id: role.id, subject, action: 'manage' })
|
||||||
|
.del();
|
||||||
|
|
||||||
|
// Restore the original permissions for the subject
|
||||||
|
const restoredPermissions = actions.map((action) => ({
|
||||||
|
role_id: role.id,
|
||||||
|
subject,
|
||||||
|
action,
|
||||||
|
conditions: JSON.stringify(
|
||||||
|
hasIsCreatorCondition ? ['isCreator'] : []
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
await knex('permissions').insert(restoredPermissions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -22,19 +22,19 @@ const authorizationList = {
|
|||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/flows/': {
|
'POST /api/v1/flows/': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'PATCH /api/v1/flows/:flowId': {
|
'PATCH /api/v1/flows/:flowId': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'DELETE /api/v1/flows/:flowId': {
|
'DELETE /api/v1/flows/:flowId': {
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'GET /api/v1/templates/': {
|
'GET /api/v1/templates/': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'GET /api/v1/steps/:stepId/connection': {
|
'GET /api/v1/steps/:stepId/connection': {
|
||||||
@@ -42,23 +42,23 @@ const authorizationList = {
|
|||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'PATCH /api/v1/steps/:stepId': {
|
'PATCH /api/v1/steps/:stepId': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/steps/:stepId/test': {
|
'POST /api/v1/steps/:stepId/test': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'GET /api/v1/steps/:stepId/previous-steps': {
|
'GET /api/v1/steps/:stepId/previous-steps': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/steps/:stepId/dynamic-fields': {
|
'POST /api/v1/steps/:stepId/dynamic-fields': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/steps/:stepId/dynamic-data': {
|
'POST /api/v1/steps/:stepId/dynamic-data': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'GET /api/v1/connections/:connectionId/flows': {
|
'GET /api/v1/connections/:connectionId/flows': {
|
||||||
@@ -66,11 +66,11 @@ const authorizationList = {
|
|||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/connections/:connectionId/test': {
|
'POST /api/v1/connections/:connectionId/test': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'POST /api/v1/connections/:connectionId/verify': {
|
'POST /api/v1/connections/:connectionId/verify': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'GET /api/v1/apps/:appKey/flows': {
|
'GET /api/v1/apps/:appKey/flows': {
|
||||||
@@ -94,59 +94,59 @@ const authorizationList = {
|
|||||||
subject: 'Execution',
|
subject: 'Execution',
|
||||||
},
|
},
|
||||||
'DELETE /api/v1/steps/:stepId': {
|
'DELETE /api/v1/steps/:stepId': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'PATCH /api/v1/connections/:connectionId': {
|
'PATCH /api/v1/connections/:connectionId': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'DELETE /api/v1/connections/:connectionId': {
|
'DELETE /api/v1/connections/:connectionId': {
|
||||||
action: 'delete',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'POST /api/v1/connections/:connectionId/reset': {
|
'POST /api/v1/connections/:connectionId/reset': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'PATCH /api/v1/flows/:flowId/status': {
|
'PATCH /api/v1/flows/:flowId/status': {
|
||||||
action: 'publish',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/flows/:flowId/duplicate': {
|
'POST /api/v1/flows/:flowId/duplicate': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/flows/:flowId/export': {
|
'POST /api/v1/flows/:flowId/export': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/flows/import': {
|
'POST /api/v1/flows/import': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/flows/:flowId/steps': {
|
'POST /api/v1/flows/:flowId/steps': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'POST /api/v1/apps/:appKey/connections': {
|
'POST /api/v1/apps/:appKey/connections': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'POST /api/v1/connections/:connectionId/auth-url': {
|
'POST /api/v1/connections/:connectionId/auth-url': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Connection',
|
subject: 'Connection',
|
||||||
},
|
},
|
||||||
'POST /api/v1/folders/': {
|
'POST /api/v1/folders/': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'PATCH /api/v1/folders/:folderId': {
|
'PATCH /api/v1/folders/:folderId': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'DELETE /api/v1/folders/:folderId': {
|
'DELETE /api/v1/folders/:folderId': {
|
||||||
action: 'create',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'GET /api/v1/folders/': {
|
'GET /api/v1/folders/': {
|
||||||
@@ -154,7 +154,7 @@ const authorizationList = {
|
|||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'PATCH /api/v1/flows/:flowId/folder': {
|
'PATCH /api/v1/flows/:flowId/folder': {
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
},
|
},
|
||||||
'GET /api/v1/flows/:flowId/folder': {
|
'GET /api/v1/flows/:flowId/folder': {
|
||||||
|
|||||||
@@ -17,56 +17,22 @@ const permissionCatalog = {
|
|||||||
conditions: [
|
conditions: [
|
||||||
{
|
{
|
||||||
key: 'isCreator',
|
key: 'isCreator',
|
||||||
label: 'Is creator'
|
label: 'Is creator',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
|
||||||
label: 'Create',
|
|
||||||
key: 'create',
|
|
||||||
subjects: [
|
|
||||||
Connection.key,
|
|
||||||
Flow.key,
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Read',
|
label: 'Read',
|
||||||
key: 'read',
|
key: 'read',
|
||||||
subjects: [
|
subjects: [Connection.key, Execution.key, Flow.key],
|
||||||
Connection.key,
|
|
||||||
Execution.key,
|
|
||||||
Flow.key,
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Update',
|
label: 'Manage',
|
||||||
key: 'update',
|
key: 'manage',
|
||||||
subjects: [
|
subjects: [Connection.key, Flow.key],
|
||||||
Connection.key,
|
|
||||||
Flow.key,
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: 'Delete',
|
|
||||||
key: 'delete',
|
|
||||||
subjects: [
|
|
||||||
Connection.key,
|
|
||||||
Flow.key,
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Publish',
|
|
||||||
key: 'publish',
|
|
||||||
subjects: [
|
|
||||||
Flow.key,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
subjects: [
|
subjects: [Connection, Flow, Execution],
|
||||||
Connection,
|
|
||||||
Flow,
|
|
||||||
Execution
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default permissionCatalog;
|
export default permissionCatalog;
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ describe('Permission model', () => {
|
|||||||
it('filter should return only valid permissions based on permission catalog', () => {
|
it('filter should return only valid permissions based on permission catalog', () => {
|
||||||
const permissions = [
|
const permissions = [
|
||||||
{ action: 'read', subject: 'Flow', conditions: ['isCreator'] },
|
{ action: 'read', subject: 'Flow', conditions: ['isCreator'] },
|
||||||
{ action: 'delete', subject: 'Connection', conditions: [] },
|
{ action: 'manage', subject: 'Connection', conditions: [] },
|
||||||
{ action: 'publish', subject: 'Flow', conditions: ['isCreator'] },
|
{ action: 'manage', subject: 'Flow', conditions: ['isCreator'] },
|
||||||
{ action: 'update', subject: 'Execution', conditions: [] }, // Invalid subject
|
{ action: 'manage', subject: 'Execution', conditions: [] }, // Invalid subject
|
||||||
{ action: 'read', subject: 'Execution', conditions: ['invalid'] }, // Invalid condition
|
{ action: 'manage', subject: 'Execution', conditions: ['invalid'] }, // Invalid condition
|
||||||
{ action: 'invalid', subject: 'Execution', conditions: [] }, // Invalid action
|
{ action: 'invalid', subject: 'Execution', conditions: [] }, // Invalid action
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -25,15 +25,15 @@ describe('Permission model', () => {
|
|||||||
|
|
||||||
expect(result).toStrictEqual([
|
expect(result).toStrictEqual([
|
||||||
{ action: 'read', subject: 'Flow', conditions: ['isCreator'] },
|
{ action: 'read', subject: 'Flow', conditions: ['isCreator'] },
|
||||||
{ action: 'delete', subject: 'Connection', conditions: [] },
|
{ action: 'manage', subject: 'Connection', conditions: [] },
|
||||||
{ action: 'publish', subject: 'Flow', conditions: ['isCreator'] },
|
{ action: 'manage', subject: 'Flow', conditions: ['isCreator'] },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('findAction', () => {
|
describe('findAction', () => {
|
||||||
it('should return action from permission catalog', () => {
|
it('should return action from permission catalog', () => {
|
||||||
const action = Permission.findAction('create');
|
const action = Permission.findAction('manage');
|
||||||
expect(action.key).toStrictEqual('create');
|
expect(action.key).toStrictEqual('manage');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return undefined for invalid actions', () => {
|
it('should return undefined for invalid actions', () => {
|
||||||
@@ -45,7 +45,7 @@ describe('Permission model', () => {
|
|||||||
describe('isSubjectValid', () => {
|
describe('isSubjectValid', () => {
|
||||||
it('should return true for valid subjects', () => {
|
it('should return true for valid subjects', () => {
|
||||||
const validAction = permissionCatalog.actions.find(
|
const validAction = permissionCatalog.actions.find(
|
||||||
(action) => action.key === 'create'
|
(action) => action.key === 'manage'
|
||||||
);
|
);
|
||||||
|
|
||||||
const validSubject = Permission.isSubjectValid('Connection', validAction);
|
const validSubject = Permission.isSubjectValid('Connection', validAction);
|
||||||
@@ -54,7 +54,7 @@ describe('Permission model', () => {
|
|||||||
|
|
||||||
it('should return false for invalid subjects', () => {
|
it('should return false for invalid subjects', () => {
|
||||||
const validAction = permissionCatalog.actions.find(
|
const validAction = permissionCatalog.actions.find(
|
||||||
(action) => action.key === 'create'
|
(action) => action.key === 'manage'
|
||||||
);
|
);
|
||||||
|
|
||||||
const invalidSubject = Permission.isSubjectValid(
|
const invalidSubject = Permission.isSubjectValid(
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ describe('Role model', () => {
|
|||||||
description: 'Updated description',
|
description: 'Updated description',
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
action: 'update',
|
action: 'manage',
|
||||||
subject: 'Flow',
|
subject: 'Flow',
|
||||||
conditions: [],
|
conditions: [],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,31 +1,16 @@
|
|||||||
const getPermissionsCatalogMock = async () => {
|
const getPermissionsCatalogMock = async () => {
|
||||||
const data = {
|
const data = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
|
||||||
key: 'create',
|
|
||||||
label: 'Create',
|
|
||||||
subjects: ['Connection', 'Flow'],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'read',
|
key: 'read',
|
||||||
label: 'Read',
|
label: 'Read',
|
||||||
subjects: ['Connection', 'Execution', 'Flow'],
|
subjects: ['Connection', 'Execution', 'Flow'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'update',
|
key: 'manage',
|
||||||
label: 'Update',
|
label: 'Manage',
|
||||||
subjects: ['Connection', 'Flow'],
|
subjects: ['Connection', 'Flow'],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'delete',
|
|
||||||
label: 'Delete',
|
|
||||||
subjects: ['Connection', 'Flow'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'publish',
|
|
||||||
label: 'Publish',
|
|
||||||
subjects: ['Flow'],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
conditions: [
|
conditions: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,98 +14,22 @@ export class AdminCreateRolePage extends AuthenticatedPage {
|
|||||||
this.nameInput = page.getByTestId('name-input');
|
this.nameInput = page.getByTestId('name-input');
|
||||||
this.descriptionInput = page.getByTestId('description-input');
|
this.descriptionInput = page.getByTestId('description-input');
|
||||||
this.createButton = page.getByTestId('create-button');
|
this.createButton = page.getByTestId('create-button');
|
||||||
this.connectionRow = page.getByTestId('Connection-permission-row');
|
|
||||||
this.executionRow = page.getByTestId('Execution-permission-row');
|
|
||||||
this.flowRow = page.getByTestId('Flow-permission-row');
|
|
||||||
this.pageTitle = page.getByTestId('create-role-title');
|
this.pageTitle = page.getByTestId('create-role-title');
|
||||||
this.permissionsCatalog = page.getByTestId('permissions-catalog');
|
this.permissionsCatalog = page.getByTestId('permissions-catalog');
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
this.connectionPermissionRow = page.getByTestId(
|
||||||
* @param {('Connection'|'Execution'|'Flow')} subject
|
'Connection-permission-row'
|
||||||
*/
|
);
|
||||||
getRoleConditionsModal(subject) {
|
this.flowPermissionRow = page.getByTestId('Flow-permission-row');
|
||||||
return new RoleConditionsModal(this.page, subject);
|
this.executionPermissionRow = page.getByTestId('Execution-permission-row');
|
||||||
}
|
this.isCreatorReadCheckbox = page
|
||||||
|
.getByTestId('isCreator-read-checkbox')
|
||||||
async getPermissionConfigs() {
|
.locator('input');
|
||||||
const subjects = ['Connection', 'Flow', 'Execution'];
|
this.readCheckbox = page.getByTestId('read-checkbox').locator('input');
|
||||||
const permissionConfigs = [];
|
this.isCreatorManageCheckbox = page
|
||||||
for (let subject of subjects) {
|
.getByTestId('isCreator-manage-checkbox')
|
||||||
const row = this.getSubjectRow(subject);
|
.locator('input');
|
||||||
const actionInputs = await this.getRowInputs(row);
|
this.manageCheckbox = page.getByTestId('manage-checkbox').locator('input');
|
||||||
Object.keys(actionInputs).forEach((action) => {
|
|
||||||
permissionConfigs.push({
|
|
||||||
action,
|
|
||||||
locator: actionInputs[action],
|
|
||||||
subject,
|
|
||||||
row,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return permissionConfigs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {(
|
|
||||||
* 'Connection' | 'Flow' | 'Execution'
|
|
||||||
* )} subject
|
|
||||||
*/
|
|
||||||
getSubjectRow(subject) {
|
|
||||||
const k = `${subject.toLowerCase()}Row`;
|
|
||||||
if (this[k]) {
|
|
||||||
return this[k];
|
|
||||||
} else {
|
|
||||||
throw 'Unknown row';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {import('@playwright/test').Locator} row
|
|
||||||
*/
|
|
||||||
async getRowInputs(row) {
|
|
||||||
const inputs = {
|
|
||||||
// settingsButton: row.getByTestId('permission-settings-button')
|
|
||||||
};
|
|
||||||
for (let input of ['create', 'read', 'update', 'delete', 'publish']) {
|
|
||||||
const testId = `${input}-checkbox`;
|
|
||||||
if ((await row.getByTestId(testId).count()) > 0) {
|
|
||||||
inputs[input] = row.getByTestId(testId).locator('input');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inputs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {import('@playwright/test').Locator} row
|
|
||||||
*/
|
|
||||||
async clickPermissionSettings(row) {
|
|
||||||
await row.getByTestId('permission-settings-button').click();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} subject
|
|
||||||
* @param {'create'|'read'|'update'|'delete'|'publish'} action
|
|
||||||
* @param {boolean} val
|
|
||||||
*/
|
|
||||||
async updateAction(subject, action, val) {
|
|
||||||
const row = await this.getSubjectRow(subject);
|
|
||||||
const inputs = await this.getRowInputs(row);
|
|
||||||
if (inputs[action]) {
|
|
||||||
if (await inputs[action].isChecked()) {
|
|
||||||
if (!val) {
|
|
||||||
await inputs[action].click();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (val) {
|
|
||||||
await inputs[action].click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(`${subject} does not have action ${action}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForPermissionsCatalogToVisible() {
|
async waitForPermissionsCatalogToVisible() {
|
||||||
|
|||||||
@@ -1,69 +1,55 @@
|
|||||||
const { test, expect } = require('../../fixtures/index');
|
const { test, expect } = require('../../fixtures/index');
|
||||||
|
|
||||||
test(
|
test('Check Own permissions when All are checked', async ({
|
||||||
'Role permissions conform with role conditions ',
|
adminRolesPage,
|
||||||
async({ adminRolesPage, adminCreateRolePage }) => {
|
adminCreateRolePage,
|
||||||
await adminRolesPage.navigateTo();
|
}) => {
|
||||||
await adminRolesPage.createRoleButton.click();
|
await adminRolesPage.navigateTo();
|
||||||
|
await adminRolesPage.createRoleButton.click();
|
||||||
|
await adminCreateRolePage.waitForPermissionsCatalogToVisible();
|
||||||
|
|
||||||
/*
|
await adminCreateRolePage.connectionPermissionRow
|
||||||
example config: {
|
.locator(adminCreateRolePage.readCheckbox)
|
||||||
action: 'read',
|
.check();
|
||||||
subject: 'connection',
|
await expect(
|
||||||
row: page.getByTestId('connection-permission-row'),
|
adminCreateRolePage.connectionPermissionRow.locator(
|
||||||
locator: row.getByTestId('read-checkbox')
|
adminCreateRolePage.isCreatorReadCheckbox
|
||||||
}
|
)
|
||||||
*/
|
).toBeChecked();
|
||||||
const permissionConfigs =
|
|
||||||
await adminCreateRolePage.getPermissionConfigs();
|
|
||||||
|
|
||||||
await test.step(
|
await adminCreateRolePage.flowPermissionRow
|
||||||
'Iterate over each permission config and make sure role conditions conform',
|
.locator(adminCreateRolePage.readCheckbox)
|
||||||
async () => {
|
.check();
|
||||||
for (let config of permissionConfigs) {
|
await expect(
|
||||||
await config.locator.click();
|
adminCreateRolePage.flowPermissionRow.locator(
|
||||||
await adminCreateRolePage.clickPermissionSettings(config.row);
|
adminCreateRolePage.isCreatorReadCheckbox
|
||||||
const modal = adminCreateRolePage.getRoleConditionsModal(
|
)
|
||||||
config.subject
|
).toBeChecked();
|
||||||
);
|
|
||||||
await expect(modal.modal).toBeVisible();
|
|
||||||
const conditions = await modal.getAvailableConditions();
|
|
||||||
for (let conditionAction of Object.keys(conditions)) {
|
|
||||||
if (conditionAction === config.action) {
|
|
||||||
await expect(conditions[conditionAction]).not.toBeDisabled();
|
|
||||||
} else {
|
|
||||||
await expect(conditions[conditionAction]).toBeDisabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await modal.close();
|
|
||||||
await config.locator.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
test(
|
await adminCreateRolePage.executionPermissionRow
|
||||||
'Default role permissions conforms with role conditions',
|
.locator(adminCreateRolePage.readCheckbox)
|
||||||
async({ adminRolesPage, adminCreateRolePage }) => {
|
.check();
|
||||||
await adminRolesPage.navigateTo();
|
await expect(
|
||||||
await adminRolesPage.createRoleButton.click();
|
adminCreateRolePage.executionPermissionRow.locator(
|
||||||
|
adminCreateRolePage.isCreatorReadCheckbox
|
||||||
|
)
|
||||||
|
).toBeChecked();
|
||||||
|
|
||||||
const subjects = ['Connection', 'Execution', 'Flow'];
|
await adminCreateRolePage.connectionPermissionRow
|
||||||
for (let subject of subjects) {
|
.locator(adminCreateRolePage.manageCheckbox)
|
||||||
const row = adminCreateRolePage.getSubjectRow(subject);
|
.check();
|
||||||
const modal = adminCreateRolePage.getRoleConditionsModal(subject);
|
await expect(
|
||||||
await adminCreateRolePage.clickPermissionSettings(row);
|
adminCreateRolePage.connectionPermissionRow.locator(
|
||||||
await expect(modal.modal).toBeVisible();
|
adminCreateRolePage.isCreatorManageCheckbox
|
||||||
const availableConditions = await modal.getAvailableConditions();
|
)
|
||||||
const conditions = ['create', 'read', 'update', 'delete', 'publish'];
|
).toBeChecked();
|
||||||
for (let condition of conditions) {
|
|
||||||
if (availableConditions[condition]) {
|
|
||||||
await expect(availableConditions[condition]).toBeDisabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await modal.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
await adminCreateRolePage.flowPermissionRow
|
||||||
);
|
.locator(adminCreateRolePage.manageCheckbox)
|
||||||
|
.check();
|
||||||
|
await expect(
|
||||||
|
adminCreateRolePage.flowPermissionRow.locator(
|
||||||
|
adminCreateRolePage.isCreatorManageCheckbox
|
||||||
|
)
|
||||||
|
).toBeChecked();
|
||||||
|
});
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={URLS.CREATE_USER}
|
path={URLS.CREATE_USER}
|
||||||
element={
|
element={
|
||||||
<Can I="create" a="User">
|
<Can I="manage" a="User">
|
||||||
<CreateUser />
|
<CreateUser />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={URLS.USER_PATTERN}
|
path={URLS.USER_PATTERN}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="User">
|
<Can I="manage" a="User">
|
||||||
<EditUser />
|
<EditUser />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={URLS.CREATE_ROLE}
|
path={URLS.CREATE_ROLE}
|
||||||
element={
|
element={
|
||||||
<Can I="create" a="Role">
|
<Can I="manage" a="Role">
|
||||||
<CreateRole />
|
<CreateRole />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={URLS.ROLE_PATTERN}
|
path={URLS.ROLE_PATTERN}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="Role">
|
<Can I="manage" a="Role">
|
||||||
<EditRole />
|
<EditRole />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={URLS.USER_INTERFACE}
|
path={URLS.USER_INTERFACE}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="Config">
|
<Can I="manage" a="Config">
|
||||||
<UserInterface />
|
<UserInterface />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -86,8 +86,8 @@ export default (
|
|||||||
path={URLS.AUTHENTICATION}
|
path={URLS.AUTHENTICATION}
|
||||||
element={
|
element={
|
||||||
<Can I="read" a="SamlAuthProvider">
|
<Can I="read" a="SamlAuthProvider">
|
||||||
<Can I="update" a="SamlAuthProvider">
|
<Can I="manage" a="SamlAuthProvider">
|
||||||
<Can I="create" a="SamlAuthProvider">
|
<Can I="manage" a="SamlAuthProvider">
|
||||||
<Authentication />
|
<Authentication />
|
||||||
</Can>
|
</Can>
|
||||||
</Can>
|
</Can>
|
||||||
@@ -98,7 +98,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={URLS.ADMIN_APPS}
|
path={URLS.ADMIN_APPS}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="App">
|
<Can I="manage" a="App">
|
||||||
<AdminApplications />
|
<AdminApplications />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.ADMIN_APP_PATTERN}/*`}
|
path={`${URLS.ADMIN_APP_PATTERN}/*`}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="App">
|
<Can I="manage" a="App">
|
||||||
<AdminApplication />
|
<AdminApplication />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.ADMIN_TEMPLATES}/*`}
|
path={`${URLS.ADMIN_TEMPLATES}/*`}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="Config">
|
<Can I="manage" a="Config">
|
||||||
<AdminTemplates />
|
<AdminTemplates />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.ADMIN_CREATE_TEMPLATE_PATTERN}/*`}
|
path={`${URLS.ADMIN_CREATE_TEMPLATE_PATTERN}/*`}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="Config">
|
<Can I="manage" a="Config">
|
||||||
<AdminCreateTemplate />
|
<AdminCreateTemplate />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ export default (
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.ADMIN_UPDATE_TEMPLATE_PATTERN}/*`}
|
path={`${URLS.ADMIN_UPDATE_TEMPLATE_PATTERN}/*`}
|
||||||
element={
|
element={
|
||||||
<Can I="update" a="Config">
|
<Can I="manage" a="Config">
|
||||||
<AdminUpdateTemplate />
|
<AdminUpdateTemplate />
|
||||||
</Can>
|
</Can>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,15 +93,15 @@ function SettingsLayout() {
|
|||||||
const closeDrawer = () => setDrawerOpen(false);
|
const closeDrawer = () => setDrawerOpen(false);
|
||||||
|
|
||||||
const drawerLinks = createDrawerLinks({
|
const drawerLinks = createDrawerLinks({
|
||||||
canCreateFlows: currentUserAbility.can('create', 'Flow'),
|
canCreateFlows: currentUserAbility.can('manage', 'Flow'),
|
||||||
canReadUser: currentUserAbility.can('read', 'User'),
|
canReadUser: currentUserAbility.can('read', 'User'),
|
||||||
canReadRole: currentUserAbility.can('read', 'Role'),
|
canReadRole: currentUserAbility.can('read', 'Role'),
|
||||||
canUpdateConfig: currentUserAbility.can('update', 'Config'),
|
canUpdateConfig: currentUserAbility.can('manage', 'Config'),
|
||||||
canManageSamlAuthProvider:
|
canManageSamlAuthProvider: currentUserAbility.can(
|
||||||
currentUserAbility.can('read', 'SamlAuthProvider') &&
|
'manage',
|
||||||
currentUserAbility.can('update', 'SamlAuthProvider') &&
|
'SamlAuthProvider',
|
||||||
currentUserAbility.can('create', 'SamlAuthProvider'),
|
),
|
||||||
canUpdateApp: currentUserAbility.can('update', 'App'),
|
canUpdateApp: currentUserAbility.can('manage', 'App'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const drawerBottomLinks = [
|
const drawerBottomLinks = [
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function AdminTemplateContextMenu(props) {
|
|||||||
hideBackdrop={false}
|
hideBackdrop={false}
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
>
|
>
|
||||||
<Can I="delete" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem disabled={!allowed} onClick={onTemplateDelete}>
|
<MenuItem disabled={!allowed} onClick={onTemplateDelete}>
|
||||||
{formatMessage('adminTemplateContextMenu.delete')}
|
{formatMessage('adminTemplateContextMenu.delete')}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ function ContextMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
<Can I="update" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={createActionHandler({ type: 'test' })}
|
onClick={createActionHandler({ type: 'test' })}
|
||||||
@@ -62,7 +62,7 @@ function ContextMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
<Can I="create" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
component={Link}
|
component={Link}
|
||||||
@@ -79,7 +79,7 @@ function ContextMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
<Can I="delete" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={createActionHandler({ type: 'delete' })}
|
onClick={createActionHandler({ type: 'delete' })}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function AppConnections(props) {
|
|||||||
|
|
||||||
if (!hasConnections) {
|
if (!hasConnections) {
|
||||||
return (
|
return (
|
||||||
<Can I="create" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<NoResultFound
|
<NoResultFound
|
||||||
text={formatMessage('app.noConnections')}
|
text={formatMessage('app.noConnections')}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function AppFlows(props) {
|
|||||||
|
|
||||||
if (!hasFlows) {
|
if (!hasFlows) {
|
||||||
return (
|
return (
|
||||||
<Can I="create" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<NoResultFound
|
<NoResultFound
|
||||||
text={formatMessage('app.noFlows')}
|
text={formatMessage('app.noFlows')}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function DeleteRoleButton(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Can I="delete" a="Role" passThrough>
|
<Can I="manage" a="Role" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={!allowed || disabled}
|
disabled={!allowed || disabled}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default function EditorLayout() {
|
|||||||
)}
|
)}
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
<Can I="publish" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<Button
|
<Button
|
||||||
disabled={!allowed || !flow}
|
disabled={!allowed || !flow}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ function ContextMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
<Can I="create" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem disabled={!allowed} onClick={onFlowDuplicate}>
|
<MenuItem disabled={!allowed} onClick={onFlowDuplicate}>
|
||||||
{formatMessage('flow.duplicate')}
|
{formatMessage('flow.duplicate')}
|
||||||
@@ -139,7 +139,7 @@ function ContextMenu(props) {
|
|||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
{isCurrentUserAdmin && (
|
{isCurrentUserAdmin && (
|
||||||
<Can I="create" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem disabled={!allowed} onClick={onCreateTemplate}>
|
<MenuItem disabled={!allowed} onClick={onCreateTemplate}>
|
||||||
{formatMessage('flow.createTemplateFromFlow')}
|
{formatMessage('flow.createTemplateFromFlow')}
|
||||||
@@ -148,7 +148,7 @@ function ContextMenu(props) {
|
|||||||
</Can>
|
</Can>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Can I="update" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem disabled={!allowed} onClick={onFlowFolderUpdate}>
|
<MenuItem disabled={!allowed} onClick={onFlowFolderUpdate}>
|
||||||
{formatMessage('flow.moveTo')}
|
{formatMessage('flow.moveTo')}
|
||||||
@@ -164,7 +164,7 @@ function ContextMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
<Can I="delete" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<MenuItem disabled={!allowed} onClick={onFlowDelete}>
|
<MenuItem disabled={!allowed} onClick={onFlowDelete}>
|
||||||
{formatMessage('flow.delete')}
|
{formatMessage('flow.delete')}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function FlowsButtons() {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { data: config } = useAutomatischConfig();
|
const { data: config } = useAutomatischConfig();
|
||||||
const matchSmallScreens = useMediaQuery(theme.breakpoints.down('md'));
|
const matchSmallScreens = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
const canCreateFlow = currentUserAbility.can('create', 'Flow');
|
const canCreateFlow = currentUserAbility.can('manage', 'Flow');
|
||||||
const enableTemplates = config?.data.enableTemplates === true;
|
const enableTemplates = config?.data.enableTemplates === true;
|
||||||
|
|
||||||
const createFlowButtonData = {
|
const createFlowButtonData = {
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import ControlledCheckbox from 'components/ControlledCheckbox';
|
|
||||||
|
|
||||||
const ActionField = ({ action, subject, disabled, name, syncIsCreator }) => {
|
|
||||||
const { formState, resetField } = useFormContext();
|
|
||||||
|
|
||||||
const actionDefaultValue =
|
|
||||||
formState.defaultValues?.[name]?.[subject.key]?.[action.key].value;
|
|
||||||
const conditionFieldName = `${name}.${subject.key}.${action.key}.conditions.isCreator`;
|
|
||||||
const conditionFieldTouched =
|
|
||||||
formState.touchedFields?.[name]?.[subject.key]?.[action.key]?.conditions
|
|
||||||
?.isCreator === true;
|
|
||||||
|
|
||||||
const handleSyncIsCreator = (newValue) => {
|
|
||||||
if (
|
|
||||||
syncIsCreator &&
|
|
||||||
actionDefaultValue === false &&
|
|
||||||
!conditionFieldTouched
|
|
||||||
) {
|
|
||||||
resetField(conditionFieldName, { defaultValue: newValue });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ControlledCheckbox
|
|
||||||
disabled={disabled}
|
|
||||||
name={`${name}.${subject.key}.${action.key}.value`}
|
|
||||||
dataTest={`${action.key.toLowerCase()}-checkbox`}
|
|
||||||
onChange={(e, value) => {
|
|
||||||
handleSyncIsCreator(value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
ActionField.propTypes = {
|
|
||||||
action: PropTypes.shape({
|
|
||||||
key: PropTypes.string.isRequired,
|
|
||||||
subjects: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
||||||
}),
|
|
||||||
subject: PropTypes.shape({
|
|
||||||
key: PropTypes.string.isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
disabled: PropTypes.bool,
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
syncIsCreator: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ActionField;
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useFormContext } from 'react-hook-form';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||||
|
|
||||||
|
const AllEntitiesPermissions = ({
|
||||||
|
action,
|
||||||
|
subject,
|
||||||
|
disabled,
|
||||||
|
name,
|
||||||
|
syncIsCreator,
|
||||||
|
}) => {
|
||||||
|
const { getValues, formState, resetField } = useFormContext();
|
||||||
|
|
||||||
|
const fieldName = `${name}.${subject.key}.${action.key}.allEntities`;
|
||||||
|
const defaultValue =
|
||||||
|
formState.defaultValues?.[name]?.[subject.key]?.[action.key].allEntities;
|
||||||
|
const ownEntitiesFieldName = `${name}.${subject.key}.${action.key}.ownEntities`;
|
||||||
|
const ownEntitiesFieldTouched =
|
||||||
|
formState.touchedFields?.[name]?.[subject.key]?.[action.key]
|
||||||
|
?.ownEntities === true;
|
||||||
|
|
||||||
|
const currentValue = getValues(fieldName);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (currentValue === true) {
|
||||||
|
resetField(ownEntitiesFieldName, { defaultValue: true });
|
||||||
|
}
|
||||||
|
}, [ownEntitiesFieldName, currentValue]);
|
||||||
|
|
||||||
|
const handleSyncIsCreator = (newValue) => {
|
||||||
|
if (syncIsCreator && defaultValue === false && !ownEntitiesFieldTouched) {
|
||||||
|
resetField(ownEntitiesFieldName, { defaultValue: newValue });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newValue === true) {
|
||||||
|
resetField(ownEntitiesFieldName, { defaultValue: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ControlledCheckbox
|
||||||
|
disabled={disabled}
|
||||||
|
name={fieldName}
|
||||||
|
dataTest={`${action.key.toLowerCase()}-checkbox`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
AllEntitiesPermissions.propTypes = {
|
||||||
|
action: PropTypes.shape({
|
||||||
|
key: PropTypes.string.isRequired,
|
||||||
|
subjects: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
}),
|
||||||
|
subject: PropTypes.shape({
|
||||||
|
key: PropTypes.string.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
syncIsCreator: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AllEntitiesPermissions;
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useFormContext } from 'react-hook-form';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||||
|
|
||||||
|
const OwnEntitiesPermission = ({ action, subject, disabled, name }) => {
|
||||||
|
const { getValues, resetField } = useFormContext();
|
||||||
|
|
||||||
|
const fieldName = `${name}.${subject.key}.${action.key}.ownEntities`;
|
||||||
|
const allEntitiesFieldName = `${name}.${subject.key}.${action.key}.allEntities`;
|
||||||
|
|
||||||
|
const currentValue = getValues(fieldName);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (currentValue === false) {
|
||||||
|
resetField(allEntitiesFieldName, { defaultValue: false });
|
||||||
|
}
|
||||||
|
}, [allEntitiesFieldName, currentValue]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ControlledCheckbox
|
||||||
|
name={fieldName}
|
||||||
|
disabled={disabled}
|
||||||
|
dataTest={`isCreator-${action.key.toLowerCase()}-checkbox`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
OwnEntitiesPermission.propTypes = {
|
||||||
|
action: PropTypes.shape({
|
||||||
|
key: PropTypes.string.isRequired,
|
||||||
|
subjects: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
}),
|
||||||
|
subject: PropTypes.shape({
|
||||||
|
key: PropTypes.string.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OwnEntitiesPermission;
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
IconButton,
|
|
||||||
Skeleton,
|
Skeleton,
|
||||||
Stack,
|
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
@@ -10,7 +8,6 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
|
||||||
|
|
||||||
import ControlledCheckbox from 'components/ControlledCheckbox';
|
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||||
|
|
||||||
@@ -21,7 +18,7 @@ const PermissionCatalogFieldLoader = () => {
|
|||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell component="th" />
|
<TableCell component="th" />
|
||||||
{[...Array(5)].map((row, index) => (
|
{[...Array(4)].map((row, index) => (
|
||||||
<TableCell key={index} component="th">
|
<TableCell key={index} component="th">
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -30,27 +27,26 @@ const PermissionCatalogFieldLoader = () => {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{[...Array(3)].map((row, index) => (
|
{[...Array(3)].map((row, subjectIndex) => (
|
||||||
<TableRow key={index} sx={{ '&:last-child td': { border: 0 } }}>
|
<TableRow
|
||||||
|
key={subjectIndex}
|
||||||
|
sx={{ '&:last-child td': { border: 0 } }}
|
||||||
|
>
|
||||||
<TableCell scope="row">
|
<TableCell scope="row">
|
||||||
<Skeleton width={40} />
|
<Skeleton width={40} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
{[...Array(5)].map((action, index) => (
|
{[...Array(4)].map(
|
||||||
<TableCell key={index} align="center">
|
(action, actionIndex) =>
|
||||||
<Typography variant="subtitle2">
|
(subjectIndex !== 2 ||
|
||||||
<ControlledCheckbox name="value" disabled />
|
(actionIndex !== 3 && actionIndex !== 2)) && (
|
||||||
</Typography>
|
<TableCell key={actionIndex} align="center">
|
||||||
</TableCell>
|
<Typography variant="subtitle2">
|
||||||
))}
|
<ControlledCheckbox name="value" disabled />
|
||||||
|
</Typography>
|
||||||
<TableCell>
|
</TableCell>
|
||||||
<Stack direction="row" gap={1} justifyContent="right">
|
),
|
||||||
<IconButton color="info" size="small" disabled>
|
)}
|
||||||
<SettingsIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
|
||||||
import IconButton from '@mui/material/IconButton';
|
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import Stack from '@mui/material/Stack';
|
|
||||||
import Table from '@mui/material/Table';
|
import Table from '@mui/material/Table';
|
||||||
import TableBody from '@mui/material/TableBody';
|
import TableBody from '@mui/material/TableBody';
|
||||||
import TableCell from '@mui/material/TableCell';
|
import TableCell from '@mui/material/TableCell';
|
||||||
@@ -10,12 +6,14 @@ import TableContainer from '@mui/material/TableContainer';
|
|||||||
import TableHead from '@mui/material/TableHead';
|
import TableHead from '@mui/material/TableHead';
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import usePermissionCatalog from 'hooks/usePermissionCatalog.ee';
|
import usePermissionCatalog from 'hooks/usePermissionCatalog.ee';
|
||||||
import PermissionSettings from './PermissionSettings.ee';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
import AllEntitiesPermissions from './AllEntitiesPermissions';
|
||||||
|
import ConditionField from './OwnEntitiesPermission';
|
||||||
import PermissionCatalogFieldLoader from './PermissionCatalogFieldLoader';
|
import PermissionCatalogFieldLoader from './PermissionCatalogFieldLoader';
|
||||||
import ActionField from './ActionField';
|
|
||||||
|
|
||||||
const PermissionCatalogField = ({
|
const PermissionCatalogField = ({
|
||||||
name = 'permissions',
|
name = 'permissions',
|
||||||
@@ -23,10 +21,10 @@ const PermissionCatalogField = ({
|
|||||||
syncIsCreator = false,
|
syncIsCreator = false,
|
||||||
loading = false,
|
loading = false,
|
||||||
}) => {
|
}) => {
|
||||||
|
const formatMessage = useFormatMessage();
|
||||||
const { data, isLoading: isPermissionCatalogLoading } =
|
const { data, isLoading: isPermissionCatalogLoading } =
|
||||||
usePermissionCatalog();
|
usePermissionCatalog();
|
||||||
const permissionCatalog = data?.data;
|
const permissionCatalog = data?.data;
|
||||||
const [dialogName, setDialogName] = React.useState();
|
|
||||||
|
|
||||||
if (isPermissionCatalogLoading || loading)
|
if (isPermissionCatalogLoading || loading)
|
||||||
return <PermissionCatalogFieldLoader />;
|
return <PermissionCatalogFieldLoader />;
|
||||||
@@ -39,24 +37,44 @@ const PermissionCatalogField = ({
|
|||||||
<TableCell component="th" />
|
<TableCell component="th" />
|
||||||
|
|
||||||
{permissionCatalog?.actions.map((action) => (
|
{permissionCatalog?.actions.map((action) => (
|
||||||
<TableCell component="th" key={action.key}>
|
<React.Fragment key={action.key}>
|
||||||
<Typography
|
<TableCell component="th" key={action.key}>
|
||||||
component="div"
|
<Typography
|
||||||
variant="subtitle1"
|
component="div"
|
||||||
align="center"
|
variant="subtitle2"
|
||||||
sx={{
|
align="center"
|
||||||
color: 'text.secondary',
|
sx={{
|
||||||
fontWeight: 700,
|
color: 'text.secondary',
|
||||||
}}
|
fontWeight: 700,
|
||||||
>
|
}}
|
||||||
{action.label}
|
>
|
||||||
</Typography>
|
{action.label}{' '}
|
||||||
</TableCell>
|
{formatMessage('permissionCatalogField.ownEntitiesLabel')}
|
||||||
))}
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<TableCell component="th" />
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
key={`${action.key}-isCreator-condition`}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
component="div"
|
||||||
|
variant="subtitle2"
|
||||||
|
align="center"
|
||||||
|
sx={{
|
||||||
|
color: 'text.secondary',
|
||||||
|
fontWeight: 700,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{action.label}{' '}
|
||||||
|
{formatMessage('permissionCatalogField.allEntitiesLabel')}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{permissionCatalog?.subjects.map((subject) => (
|
{permissionCatalog?.subjects.map((subject) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
@@ -71,44 +89,43 @@ const PermissionCatalogField = ({
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
{permissionCatalog?.actions.map((action) => (
|
{permissionCatalog?.actions.map((action) => (
|
||||||
<TableCell key={`${subject.key}.${action.key}`} align="center">
|
<React.Fragment key={`${subject.key}.${action.key}`}>
|
||||||
<Typography variant="subtitle2" component="div">
|
<TableCell
|
||||||
{action.subjects.includes(subject.key) && (
|
key={`${subject.key}.${action.key}-isCreator-condition`}
|
||||||
<ActionField
|
align="center"
|
||||||
action={action}
|
|
||||||
subject={subject}
|
|
||||||
disabled={disabled}
|
|
||||||
name={name}
|
|
||||||
syncIsCreator={syncIsCreator}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!action.subjects.includes(subject.key) && '-'}
|
|
||||||
</Typography>
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<TableCell>
|
|
||||||
<Stack direction="row" gap={1} justifyContent="right">
|
|
||||||
<IconButton
|
|
||||||
color="info"
|
|
||||||
size="small"
|
|
||||||
onClick={() => setDialogName(subject.key)}
|
|
||||||
disabled={disabled}
|
|
||||||
data-test="permission-settings-button"
|
|
||||||
>
|
>
|
||||||
<SettingsIcon />
|
<Typography variant="subtitle2" component="div">
|
||||||
</IconButton>
|
{action.subjects.includes(subject.key) && (
|
||||||
|
<ConditionField
|
||||||
|
action={action}
|
||||||
|
subject={subject}
|
||||||
|
disabled={disabled}
|
||||||
|
name={name}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!action.subjects.includes(subject.key) && '-'}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<PermissionSettings
|
<TableCell
|
||||||
open={dialogName === subject.key}
|
key={`${subject.key}.${action.key}`}
|
||||||
onClose={() => setDialogName('')}
|
align="center"
|
||||||
fieldPrefix={`${name}.${subject.key}`}
|
>
|
||||||
subject={subject.key}
|
<Typography variant="subtitle2" component="div">
|
||||||
actions={permissionCatalog?.actions}
|
{action.subjects.includes(subject.key) && (
|
||||||
conditions={permissionCatalog?.conditions}
|
<AllEntitiesPermissions
|
||||||
/>
|
action={action}
|
||||||
</Stack>
|
subject={subject}
|
||||||
</TableCell>
|
disabled={disabled}
|
||||||
|
name={name}
|
||||||
|
syncIsCreator={syncIsCreator}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!action.subjects.includes(subject.key) && '-'}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
@@ -116,6 +133,7 @@ const PermissionCatalogField = ({
|
|||||||
</TableContainer>
|
</TableContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
PermissionCatalogField.propTypes = {
|
PermissionCatalogField.propTypes = {
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ export function getRoleWithComputedPermissions(role) {
|
|||||||
[permission.subject]: {
|
[permission.subject]: {
|
||||||
...(computedPermissions[permission.subject] || {}),
|
...(computedPermissions[permission.subject] || {}),
|
||||||
[permission.action]: {
|
[permission.action]: {
|
||||||
conditions: Object.fromEntries(
|
allEntities: permission.conditions.includes('isCreator') === false,
|
||||||
permission.conditions.map((condition) => [condition, true]),
|
ownEntities: true,
|
||||||
),
|
|
||||||
value: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -28,15 +26,19 @@ export function getPermissions(computedPermissions) {
|
|||||||
(permissions, computedPermissionEntry) => {
|
(permissions, computedPermissionEntry) => {
|
||||||
const [subject, actionsWithConditions] = computedPermissionEntry;
|
const [subject, actionsWithConditions] = computedPermissionEntry;
|
||||||
for (const action in actionsWithConditions) {
|
for (const action in actionsWithConditions) {
|
||||||
const { value: permitted, conditions = {} } =
|
const { ownEntities, allEntities } = actionsWithConditions[action];
|
||||||
actionsWithConditions[action];
|
|
||||||
if (permitted) {
|
if (ownEntities && !allEntities) {
|
||||||
permissions.push({
|
permissions.push({
|
||||||
action,
|
action,
|
||||||
subject,
|
subject,
|
||||||
conditions: Object.entries(conditions)
|
conditions: ['isCreator'],
|
||||||
.filter(([, enabled]) => enabled)
|
});
|
||||||
.map(([condition]) => condition),
|
} else if (ownEntities && allEntities) {
|
||||||
|
permissions.push({
|
||||||
|
action,
|
||||||
|
subject,
|
||||||
|
conditions: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,18 +48,9 @@ export function getPermissions(computedPermissions) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getComputedPermissionsDefaultValues = (
|
export const getComputedPermissionsDefaultValues = (data) => {
|
||||||
data,
|
|
||||||
conditionsInitialValues,
|
|
||||||
) => {
|
|
||||||
if (!data) return {};
|
if (!data) return {};
|
||||||
|
|
||||||
const conditions = {};
|
|
||||||
data.conditions.forEach((condition) => {
|
|
||||||
conditions[condition.key] =
|
|
||||||
conditionsInitialValues?.[condition.key] || false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = {};
|
const result = {};
|
||||||
|
|
||||||
data.subjects.forEach((subject) => {
|
data.subjects.forEach((subject) => {
|
||||||
@@ -69,8 +62,8 @@ export const getComputedPermissionsDefaultValues = (
|
|||||||
|
|
||||||
if (action.subjects.includes(subjectKey)) {
|
if (action.subjects.includes(subjectKey)) {
|
||||||
result[subjectKey][actionKey] = {
|
result[subjectKey][actionKey] = {
|
||||||
value: false,
|
ownEntities: false,
|
||||||
conditions: { ...conditions },
|
allEntities: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -403,5 +403,7 @@
|
|||||||
"executionFilters.statusFilterSuccessfulOption": "Successful",
|
"executionFilters.statusFilterSuccessfulOption": "Successful",
|
||||||
"executionFilters.statusFilterFailedOption": "Failed",
|
"executionFilters.statusFilterFailedOption": "Failed",
|
||||||
"executionFilters.startDateLabel": "Start Date",
|
"executionFilters.startDateLabel": "Start Date",
|
||||||
"executionFilters.endDateLabel": "End Date"
|
"executionFilters.endDateLabel": "End Date",
|
||||||
|
"permissionCatalogField.ownEntitiesLabel": "(own entities)",
|
||||||
|
"permissionCatalogField.allEntitiesLabel": "(all entities)"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default function Application() {
|
|||||||
'data-test': 'add-connection-button',
|
'data-test': 'add-connection-button',
|
||||||
to: URLS.APP_ADD_CONNECTION(appKey, false),
|
to: URLS.APP_ADD_CONNECTION(appKey, false),
|
||||||
disabled:
|
disabled:
|
||||||
!currentUserAbility.can('create', 'Connection') ||
|
!currentUserAbility.can('manage', 'Connection') ||
|
||||||
appConfig?.data?.useOnlyPredefinedAuthClients === true ||
|
appConfig?.data?.useOnlyPredefinedAuthClients === true ||
|
||||||
appConfig?.data?.disabled === true,
|
appConfig?.data?.disabled === true,
|
||||||
};
|
};
|
||||||
@@ -92,7 +92,7 @@ export default function Application() {
|
|||||||
'data-test': 'add-connection-with-auth-client-button',
|
'data-test': 'add-connection-with-auth-client-button',
|
||||||
to: URLS.APP_ADD_CONNECTION(appKey, true),
|
to: URLS.APP_ADD_CONNECTION(appKey, true),
|
||||||
disabled:
|
disabled:
|
||||||
!currentUserAbility.can('create', 'Connection') ||
|
!currentUserAbility.can('manage', 'Connection') ||
|
||||||
appOAuthClients?.data?.length === 0 ||
|
appOAuthClients?.data?.length === 0 ||
|
||||||
appConfig?.data?.disabled === true,
|
appConfig?.data?.disabled === true,
|
||||||
};
|
};
|
||||||
@@ -139,7 +139,7 @@ export default function Application() {
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.FLOWS}/*`}
|
path={`${URLS.FLOWS}/*`}
|
||||||
element={
|
element={
|
||||||
<Can I="create" a="Flow" passThrough>
|
<Can I="manage" a="Flow" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<ConditionalIconButton
|
<ConditionalIconButton
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -162,7 +162,7 @@ export default function Application() {
|
|||||||
<Route
|
<Route
|
||||||
path={`${URLS.CONNECTIONS}/*`}
|
path={`${URLS.CONNECTIONS}/*`}
|
||||||
element={
|
element={
|
||||||
<Can I="create" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<SplitButton
|
<SplitButton
|
||||||
disabled={!allowed}
|
disabled={!allowed}
|
||||||
@@ -248,7 +248,7 @@ export default function Application() {
|
|||||||
<Route
|
<Route
|
||||||
path="/connections/add"
|
path="/connections/add"
|
||||||
element={
|
element={
|
||||||
<Can I="create" a="Connection">
|
<Can I="manage" a="Connection">
|
||||||
<AddAppConnection
|
<AddAppConnection
|
||||||
onClose={goToApplicationPage}
|
onClose={goToApplicationPage}
|
||||||
application={app}
|
application={app}
|
||||||
@@ -260,7 +260,7 @@ export default function Application() {
|
|||||||
<Route
|
<Route
|
||||||
path="/connections/:connectionId/reconnect"
|
path="/connections/:connectionId/reconnect"
|
||||||
element={
|
element={
|
||||||
<Can I="create" a="Connection">
|
<Can I="manage" a="Connection">
|
||||||
<ReconnectConnection
|
<ReconnectConnection
|
||||||
application={app}
|
application={app}
|
||||||
onClose={goToApplicationPage}
|
onClose={goToApplicationPage}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default function Applications() {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
order={{ xs: 1, sm: 2 }}
|
order={{ xs: 1, sm: 2 }}
|
||||||
>
|
>
|
||||||
<Can I="create" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<ConditionalIconButton
|
<ConditionalIconButton
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -84,7 +84,7 @@ export default function Applications() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{!isLoading && !hasApps && (
|
{!isLoading && !hasApps && (
|
||||||
<Can I="create" a="Connection" passThrough>
|
<Can I="manage" a="Connection" passThrough>
|
||||||
{(allowed) => (
|
{(allowed) => (
|
||||||
<NoResultFound
|
<NoResultFound
|
||||||
text={formatMessage('apps.noConnections')}
|
text={formatMessage('apps.noConnections')}
|
||||||
|
|||||||
@@ -73,9 +73,6 @@ export default function CreateRole() {
|
|||||||
description: '',
|
description: '',
|
||||||
computedPermissions: getComputedPermissionsDefaultValues(
|
computedPermissions: getComputedPermissionsDefaultValues(
|
||||||
permissionCatalogData?.data,
|
permissionCatalogData?.data,
|
||||||
{
|
|
||||||
isCreator: true,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
[permissionCatalogData],
|
[permissionCatalogData],
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function CreateUser() {
|
|||||||
const roles = rolesData?.data;
|
const roles = rolesData?.data;
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const currentUserAbility = useCurrentUserAbility();
|
const currentUserAbility = useCurrentUserAbility();
|
||||||
const canUpdateRole = currentUserAbility.can('update', 'Role');
|
const canUpdateRole = currentUserAbility.can('manage', 'Role');
|
||||||
|
|
||||||
const handleUserCreation = async (userData) => {
|
const handleUserCreation = async (userData) => {
|
||||||
try {
|
try {
|
||||||
@@ -125,7 +125,7 @@ export default function CreateUser() {
|
|||||||
helperText={errors?.email?.message}
|
helperText={errors?.email?.message}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Can I="update" a="Role">
|
<Can I="manage" a="Role">
|
||||||
<ControlledAutocomplete
|
<ControlledAutocomplete
|
||||||
name="roleId"
|
name="roleId"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export default function EditRole() {
|
|||||||
try {
|
try {
|
||||||
setPermissionError(null);
|
setPermissionError(null);
|
||||||
const newPermissions = getPermissions(roleData.computedPermissions);
|
const newPermissions = getPermissions(roleData.computedPermissions);
|
||||||
|
|
||||||
await updateRole({
|
await updateRole({
|
||||||
name: roleData.name,
|
name: roleData.name,
|
||||||
description: roleData.description,
|
description: roleData.description,
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default function EditUser() {
|
|||||||
const enqueueSnackbar = useEnqueueSnackbar();
|
const enqueueSnackbar = useEnqueueSnackbar();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const currentUserAbility = useCurrentUserAbility();
|
const currentUserAbility = useCurrentUserAbility();
|
||||||
const canUpdateRole = currentUserAbility.can('update', 'Role');
|
const canUpdateRole = currentUserAbility.can('manage', 'Role');
|
||||||
|
|
||||||
const handleUserUpdate = async (userDataToUpdate) => {
|
const handleUserUpdate = async (userDataToUpdate) => {
|
||||||
try {
|
try {
|
||||||
@@ -169,7 +169,7 @@ export default function EditUser() {
|
|||||||
helperText={errors?.email?.message}
|
helperText={errors?.email?.message}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Can I="update" a="Role">
|
<Can I="manage" a="Role">
|
||||||
<ControlledAutocomplete
|
<ControlledAutocomplete
|
||||||
name="roleId"
|
name="roleId"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ export default function Flows() {
|
|||||||
{!isLoading && !navigateToLastPage && !hasFlows && (
|
{!isLoading && !navigateToLastPage && !hasFlows && (
|
||||||
<NoResultFound
|
<NoResultFound
|
||||||
text={formatMessage('flows.noFlows')}
|
text={formatMessage('flows.noFlows')}
|
||||||
{...(currentUserAbility.can('create', 'Flow') && {
|
{...(currentUserAbility.can('manage', 'Flow') && {
|
||||||
to: URLS.CREATE_FLOW,
|
to: URLS.CREATE_FLOW,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user