141 lines
4.7 KiB
JavaScript
141 lines
4.7 KiB
JavaScript
"use strict";
|
|
|
|
const Router = require("koa-router");
|
|
|
|
const db = require("./db");
|
|
const apiFunctions = require("./api-functions");
|
|
const Filter = require("../common/filter");
|
|
|
|
const router = new Router();
|
|
|
|
const RESOURCE_DELETE = 1 << 0;
|
|
const RESOURCE_DB = 1 << 1;
|
|
|
|
const resources = {
|
|
devices: 0 | RESOURCE_DELETE,
|
|
presets: 0 | RESOURCE_DELETE,
|
|
provisions: 0 | RESOURCE_DELETE,
|
|
files: 0 | RESOURCE_DELETE,
|
|
virtual_parameters: 0 | RESOURCE_DELETE,
|
|
faults: 0 | RESOURCE_DELETE,
|
|
tasks: 0
|
|
};
|
|
|
|
for (let [resource, flags] of Object.entries(resources)) {
|
|
router.head(`/${resource}`, async (ctx, next) => {
|
|
let filter, limit;
|
|
if (ctx.request.query.filter) filter = new Filter(ctx.request.query.filter);
|
|
if (ctx.request.query.limit) limit = +ctx.request.query.limit;
|
|
|
|
if (!ctx.state.authorizer.hasAccess(resource, 1)) return next();
|
|
|
|
// Exclude temporary tasks and faults
|
|
if (resource === "tasks" || resource === "faults") {
|
|
let f = new Filter(["NOT", ["<", "expiry", Date.now() + 60000]]);
|
|
filter = f.and(filter);
|
|
}
|
|
|
|
let count;
|
|
if (flags & RESOURCE_DB) count = await db.count(resource, filter, limit);
|
|
else count = await apiFunctions.count(resource, filter, limit);
|
|
|
|
ctx.set("X-Total-Count", count);
|
|
ctx.body = "";
|
|
});
|
|
|
|
router.get(`/${resource}`, async (ctx, next) => {
|
|
let filter, limit, skip, projection;
|
|
if (ctx.request.query.filter) filter = new Filter(ctx.request.query.filter);
|
|
if (ctx.request.query.limit) limit = +ctx.request.query.limit;
|
|
if (ctx.request.query.skip) skip = +ctx.request.query.skip;
|
|
if (ctx.request.query.projection) projection = ctx.request.query.projection;
|
|
|
|
if (!ctx.state.authorizer.hasAccess(resource, 2)) return next();
|
|
|
|
// Exclude temporary tasks and faults
|
|
if (resource === "tasks" || resource === "faults") {
|
|
let f = new Filter(["NOT", ["<", "expiry", Date.now() + 60000]]);
|
|
filter = f.and(filter);
|
|
}
|
|
|
|
let res;
|
|
if (flags & RESOURCE_DB)
|
|
res = await db.query(resource, filter, limit, skip);
|
|
else
|
|
res = await apiFunctions.query(resource, filter, limit, skip, projection);
|
|
|
|
ctx.body = res;
|
|
});
|
|
|
|
router.head(`/${resource}/:id`, async (ctx, next) => {
|
|
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
|
|
if (!ctx.state.authorizer.hasAccess(resource, 2)) return next();
|
|
|
|
let res;
|
|
if (flags & RESOURCE_DB) res = await db.query(resource, filter);
|
|
else res = await apiFunctions.query(resource, filter);
|
|
|
|
if (!res.length) return next();
|
|
ctx.body = "";
|
|
});
|
|
|
|
router.get(`/${resource}/:id`, async (ctx, next) => {
|
|
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
|
|
if (!ctx.state.authorizer.hasAccess(resource, 2)) return next();
|
|
|
|
let res;
|
|
if (flags & RESOURCE_DB) res = await db.query(resource, filter);
|
|
else res = await apiFunctions.query(resource, filter);
|
|
if (!res.length) return next();
|
|
ctx.body = res[0];
|
|
});
|
|
|
|
// TODO add PUT, PATCH routes
|
|
if (flags & RESOURCE_DELETE && !(flags & RESOURCE_DB))
|
|
router.delete(`/${resource}/:id`, async (ctx, next) => {
|
|
const authorizer = ctx.state.authorizer;
|
|
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
|
|
if (!authorizer.hasAccess(resource, 2)) return next();
|
|
let res = await apiFunctions.query(resource, filter);
|
|
if (!res.length) return next();
|
|
|
|
const validate = authorizer.getValidator(resource, res[0]);
|
|
if (!validate("delete")) return (ctx.status = 403);
|
|
|
|
await apiFunctions.deleteResource(resource, ctx.params.id);
|
|
ctx.body = "";
|
|
});
|
|
}
|
|
|
|
router.post("/devices/:id/tasks", async (ctx, next) => {
|
|
const authorizer = ctx.state.authorizer;
|
|
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
|
|
if (!authorizer.hasAccess("devices", 2)) return next();
|
|
let devices = await apiFunctions.query("devices", filter);
|
|
if (!devices.length) return next();
|
|
|
|
const validate = authorizer.getValidator("devices", devices[0]);
|
|
for (let t of ctx.request.body)
|
|
if (!validate("task", t)) return (ctx.status = 403);
|
|
|
|
let res = await apiFunctions.postTasks(ctx.params.id, ctx.request.body);
|
|
ctx.set("Connection-Request", res.connectionRequest);
|
|
ctx.body = res.tasks;
|
|
});
|
|
|
|
router.post("/devices/:id/tags", async (ctx, next) => {
|
|
const authorizer = ctx.state.authorizer;
|
|
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
|
|
if (!authorizer.hasAccess("devices", 2)) return next();
|
|
let res = await apiFunctions.query("devices", filter);
|
|
if (!res.length) return next();
|
|
|
|
const validate = authorizer.getValidator("devices", res[0]);
|
|
if (!validate("tags", ctx.request.body)) return (ctx.status = 403);
|
|
|
|
await apiFunctions.updateTags(ctx.params.id, ctx.request.body);
|
|
ctx.body = "";
|
|
});
|
|
|
|
module.exports = router;
|