remove keyword handling for now, remove asterisk matching from room permissions, add role system
This commit is contained in:
parent
0e5e15170c
commit
51561a1d42
@ -3,7 +3,7 @@
|
|||||||
"name": "permissions",
|
"name": "permissions",
|
||||||
"description": "Official permissions system for commands",
|
"description": "Official permissions system for commands",
|
||||||
"tags": ["api", "permissions"],
|
"tags": ["api", "permissions"],
|
||||||
"version": "0.0.0",
|
"version": "0.1.0",
|
||||||
"dependencies": ["control?"],
|
"dependencies": ["control?"],
|
||||||
"npmDependencies": []
|
"npmDependencies": []
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,34 @@ import { fullIDMatcher } from '@squeebot/core/lib/common';
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
declare type RoleReceiver = (msg: IMessage) => string[];
|
||||||
|
|
||||||
@Configurable({users: {}, rooms: {}})
|
@Configurable({users: {}, rooms: {}})
|
||||||
class PermissionsPlugin extends Plugin {
|
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 {
|
userPermitted(msg: IMessage, required: string[]): boolean {
|
||||||
// Boot all guests instantly
|
// Boot all guests instantly
|
||||||
if (msg.guest === true) {
|
if (msg.guest === true) {
|
||||||
return false;
|
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 userFull = msg.fullSenderID;
|
||||||
const roomFull = msg.fullRoomID;
|
const roomFull = msg.fullRoomID;
|
||||||
if (!userFull || !roomFull) {
|
if (!userFull || !roomFull) {
|
||||||
@ -46,18 +66,10 @@ class PermissionsPlugin extends Plugin {
|
|||||||
const users = this.config.config.rooms[ch];
|
const users = this.config.config.rooms[ch];
|
||||||
for (const user in users) {
|
for (const user in users) {
|
||||||
if (fullIDMatcher(userFull, user)) {
|
if (fullIDMatcher(userFull, user)) {
|
||||||
const perms = users[user];
|
const perms = [...users[user], ...userRoles];
|
||||||
if (perms.indexOf('*') !== -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let has = false;
|
let has = false;
|
||||||
for (const perm of required) {
|
for (const perm of required) {
|
||||||
if (perm === '*') {
|
|
||||||
has = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perms.indexOf(perm) !== -1) {
|
if (perms.indexOf(perm) !== -1) {
|
||||||
has = true;
|
has = true;
|
||||||
break;
|
break;
|
||||||
@ -82,11 +94,6 @@ class PermissionsPlugin extends Plugin {
|
|||||||
|
|
||||||
let has = false;
|
let has = false;
|
||||||
for (const perm of required) {
|
for (const perm of required) {
|
||||||
if (perm === '*') {
|
|
||||||
has = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perms.indexOf(perm) !== -1) {
|
if (perms.indexOf(perm) !== -1) {
|
||||||
has = true;
|
has = true;
|
||||||
break;
|
break;
|
||||||
@ -110,6 +117,14 @@ class PermissionsPlugin extends Plugin {
|
|||||||
this.emit('pluginUnloaded', this));
|
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;
|
module.exports = PermissionsPlugin;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "simplecommands",
|
"name": "simplecommands",
|
||||||
"description": "Official Simplistic Commands API for Squeebot 3",
|
"description": "Official Simplistic Commands API for Squeebot 3",
|
||||||
"tags": ["handler", "commands", "api"],
|
"tags": ["handler", "commands", "api"],
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"dependencies": ["control?", "permissions?"],
|
"dependencies": ["control?", "permissions?"],
|
||||||
"npmDependencies": []
|
"npmDependencies": []
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ const rates: {[key: string]: Rate} = {};
|
|||||||
prefix: {
|
prefix: {
|
||||||
'*': '!'
|
'*': '!'
|
||||||
},
|
},
|
||||||
keywords: ['squeebot'],
|
|
||||||
rateLimits: [],
|
rateLimits: [],
|
||||||
channelMatching: false,
|
channelMatching: false,
|
||||||
})
|
})
|
||||||
@ -238,83 +237,6 @@ class SqueebotCommandsAPIPlugin extends Plugin {
|
|||||||
// Done
|
// Done
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handleKeywords(
|
|
||||||
msg: IMessage,
|
|
||||||
keyword: string,
|
|
||||||
plugins: string[],
|
|
||||||
msr: MessageResolver): Promise<void> {
|
|
||||||
const text = msg.text.toLowerCase();
|
|
||||||
|
|
||||||
// Only pass command specs which have `match` and match rooms
|
|
||||||
let matching = [];
|
|
||||||
for (const spec of this.commands) {
|
|
||||||
if (!spec.match) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugins.length && plugins.indexOf(spec.plugin) === -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof spec.match === 'function') {
|
|
||||||
try {
|
|
||||||
const match = spec.match(msg);
|
|
||||||
if (match == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
spec.tempargv = match;
|
|
||||||
} catch (e) {}
|
|
||||||
} else {
|
|
||||||
const rgx = text.match(spec.match);
|
|
||||||
if (rgx == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
spec.tempargv = rgx.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
matching.push(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
matching = this.roomMatcher(msg, matching);
|
|
||||||
|
|
||||||
// Nothing matches room requirements
|
|
||||||
if (!matching.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iteration 2: Sort the array so that the ones that had room matching come up first
|
|
||||||
const sorted = [];
|
|
||||||
for (const spec of matching) {
|
|
||||||
if (spec.source) {
|
|
||||||
sorted.push(spec);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sorted.push(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iteration 3: Match permissions for user
|
|
||||||
const permitted = this.permissionMatcher(msg, sorted);
|
|
||||||
|
|
||||||
// Rate limit check
|
|
||||||
if (permitted.length &&
|
|
||||||
this.config.get('rateLimits', []).length &&
|
|
||||||
this.doLimiting(msg.fullRoomID!, msg.fullSenderID!)) {
|
|
||||||
logger.warn('[%s] User %s rate limited', this.name, msg.fullSenderID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start executing
|
|
||||||
for (const spec of permitted) {
|
|
||||||
const success = await spec.execute(msg, msr, spec, keyword,
|
|
||||||
...(spec.tempargv ? spec.tempargv : []));
|
|
||||||
if (success) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener('message')
|
@EventListener('message')
|
||||||
public digest(msg: IMessage, chan: IChannel, msr: MessageResolver): void {
|
public digest(msg: IMessage, chan: IChannel, msr: MessageResolver): void {
|
||||||
if (msg.type !== EMessageType.message) {
|
if (msg.type !== EMessageType.message) {
|
||||||
@ -328,18 +250,6 @@ class SqueebotCommandsAPIPlugin extends Plugin {
|
|||||||
|
|
||||||
const text = msg.text;
|
const text = msg.text;
|
||||||
const prefixes = this.config.config.prefix;
|
const prefixes = this.config.config.prefix;
|
||||||
const keywords = this.config.config.keywords;
|
|
||||||
|
|
||||||
// Attempt to match keywords
|
|
||||||
if (keywords && keywords.length) {
|
|
||||||
for (const kw of keywords) {
|
|
||||||
if (text.toLowerCase().match(kw) != null) {
|
|
||||||
this.handleKeywords(msg, kw, allowedPlugins, msr).catch(e =>
|
|
||||||
logger.error('[%s] Command handler threw an error:', this.name, e.stack));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!prefixes) {
|
if (!prefixes) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user