resource-watch/doc-orchestrator

View on GitHub
app/src/routes/api/v1/task.router.js

Summary

Maintainability
C
1 day
Test Coverage
B
83%
const Router = require('koa-router');
const logger = require('logger');
const TaskService = require('services/task.service');
const TaskSerializer = require('serializers/task.serializer');
const TaskNotFound = require('errors/task-not-found.error');

const router = new Router({
    prefix: '/doc-importer/task',
});

const serializeObjToQuery = (obj) => Object.keys(obj).reduce((a, k) => {
    a.push(`${k}=${encodeURIComponent(obj[k])}`);
    return a;
}, []).join('&');

const getHostForPaginationLink = (ctx) => {
    if ('x-rw-domain' in ctx.request.header) {
        return ctx.request.header['x-rw-domain'];
    }
    if ('referer' in ctx.request.header) {
        const url = new URL(ctx.request.header.referer);
        return url.host;
    }
    return ctx.request.host;
};

class TaskRouter {

    static getUser(ctx) {
        let user = { ...(ctx.request.query.loggedUser ? JSON.parse(ctx.request.query.loggedUser) : {}), ...ctx.request.body.loggedUser };
        if (ctx.request.body.fields) {
            user = Object.assign(user, JSON.parse(ctx.request.body.fields.loggedUser));
        }
        return user;
    }

    static async get(ctx) {
        const id = ctx.params.task;
        logger.info(`[TaskRouter] Getting task with id: ${id}`);
        try {
            const task = await TaskService.get(id);

            ctx.body = TaskSerializer.serialize(task);
        } catch (err) {
            if (err instanceof TaskNotFound) {
                ctx.throw(404, err.message);
                return;
            }
            throw err;
        }
    }

    static async getAll(ctx) {
        logger.info(`[TaskRouter] Getting all tasks`);
        const { query } = ctx;

        if (parseInt(query['page[size]'], 10) > 100) {
            ctx.throw(400, 'Invalid page size');
        }

        try {
            const tasks = await TaskService.getAll(query);

            const clonedQuery = { ...query };
            delete clonedQuery['page[size]'];
            delete clonedQuery['page[number]'];
            delete clonedQuery.ids;
            delete clonedQuery.loggedUser;
            const serializedQuery = serializeObjToQuery(clonedQuery) ? `?${serializeObjToQuery(clonedQuery)}&` : '?';
            const apiVersion = ctx.mountPath.split('/')[ctx.mountPath.split('/').length - 1];
            const link = `${ctx.request.protocol}://${getHostForPaginationLink(ctx)}/${apiVersion}${ctx.request.path}${serializedQuery}`;

            ctx.body = TaskSerializer.serialize(tasks, link, query.skipLogs === 'true');
        } catch (err) {
            if (err instanceof TaskNotFound) {
                ctx.throw(404, err.message);
                return;
            }
            throw err;
        }
    }

    static async delete(ctx) {
        const id = ctx.params.task;
        logger.info(`[TaskRouter] Deleting task with id: ${id}`);
        try {
            const task = await TaskService.delete(id);
            ctx.body = TaskSerializer.serialize(task);
        } catch (err) {
            if (err instanceof TaskNotFound) {
                ctx.throw(404, err.message);
                return;
            }
            throw err;
        }
    }

}

const authorizationMiddleware = async (ctx, next) => {
    logger.info(`[Task Router] Checking authorization`);
    const user = TaskRouter.getUser(ctx);
    if (!user) {
        ctx.throw(401, 'Unauthorized');
        return;
    }
    if (user.role !== 'ADMIN' && user.role !== 'SUPERADMIN') {
        ctx.throw(403, 'Forbidden');
        return;
    }
    await next();
};

router.get('/', TaskRouter.getAll);
router.get('/:task', TaskRouter.get);
router.delete('/:task', authorizationMiddleware, TaskRouter.delete);

module.exports = router;