mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
chore(core): Add custom role management service and endpoints (#18717)
This commit is contained in:
@@ -131,6 +131,8 @@ exports[`Scope Information ensure scopes are defined correctly 1`] = `
|
||||
"workflowTags:update",
|
||||
"workflowTags:list",
|
||||
"workflowTags:*",
|
||||
"role:manage",
|
||||
"role:*",
|
||||
"*",
|
||||
]
|
||||
`;
|
||||
|
||||
@@ -29,6 +29,7 @@ export const RESOURCES = {
|
||||
dataStore: [...DEFAULT_OPERATIONS, 'readRow', 'writeRow', 'listProject'] as const,
|
||||
execution: ['delete', 'read', 'list', 'get'] as const,
|
||||
workflowTags: ['update', 'list'] as const,
|
||||
role: ['manage'] as const,
|
||||
} as const;
|
||||
|
||||
export const API_KEY_RESOURCES = {
|
||||
|
||||
@@ -6,7 +6,7 @@ export * from './scope-information';
|
||||
export * from './roles/role-maps.ee';
|
||||
export * from './roles/all-roles';
|
||||
|
||||
export { projectRoleSchema, teamRoleSchema } from './schemas.ee';
|
||||
export { projectRoleSchema, teamRoleSchema, roleSchema, Role, scopeSchema } from './schemas.ee';
|
||||
|
||||
export { hasScope } from './utilities/has-scope.ee';
|
||||
export { hasGlobalScope } from './utilities/has-global-scope.ee';
|
||||
|
||||
@@ -27,18 +27,27 @@ const ROLE_NAMES: Record<AllRoleTypes, string> = {
|
||||
'workflow:editor': 'Workflow Editor',
|
||||
};
|
||||
|
||||
const mapToRoleObject = <T extends keyof typeof ROLE_NAMES>(roles: Record<T, Scope[]>) =>
|
||||
const mapToRoleObject = <T extends keyof typeof ROLE_NAMES>(
|
||||
roles: Record<T, Scope[]>,
|
||||
roleType: 'global' | 'project' | 'credential' | 'workflow',
|
||||
) =>
|
||||
(Object.keys(roles) as T[]).map((role) => ({
|
||||
role,
|
||||
name: ROLE_NAMES[role],
|
||||
slug: role,
|
||||
displayName: ROLE_NAMES[role],
|
||||
scopes: getRoleScopes(role),
|
||||
description: ROLE_NAMES[role],
|
||||
licensed: false,
|
||||
systemRole: true,
|
||||
roleType,
|
||||
}));
|
||||
|
||||
export const ALL_ROLES: AllRolesMap = {
|
||||
global: mapToRoleObject(GLOBAL_SCOPE_MAP),
|
||||
project: mapToRoleObject(PROJECT_SCOPE_MAP),
|
||||
credential: mapToRoleObject(CREDENTIALS_SHARING_SCOPE_MAP),
|
||||
workflow: mapToRoleObject(WORKFLOW_SHARING_SCOPE_MAP),
|
||||
global: mapToRoleObject(GLOBAL_SCOPE_MAP, 'global'),
|
||||
project: mapToRoleObject(PROJECT_SCOPE_MAP, 'project'),
|
||||
credential: mapToRoleObject(CREDENTIALS_SHARING_SCOPE_MAP, 'credential'),
|
||||
workflow: mapToRoleObject(WORKFLOW_SHARING_SCOPE_MAP, 'workflow'),
|
||||
};
|
||||
|
||||
export const isBuiltInRole = (role: string): role is AllRoleTypes => {
|
||||
return Object.prototype.hasOwnProperty.call(ROLE_NAMES, role);
|
||||
};
|
||||
|
||||
@@ -80,6 +80,7 @@ export const GLOBAL_OWNER_SCOPES: Scope[] = [
|
||||
'folder:move',
|
||||
'oidc:manage',
|
||||
'dataStore:list',
|
||||
'role:manage',
|
||||
];
|
||||
|
||||
export const GLOBAL_ADMIN_SCOPES = GLOBAL_OWNER_SCOPES.concat();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { PROJECT_OWNER_ROLE_SLUG } from './constants.ee';
|
||||
import { ALL_SCOPES } from './scope-information';
|
||||
|
||||
export const roleNamespaceSchema = z.enum(['global', 'project', 'credential', 'workflow']);
|
||||
|
||||
@@ -25,3 +26,21 @@ export const projectRoleSchema = z.union([personalRoleSchema, teamRoleSchema]);
|
||||
export const credentialSharingRoleSchema = z.enum(['credential:owner', 'credential:user']);
|
||||
|
||||
export const workflowSharingRoleSchema = z.enum(['workflow:owner', 'workflow:editor']);
|
||||
|
||||
const ALL_SCOPES_LOOKUP_SET = new Set(ALL_SCOPES as string[]);
|
||||
|
||||
export const scopeSchema = z.string().refine((val) => ALL_SCOPES_LOOKUP_SET.has(val), {
|
||||
message: 'Invalid scope',
|
||||
});
|
||||
|
||||
export const roleSchema = z.object({
|
||||
slug: z.string().min(1),
|
||||
displayName: z.string().min(1),
|
||||
description: z.string().nullable(),
|
||||
systemRole: z.boolean(),
|
||||
roleType: roleNamespaceSchema,
|
||||
licensed: z.boolean(),
|
||||
scopes: z.array(scopeSchema),
|
||||
});
|
||||
|
||||
export type Role = z.infer<typeof roleSchema>;
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
credentialSharingRoleSchema,
|
||||
globalRoleSchema,
|
||||
projectRoleSchema,
|
||||
Role,
|
||||
roleNamespaceSchema,
|
||||
teamRoleSchema,
|
||||
workflowSharingRoleSchema,
|
||||
@@ -63,19 +64,11 @@ export type CustomRole = string;
|
||||
/** Union of all possible role types in the system */
|
||||
export type AllRoleTypes = GlobalRole | ProjectRole | WorkflowSharingRole | CredentialSharingRole;
|
||||
|
||||
type RoleObject<T extends AllRoleTypes> = {
|
||||
role: T;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
scopes: Scope[];
|
||||
licensed: boolean;
|
||||
};
|
||||
|
||||
export type AllRolesMap = {
|
||||
global: Array<RoleObject<GlobalRole>>;
|
||||
project: Array<RoleObject<ProjectRole>>;
|
||||
credential: Array<RoleObject<CredentialSharingRole>>;
|
||||
workflow: Array<RoleObject<WorkflowSharingRole>>;
|
||||
global: Role[];
|
||||
project: Role[];
|
||||
credential: Role[];
|
||||
workflow: Role[];
|
||||
};
|
||||
|
||||
export type DbScope = {
|
||||
|
||||
@@ -34,6 +34,7 @@ describe('permissions', () => {
|
||||
folder: {},
|
||||
insights: {},
|
||||
dataStore: {},
|
||||
role: {},
|
||||
});
|
||||
});
|
||||
it('getResourcePermissions', () => {
|
||||
@@ -134,6 +135,7 @@ describe('permissions', () => {
|
||||
dataStore: {},
|
||||
execution: {},
|
||||
workflowTags: {},
|
||||
role: {},
|
||||
};
|
||||
|
||||
expect(getResourcePermissions(scopes)).toEqual(permissionRecord);
|
||||
|
||||
Reference in New Issue
Block a user