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:
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(){