first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
import {
|
||||
createTeamProject,
|
||||
linkUserToProject,
|
||||
randomCredentialPayload,
|
||||
testDb,
|
||||
} from '@n8n/backend-test-utils';
|
||||
import type { User } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
|
||||
import { CredentialsHelper } from '@/credentials-helper';
|
||||
|
||||
import { saveCredential } from './shared/db/credentials';
|
||||
import { createOwner, createAdmin, createMember } from './shared/db/users';
|
||||
|
||||
let credentialHelper: CredentialsHelper;
|
||||
let owner: User;
|
||||
let admin: User;
|
||||
let member: User;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
credentialHelper = Container.get(CredentialsHelper);
|
||||
owner = await createOwner();
|
||||
admin = await createAdmin();
|
||||
member = await createMember();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
describe('CredentialsHelper', () => {
|
||||
describe('credentialOwnedBySuperUsers', () => {
|
||||
test.each([
|
||||
{
|
||||
testName: 'owners are super users',
|
||||
user: () => owner,
|
||||
credentialRole: 'credential:owner',
|
||||
expectedResult: true,
|
||||
} as const,
|
||||
{
|
||||
testName: 'admins are super users',
|
||||
user: () => admin,
|
||||
credentialRole: 'credential:owner',
|
||||
expectedResult: true,
|
||||
} as const,
|
||||
{
|
||||
testName: 'owners need to own the credential',
|
||||
user: () => owner,
|
||||
credentialRole: 'credential:user',
|
||||
expectedResult: false,
|
||||
} as const,
|
||||
{
|
||||
testName: 'admins need to own the credential',
|
||||
user: () => admin,
|
||||
credentialRole: 'credential:user',
|
||||
expectedResult: false,
|
||||
} as const,
|
||||
{
|
||||
testName: 'members are no super users',
|
||||
user: () => member,
|
||||
credentialRole: 'credential:owner',
|
||||
expectedResult: false,
|
||||
} as const,
|
||||
])('$testName', async ({ user, credentialRole, expectedResult }) => {
|
||||
const credential = await saveCredential(randomCredentialPayload(), {
|
||||
user: user(),
|
||||
role: credentialRole,
|
||||
});
|
||||
|
||||
const result = await credentialHelper.credentialCanUseExternalSecrets(credential);
|
||||
|
||||
expect(result).toBe(expectedResult);
|
||||
});
|
||||
|
||||
test('credential in team project with instance owner as an admin can use external secrets', async () => {
|
||||
const teamProject = await createTeamProject();
|
||||
const [credential] = await Promise.all([
|
||||
await saveCredential(randomCredentialPayload(), {
|
||||
project: teamProject,
|
||||
role: 'credential:owner',
|
||||
}),
|
||||
await linkUserToProject(owner, teamProject, 'project:admin'),
|
||||
await linkUserToProject(member, teamProject, 'project:admin'),
|
||||
]);
|
||||
|
||||
const result = await credentialHelper.credentialCanUseExternalSecrets(credential);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test('credential in team project with instance admin as an admin can use external secrets', async () => {
|
||||
const teamProject = await createTeamProject();
|
||||
const [credential] = await Promise.all([
|
||||
await saveCredential(randomCredentialPayload(), {
|
||||
project: teamProject,
|
||||
role: 'credential:owner',
|
||||
}),
|
||||
await linkUserToProject(admin, teamProject, 'project:admin'),
|
||||
await linkUserToProject(member, teamProject, 'project:admin'),
|
||||
]);
|
||||
|
||||
const result = await credentialHelper.credentialCanUseExternalSecrets(credential);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test('credential in team project with instance owner as an editor cannot use external secrets', async () => {
|
||||
const teamProject = await createTeamProject();
|
||||
const [credential] = await Promise.all([
|
||||
await saveCredential(randomCredentialPayload(), {
|
||||
project: teamProject,
|
||||
role: 'credential:owner',
|
||||
}),
|
||||
await linkUserToProject(owner, teamProject, 'project:editor'),
|
||||
await linkUserToProject(member, teamProject, 'project:admin'),
|
||||
]);
|
||||
|
||||
const result = await credentialHelper.credentialCanUseExternalSecrets(credential);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test('credential in team project with instance admin as an editor cannot use external secrets', async () => {
|
||||
const teamProject = await createTeamProject();
|
||||
const [credential] = await Promise.all([
|
||||
await saveCredential(randomCredentialPayload(), {
|
||||
project: teamProject,
|
||||
role: 'credential:owner',
|
||||
}),
|
||||
await linkUserToProject(admin, teamProject, 'project:editor'),
|
||||
await linkUserToProject(member, teamProject, 'project:admin'),
|
||||
]);
|
||||
|
||||
const result = await credentialHelper.credentialCanUseExternalSecrets(credential);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test('credential in team project with no instance admin or owner as part of the project cannot use external secrets', async () => {
|
||||
const teamProject = await createTeamProject();
|
||||
const [credential] = await Promise.all([
|
||||
await saveCredential(randomCredentialPayload(), {
|
||||
project: teamProject,
|
||||
role: 'credential:owner',
|
||||
}),
|
||||
await linkUserToProject(member, teamProject, 'project:admin'),
|
||||
]);
|
||||
|
||||
const result = await credentialHelper.credentialCanUseExternalSecrets(credential);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user