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
@@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
|
||||
const validators = {
|
||||
pass: require("./validators/pass"),
|
||||
test: require("./validators/test")
|
||||
};
|
||||
|
||||
class Authorizer {
|
||||
constructor(permissionSets) {
|
||||
this.permissionSets = permissionSets;
|
||||
this.validtorCache = new WeakMap();
|
||||
this.hasAccessCache = {};
|
||||
}
|
||||
|
||||
hasAccess(resourceType, access) {
|
||||
const cacheKey = `${resourceType}-${access}`;
|
||||
if (cacheKey in this.hasAccessCache)
|
||||
return this.hasAccessCache[cacheKey];
|
||||
|
||||
let has = false;
|
||||
for (const permissionSet of this.permissionSets) {
|
||||
for (const perm of permissionSet) {
|
||||
if (perm[resourceType]) {
|
||||
if (perm[resourceType].access >= access) {
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.hasAccessCache[cacheKey] = has;
|
||||
return has;
|
||||
}
|
||||
|
||||
getValidator(resourceType, resource) {
|
||||
if (this.validtorCache.has(resource))
|
||||
return this.validtorCache.get(resource);
|
||||
|
||||
let funcs = {};
|
||||
|
||||
for (let permissionSet of this.permissionSets)
|
||||
for (let perm of permissionSet)
|
||||
if (perm[resourceType]) {
|
||||
if (perm[resourceType].access >= 3) {
|
||||
if (perm[resourceType].validate)
|
||||
for (let [k, v] of Object.entries(perm[resourceType].validate))
|
||||
funcs[k] = v;
|
||||
} else {
|
||||
funcs = {};
|
||||
}
|
||||
}
|
||||
|
||||
const validator = (mutationType, mutation, any) => {
|
||||
let valid = false;
|
||||
for (let [k, v] of Object.entries(funcs))
|
||||
if (v) {
|
||||
let res = validators[k](
|
||||
resourceType,
|
||||
resource,
|
||||
mutationType,
|
||||
mutation,
|
||||
any
|
||||
);
|
||||
|
||||
if (res > 0) valid = true;
|
||||
else if (res < 0) return false;
|
||||
}
|
||||
|
||||
return valid;
|
||||
};
|
||||
|
||||
this.validtorCache.set(resource, validator);
|
||||
return validator;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Authorizer;
|
||||
+5
-3
@@ -17,9 +17,10 @@ function* permute(arr) {
|
||||
|
||||
class Filter {
|
||||
constructor(str) {
|
||||
if (Array.isArray(str)) this.ast = str;
|
||||
if (!str) this.ast = null;
|
||||
else if (Array.isArray(str)) this.ast = str;
|
||||
else if (str instanceof Filter) this.ast = str.ast;
|
||||
else if (!str) this.ast = null;
|
||||
else if (Array.isArray(str.ast) || str.ast === null) this.ast = str.ast;
|
||||
else this.ast = filterParser.parse(str);
|
||||
}
|
||||
|
||||
@@ -33,6 +34,7 @@ class Filter {
|
||||
|
||||
or(fltr) {
|
||||
if (!fltr || !this.ast) return this;
|
||||
else if (!fltr.ast) return fltr;
|
||||
|
||||
let f = ["OR"];
|
||||
|
||||
@@ -46,7 +48,7 @@ class Filter {
|
||||
}
|
||||
|
||||
and(fltr) {
|
||||
if (!fltr) return this;
|
||||
if (!fltr || !fltr.ast) return this;
|
||||
else if (!this.ast) return fltr;
|
||||
|
||||
let f = ["AND"];
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
function pass() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
module.exports = pass;
|
||||
@@ -0,0 +1,14 @@
|
||||
function test(resourceType, resource) {
|
||||
if (resourceType === "devices") {
|
||||
if (resource["Tags.test"] && resource["Tags.test"].value[0]) return 1;
|
||||
} else if (resourceType === "presets") {
|
||||
if (resource["_id"].startsWith("test-"))
|
||||
// TODO check "test" tag too
|
||||
return 1;
|
||||
} else if (resourceType === "provisions") {
|
||||
if (resource["_id"].startsWith("test-")) return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
module.exports = test;
|
||||
Reference in new issue
Block a user