New authorization checking API

This commit is contained in:
Juhani Haverinen 2015-02-22 17:25:51 +02:00
parent 8c293eff11
commit a10f4aeb61
1 changed files with 75 additions and 64 deletions

139
botcmd.py
View File

@ -15,10 +15,8 @@ gods=[]
godslock=threading.Lock() godslock=threading.Lock()
msgs={} msgs={}
msglock=threading.Lock() msglock=threading.Lock()
authcmds={} authcheck={}
authcmdlock=threading.Lock() authchecklock=threading.Lock()
authfuncs={}
authfunclock=threading.Lock()
die_expr=re.compile("#[0-9]*d([0-9]+|%)") die_expr=re.compile("#[0-9]*d([0-9]+|%)")
@ -119,33 +117,67 @@ def savetrusted():
loadtrusted() loadtrusted()
loadgods() loadgods()
def addauthcmd(nick,cmd):
authcmdlock.acquire()
trustedlock.acquire()
if nick in trusted:
if nick not in authcmds:
authcmds[nick]=[]
authcmds[nick].append(cmd)
trustedlock.release()
authcmdlock.release()
def addauthfunc(nick,f):
authfunclock.acquire()
trustedlock.acquire()
if nick in trusted:
if nick not in authfuncs:
authfuncs[nick]=[]
authfuncs[nick].append(f)
trustedlock.release()
authfunclock.release()
def chmode(irc,chan,nick,mode,args): def chmode(irc,chan,nick,mode,args):
if len(args)==0: if len(args)==0:
addauthcmd(nick,'MODE %s %s %s'%(chan,mode,nick)) if isauthorized(irc, nick):
irc.send('MODE %s %s %s'%(chan,mode,nick))
else: else:
for name in args: for name in args:
addauthcmd(nick,'MODE %s %s %s'%(chan,mode,name)) if isauthorized(irc, nick):
irc.msg('NickServ', 'ACC '+nick) irc.send('MODE %s %s %s'%(chan,mode,name))
def istrusted(nick):
trustedlock.acquire()
if nick in trusted:
trustedlock.release()
return True
else:
trustedlock.release()
return False
def initauthcheck(nick):
global authcheck, authchecklock
authchecklock.acquire()
authcheck[nick]=None
authchecklock.release()
def setauthcheckstate(nick, state):
global authcheck, authchecklock
authchecklock.acquire()
if nick in authcheck:
authcheck[nick]=state
authchecklock.release()
def getauthcheckstate(nick):
global authcheck, authchecklock
authchecklock.acquire()
if nick in authcheck:
state=authcheck[nick]
authchecklock.release()
return state
def removeauthcheck(nick):
global authcheck, authchecklock
authchecklock.acquire()
if nick in authcheck:
del authcheck[nick]
authchecklock.release()
def isauthorized(irc, nick):
if not istrusted(nick):
return False
initauthcheck(nick)
irc.msg('NickServ', 'acc '+nick)
cron.queuejob(5, (lambda : setauthcheckstate(nick, False)))
state=None
while state==None:
state=getauthcheckstate(nick)
time.sleep(0.1)
removeauthcheck(nick)
return state
def parse((line,irc)): def parse((line,irc)):
line=line.split(' ') line=line.split(' ')
@ -175,8 +207,8 @@ def parse((line,irc)):
elif random.randint(0,9)==0 and len(line)==5: elif random.randint(0,9)==0 and len(line)==5:
irc.send('KICK %s %s :Bam'%(chan,nick)) irc.send('KICK %s %s :Bam'%(chan,nick))
else: else:
addauthcmd(nick,'KICK %s %s :%s'%(chan,line[4],' '.join(line[5:]))) if isauthorized(irc, nick):
irc.msg('NickServ', 'ACC '+nick) irc.send('KICK %s %s :%s'%(chan,line[4],' '.join(line[5:])))
else: else:
irc.msg(chan, 'Usage #kick nick reason') irc.msg(chan, 'Usage #kick nick reason')
elif line[3]==':#src': elif line[3]==':#src':
@ -200,21 +232,22 @@ def parse((line,irc)):
trustnick=nick trustnick=nick
else: else:
irc.msg(chan, 'Usage #trusted? [nick]') irc.msg(chan, 'Usage #trusted? [nick]')
if trustnick: if istrusted(nick):
addauthcmd(trustnick,'PRIVMSG %s :%s is trusted'%(chan,trustnick)) irc.msg(chan, '%s is trusted')
irc.msg('NickServ', 'ACC '+trustnick) else:
irc.msg(chan, '%s is not trusted')
elif line[3]==':#trust': elif line[3]==':#trust':
if len(line)==5: if len(line)==5:
addauthfunc(nick,(lambda :addtrusted(line[4]))) if isauthorized(irc, nick):
irc.msg('NickServ', 'ACC '+nick) addtrusted(line[4])
else: else:
irc.msg(chan, 'Usage #trust nick') irc.msg(chan, 'Usage #trust nick')
elif line[3]==':#untrust': elif line[3]==':#untrust':
if len(line)==5: if len(line)==5:
godslock.acquire() godslock.acquire()
if line[4] not in gods: if line[4] not in gods:
addauthfunc(nick,(lambda :rmtrusted(line[4]))) if isauthorized(irc, nick):
irc.msg('NickServ', 'ACC '+nick) rmtrusted(line[4])
godslock.release() godslock.release()
else: else:
irc.msg(chan, 'Usage #untrust nick') irc.msg(chan, 'Usage #untrust nick')
@ -224,8 +257,8 @@ def parse((line,irc)):
trustedlock.release() trustedlock.release()
elif line[3]==':#invite': elif line[3]==':#invite':
if len(line)==5: if len(line)==5:
addauthcmd(nick, 'INVITE %s %s'%(line[4], chan)) if authorized(irc, nick):
irc.msg('NickServ', 'ACC '+nick) irc.send('INVITE %s %s' % (line[4], chan))
else: else:
irc.msg(chan, 'Usage #invite nick') irc.msg(chan, 'Usage #invite nick')
elif line[3]==':#help': elif line[3]==':#help':
@ -234,11 +267,6 @@ def parse((line,irc)):
irc.msg(chan, helptext) irc.msg(chan, helptext)
elif line[3]==':#esoteric' and chan=='#esoteric': elif line[3]==':#esoteric' and chan=='#esoteric':
irc.msg(chan, 'Nothing here') irc.msg(chan, 'Nothing here')
elif line[3]==':#cron':
if len(line)>=6:
cron.queuejob(int(line[4]), (lambda : irc.msg(chan, ' '.join(line[5:]))))
else:
irc.msg(chan, 'Usage #cron time message')
elif line[3][1:] in [irc.nick, irc.nick+',', irc.nick+':']: elif line[3][1:] in [irc.nick, irc.nick+',', irc.nick+':']:
irc.msg(chan, '%s: %s' % (nick, doctor.respond(' '.join(line[4:])))) irc.msg(chan, '%s: %s' % (nick, doctor.respond(' '.join(line[4:]))))
elif die_expr.match(line[3][1:]): elif die_expr.match(line[3][1:]):
@ -264,36 +292,19 @@ def parse((line,irc)):
else: else:
irc.msg(chan, str(result)) irc.msg(chan, str(result))
elif line[1]=='NOTICE' and line[0].split('!')[0]==':NickServ' and line[4]=='ACC': elif line[1]=='NOTICE' and line[0].split('!')[0]==':NickServ' and line[4]=='ACC':
authfunclock.acquire()
authcmdlock.acquire()
if line[5]=='3' or line[5]=='2': if line[5]=='3' or line[5]=='2':
trustedlock.acquire() setauthcheckstate(line[3][1:], True)
if line[3][1:] in trusted:
trustedlock.release()
if line[3][1:] in authcmds:
for i in authcmds.pop(line[3][1:]):
irc.send(i)
if line[3][1:] in authfuncs:
for i in authfuncs.pop(line[3][1:]):
i()
else:
trustedlock.release()
else: else:
if line[3][1:] in authcmds: setauthcheckstate(line[3][1:], False)
authcmds.pop(line[3][1:])
if line[3][1:] in authfuncs:
authfuncs.pop(line[3][1:])
if line[5]=='0': if line[5]=='0':
irc.msg(line[3][1:], 'Register account with NickServ') irc.msg(line[3][1:], 'Register account with NickServ')
elif line[5]=='1': elif line[5]=='1':
irc.msg(line[3][1:], 'PRIVMSG %s :Identify with NickServ') irc.msg(line[3][1:], 'PRIVMSG %s :Identify with NickServ')
else: else:
irc.msg(line[3][1:], 'WTF, NickServ returned %s'+line[5]) irc.msg(line[3][1:], 'WTF, NickServ returned %s'+line[5])
authcmdlock.release()
authfunclock.release()
elif line[1]=='INVITE' and line[2]==irc.nick and line[3][1:] in irc.chan.split(' '): elif line[1]=='INVITE' and line[2]==irc.nick and line[3][1:] in irc.chan.split(' '):
addauthcmd(nick, 'JOIN '+line[3]) if isauthorized(irc, nick):
irc.msg('NickServ', 'ACC '+nick) irc.send('JOIN '+line[3])
elif line[1]=='482': elif line[1]=='482':
irc.msg(line[3], 'Not op') irc.msg(line[3], 'Not op')
#elif line[1]=='332' or line[1]=='TOPIC': #elif line[1]=='332' or line[1]=='TOPIC':