Files
scrypted/server/src/plugin/acl.ts
2022-12-19 10:02:29 -08:00

104 lines
2.9 KiB
TypeScript

import { EventDetails, ScryptedInterface, ScryptedUserAccessControl } from "@scrypted/types";
/**
* Scrypted Access Controls allow selective reading of state, subscription to evemts,
* and invocation of methods.
* Everything else should be rejected.
*/
export class AccessControls {
constructor(public acl: ScryptedUserAccessControl) {
}
deny(reason: string = 'User does not have permission') {
throw new Error(reason);
}
shouldRejectDevice(id: string) {
if (this.acl.devicesAccessControls === null)
return false;
if (!this.acl.devicesAccessControls)
return true;
const dacls = this.acl.devicesAccessControls.filter(dacl => dacl.id === id);
return !dacls.length;
}
shouldRejectProperty(id: string, property: string) {
if (this.acl.devicesAccessControls === null)
return false;
if (!this.acl.devicesAccessControls)
return true;
const dacls = this.acl.devicesAccessControls.filter(dacl => dacl.id === id);
for (const dacl of dacls) {
if (!dacl.properties || dacl.properties.includes(property))
return false;
}
return true;
}
shouldRejectEvent(id: string, eventDetails: EventDetails) {
if (this.acl.devicesAccessControls === null)
return false;
if (!this.acl.devicesAccessControls)
return true;
const dacls = this.acl.devicesAccessControls.filter(dacl => dacl.id === id);
const { property } = eventDetails;
if (property) {
for (const dacl of dacls) {
if (!dacl.properties || dacl.properties.includes(property))
return false;
}
}
const { eventInterface } = eventDetails;
for (const dacl of dacls) {
if (!dacl.interfaces || dacl.interfaces.includes(eventInterface))
return false;
}
return true;
}
shouldRejectInterface(id: string, scryptedInterface: ScryptedInterface) {
if (this.acl.devicesAccessControls === null)
return false;
if (!this.acl.devicesAccessControls)
return true;
const dacls = this.acl.devicesAccessControls.filter(dacl => dacl.id === id);
for (const dacl of dacls) {
if (!dacl.interfaces || dacl.interfaces.includes(scryptedInterface))
return false;
}
return true;
}
shouldRejectMethod(id: string, method: string) {
if (this.acl.devicesAccessControls === null)
return false;
if (!this.acl.devicesAccessControls)
return true;
const dacls = this.acl.devicesAccessControls.filter(dacl => dacl.id === id);
for (const dacl of dacls) {
if (!dacl.methods || dacl.methods.includes(method))
return false;
}
return true;
}
}