mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-02 17:29:22 +01:00
Merge pull request #1122 from nyuszika7h/fix-cap-neg
Fix capability negotiation
This commit is contained in:
commit
c8ce6230ca
@ -961,6 +961,11 @@ class Irc(IrcCommandDispatcher):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Notes:
|
||||||
|
# * using sendMsg instead of queueMsg because these messages cannot
|
||||||
|
# be throttled.
|
||||||
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('LS', '302')))
|
||||||
|
|
||||||
if self.password:
|
if self.password:
|
||||||
log.info('%s: Queuing PASS command, not logging the password.',
|
log.info('%s: Queuing PASS command, not logging the password.',
|
||||||
self.network)
|
self.network)
|
||||||
@ -987,12 +992,8 @@ class Irc(IrcCommandDispatcher):
|
|||||||
elif self.sasl_username and self.sasl_password:
|
elif self.sasl_username and self.sasl_password:
|
||||||
self.sasl = 'plain'
|
self.sasl = 'plain'
|
||||||
|
|
||||||
# Notes:
|
if self.sasl:
|
||||||
# * not sending caps at once, because the server has no granularity
|
self.REQUEST_CAPABILITIES.add('sasl')
|
||||||
# in telling between ACK and NAK
|
|
||||||
# * using sendMsg instead of queueMsg because these messages cannot
|
|
||||||
# be throttled.
|
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('LS', '302')))
|
|
||||||
|
|
||||||
def doAuthenticate(self, msg):
|
def doAuthenticate(self, msg):
|
||||||
if len(msg.args) == 1 and msg.args[0] == '+':
|
if len(msg.args) == 1 and msg.args[0] == '+':
|
||||||
@ -1034,28 +1035,24 @@ class Irc(IrcCommandDispatcher):
|
|||||||
if len(msg.args) != 3:
|
if len(msg.args) != 3:
|
||||||
log.warning('Bad CAP ACK from server: %r', msg)
|
log.warning('Bad CAP ACK from server: %r', msg)
|
||||||
return
|
return
|
||||||
for cap in msg.args[2].split(' '):
|
caps = msg.args[2]
|
||||||
log.info('%s: Server acknowledged capability %r',
|
log.info('%s: Server acknowledged capabilities: %s',
|
||||||
self.network, cap)
|
self.network, caps)
|
||||||
self.state.capabilities_ack.add(cap)
|
self.state.capabilities_ack.update(caps)
|
||||||
|
|
||||||
if cap == 'sasl':
|
if 'sasl' in caps:
|
||||||
self.sendMsg(ircmsgs.IrcMsg(
|
self.sendMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', args=(self.sasl.upper(),)))
|
||||||
command='AUTHENTICATE',
|
else:
|
||||||
args=(self.sasl.upper(),)))
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
||||||
def doCapNak(self, msg):
|
def doCapNak(self, msg):
|
||||||
if len(msg.args) != 3:
|
if len(msg.args) != 3:
|
||||||
log.warning('Bad CAP NAK from server: %r', msg)
|
log.warning('Bad CAP NAK from server: %r', msg)
|
||||||
return
|
return
|
||||||
for cap in msg.args[2].split(' '):
|
caps = msg.args[2]
|
||||||
self.state.capabilities_nak.add(cap)
|
self.state.capabilities_nak.update(caps)
|
||||||
log.warning('%s: Server refused capability %r',
|
log.warning('%s: Server refused capabilities: %s',
|
||||||
self.network, cap)
|
self.network, caps)
|
||||||
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
||||||
if cap == 'sasl':
|
|
||||||
self.sendMsg(ircmsgs.IrcMsg(
|
|
||||||
command='CAP',
|
|
||||||
args=('END',)))
|
|
||||||
def _addCapabilities(self, capstring):
|
def _addCapabilities(self, capstring):
|
||||||
for item in capstring.split():
|
for item in capstring.split():
|
||||||
while item.startswith(('=', '~')):
|
while item.startswith(('=', '~')):
|
||||||
@ -1076,14 +1073,11 @@ class Irc(IrcCommandDispatcher):
|
|||||||
self._addCapabilities(msg.args[2])
|
self._addCapabilities(msg.args[2])
|
||||||
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
||||||
self.REQUEST_CAPABILITIES
|
self.REQUEST_CAPABILITIES
|
||||||
for cap in common_supported_capabilities:
|
# NOTE: Capabilities are requested in alphabetic order, because
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', cap)))
|
# sets are unordered, and their "order" is nondeterministic.
|
||||||
|
# This is needed for the tests.
|
||||||
if 'sasl' in self.state.capabilities_ls and self.sasl:
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP',
|
||||||
# TODO: use the value of self.state.capabilities_ls['sasl']
|
args=('REQ', ' '.join(sorted(common_supported_capabilities)))))
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', 'sasl')))
|
|
||||||
else:
|
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
|
||||||
else:
|
else:
|
||||||
log.warning('Bad CAP LS from server: %r', msg)
|
log.warning('Bad CAP LS from server: %r', msg)
|
||||||
return
|
return
|
||||||
|
@ -378,32 +378,40 @@ class IrcStateTestCase(SupyTestCase):
|
|||||||
class IrcTestCase(SupyTestCase):
|
class IrcTestCase(SupyTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.irc = irclib.Irc('test')
|
self.irc = irclib.Irc('test')
|
||||||
|
|
||||||
#m = self.irc.takeMsg()
|
#m = self.irc.takeMsg()
|
||||||
#self.failUnless(m.command == 'PASS', 'Expected PASS, got %r.' % m)
|
#self.failUnless(m.command == 'PASS', 'Expected PASS, got %r.' % m)
|
||||||
m = self.irc.takeMsg()
|
|
||||||
self.failUnless(m.command == 'NICK', 'Expected NICK, got %r.' % m)
|
|
||||||
m = self.irc.takeMsg()
|
|
||||||
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
self.failUnless(m.args == ('LS', '302'), 'Expected CAP LS 302, got %r.' % m)
|
self.failUnless(m.args == ('LS', '302'), 'Expected CAP LS 302, got %r.' % m)
|
||||||
|
|
||||||
|
m = self.irc.takeMsg()
|
||||||
|
self.failUnless(m.command == 'NICK', 'Expected NICK, got %r.' % m)
|
||||||
|
|
||||||
|
m = self.irc.takeMsg()
|
||||||
|
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||||
args=('*', 'LS', '*', 'account-tag multi-prefix')))
|
args=('*', 'LS', '*', 'account-tag multi-prefix')))
|
||||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||||
args=('*', 'LS', 'extended-join')))
|
args=('*', 'LS', 'extended-join')))
|
||||||
|
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
self.assertEqual(m.args[0], 'REQ', m)
|
self.assertEqual(m.args[0], 'REQ', m)
|
||||||
m = self.irc.takeMsg()
|
# NOTE: Capabilities are requested in alphabetic order, because
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
# sets are unordered, and their "order" is nondeterministic.
|
||||||
self.assertEqual(m.args[0], 'REQ', m)
|
self.assertEqual(m.args[1], 'account-tag extended-join multi-prefix')
|
||||||
m = self.irc.takeMsg()
|
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||||
self.assertEqual(m.args[0], 'REQ', m)
|
args=('*', 'ACK', 'account-tag multi-prefix extended-join')))
|
||||||
|
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
self.assertEqual(m.args, ('END',), m)
|
self.assertEqual(m.args, ('END',), m)
|
||||||
|
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m is None, m)
|
self.failUnless(m is None, m)
|
||||||
|
|
||||||
@ -501,9 +509,9 @@ class IrcCallbackTestCase(SupyTestCase):
|
|||||||
user = 'user any user'
|
user = 'user any user'
|
||||||
conf.supybot.user.setValue(user)
|
conf.supybot.user.setValue(user)
|
||||||
expected = [
|
expected = [
|
||||||
|
ircmsgs.IrcMsg(command='CAP', args=('LS', '302')),
|
||||||
ircmsgs.nick(nick),
|
ircmsgs.nick(nick),
|
||||||
ircmsgs.user('limnoria', user),
|
ircmsgs.user('limnoria', user),
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('LS', '302')),
|
|
||||||
]
|
]
|
||||||
irc = irclib.Irc('test')
|
irc = irclib.Irc('test')
|
||||||
msgs = [irc.takeMsg()]
|
msgs = [irc.takeMsg()]
|
||||||
@ -518,7 +526,7 @@ class IrcCallbackTestCase(SupyTestCase):
|
|||||||
while msgs[-1] is not None:
|
while msgs[-1] is not None:
|
||||||
msgs.append(irc.takeMsg())
|
msgs.append(irc.takeMsg())
|
||||||
msgs.pop()
|
msgs.pop()
|
||||||
expected.insert(0, ircmsgs.password(password))
|
expected.insert(1, ircmsgs.password(password))
|
||||||
self.assertEqual(msgs, expected)
|
self.assertEqual(msgs, expected)
|
||||||
finally:
|
finally:
|
||||||
conf.supybot.nick.setValue(originalNick)
|
conf.supybot.nick.setValue(originalNick)
|
||||||
|
Loading…
Reference in New Issue
Block a user