n8n/packages/cli/src/services/ownership.service.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

83 lines
2.7 KiB
TypeScript
Raw Normal View History

import { Service } from 'typedi';
import { CacheService } from '@/services/cache/cache.service';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import type { User } from '@db/entities/User';
import { RoleService } from './role.service';
2023-12-11 04:35:09 -08:00
import { UserRepository } from '@/databases/repositories/user.repository';
import type { ListQuery } from '@/requests';
import { ApplicationError } from 'n8n-workflow';
@Service()
export class OwnershipService {
constructor(
private cacheService: CacheService,
2023-12-11 04:35:09 -08:00
private userRepository: UserRepository,
private roleService: RoleService,
private sharedWorkflowRepository: SharedWorkflowRepository,
) {}
/**
* Retrieve the user who owns the workflow. Note that workflow ownership is **immutable**.
*/
async getWorkflowOwnerCached(workflowId: string) {
const cachedValue = await this.cacheService.getHashValue<User>(
'workflow-ownership',
workflowId,
);
2023-12-11 04:35:09 -08:00
if (cachedValue) return this.userRepository.create(cachedValue);
const workflowOwnerRole = await this.roleService.findWorkflowOwnerRole();
if (!workflowOwnerRole) throw new ApplicationError('Failed to find workflow owner role');
const sharedWorkflow = await this.sharedWorkflowRepository.findOneOrFail({
where: { workflowId, roleId: workflowOwnerRole.id },
relations: ['user', 'user.globalRole'],
});
void this.cacheService.setHash('workflow-ownership', { [workflowId]: sharedWorkflow.user });
return sharedWorkflow.user;
}
addOwnedByAndSharedWith(
rawWorkflow: ListQuery.Workflow.WithSharing,
): ListQuery.Workflow.WithOwnedByAndSharedWith;
addOwnedByAndSharedWith(
rawCredential: ListQuery.Credentials.WithSharing,
): ListQuery.Credentials.WithOwnedByAndSharedWith;
addOwnedByAndSharedWith(
rawEntity: ListQuery.Workflow.WithSharing | ListQuery.Credentials.WithSharing,
): ListQuery.Workflow.WithOwnedByAndSharedWith | ListQuery.Credentials.WithOwnedByAndSharedWith {
const { shared, ...rest } = rawEntity;
const entity = rest as
| ListQuery.Workflow.WithOwnedByAndSharedWith
| ListQuery.Credentials.WithOwnedByAndSharedWith;
Object.assign(entity, { ownedBy: null, sharedWith: [] });
shared?.forEach(({ user, role }) => {
const { id, email, firstName, lastName } = user;
if (role.name === 'owner') {
entity.ownedBy = { id, email, firstName, lastName };
} else {
entity.sharedWith.push({ id, email, firstName, lastName });
}
});
return entity;
}
2023-12-11 04:35:09 -08:00
async getInstanceOwner() {
const globalOwnerRole = await this.roleService.findGlobalOwnerRole();
return await this.userRepository.findOneOrFail({
2023-12-11 04:35:09 -08:00
where: { globalRoleId: globalOwnerRole.id },
relations: ['globalRole'],
});
}
}