Implement authentication and access control
This commit is contained in:
1 parent
e1bdcda191
commit
327cb78f1a
27 files changed
+600
-167
No files matched your search
+42
-9
@@ -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 = "";
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user