refactor(core): Use DI in PermissionChecker (no-changelog) (#8344)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2024-01-16 14:15:29 +01:00
committed by GitHub
parent 420b4271a9
commit 64ceb16af6
7 changed files with 52 additions and 42 deletions

View File

@@ -1,22 +1,32 @@
import { Service } from 'typedi';
import type { INode, Workflow } from 'n8n-workflow';
import { NodeOperationError, WorkflowOperationError } from 'n8n-workflow';
import config from '@/config';
import { isSharingEnabled } from './UserManagementHelper';
import { OwnershipService } from '@/services/ownership.service';
import Container from 'typedi';
import { RoleService } from '@/services/role.service';
import { UserRepository } from '@db/repositories/user.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
@Service()
export class PermissionChecker {
constructor(
private readonly userRepository: UserRepository,
private readonly sharedCredentialsRepository: SharedCredentialsRepository,
private readonly sharedWorkflowRepository: SharedWorkflowRepository,
private readonly roleService: RoleService,
private readonly ownershipService: OwnershipService,
) {}
/**
* Check if a user is permitted to execute a workflow.
*/
static async check(workflow: Workflow, userId: string) {
async check(workflow: Workflow, userId: string) {
// allow if no nodes in this workflow use creds
const credIdsToNodes = PermissionChecker.mapCredIdsToNodes(workflow);
const credIdsToNodes = this.mapCredIdsToNodes(workflow);
const workflowCredIds = Object.keys(credIdsToNodes);
@@ -24,7 +34,7 @@ export class PermissionChecker {
// allow if requesting user is instance owner
const user = await Container.get(UserRepository).findOneOrFail({
const user = await this.userRepository.findOneOrFail({
where: { id: userId },
relations: ['globalRole'],
});
@@ -37,7 +47,7 @@ export class PermissionChecker {
let workflowUserIds = [userId];
if (workflow.id && isSharingEnabled()) {
const workflowSharings = await Container.get(SharedWorkflowRepository).find({
const workflowSharings = await this.sharedWorkflowRepository.find({
relations: ['workflow'],
where: { workflowId: workflow.id },
select: ['userId'],
@@ -45,9 +55,9 @@ export class PermissionChecker {
workflowUserIds = workflowSharings.map((s) => s.userId);
}
const roleId = await Container.get(RoleService).findCredentialOwnerRoleId();
const roleId = await this.roleService.findCredentialOwnerRoleId();
const credentialSharings = await Container.get(SharedCredentialsRepository).findSharings(
const credentialSharings = await this.sharedCredentialsRepository.findSharings(
workflowUserIds,
roleId,
);
@@ -68,7 +78,7 @@ export class PermissionChecker {
});
}
static async checkSubworkflowExecutePolicy(
async checkSubworkflowExecutePolicy(
subworkflow: Workflow,
parentWorkflowId: string,
node?: INode,
@@ -94,11 +104,9 @@ export class PermissionChecker {
}
const parentWorkflowOwner =
await Container.get(OwnershipService).getWorkflowOwnerCached(parentWorkflowId);
await this.ownershipService.getWorkflowOwnerCached(parentWorkflowId);
const subworkflowOwner = await Container.get(OwnershipService).getWorkflowOwnerCached(
subworkflow.id,
);
const subworkflowOwner = await this.ownershipService.getWorkflowOwnerCached(subworkflow.id);
const description =
subworkflowOwner.id === parentWorkflowOwner.id
@@ -134,7 +142,7 @@ export class PermissionChecker {
}
}
private static mapCredIdsToNodes(workflow: Workflow) {
private mapCredIdsToNodes(workflow: Workflow) {
return Object.values(workflow.nodes).reduce<{ [credentialId: string]: INode[] }>(
(map, node) => {
if (node.disabled || !node.credentials) return map;

View File

@@ -795,8 +795,8 @@ async function executeWorkflow(
let data;
try {
await PermissionChecker.check(workflow, additionalData.userId);
await PermissionChecker.checkSubworkflowExecutePolicy(
await Container.get(PermissionChecker).check(workflow, additionalData.userId);
await Container.get(PermissionChecker).checkSubworkflowExecutePolicy(
workflow,
options.parentWorkflowId,
options.node,

View File

@@ -176,7 +176,7 @@ export async function executeErrorWorkflow(
const failedNode = workflowErrorData.execution?.lastNodeExecuted
? workflowInstance.getNode(workflowErrorData.execution?.lastNodeExecuted)
: undefined;
await PermissionChecker.checkSubworkflowExecutePolicy(
await Container.get(PermissionChecker).checkSubworkflowExecutePolicy(
workflowInstance,
workflowErrorData.workflow.id!,
failedNode ?? undefined,

View File

@@ -327,7 +327,7 @@ export class WorkflowRunner {
);
try {
await PermissionChecker.check(workflow, data.userId);
await Container.get(PermissionChecker).check(workflow, data.userId);
} catch (error) {
ErrorReporter.error(error);
// Create a failed execution with the data for the node

View File

@@ -142,7 +142,7 @@ class WorkflowRunnerProcess {
pinData: this.data.pinData,
});
try {
await PermissionChecker.check(this.workflow, userId);
await Container.get(PermissionChecker).check(this.workflow, userId);
} catch (error) {
const caughtError = error as NodeOperationError;
const failedExecutionData = generateFailedExecutionFromError(

View File

@@ -185,7 +185,7 @@ export class Worker extends BaseCommand {
);
try {
await PermissionChecker.check(workflow, workflowOwner.id);
await Container.get(PermissionChecker).check(workflow, workflowOwner.id);
} catch (error) {
if (error instanceof NodeOperationError) {
const failedExecution = generateFailedExecutionFromError(