Implement authentication and access control

This commit is contained in:
Zaid Abdulla committed 2018-12-26 00:22:07 -08:00
1 parent e1bdcda191
commit 327cb78f1a
27 files changed
+600 -167

No files matched your search

+42 -9
View File
@@ -18,11 +18,13 @@ const resources = {
};
for (let [resource, update] of Object.entries(resources)) {
router.head(`/${resource}`, async ctx => {
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]]);
@@ -34,12 +36,14 @@ for (let [resource, update] of Object.entries(resources)) {
ctx.body = "";
});
router.get(`/${resource}`, async ctx => {
router.get(`/${resource}`, async (ctx, next) => {
let filter, limit, skip;
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.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]]);
@@ -57,6 +61,8 @@ for (let [resource, update] of Object.entries(resources)) {
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 = await apiFunctions.query(resource, filter);
if (!res.length) return next();
ctx.body = "";
@@ -64,6 +70,8 @@ for (let [resource, update] of Object.entries(resources)) {
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 = await apiFunctions.query(resource, filter);
if (!res.length) return next();
ctx.body = res[0];
@@ -71,22 +79,47 @@ for (let [resource, update] of Object.entries(resources)) {
// TODO add PUT, PATCH routes
if (update)
router.delete(`/${resource}/:id`, async ctx => {
let found = await apiFunctions.deleteResource(resource, ctx.params.id);
if (found) ctx.status = 200;
else ctx.status = 404;
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 => {
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);
// TODO 404 if no such device
ctx.set("Connection-Request", res.connectionRequest);
ctx.body = res.tasks;
});
router.post("/devices/:id/tags", async ctx => {
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 = "";
});