BastliBridge

A bot framework bridgin multiple IM protocols, and mail
git clone git://xatko.vsos.ethz.ch/BastliBridge.git
Log | Files | Refs | Submodules

commit 3c4e54212a06880a44efd0aa4195573d068207d4
parent d9629eadead38454b7eea50bf4182b8e5e7554ae
Author: Dominik Schmidt <dominik@schm1dt.ch>
Date:   Wed,  5 Sep 2018 13:52:20 +0200

Add admin-handling for IRC and commandMachine

Diffstat:
src/bastlibridge/bot.d | 10+++++-----
src/bastlibridge/command.d | 48++++++++++++++++++++++++++++++++----------------
src/bastlibridge/interfaces/irc.d | 24++++++++++++++++++++++--
3 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/src/bastlibridge/bot.d b/src/bastlibridge/bot.d @@ -91,11 +91,11 @@ struct IDCounter(T){ static this(){ - globalCommands.add!((Message m, in char[] a, in char[] b){m.source.manager.link(a,b);})("link"); - globalCommands.add!((Message m, in char[] a, in char[] b){m.source.manager.linkDirected(a,b);})("linkDirected"); - globalCommands.add!((Message m, in char[] b){m.source.manager.link(m.source.name~":"~m.getChannelName(),b);})("linkWith"); - globalCommands.add!((Message m){m.source.stop();})("quit"); - globalCommands.add!((Message m){m.source.manager.teardown();})("teardown"); + globalCommands.add!((Message m, in char[] a, in char[] b){m.source.manager.link(a,b);})("link", CommandOptions(true)); + globalCommands.add!((Message m, in char[] a, in char[] b){m.source.manager.linkDirected(a,b);})("linkDirected", CommandOptions(true)); + globalCommands.add!((Message m, in char[] b){m.source.manager.link(m.source.name~":"~m.getChannelName(),b);})("linkWith", CommandOptions(true)); + globalCommands.add!((Message m){m.source.stop();})("quit", CommandOptions(true)); + globalCommands.add!((Message m){m.source.manager.teardown();})("teardown", CommandOptions(true)); globalCommands.add!((Message m, in char[] other){m.respond(enforce(m.source.manager.getEndpoint(other),"Endpoint unknown").endpoint.lastSeen());})("lastUpdate"); } diff --git a/src/bastlibridge/command.d b/src/bastlibridge/command.d @@ -16,25 +16,38 @@ class CommandException : Exception{ } } +struct CommandOptions{ + bool admin=false; +} + struct CommandMachine{ struct Function{ void function(Message m, in char[] args) func; - bool need_auth=false; + CommandOptions co; } Function[string] commands; - auto execute(in char[] name, Message m, in char[] args) + bool available(in char[] name){ + return cast(bool)(name in commands); + } + + void execute(in char[] name, Message m, in char[] args) in{ assert(name); assert(m); } do{ - auto cmd=enforce!CommandException(name in commands, format("Command %s unknown", name)); - assert(cmd); - if(cmd.need_auth && !m.auth()){ - throw new CommandException("Permission denied"); + try{ + auto cmd=enforce!CommandException(name in commands, format("Command %s unknown", name)); + if(cmd.co.admin && !m.auth()){ + throw new CommandException("Permission denied"); + } + cmd.func(m, args); + } + catch(Exception e){ + m.respond(e.msg); + warning(e.toString); } - return cmd.func(m, args); } static void wrapperFunction(alias T)(Message m, in char[] args) if(isCallable!T){ @@ -51,18 +64,21 @@ struct CommandMachine{ auto ref evaluate(alias Func)(){ return Func(pop()); } - - try{ - T(m, staticMap!(evaluate, fct)); + + T(m, staticMap!(evaluate, fct)); + } + + void add(alias T)(string name){ + static if(hasUDA!(T, CommandOptions)){ + add!T(name, getUDA!(T, CommandOptions)); } - catch(Exception e){ - m.respond(e.msg); - warning(e.toString); + else{ + add!T(name, CommandOptions.init); } + } - - void add(alias T)(string name) if(isCallable!T && is(Parameters!T[0] == Message)){ - commands[name]=Function(&wrapperFunction!T, hasUDA!(T, "admin")); + void add(alias T)(string name, CommandOptions co) if(isCallable!T && is(Parameters!T[0] == Message)){ + commands[name]=Function(&wrapperFunction!T, co); } } CommandMachine globalCommands; diff --git a/src/bastlibridge/interfaces/irc.d b/src/bastlibridge/interfaces/irc.d @@ -54,7 +54,11 @@ final class IRCMessage : Message{ } override bool auth(){ - return user.nickName=="Doeme"; + bool* val=user.nickName in (cast(IRC)source).admins; + if(!val){ + return false; + } + return *val; } override void respond(in char[] r){ @@ -180,6 +184,8 @@ final class IRC : QueuedEndpoint{ } } + bool[string] admins; + this(Manager m, string args){ super(m,args); @@ -202,6 +208,9 @@ final class IRC : QueuedEndpoint{ case "nick": nick=s[2]; break; + case "admin": + admins[s[2]]=true; + break; default: info = irc.url.parse(cast(string)s[0]); have_addr=true; @@ -255,9 +264,20 @@ final class IRC : QueuedEndpoint{ this.manager.distribute(Port(this,chan), msg); } + static CommandMachine ircCommands; + static this(){ + ircCommands.add!((Message m, const(char)[] name){(cast(IRC)m.source).admins[name.idup]=true;})("addAdmin", CommandOptions(true)); + ircCommands.add!((Message m, const(char)[] name){(cast(IRC)m.source).admins[name.idup]=false;})("removeAdmin", CommandOptions(true)); + } + void onCommand(IRCMessage msg){ auto s=msg.msg[commandPrefix.length+1..$].findSplit(" "); - globalCommands.execute(s[0], msg, s[2]); + if(ircCommands.available(s[0])){ + ircCommands.execute(s[0], msg, s[2]); + } + else{ + globalCommands.execute(s[0], msg, s[2]); + } } override void open(){