mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +00:00
refactor: Adjust credential endpoints permissions (#4656) (no-changelog)
* refactor: Adjust credential endpoints permissions
This commit is contained in:
@@ -26,12 +26,19 @@ export class PermissionChecker {
|
|||||||
// allow if all creds used in this workflow are a subset of
|
// allow if all creds used in this workflow are a subset of
|
||||||
// all creds accessible to users who have access to this workflow
|
// all creds accessible to users who have access to this workflow
|
||||||
|
|
||||||
|
let workflowUserIds: string[] = [];
|
||||||
|
|
||||||
|
if (workflow.id) {
|
||||||
const workflowSharings = await Db.collections.SharedWorkflow.find({
|
const workflowSharings = await Db.collections.SharedWorkflow.find({
|
||||||
relations: ['workflow'],
|
relations: ['workflow'],
|
||||||
where: { workflow: { id: Number(workflow.id) } },
|
where: { workflow: { id: Number(workflow.id) } },
|
||||||
});
|
});
|
||||||
|
|
||||||
const workflowUserIds = workflowSharings.map((s) => s.userId);
|
workflowUserIds = workflowSharings.map((s) => s.userId);
|
||||||
|
} else {
|
||||||
|
// unsaved workflows have no id, so only get credentials for current user
|
||||||
|
workflowUserIds = [userId];
|
||||||
|
}
|
||||||
|
|
||||||
const credentialSharings = await Db.collections.SharedCredentials.find({
|
const credentialSharings = await Db.collections.SharedCredentials.find({
|
||||||
where: { user: In(workflowUserIds) },
|
where: { user: In(workflowUserIds) },
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ credentialsController.use('/', EECredentialsController);
|
|||||||
credentialsController.get(
|
credentialsController.get(
|
||||||
'/',
|
'/',
|
||||||
ResponseHelper.send(async (req: CredentialRequest.GetAll): Promise<ICredentialsResponse[]> => {
|
ResponseHelper.send(async (req: CredentialRequest.GetAll): Promise<ICredentialsResponse[]> => {
|
||||||
const credentials = await CredentialsService.getAll(req.user);
|
const credentials = await CredentialsService.getAll(req.user, { roles: ['owner'] });
|
||||||
|
|
||||||
return credentials.map((credential) => {
|
return credentials.map((credential) => {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
import { DeleteResult, EntityManager, In, Not } from 'typeorm';
|
import { DeleteResult, EntityManager, FindOneOptions, In, Not, ObjectLiteral } from 'typeorm';
|
||||||
import * as Db from '@/Db';
|
import * as Db from '@/Db';
|
||||||
import { RoleService } from '@/role/role.service';
|
import { RoleService } from '@/role/role.service';
|
||||||
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||||
@@ -25,6 +25,35 @@ export class EECredentialsService extends CredentialsService {
|
|||||||
return { ownsCredential: true, credential };
|
return { ownsCredential: true, credential };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the sharing that matches a user and a credential.
|
||||||
|
*/
|
||||||
|
static async getSharing(
|
||||||
|
user: User,
|
||||||
|
credentialId: number | string,
|
||||||
|
relations: string[] = ['credentials'],
|
||||||
|
{ allowGlobalOwner } = { allowGlobalOwner: true },
|
||||||
|
): Promise<SharedCredentials | undefined> {
|
||||||
|
const options: FindOneOptions<SharedCredentials> & { where: ObjectLiteral } = {
|
||||||
|
where: {
|
||||||
|
credentials: { id: credentialId },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Omit user from where if the requesting user is the global
|
||||||
|
// owner. This allows the global owner to view and delete
|
||||||
|
// credentials they don't own.
|
||||||
|
if (!allowGlobalOwner || user.globalRole.name !== 'owner') {
|
||||||
|
options.where.user = { id: user.id };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relations?.length) {
|
||||||
|
options.relations = relations;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Db.collections.SharedCredentials.findOne(options);
|
||||||
|
}
|
||||||
|
|
||||||
static async getSharings(
|
static async getSharings(
|
||||||
transaction: EntityManager,
|
transaction: EntityManager,
|
||||||
credentialId: string,
|
credentialId: string,
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ export class CredentialsService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getAll(user: User, options?: { relations: string[] }): Promise<ICredentialsDb[]> {
|
static async getAll(
|
||||||
|
user: User,
|
||||||
|
options?: { relations?: string[]; roles?: string[] },
|
||||||
|
): Promise<ICredentialsDb[]> {
|
||||||
const SELECT_FIELDS: Array<keyof ICredentialsDb> = [
|
const SELECT_FIELDS: Array<keyof ICredentialsDb> = [
|
||||||
'id',
|
'id',
|
||||||
'name',
|
'name',
|
||||||
@@ -52,11 +55,21 @@ export class CredentialsService {
|
|||||||
|
|
||||||
// if member, return credentials owned by or shared with member
|
// if member, return credentials owned by or shared with member
|
||||||
|
|
||||||
const userSharings = await Db.collections.SharedCredentials.find({
|
const whereConditions: FindManyOptions = {
|
||||||
where: {
|
where: {
|
||||||
user,
|
user,
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (options?.roles?.length) {
|
||||||
|
whereConditions.where = {
|
||||||
|
...whereConditions.where,
|
||||||
|
role: { name: In(options.roles) },
|
||||||
|
} as FindManyOptions;
|
||||||
|
whereConditions.relations = ['role'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const userSharings = await Db.collections.SharedCredentials.find(whereConditions);
|
||||||
|
|
||||||
return Db.collections.Credentials.find({
|
return Db.collections.Credentials.find({
|
||||||
select: SELECT_FIELDS,
|
select: SELECT_FIELDS,
|
||||||
@@ -77,7 +90,7 @@ export class CredentialsService {
|
|||||||
static async getSharing(
|
static async getSharing(
|
||||||
user: User,
|
user: User,
|
||||||
credentialId: number | string,
|
credentialId: number | string,
|
||||||
relations: string[] | undefined = ['credentials'],
|
relations: string[] = ['credentials'],
|
||||||
{ allowGlobalOwner } = { allowGlobalOwner: true },
|
{ allowGlobalOwner } = { allowGlobalOwner: true },
|
||||||
): Promise<SharedCredentials | undefined> {
|
): Promise<SharedCredentials | undefined> {
|
||||||
const options: FindOneOptions = {
|
const options: FindOneOptions = {
|
||||||
@@ -90,8 +103,14 @@ export class CredentialsService {
|
|||||||
// owner. This allows the global owner to view and delete
|
// owner. This allows the global owner to view and delete
|
||||||
// credentials they don't own.
|
// credentials they don't own.
|
||||||
if (!allowGlobalOwner || user.globalRole.name !== 'owner') {
|
if (!allowGlobalOwner || user.globalRole.name !== 'owner') {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
options.where = {
|
||||||
options.where.user = { id: user.id };
|
...options.where,
|
||||||
|
user: { id: user.id },
|
||||||
|
role: { name: 'owner' },
|
||||||
|
} as FindOneOptions;
|
||||||
|
if (!relations.includes('role')) {
|
||||||
|
relations.push('role');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relations?.length) {
|
if (relations?.length) {
|
||||||
|
|||||||
@@ -247,13 +247,14 @@ EEWorkflowController.post(
|
|||||||
const workflow = new WorkflowEntity();
|
const workflow = new WorkflowEntity();
|
||||||
Object.assign(workflow, req.body.workflowData);
|
Object.assign(workflow, req.body.workflowData);
|
||||||
|
|
||||||
|
if (workflow.id !== undefined) {
|
||||||
const safeWorkflow = await EEWorkflows.preventTampering(
|
const safeWorkflow = await EEWorkflows.preventTampering(
|
||||||
workflow,
|
workflow,
|
||||||
workflow.id.toString(),
|
workflow.id.toString(),
|
||||||
req.user,
|
req.user,
|
||||||
);
|
);
|
||||||
|
|
||||||
req.body.workflowData.nodes = safeWorkflow.nodes;
|
req.body.workflowData.nodes = safeWorkflow.nodes;
|
||||||
|
}
|
||||||
|
|
||||||
return EEWorkflows.runManually(req.body, req.user, GenericHelpers.getSessionId(req));
|
return EEWorkflows.runManually(req.body, req.user, GenericHelpers.getSessionId(req));
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user