90 lines
1.8 KiB
TypeScript
90 lines
1.8 KiB
TypeScript
import Session from "./session";
|
|
|
|
interface IRule<T> {
|
|
".write"?: T
|
|
".read"?: T
|
|
}
|
|
|
|
type IRuleConfig<T> = {
|
|
[segment: string]: IRuleConfig<T>;
|
|
} | IRule<T>;
|
|
|
|
type IRuleRaw = IRuleConfig<string>;
|
|
type IRuleParsed = IRuleConfig<boolean>;
|
|
|
|
const resolve = (value: any) => {
|
|
if (value === true) {
|
|
return true;
|
|
} else if (typeof value === "string") {
|
|
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export class Rules {
|
|
rules: IRuleParsed;
|
|
constructor(private config: string) {
|
|
let parsed: IRuleRaw = JSON.parse(config);
|
|
|
|
const analyze = (raw: IRuleRaw) => {
|
|
let r: IRuleParsed = {};
|
|
|
|
if (raw[".read"]) {
|
|
let res = resolve(raw[".read"]);
|
|
if (res) {
|
|
r[".read"] = res;
|
|
}
|
|
delete raw[".read"];
|
|
}
|
|
|
|
if (raw[".write"]) {
|
|
let res = resolve(raw[".write"]);
|
|
if (res) {
|
|
r[".write"] = res;
|
|
}
|
|
delete raw[".write"];
|
|
}
|
|
|
|
for (let segment in raw) {
|
|
if (segment.startsWith("."))
|
|
continue;
|
|
|
|
r[segment] = analyze(raw[segment]);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
this.rules = analyze(parsed);
|
|
}
|
|
|
|
hasPermission(path: string[], session: Session) {
|
|
let read = this.rules[".read"] || false;
|
|
let write = this.rules[".write"] || false;
|
|
|
|
let rules = this.rules;
|
|
|
|
for (let segment of path) {
|
|
rules = rules[segment];
|
|
if (rules[segment]) {
|
|
if (rules[".read"]) {
|
|
read = rules[".read"]
|
|
}
|
|
|
|
if (rules[".write"]) {
|
|
read = rules[".write"]
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return {
|
|
read,
|
|
write
|
|
}
|
|
}
|
|
|
|
toJSON() {
|
|
return this.config;
|
|
}
|
|
} |