Files
n8n-enterprise-unlocked/packages/editor-ui/src/permissions.ts
Alex Grozav 898c25fd7e feat: Add workflow sharing functionality and permissions (#4370)
* feat(editor): extract credentials view into reusable layout components for workflows view

* feat(editor): add workflow card and start work on empty state

* feat: add hoverable card and finish workflows empty state

* fix: undo workflows response interface changes

* chore: fix linting issues.

* fix: remove enterprise sharing env schema

* fix(editor): fix workflows resource view when sharing is enabled

* fix: change owner tag design and order

* feat: add personalization survey on workflows page

* fix: update component snapshots

* feat: refactored workflow card to use workflow-activator properly

* fix: fix workflow activator and proptypes

* fix: hide owner tag for workflow card until sharing is available

* fix: fixed ownedBy and sharedWith appearing for workflows list

* feat: update tags component design

* refactor: change resource filter select to n8n-user-select

* fix: made telemetry messages reusable

* chore: remove unused import

* refactor: fix component name casing

* refactor: use Vue.set to make workflow property reactive

* feat: add support for clicking on tags for filtering

* chore: fix tags linting issues

* fix: fix resources list layout when title words are very long

* refactor: add active and inactive status text to workflow activator

* fix: fix credentials and workflows sorting when name contains leading whitespace

* fix: remove wrongfully added style tag

* feat: add translations and storybook examples for truncated tags

* fix: remove enterprise sharing env from schema

* refactor: fix workflows module and workflows field store naming conflict

* feat: add workflow share button and open dummy modal

* feat: add workflow sharing modal (in progress)

* feat: add message when sharing disabled

* feat: add sharing messages based on flags

* feat: add workflow sharing api integration and readonly state handling

* fix: change how foreign credentials are handled

* refactor: migrate newly added workflow sharing store methods to pinia

* fix: update foreign credentials handler and add executable prop to node-settings

* fix: fix credentials display issue caused by addCredentials override

* fix: fix various issues when sharing from empty state

* fix: update node duplication credentials

* fix: revert defautl values for sharing env

* feat: hide share button behind feature flag

* chore: add env variable for sharing feature (testing only)

* fix: change enterprise-edition component casing
2022-11-15 14:25:04 +02:00

93 lines
3.8 KiB
TypeScript

/**
* Permissions table implementation
*
* @usage getCredentialPermissions(user, credential).isOwner;
*/
import {IUser, ICredentialsResponse, IRootState, IWorkflowDb} from "@/Interface";
import {EnterpriseEditionFeature, PLACEHOLDER_EMPTY_WORKFLOW_ID} from "@/constants";
import { useSettingsStore } from "./stores/settings";
export enum UserRole {
InstanceOwner = 'isInstanceOwner',
ResourceOwner = 'isOwner',
ResourceEditor = 'isEditor',
ResourceReader = 'isReader',
}
export type IPermissions = Record<string, boolean>;
type IPermissionsTableRowTestFn = (permissions: IPermissions) => boolean;
export interface IPermissionsTableRow {
name: string;
test: string[] | IPermissionsTableRowTestFn;
}
export type IPermissionsTable = IPermissionsTableRow[];
/**
* Returns the permissions for the given user and resource
*
* @param user
* @param table
*/
export const parsePermissionsTable = (user: IUser | null, table: IPermissionsTable): IPermissions => {
const genericTable = [
{ name: UserRole.InstanceOwner, test: () => user?.isOwner },
];
return [
...genericTable,
...table,
].reduce((permissions: IPermissions, row) => {
permissions[row.name] = Array.isArray(row.test)
? row.test.some((ability) => permissions[ability])
: (row.test as IPermissionsTableRowTestFn)(permissions);
return permissions;
}, {});
};
/**
* User permissions definition
*/
export const getCredentialPermissions = (user: IUser | null, credential: ICredentialsResponse) => {
const settingsStore = useSettingsStore();
const table: IPermissionsTable = [
{ name: UserRole.ResourceOwner, test: () => !!(credential && credential.ownedBy && credential.ownedBy.id === user?.id) || !settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Sharing) },
{ name: UserRole.ResourceReader, test: () => !!(credential && credential.sharedWith && credential.sharedWith.find((sharee) => sharee.id === user?.id)) },
{ name: 'read', test: [UserRole.ResourceOwner, UserRole.InstanceOwner, UserRole.ResourceReader] },
{ name: 'save', test: [UserRole.ResourceOwner, UserRole.InstanceOwner] },
{ name: 'updateName', test: [UserRole.ResourceOwner, UserRole.InstanceOwner] },
{ name: 'updateConnection', test: [UserRole.ResourceOwner] },
{ name: 'updateSharing', test: [UserRole.ResourceOwner] },
{ name: 'updateNodeAccess', test: [UserRole.ResourceOwner] },
{ name: 'delete', test: [UserRole.ResourceOwner, UserRole.InstanceOwner] },
{ name: 'use', test: [UserRole.ResourceOwner, UserRole.ResourceReader] },
];
return parsePermissionsTable(user, table);
};
export const getWorkflowPermissions = (user: IUser | null, workflow: IWorkflowDb) => {
const settingsStore = useSettingsStore();
const isNewWorkflow = workflow.id === PLACEHOLDER_EMPTY_WORKFLOW_ID;
const table: IPermissionsTable = [
{ name: UserRole.ResourceOwner, test: () => !!(isNewWorkflow || workflow && workflow.ownedBy && workflow.ownedBy.id === user?.id) || !settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.WorkflowSharing) },
{ name: UserRole.ResourceReader, test: () => !!(workflow && workflow.sharedWith && workflow.sharedWith.find((sharee) => sharee.id === user?.id)) },
{ name: 'read', test: [UserRole.ResourceOwner, UserRole.InstanceOwner, UserRole.ResourceReader] },
{ name: 'save', test: [UserRole.ResourceOwner, UserRole.InstanceOwner] },
{ name: 'updateName', test: [UserRole.ResourceOwner, UserRole.InstanceOwner] },
{ name: 'updateConnection', test: [UserRole.ResourceOwner] },
{ name: 'updateSharing', test: [UserRole.ResourceOwner] },
{ name: 'updateNodeAccess', test: [UserRole.ResourceOwner] },
{ name: 'delete', test: [UserRole.ResourceOwner, UserRole.InstanceOwner] },
{ name: 'use', test: [UserRole.ResourceOwner, UserRole.ResourceReader] },
];
return parsePermissionsTable(user, table);
};