fix(core): Only show personal credentials in the personal space (#12433)

This commit is contained in:
Danny Martini
2025-01-09 18:06:47 +01:00
committed by GitHub
parent 980d0bcb5e
commit 8a42d55d91
2 changed files with 13 additions and 31 deletions

View File

@@ -20,7 +20,6 @@ import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
import { CredentialTypes } from '@/credential-types'; import { CredentialTypes } from '@/credential-types';
import { createCredentialsFromCredentialsEntity } from '@/credentials-helper'; import { createCredentialsFromCredentialsEntity } from '@/credentials-helper';
import { CredentialsEntity } from '@/databases/entities/credentials-entity'; import { CredentialsEntity } from '@/databases/entities/credentials-entity';
import type { ProjectRelation } from '@/databases/entities/project-relation';
import { SharedCredentials } from '@/databases/entities/shared-credentials'; import { SharedCredentials } from '@/databases/entities/shared-credentials';
import type { User } from '@/databases/entities/user'; import type { User } from '@/databases/entities/user';
import { CredentialsRepository } from '@/databases/repositories/credentials.repository'; import { CredentialsRepository } from '@/databases/repositories/credentials.repository';
@@ -85,23 +84,6 @@ export class CredentialsService {
listQueryOptions.includeData = true; listQueryOptions.includeData = true;
} }
let projectRelations: ProjectRelation[] | undefined = undefined;
if (includeScopes) {
projectRelations = await this.projectService.getProjectRelationsForUser(user);
if (listQueryOptions.filter?.projectId && user.hasGlobalScope('credential:list')) {
// Only instance owners and admins have the credential:list scope
// Those users should be able to use _all_ credentials within their workflows.
// TODO: Change this so we filter by `workflowId` in this case. Require a slight FE change
const projectRelation = projectRelations.find(
(relation) => relation.projectId === listQueryOptions.filter?.projectId,
);
if (projectRelation?.role === 'project:personalOwner') {
// Will not affect team projects as these have admins, not owners.
delete listQueryOptions.filter?.projectId;
}
}
}
if (returnAll) { if (returnAll) {
let credentials = await this.credentialsRepository.findMany(listQueryOptions); let credentials = await this.credentialsRepository.findMany(listQueryOptions);
@@ -123,9 +105,8 @@ export class CredentialsService {
} }
if (includeScopes) { if (includeScopes) {
credentials = credentials.map((c) => const projectRelations = await this.projectService.getProjectRelationsForUser(user);
this.roleService.addScopes(c, user, projectRelations!), credentials = credentials.map((c) => this.roleService.addScopes(c, user, projectRelations));
);
} }
if (includeData) { if (includeData) {
@@ -179,7 +160,8 @@ export class CredentialsService {
} }
if (includeScopes) { if (includeScopes) {
credentials = credentials.map((c) => this.roleService.addScopes(c, user, projectRelations!)); const projectRelations = await this.projectService.getProjectRelationsForUser(user);
credentials = credentials.map((c) => this.roleService.addScopes(c, user, projectRelations));
} }
if (includeData) { if (includeData) {

View File

@@ -632,25 +632,25 @@ describe('GET /credentials', () => {
expect(response.body.data.map((credential) => credential.id)).toContain(memberCredential.id); expect(response.body.data.map((credential) => credential.id)).toContain(memberCredential.id);
}); });
test('should return all credentials to instance owners when working on their own personal project', async () => { test('should not ignore the project filter when the request is done by an owner and also includes the scopes', async () => {
const ownerCredential = await saveCredential(payload(), { const ownerCredential = await saveCredential(payload(), {
user: owner, user: owner,
role: 'credential:owner', role: 'credential:owner',
}); });
const memberCredential = await saveCredential(payload(), { // should not show up
user: member, await saveCredential(payload(), { user: member, role: 'credential:owner' });
role: 'credential:owner',
});
const response: GetAllResponse = await testServer const response: GetAllResponse = await testServer
.authAgentFor(owner) .authAgentFor(owner)
.get('/credentials') .get('/credentials')
.query(`filter={ "projectId": "${ownerPersonalProject.id}" }&includeScopes=true`) .query({
filter: JSON.stringify({ projectId: ownerPersonalProject.id }),
includeScopes: true,
})
.expect(200); .expect(200);
expect(response.body.data).toHaveLength(2); expect(response.body.data).toHaveLength(1);
expect(response.body.data.map((credential) => credential.id)).toContain(ownerCredential.id); expect(response.body.data[0].id).toBe(ownerCredential.id);
expect(response.body.data.map((credential) => credential.id)).toContain(memberCredential.id);
}); });
}); });