refactor: Refactor variables controller into a RestController (no-changelog) (#7822)
Github issue / Community forum post (link here to close automatically):
This commit is contained in:
@@ -23,7 +23,7 @@ import {
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import { In } from 'typeorm';
|
||||
import type { SourceControlledFile } from './types/sourceControlledFile';
|
||||
import { VariablesService } from '../variables/variables.service';
|
||||
import { VariablesService } from '../variables/variables.service.ee';
|
||||
import { TagRepository } from '@db/repositories/tag.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
@@ -24,7 +24,7 @@ import type { SourceControlWorkflowVersionId } from './types/sourceControlWorkfl
|
||||
import { getCredentialExportPath, getWorkflowExportPath } from './sourceControlHelper.ee';
|
||||
import type { SourceControlledFile } from './types/sourceControlledFile';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { VariablesService } from '../variables/variables.service';
|
||||
import { VariablesService } from '../variables/variables.service.ee';
|
||||
import { TagRepository } from '@db/repositories/tag.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
@@ -1,43 +1,51 @@
|
||||
import express from 'express';
|
||||
import { Container } from 'typedi';
|
||||
import { Container, Service } from 'typedi';
|
||||
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import type { VariablesRequest } from '@/requests';
|
||||
import { VariablesRequest } from '@/requests';
|
||||
import { Authorized, Delete, Get, Patch, Post, RestController } from '@/decorators';
|
||||
import {
|
||||
VariablesService,
|
||||
VariablesLicenseError,
|
||||
EEVariablesService,
|
||||
VariablesValidationError,
|
||||
} from './variables.service.ee';
|
||||
import { isVariablesEnabled } from './enviromentHelpers';
|
||||
import { Logger } from '@/Logger';
|
||||
import type { RequestHandler } from 'express';
|
||||
|
||||
export const EEVariablesController = express.Router();
|
||||
const variablesLicensedMiddleware: RequestHandler = (req, res, next) => {
|
||||
if (isVariablesEnabled()) {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({ status: 'error', message: 'Unauthorized' });
|
||||
}
|
||||
};
|
||||
|
||||
EEVariablesController.use((req, res, next) => {
|
||||
if (!isVariablesEnabled()) {
|
||||
next('router');
|
||||
return;
|
||||
@Service()
|
||||
@Authorized()
|
||||
@RestController('/variables')
|
||||
export class VariablesController {
|
||||
constructor(
|
||||
private variablesService: VariablesService,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
@Get('/')
|
||||
async getVariables() {
|
||||
return Container.get(VariablesService).getAllCached();
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
EEVariablesController.post(
|
||||
'/',
|
||||
ResponseHelper.send(async (req: VariablesRequest.Create) => {
|
||||
@Post('/', { middlewares: [variablesLicensedMiddleware] })
|
||||
async createVariable(req: VariablesRequest.Create) {
|
||||
if (req.user.globalRole.name !== 'owner') {
|
||||
Container.get(Logger).info(
|
||||
'Attempt to update a variable blocked due to lack of permissions',
|
||||
{
|
||||
userId: req.user.id,
|
||||
},
|
||||
);
|
||||
throw new ResponseHelper.AuthError('Unauthorized');
|
||||
this.logger.info('Attempt to update a variable blocked due to lack of permissions', {
|
||||
userId: req.user.id,
|
||||
});
|
||||
throw new ResponseHelper.UnauthorizedError('Unauthorized');
|
||||
}
|
||||
const variable = req.body;
|
||||
delete variable.id;
|
||||
try {
|
||||
return await Container.get(EEVariablesService).create(variable);
|
||||
return await Container.get(VariablesService).create(variable);
|
||||
} catch (error) {
|
||||
if (error instanceof VariablesLicenseError) {
|
||||
throw new ResponseHelper.BadRequestError(error.message);
|
||||
@@ -46,27 +54,32 @@ EEVariablesController.post(
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
EEVariablesController.patch(
|
||||
'/:id(\\w+)',
|
||||
ResponseHelper.send(async (req: VariablesRequest.Update) => {
|
||||
@Get('/:id')
|
||||
async getVariable(req: VariablesRequest.Get) {
|
||||
const id = req.params.id;
|
||||
const variable = await Container.get(VariablesService).getCached(id);
|
||||
if (variable === null) {
|
||||
throw new ResponseHelper.NotFoundError(`Variable with id ${req.params.id} not found`);
|
||||
}
|
||||
return variable;
|
||||
}
|
||||
|
||||
@Patch('/:id', { middlewares: [variablesLicensedMiddleware] })
|
||||
async updateVariable(req: VariablesRequest.Update) {
|
||||
const id = req.params.id;
|
||||
if (req.user.globalRole.name !== 'owner') {
|
||||
Container.get(Logger).info(
|
||||
'Attempt to update a variable blocked due to lack of permissions',
|
||||
{
|
||||
id,
|
||||
userId: req.user.id,
|
||||
},
|
||||
);
|
||||
throw new ResponseHelper.AuthError('Unauthorized');
|
||||
this.logger.info('Attempt to update a variable blocked due to lack of permissions', {
|
||||
id,
|
||||
userId: req.user.id,
|
||||
});
|
||||
throw new ResponseHelper.UnauthorizedError('Unauthorized');
|
||||
}
|
||||
const variable = req.body;
|
||||
delete variable.id;
|
||||
try {
|
||||
return await Container.get(EEVariablesService).update(id, variable);
|
||||
return await Container.get(VariablesService).update(id, variable);
|
||||
} catch (error) {
|
||||
if (error instanceof VariablesLicenseError) {
|
||||
throw new ResponseHelper.BadRequestError(error.message);
|
||||
@@ -75,5 +88,20 @@ EEVariablesController.patch(
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@Delete('/:id')
|
||||
async deleteVariable(req: VariablesRequest.Delete) {
|
||||
const id = req.params.id;
|
||||
if (req.user.globalRole.name !== 'owner') {
|
||||
this.logger.info('Attempt to delete a variable blocked due to lack of permissions', {
|
||||
id,
|
||||
userId: req.user.id,
|
||||
});
|
||||
throw new ResponseHelper.UnauthorizedError('Unauthorized');
|
||||
}
|
||||
await this.variablesService.delete(id);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import express from 'express';
|
||||
import { Container } from 'typedi';
|
||||
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import type { VariablesRequest } from '@/requests';
|
||||
import { VariablesService } from './variables.service';
|
||||
import { EEVariablesController } from './variables.controller.ee';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
export const variablesController = express.Router();
|
||||
|
||||
variablesController.use('/', EEVariablesController);
|
||||
variablesController.use(EEVariablesController);
|
||||
|
||||
variablesController.get(
|
||||
'/',
|
||||
ResponseHelper.send(async () => {
|
||||
return Container.get(VariablesService).getAllCached();
|
||||
}),
|
||||
);
|
||||
|
||||
variablesController.post(
|
||||
'/',
|
||||
ResponseHelper.send(async () => {
|
||||
throw new ResponseHelper.BadRequestError('No variables license found');
|
||||
}),
|
||||
);
|
||||
|
||||
variablesController.get(
|
||||
'/:id(\\w+)',
|
||||
ResponseHelper.send(async (req: VariablesRequest.Get) => {
|
||||
const id = req.params.id;
|
||||
const variable = await Container.get(VariablesService).getCached(id);
|
||||
if (variable === null) {
|
||||
throw new ResponseHelper.NotFoundError(`Variable with id ${req.params.id} not found`);
|
||||
}
|
||||
return variable;
|
||||
}),
|
||||
);
|
||||
|
||||
variablesController.patch(
|
||||
'/:id(\\w+)',
|
||||
ResponseHelper.send(async () => {
|
||||
throw new ResponseHelper.BadRequestError('No variables license found');
|
||||
}),
|
||||
);
|
||||
|
||||
variablesController.delete(
|
||||
'/:id(\\w+)',
|
||||
ResponseHelper.send(async (req: VariablesRequest.Delete) => {
|
||||
const id = req.params.id;
|
||||
if (req.user.globalRole.name !== 'owner') {
|
||||
Container.get(Logger).info(
|
||||
'Attempt to delete a variable blocked due to lack of permissions',
|
||||
{
|
||||
id,
|
||||
userId: req.user.id,
|
||||
},
|
||||
);
|
||||
throw new ResponseHelper.AuthError('Unauthorized');
|
||||
}
|
||||
await Container.get(VariablesService).delete(id);
|
||||
|
||||
return true;
|
||||
}),
|
||||
);
|
||||
@@ -3,13 +3,60 @@ import type { Variables } from '@db/entities/Variables';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
import { canCreateNewVariable } from './enviromentHelpers';
|
||||
import { VariablesService } from './variables.service';
|
||||
import { CacheService } from '@/services/cache.service';
|
||||
import { VariablesRepository } from '@db/repositories/variables.repository';
|
||||
import type { DeepPartial } from 'typeorm';
|
||||
|
||||
export class VariablesLicenseError extends Error {}
|
||||
export class VariablesValidationError extends Error {}
|
||||
|
||||
@Service()
|
||||
export class EEVariablesService extends VariablesService {
|
||||
export class VariablesService {
|
||||
constructor(
|
||||
protected cacheService: CacheService,
|
||||
protected variablesRepository: VariablesRepository,
|
||||
) {}
|
||||
|
||||
async getAllCached(): Promise<Variables[]> {
|
||||
const variables = await this.cacheService.get('variables', {
|
||||
async refreshFunction() {
|
||||
// TODO: log refresh cache metric
|
||||
return Container.get(VariablesService).findAll();
|
||||
},
|
||||
});
|
||||
return (variables as Array<DeepPartial<Variables>>).map((v) =>
|
||||
this.variablesRepository.create(v),
|
||||
);
|
||||
}
|
||||
|
||||
async getCount(): Promise<number> {
|
||||
return (await this.getAllCached()).length;
|
||||
}
|
||||
|
||||
async getCached(id: string): Promise<Variables | null> {
|
||||
const variables = await this.getAllCached();
|
||||
const foundVariable = variables.find((variable) => variable.id === id);
|
||||
if (!foundVariable) {
|
||||
return null;
|
||||
}
|
||||
return this.variablesRepository.create(foundVariable as DeepPartial<Variables>);
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await this.variablesRepository.delete(id);
|
||||
await this.updateCache();
|
||||
}
|
||||
|
||||
async updateCache(): Promise<void> {
|
||||
// TODO: log update cache metric
|
||||
const variables = await this.findAll();
|
||||
await this.cacheService.set('variables', variables);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Variables[]> {
|
||||
return this.variablesRepository.find();
|
||||
}
|
||||
|
||||
validateVariable(variable: Omit<Variables, 'id'>): void {
|
||||
if (variable.key.length > 50) {
|
||||
throw new VariablesValidationError('key cannot be longer than 50 characters');
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import type { Variables } from '@db/entities/Variables';
|
||||
import { CacheService } from '@/services/cache.service';
|
||||
import Container, { Service } from 'typedi';
|
||||
import { VariablesRepository } from '@db/repositories/variables.repository';
|
||||
import type { DeepPartial } from 'typeorm';
|
||||
|
||||
@Service()
|
||||
export class VariablesService {
|
||||
constructor(
|
||||
protected cacheService: CacheService,
|
||||
protected variablesRepository: VariablesRepository,
|
||||
) {}
|
||||
|
||||
async getAllCached(): Promise<Variables[]> {
|
||||
const variables = await this.cacheService.get('variables', {
|
||||
async refreshFunction() {
|
||||
// TODO: log refresh cache metric
|
||||
return Container.get(VariablesService).findAll();
|
||||
},
|
||||
});
|
||||
return (variables as Array<DeepPartial<Variables>>).map((v) =>
|
||||
this.variablesRepository.create(v),
|
||||
);
|
||||
}
|
||||
|
||||
async getCount(): Promise<number> {
|
||||
return (await this.getAllCached()).length;
|
||||
}
|
||||
|
||||
async getCached(id: string): Promise<Variables | null> {
|
||||
const variables = await this.getAllCached();
|
||||
const foundVariable = variables.find((variable) => variable.id === id);
|
||||
if (!foundVariable) {
|
||||
return null;
|
||||
}
|
||||
return this.variablesRepository.create(foundVariable as DeepPartial<Variables>);
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await this.variablesRepository.delete(id);
|
||||
await this.updateCache();
|
||||
}
|
||||
|
||||
async updateCache(): Promise<void> {
|
||||
// TODO: log update cache metric
|
||||
const variables = await this.findAll();
|
||||
await this.cacheService.set('variables', variables);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Variables[]> {
|
||||
return this.variablesRepository.find();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user