Move identification test to use WHOIS instead of NickServ ACC

This commit is contained in:
Juhani Haverinen 2015-03-01 14:19:57 +02:00
parent ad48a0695b
commit 7e0203ab75
1 changed files with 85 additions and 69 deletions

154
botcmd.py
View File

@ -18,8 +18,8 @@ godslock = threading.Lock()
msgs = {} msgs = {}
msgslock = threading.Lock() msgslock = threading.Lock()
authcheck = {} accountcheck = {}
authchecklock = threading.Lock() accountchecklock = threading.Lock()
die_expr=re.compile("#[0-9]*d([0-9]+|%)") die_expr=re.compile("#[0-9]*d([0-9]+|%)")
@ -98,23 +98,23 @@ def savemessages():
loadmessages() loadmessages()
def addtrusted(nick): def addtrusted(account):
global trusted, trustedlock global trusted, trustedlock
trustedlock.acquire() trustedlock.acquire()
if nick not in trusted: if account not in trusted:
trusted.append(nick) trusted.append(account)
trustedlock.release() trustedlock.release()
def rmtrusted(nick): def rmtrusted(account):
global trusted, trustedlock global trusted, trustedlock
trustedlock.acquire() trustedlock.acquire()
if nick in trusted: if account in trusted:
trusted.remove(nick) trusted.remove(account)
trustedlock.release() trustedlock.release()
@ -176,63 +176,70 @@ def chmode(irc, chan, nick, mode, args):
if isauthorized(irc, nick): if isauthorized(irc, nick):
irc.send('MODE %s %s %s' % (chan, mode, name)) irc.send('MODE %s %s %s' % (chan, mode, name))
def istrusted(nick): def istrusted(account):
trustedlock.acquire() trustedlock.acquire()
if nick in trusted: if account in trusted:
trustedlock.release() trustedlock.release()
return True return True
else: else:
trustedlock.release() trustedlock.release()
return False return False
def initauthcheck(nick): def initaccountcheck(nick):
global authcheck, authchecklock global accountcheck, accountchecklock
authchecklock.acquire() accountchecklock.acquire()
authcheck[nick] = None accountcheck[nick] = None
authchecklock.release() accountchecklock.release()
def setauthcheckstate(nick, state): def setaccountcheckvalue(nick, value):
global authcheck, authchecklock global accountcheck, accountchecklock
authchecklock.acquire() accountchecklock.acquire()
if nick in authcheck: if nick in accountcheck:
authcheck[nick] = state accountcheck[nick] = value
authchecklock.release() accountchecklock.release()
def getauthcheckstate(nick): def getaccountcheckvalue(nick):
global authcheck, authchecklock global accountcheck, accountchecklock
authchecklock.acquire() accountchecklock.acquire()
if nick in authcheck: if nick in accountcheck:
state = authcheck[nick] value = accountcheck[nick]
authchecklock.release() accountchecklock.release()
return state return value
def removeauthcheck(nick): def removeaccountcheck(nick):
global authcheck, authchecklock global accountcheck, accountchecklock
authchecklock.acquire() accountchecklock.acquire()
if nick in authcheck: if nick in accountcheck:
del authcheck[nick] del accountcheck[nick]
authchecklock.release() accountchecklock.release()
def getaccount(irc, nick):
initaccountcheck(nick)
irc.send('WHOIS ' + nick)
cron.queuejob(5, (lambda : setaccountcheckvalue(nick, '')))
account = None
while account == None:
account = getaccountcheckvalue(nick)
time.sleep(0.1)
removeaccountcheck(nick)
if account == '': # '' Signifies failure
return None
else:
return account
def isauthorized(irc, nick): def isauthorized(irc, nick):
if not istrusted(nick): account = getaccount(irc, nick)
return False if account:
return istrusted(account)
initauthcheck(nick) else:
irc.msg('NickServ', 'acc ' + nick) irc.msg(nick, 'Identify with NickServ')
cron.queuejob(5, (lambda : setauthcheckstate(nick, False)))
state = None
while state == None:
state = getauthcheckstate(nick)
time.sleep(0.1)
removeauthcheck(nick)
return state
class ArgsfmtError(Exception): class ArgsfmtError(Exception):
def __init__(self, msg): def __init__(self, msg):
@ -415,28 +422,40 @@ def parse((line, irc)):
if matchcmd(cmdline, '#trusted?', '[nick]'): if matchcmd(cmdline, '#trusted?', '[nick]'):
trustnick = parsecmd(cmdline, '[nick]') trustnick = parsecmd(cmdline, '[nick]')
if trustnick == '': if trustnick == '':
trustnick=nick trustnick = nick
if istrusted(trustnick): account = getaccount(irc, trustnick)
irc.msg(chan, '%s is trusted' % trustnick) if account:
if istrusted(account):
irc.msg(chan, '%s is trusted' % trustnick)
else:
irc.msg(chan, '%s is not trusted' % trustnick)
else: else:
irc.msg(chan, '%s is not trusted' % trustnick) irc.msg(chan, 'Failed to get account for %s' % trustnick)
else: else:
irc.msg(chan, 'Usage: #trusted? [nick]') irc.msg(chan, 'Usage: #trusted? [nick]')
elif matchcmd(cmdline, '#trust'): elif matchcmd(cmdline, '#trust'):
if matchcmd(cmdline, '#trust', 'nick'): if matchcmd(cmdline, '#trust', 'nick'):
trustnick = parsecmd(cmdline, 'nick') trustnick = parsecmd(cmdline, 'nick')
if isauthorized(irc, nick): if isauthorized(irc, nick):
addtrusted(trustnick) account = getaccount(irc, trustnick)
if account:
addtrusted(account)
else:
irc.msg(chan, 'Failed to get account for %s' % trustnick)
else: else:
irc.msg(chan, 'Usage #trust nick') irc.msg(chan, 'Usage #trust nick')
elif matchcmd(cmdline, '#untrust'): elif matchcmd(cmdline, '#untrust'):
if matchcmd(cmdline, '#untrust', 'nick'): if matchcmd(cmdline, '#untrust', 'nick'):
untrustnick = parsecmd(cmdline, 'nick') untrustnick = parsecmd(cmdline, 'nick')
godslock.acquire() if isauthorized(irc, nick):
if untrustnick not in gods: account = getaccount(irc, untrustnick)
if isauthorized(irc, nick): if account:
rmtrusted(untrustnick) godslock.acquire()
godslock.release() if account not in gods:
rmtrusted(untrustnick)
godslock.release()
else:
irc.msg(chan, 'Failed to get account for %s' % untrustnick)
else: else:
irc.msg(chan, 'Usage #untrust nick') irc.msg(chan, 'Usage #untrust nick')
elif matchcmd(cmdline, '#ls-trusted'): elif matchcmd(cmdline, '#ls-trusted'):
@ -483,17 +502,14 @@ def parse((line, irc)):
irc.msg(chan, '%s (%s)' % (str(result), ', '.join([str(i) for i in rolls]))) irc.msg(chan, '%s (%s)' % (str(result), ', '.join([str(i) for i in rolls])))
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] == '330': # WHOIS: is logged in as
if line[5] == '3' or line[5] == '2': whoisnick = line[3]
setauthcheckstate(line[3][1:], True) account = line[4]
else: setaccountcheckvalue(whoisnick, account)
setauthcheckstate(line[3][1:], False) elif line[1] == '318': # WHOIS: End of /WHOIS list.
if line[5] == '0': whoisnick = line[3]
irc.msg(line[3][1:], 'Register account with NickServ') if getaccountcheckvalue(whoisnick) == None:
elif line[5] == '1': setaccountcheckvalue(whoisnick, '') # Mark as failed, '' is used because None is already reserved
irc.msg(line[3][1:], 'Identify with NickServ')
else:
irc.msg(line[3][1:], 'WTF, NickServ returned %s' % line[5])
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(' '):
if isauthorized(irc, nick): if isauthorized(irc, nick):
irc.send('JOIN ' + line[3]) irc.send('JOIN ' + line[3])