n8n
Version:
n8n Workflow Automation Tool
90 lines • 4.65 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubworkflowPolicyChecker = void 0;
const typedi_1 = require("typedi");
const config_1 = require("@n8n/config");
const Logger_1 = require("../Logger");
const License_1 = require("../License");
const ownership_service_1 = require("../services/ownership.service");
const subworkflow_policy_denial_error_1 = require("../errors/subworkflow-policy-denial.error");
let SubworkflowPolicyChecker = class SubworkflowPolicyChecker {
constructor(logger, license, ownershipService, globalConfig) {
this.logger = logger;
this.license = license;
this.ownershipService = ownershipService;
this.globalConfig = globalConfig;
this.denialReasons = {
none: 'Subworkflow may not be called by any workflow',
workflowsFromAList: 'Subworkflow may be called only by workflows from an allowlist',
workflowsFromSameOwner: 'Subworkflow may be called only by workflows owned by the same project',
};
}
async check(subworkflow, parentWorkflowId, node) {
const { id: subworkflowId } = subworkflow;
if (!subworkflowId)
return;
const policy = this.findPolicy(subworkflow);
if (policy === 'any')
return;
const { parentWorkflowProject, subworkflowProject } = await this.findProjects({
parentWorkflowId,
subworkflowId,
});
const areOwnedBySameProject = parentWorkflowProject.id === subworkflowProject.id;
if (policy === 'none' ||
(policy === 'workflowsFromAList' && !this.hasParentListed(subworkflow, parentWorkflowId)) ||
(policy === 'workflowsFromSameOwner' && !areOwnedBySameProject)) {
this.logDenial({ parentWorkflowId, subworkflowId, policy });
throw new subworkflow_policy_denial_error_1.SubworkflowPolicyDenialError({
subworkflowId,
subworkflowProject,
areOwnedBySameProject,
node,
});
}
}
findPolicy(subworkflow) {
var _a, _b;
if (!this.license.isSharingEnabled())
return 'workflowsFromSameOwner';
return ((_b = (_a = subworkflow.settings) === null || _a === void 0 ? void 0 : _a.callerPolicy) !== null && _b !== void 0 ? _b : this.globalConfig.workflows.callerPolicyDefaultOption);
}
async findProjects({ parentWorkflowId, subworkflowId, }) {
const [parentWorkflowProject, subworkflowProject] = await Promise.all([
this.ownershipService.getWorkflowProjectCached(parentWorkflowId),
this.ownershipService.getWorkflowProjectCached(subworkflowId),
]);
return { parentWorkflowProject, subworkflowProject };
}
hasParentListed(subworkflow, parentWorkflowId) {
var _a, _b;
const callerIds = (_b = (_a = subworkflow.settings.callerIds) === null || _a === void 0 ? void 0 : _a.split(',').map((id) => id.trim()).filter((id) => id !== '')) !== null && _b !== void 0 ? _b : [];
return callerIds.includes(parentWorkflowId);
}
logDenial({ parentWorkflowId, subworkflowId, policy, }) {
this.logger.warn('[SubworkflowPolicyChecker] Subworkflow execution denied', {
reason: this.denialReasons[policy],
parentWorkflowId,
subworkflowId,
isSharingEnabled: this.license.isSharingEnabled(),
});
}
};
exports.SubworkflowPolicyChecker = SubworkflowPolicyChecker;
exports.SubworkflowPolicyChecker = SubworkflowPolicyChecker = __decorate([
(0, typedi_1.Service)(),
__metadata("design:paramtypes", [Logger_1.Logger,
License_1.License,
ownership_service_1.OwnershipService,
config_1.GlobalConfig])
], SubworkflowPolicyChecker);
//# sourceMappingURL=subworkflow-policy-checker.service.js.map
;