131 lines
3.1 KiB
TypeScript
131 lines
3.1 KiB
TypeScript
import {
|
|
Plugin,
|
|
EventListener,
|
|
Configurable,
|
|
} from '@squeebot/core/lib/plugin';
|
|
|
|
import { logger } from '@squeebot/core/lib/core';
|
|
import { IMessage } from '@squeebot/core/lib/types';
|
|
import { fullIDMatcher } from '@squeebot/core/lib/common';
|
|
|
|
/*
|
|
users: {
|
|
'service/instance/name': [
|
|
'one',
|
|
'two',
|
|
'*'
|
|
]
|
|
},
|
|
rooms: {
|
|
'service/instance/room': {
|
|
'service/instance/name': [
|
|
'three',
|
|
'four',
|
|
]
|
|
}
|
|
}
|
|
*/
|
|
|
|
declare type RoleReceiver = (msg: IMessage) => string[];
|
|
|
|
@Configurable({users: {}, rooms: {}})
|
|
class PermissionsPlugin extends Plugin {
|
|
public roleReceivers: Map<string, RoleReceiver> = new Map<string, RoleReceiver>();
|
|
|
|
registerRoleReceiver(plugin: string, fn: RoleReceiver): void {
|
|
if (this.roleReceivers.has(plugin)) {
|
|
return;
|
|
}
|
|
|
|
this.roleReceivers.set(plugin, fn);
|
|
}
|
|
|
|
userPermitted(msg: IMessage, required: string[]): boolean {
|
|
// Boot all guests instantly
|
|
if (msg.guest === true) {
|
|
return false;
|
|
}
|
|
|
|
// Receive permissions from a role fetching function registered by
|
|
// a service or service adapter
|
|
const rr = this.roleReceivers.get(msg.source.plugin.manifest.name);
|
|
const userRoles = [];
|
|
if (rr) {
|
|
userRoles.push(...rr(msg));
|
|
}
|
|
|
|
const userFull = msg.fullSenderID;
|
|
const roomFull = msg.fullRoomID;
|
|
if (!userFull || !roomFull) {
|
|
return false;
|
|
}
|
|
|
|
// Check for room access
|
|
for (const ch in this.config.config.rooms) {
|
|
if (fullIDMatcher(roomFull, ch)) {
|
|
const users = this.config.config.rooms[ch];
|
|
for (const user in users) {
|
|
if (fullIDMatcher(userFull, user)) {
|
|
const perms = [...users[user], ...userRoles];
|
|
|
|
let has = false;
|
|
for (const perm of required) {
|
|
if (perms.indexOf(perm) !== -1) {
|
|
has = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (has) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for per-user-basis permissions
|
|
for (const user in this.config.config.users) {
|
|
if (fullIDMatcher(userFull, user)) {
|
|
const perms = this.config.config.users[user];
|
|
if (perms.indexOf('*') !== -1) {
|
|
return true;
|
|
}
|
|
|
|
let has = false;
|
|
for (const perm of required) {
|
|
if (perms.indexOf(perm) !== -1) {
|
|
has = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (has) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@EventListener('pluginUnload')
|
|
unloadEventHandler(plugin: string | Plugin): void {
|
|
if (plugin === this.name || plugin === this) {
|
|
logger.debug('[%s]', this.name, 'shutting down..');
|
|
this.config.save().then(() =>
|
|
this.emit('pluginUnloaded', this));
|
|
}
|
|
}
|
|
|
|
@EventListener('pluginUnloaded')
|
|
unloadedEventHandler(plugin: string | Plugin): void {
|
|
const str = (typeof plugin === 'string' ? plugin : plugin.manifest.name);
|
|
if (this.roleReceivers.has(str)) {
|
|
this.roleReceivers.delete(str);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = PermissionsPlugin;
|