Skip to content

Commit

Permalink
cap-gateway - change:schema validation middleware and trnaslations
Browse files Browse the repository at this point in the history
  • Loading branch information
andreibesleaga committed Aug 10, 2024
1 parent 405ab11 commit 66d4b1f
Show file tree
Hide file tree
Showing 9 changed files with 538 additions and 128 deletions.
File renamed without changes.
3 changes: 2 additions & 1 deletion cap-gateway/gateway/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Api Gateway Service - Main NodeJS microservice Express HTTP(S) Server which routes all requests (register all microservices routes)

- input sanitization middleware (should also validate the request CAP XML Schema);
- input sanitization middleware
- middleware to validate the request against CAP XML Schema - but if necessary should be moved to coressponding responding service
- ENV variable to be set to: production, when deployed, for each microservice;
- PM2 installed as a package/global and used to run and automatically restart services on crashes - also logs to .log - check package.json starter scripts;

Expand Down
14 changes: 9 additions & 5 deletions cap-gateway/gateway/controllers/admin.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { HTTP_CODE, Endpoints, SERVICE_TIMEOUT } from '../constants.js';
import { sanitizeParams } from '../middlewares/sanitize.js';
import cote from 'cote';
import cote from 'cote';

const Endpoint = Endpoints.admin;
const getError = error => ({ error: error?.response?.data ?? error?.response?.message ?? error?.message ?? error?.response});
const getError = error => ({
error: error?.response?.data ?? error?.response?.message ?? error?.message ?? error?.response,
});

export function registerAdminCalls(app) {
app.post(Endpoint.pubsub, sanitizeParams, async (req, res) => {
try {
const requester = new cote.Requester({ name: 'admin_requester_pubsub', timeout: SERVICE_TIMEOUT});
const request = { type:'start' };
const requester = new cote.Requester({ name: 'admin_requester_pubsub', timeout: SERVICE_TIMEOUT });
const request = { type: 'start' };
let r = await requester.send(request);
return (r.status!==undefined && r.error!==undefined) ? res.status(r.status).json({ error: r.error }) : res.send(r);
return r.status !== undefined && r.error !== undefined
? res.status(r.status).json({ error: r.error })
: res.send(r);
} catch (error) {
return res.status(error?.response?.status ?? HTTP_CODE.ServerError).json(getError(error));
}
Expand Down
17 changes: 11 additions & 6 deletions cap-gateway/gateway/controllers/cap.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { HTTP_CODE, Endpoints, SERVICE_TIMEOUT } from '../constants.js';
import { sanitizeParams } from '../middlewares/sanitize.js';
import cote from 'cote';
import { schemaValidator } from '../middlewares/schemaValidator.js';
import cote from 'cote';

const Endpoint = Endpoints.cap;
const getError = error => ({ error: error?.response?.data ?? error?.response?.message ?? error?.message ?? error?.response});
const getError = error => ({
error: error?.response?.data ?? error?.response?.message ?? error?.message ?? error?.response,
});

export function registerCapCalls(app) {
app.post(Endpoint.translate, sanitizeParams, async (req, res) => {
app.post(Endpoint.translate, sanitizeParams, schemaValidator, async (req, res) => {
try {
const requester = new cote.Requester({ name: 'cap_requester_translate', timeout: SERVICE_TIMEOUT});
const request = { type:'translate', message: req.body.message, exportJson: req.body.exportJson ?? false};
const requester = new cote.Requester({ name: 'cap_requester_translate', timeout: SERVICE_TIMEOUT });
const request = { type: 'translate', message: req.body.message, exportJson: req.body.exportJson ?? false };
let r = await requester.send(request);
return (r.status!==undefined && r.error!==undefined) ? res.status(r.status).json({ error: r.error }) : res.send(r);
return r.status !== undefined && r.error !== undefined
? res.status(r.status).json({ error: r.error })
: res.send(r);
} catch (error) {
return res.status(error?.response?.status ?? HTTP_CODE.ServerError).json(getError(error));
}
Expand Down
6 changes: 4 additions & 2 deletions cap-gateway/gateway/middlewares/sanitize.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import validator from 'validator';

import { HTTP_CODE } from '../constants.js';
const getError = error => ({ error: error?.response?.data ?? error?.response?.message ?? error?.message ?? error?.response});
const getError = error => ({
error: error?.response?.data ?? error?.response?.message ?? error?.message ?? error?.response,
});

const MAX_PARAM_NAME_LENGTH = 50;
const MAX_POST_PARAM_VALUES_LENGTH = 100000;
Expand Down Expand Up @@ -47,4 +49,4 @@ export async function sanitizeParams(req, res, next) {
} catch (error) {
return res.status(error.response?.status ?? error.status ?? HTTP_CODE.ServerError).json(getError(error));
}
}
}
34 changes: 34 additions & 0 deletions cap-gateway/gateway/middlewares/schemaValidator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { readFileSync } from 'fs';
import libxml from 'libxmljs';
import logger from '../logger.js';

import { HTTP_CODE } from '../constants.js';

export async function schemaValidator(req, res, next) {
// middleware for validating received XML against provided schema XSD
try {
// Load XML and XSD files
let xmlString = req.body.message ?? '';
const xsdString = readFileSync('cap.xsd', 'utf-8');

// Parse XML and XSD
const xmlDoc = libxml.parseXml(xmlString);
const xsdDoc = libxml.parseXml(xsdString);

// Validate XML against XSD
const isValid = xmlDoc.validate(xsdDoc);

// Check validation result
if (!isValid) {
const validationErrors = xmlDoc.validationErrors;
validationErrors.forEach(error => logger.error(error.message));

return res.status(HTTP_CODE.BadRequest).json({
error: 'XML does not conform to the Common Alert Protocol 1.2 XSD Schema',
});
}
} catch (error) {
logger.error(error);
}
next();
}
Loading

0 comments on commit 66d4b1f

Please sign in to comment.