Skip to content
This repository has been archived by the owner on Dec 6, 2024. It is now read-only.

Commit

Permalink
fix: Add WorkflowDraftId validation on backend (#777)
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyen102 authored Nov 1, 2021
1 parent 9264b6a commit f240d81
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const createWorkflowDraftFields = [
placeholder: 'Type a unique id for this workflow',
extra: {
explain: `This is a required field and the number of characters must be between 3 and 100 and no spaces. Only
alpha-numeric characters and dashes are allowed. Once a draft is created you can not change the workflow id.`,
alpha-numeric characters, dashes, and underscores are allowed. Once a draft is created you can not change the workflow id.`,
},
rules: 'required|string|between:3,100|alpha_dash',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const ServicesContainer = require('@aws-ee/base-services-container/lib/services-container');
const JsonSchemaValidationService = require('@aws-ee/base-services/lib/json-schema-validation-service');
const DbService = require('@aws-ee/base-services/lib/db-service');
const AuditWriterService = require('@aws-ee/base-services/lib/audit/audit-writer-service');
const SettingsServiceMock = require('@aws-ee/base-services/lib/settings/env-settings-service');
const StepTemplateService = require('../step/step-template-service');
const WorkflowTemplateService = require('../workflow-template-service');
const WorkflowDraftService = require('../workflow-draft-service');
const WorkflowService = require('../workflow-service');

// jest.mock('@aws-ee/base-workflow-core/workflow-draft-service');
jest.mock('../step/step-template-service');
jest.mock('@aws-ee/base-services/lib/audit/audit-writer-service');
jest.mock('@aws-ee/base-services/lib/db-service');
jest.mock('../workflow-template-service');
jest.mock('../workflow-service');
jest.mock('@aws-ee/base-services/lib/settings/env-settings-service');

describe('WorkflowDraftService', () => {
let workflowDraftService;
let dbService;
beforeEach(async () => {
const container = new ServicesContainer();
container.register('workflowDraftService', new WorkflowDraftService());
container.register('jsonSchemaValidationService', new JsonSchemaValidationService());
container.register('workflowTemplateService', new WorkflowTemplateService());
container.register('workflowService', new WorkflowService());
container.register('stepTemplateService', new StepTemplateService());
container.register('dbService', new DbService());
container.register('auditWriterService', new AuditWriterService());
container.register('settings', new SettingsServiceMock());
await container.initServices();

workflowDraftService = await container.find('workflowDraftService');
dbService = await container.find('dbService');
const workflowTemplateService = await container.find('workflowTemplateService');
workflowDraftService._settings = {
get: settingName => {
if (settingName === 'dbWorkflowDrafts') {
return 'WorkflowDrafts';
}
return undefined;
},
};

workflowTemplateService.mustFindVersion = jest.fn(() => {
return [
{
stepTemplateId: 'template1',
stepTemplateVersion: '1',
id: '123',
title: '',
desc: '',
skippable: true,
},
];
});
});
describe('createDraft', () => {
it('should successfully create a draft', async () => {
const requestContext = {};

const updateFn = jest.fn();
dbService.table.update = updateFn;

await workflowDraftService.createDraft(requestContext, {
workflowId: 'workflow-test-1',
templateId: 'template-1',
});
expect(updateFn).toHaveBeenCalledTimes(1);
});
});
it('should throw error when given invalid draftId', async () => {
const requestContext = {};

await expect(
workflowDraftService.createDraft(requestContext, {
workflowId: 'workflow with spaces',
templateId: 'template-1',
}),
).rejects.toThrow(
new Error(
'Workflow id "workflow with spaces" is not valid. The number of characters must be between 3 and 100 and no spaces. Only alpha-numeric characters, dashes, and underscores are allowed.',
),
);
});

describe('isWorkFlowDraftIdValid', () => {
it('valid workflow draft id', () => {
expect(workflowDraftService.isWorkFlowDraftIdValid('validId')).toEqual(true);
});
it('Invalid workflow draft id: contains spaces', () => {
expect(workflowDraftService.isWorkFlowDraftIdValid('two words')).toEqual(false);
});
it('Invalid workflow draft id: contains non-alphanumeric character', () => {
expect(workflowDraftService.isWorkFlowDraftIdValid('!@')).toEqual(false);
});
it('Invalid workflow draft id: less than 3 char', () => {
expect(workflowDraftService.isWorkFlowDraftIdValid('ab')).toEqual(false);
});
it('Invalid workflow draft id: longer than 100 char', () => {
expect(
workflowDraftService.isWorkFlowDraftIdValid(
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
),
).toEqual(false);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ class WorkflowDraftService extends Service {
const by = _.get(requestContext, 'principalIdentifier.uid');

const now = new Date().toISOString();
if (!this.isWorkFlowDraftIdValid(workflowIdRaw)) {
throw this.boom.badRequest(
`Workflow id "${workflowIdRaw}" is not valid. The number of characters must be between 3 and 100 and no spaces. Only alpha-numeric characters, dashes, and underscores are allowed.`,
true,
);
}
const workflowId = slugify(_.kebabCase(_.startsWith(workflowIdRaw, 'wf-') ? workflowIdRaw : `wf-${workflowIdRaw}`));
const draftId = `${by}_${workflowId}_${workflowVer}`;
const draft = {
Expand Down Expand Up @@ -147,6 +153,12 @@ class WorkflowDraftService extends Service {
return result;
}

isWorkFlowDraftIdValid(id) {
// The number of characters must be between 3 and 100 and no spaces. Only alpha-numeric characters, dashes, and underscores are allowed.
const regExp = /^[\d\w-]{3,100}$/;
return regExp.test(id);
}

async updateDraft(requestContext, draft = {}) {
const [jsonSchemaValidationService, workflowService] = await this.service([
'jsonSchemaValidationService',
Expand Down

0 comments on commit f240d81

Please sign in to comment.