def doMode(self, irc, msg): channel = msg.args[0] chanOp = ircdb.makeChannelCapability(channel, 'op') chanVoice = ircdb.makeChannelCapability(channel, 'voice') chanHalfOp = ircdb.makeChannelCapability(channel, 'halfop') if not ircdb.checkCapability(msg.prefix, chanOp): irc.sendMsg(ircmsgs.deop(channel, msg.nick)) for (mode, value) in ircutils.separateModes(msg.args[1:]): if not value: continue if ircutils.strEqual(value, msg.nick): # We allow someone to mode themselves to oblivion. continue if irc.isNick(value): hostmask = irc.state.nickToHostmask(value) if mode == '+o': if not self.isOp(irc, channel, hostmask): irc.queueMsg(ircmsgs.deop(channel, value)) elif mode == '+h': if not ircdb.checkCapability(hostmask, chanHalfOp): irc.queueMsg(ircmsgs.dehalfop(channel, value)) elif mode == '+v': if not ircdb.checkCapability(hostmask, chanVoice): irc.queueMsg(ircmsgs.devoice(channel, value)) elif mode == '-o': if ircdb.checkCapability(hostmask, chanOp): irc.queueMsg(ircmsgs.op(channel, value)) elif mode == '-h': if ircdb.checkCapability(hostmask, chanOp): irc.queueMsg(ircmsgs.halfop(channel, value)) elif mode == '-v': if ircdb.checkCapability(hostmask, chanOp): irc.queueMsg(ircmsgs.voice(channel, value)) else: assert ircutils.isUserHostmask(value)
def testUnban(self): self.assertError('unban foo!bar@baz') self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) m = self.getMsg('unban foo!bar@baz') self.assertEqual(m.command, 'MODE') self.assertEqual(m.args, (self.channel, '-b', 'foo!bar@baz')) self.assertNoResponse(' ', 2)
def testVoice(self): self.assertError('voice') self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) self.assertNotError('voice') m = self.getMsg('voice foo') self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+v', 'foo')) m = self.getMsg('voice foo bar') self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+v', 'foo')) m = self.irc.takeMsg() self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+v', 'bar'))
def testHalfOp(self): self.assertError('halfop') self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) self.assertNotError('halfop') m = self.getMsg('halfop foo') self.assertTrue(m.command == 'MODE' and m.args == (self.channel, '+h', 'foo')) m = self.getMsg('halfop foo bar') self.assertTrue(m.command == 'MODE' and m.args == (self.channel, '+h', 'foo')) m = self.irc.takeMsg() self.assertTrue(m.command == 'MODE' and m.args == (self.channel, '+h', 'bar'))
def testIban(self): self.irc.feedMsg(ircmsgs.join(self.channel, prefix='[email protected]')) self.assertError('iban foo!bar@baz') self.irc.feedMsg(ircmsgs.op(self.channel, self.irc.nick)) self.assertBan('iban foo!bar@baz', 'foo!bar@baz') self.assertBan('iban foobar', '[email protected]') conf.supybot.protocols.irc.strictRfc.setValue(True) self.assertError('iban $a:nyuszika7h') self.assertError('unban $a:nyuszika7h') conf.supybot.protocols.irc.strictRfc.setValue(False) self.assertBan('iban $a:nyuszika7h', '$a:nyuszika7h') self.assertNotError('unban $a:nyuszika7h')
def detonate(self, irc): fairnessInvert = False if not self.responded: if self.sender in irc.state.channels[self.channel].ops and not self.victim in irc.state.channels[self.channel].ops: print(" Sender has ops and victim does not! Throwing for a fairness detonation inversion!" ) randNum = self.rng.randint(0,4) if randNum == 0 : irc.reply("The bomb goes klunk.") fairnessInvert = True self.irc.queueMsg(ircmsgs.op(self.channel, self.victim) ) else: print "Throw failed." self.active = False #if self.showCorrectWire: # self.irc.reply('Should\'ve gone for the %s wire!' % self.goodWire) if self.showArt: self.irc.sendMsg(ircmsgs.privmsg(self.channel, ' (} ,^. . .')) self.irc.sendMsg(ircmsgs.privmsg(self.channel, ' / \\\\/\. ` `._-\' \'`-~. .')) self.irc.sendMsg(ircmsgs.privmsg(self.channel, ' \, \` ) __ ( .')) self.irc.sendMsg(ircmsgs.privmsg(self.channel, ' . / . -< //\\\\ `_- .')) self.irc.sendMsg(ircmsgs.privmsg(self.channel, ' ` . ) // \\\\ ( \' P A N T S P L O D E')) detonateMsg = "BOOM!" if self.thrown: detonateMsg = "KA" + detonateMsg else: if self.showCorrectWire : detonateMsg += " (it was %s)" % self.goodWire self.active = False self.thrown = False if fairnessInvert: #self.irc.queueMsg(irc.reply("The bomb goes klunk.") ) print "Fairness invert activated!" newVictim = self.sender self.sender = self.victim self.victim = newVictim #irc.reply("The bomb goes beep!")) #time.sleep(10) else: self.irc.queueMsg(ircmsgs.kick(self.channel, self.victim, detonateMsg) ) def reinvite(): if not self.victim in irc.state.channels[self.channel].users: self.irc.queueMsg(ircmsgs.invite(self.victim, self.channel)) if not self.responded: schedule.addEvent(reinvite, time.time()+5)
def testHandlesModes(self): st = irclib.IrcState() st.addMsg(self.irc, ircmsgs.join('#foo', prefix=self.irc.prefix)) self.failIf('bar' in st.channels['#foo'].ops) st.addMsg(self.irc, ircmsgs.op('#foo', 'bar')) self.failUnless('bar' in st.channels['#foo'].ops) st.addMsg(self.irc, ircmsgs.deop('#foo', 'bar')) self.failIf('bar' in st.channels['#foo'].ops) self.failIf('bar' in st.channels['#foo'].voices) st.addMsg(self.irc, ircmsgs.voice('#foo', 'bar')) self.failUnless('bar' in st.channels['#foo'].voices) st.addMsg(self.irc, ircmsgs.devoice('#foo', 'bar')) self.failIf('bar' in st.channels['#foo'].voices) self.failIf('bar' in st.channels['#foo'].halfops) st.addMsg(self.irc, ircmsgs.halfop('#foo', 'bar')) self.failUnless('bar' in st.channels['#foo'].halfops) st.addMsg(self.irc, ircmsgs.dehalfop('#foo', 'bar')) self.failIf('bar' in st.channels['#foo'].halfops)
def testOp(self): self.assertError('op') self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) self.assertNotError('op') m = self.getMsg('op foo') self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+o', 'foo')) m = self.getMsg('op foo bar') self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+o', 'foo')) m = self.irc.takeMsg() self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+o', 'bar')) self.irc.state.supported['MODES'] = 2 m = self.getMsg('op foo bar') try: self.failUnless(m.command == 'MODE' and m.args == (self.channel, '+oo', 'foo', 'bar')) finally: self.irc.state.supported['MODES'] = 1
def doNotice(self, irc, msg): mynick = irc.nick user = msg.nick hostname = irc.state.nickToHostmask(user) (recipients, text) = msg.args if ircmsgs.isCtcp(msg) or ircmsgs.isAction(msg) or irc.isChannel(msg.args[0]): # ignore obvious non. return elif text.startswith('!ZNCAO'): # we only process notices with !ZNCAO. textparts = text.split() # split. should be 3. if len(textparts) != 3: # make sure we have 3 parts to a valid ZNC message. self.log.error("ERROR: ZNC notice from {0} is malformed. I got: {1}".format(user, text)) return if textparts[0] == "!ZNCAO" and textparts[1] == "CHALLENGE": # if user is opped and we are not. we get challenge. self.log.info("We got a ZNC challenge from {0}".format(user)) challenge = textparts[2] for (key, value) in self._users.items(): # iterate now through our users for key. hostmask, key, channel = value[0] if ircutils.hostmaskPatternEqual(hostmask, hostname): # if we have a match. if not irc.state.channels[channel].isOp(mynick) and irc.state.channels[channel].isOp(user): # and they're opped, we're not. response = "!ZNCAO RESPONSE {0}".format(self._zncresponse(key, challenge)) # this key and the challenge. self.log.info("Sending {0} {1}".format(user, response)) irc.queueMsg(ircmsgs.notice(user, response)) elif textparts[0] == "!ZNCAO" and textparts[1] == "RESPONSE": # means we sent a challenge. we're opped, user is not. self.log.info("We got a ZNC response from {0}".format(user)) if user in self._challenges: # user is in challenges because their hostname matched. for chan in self._challenges[user]: if irc.state.channels[chan].isOp(mynick) and not irc.state.channels[chan].isOp(user): # im op. they're not. (chaltime, challenge, chaluser) = self._challenges[user][chan] if chaltime - time.time() < 60: # challenge less than 60s ago. hostmask, key, channel = self._users[chaluser][0] # find the user in the db. mychallenge = self._zncresponse(key, challenge) # create my own based on challenge/key to auth. if mychallenge == textparts[2]: # compare my md5 hash and theirs. self.log.info("Giving ZNC OP to {0} on {1} after valid key matching.".format(user, chan)) irc.queueMsg(ircmsgs.op(chan, user)) # op if they're valid. else: # invalid key. self.log.info("ERROR: Invalid key from: {0} on {1}".format(user, chan)) else: # key is too old. self.log.info("ERROR: {0} in {1} challenge was more than 60s ago.".format(user, chan)) else: self.log.info("ERROR: {0} not found in ZNC challenges.".format(user))
class IrcMsgQueueTestCase(SupyTestCase): mode = ircmsgs.op('#foo', 'jemfinch') msg = ircmsgs.privmsg('#foo', 'hey, you') msgs = [ircmsgs.privmsg('#foo', str(i)) for i in range(10)] kick = ircmsgs.kick('#foo', 'PeterB') pong = ircmsgs.pong('123') ping = ircmsgs.ping('123') topic = ircmsgs.topic('#foo') notice = ircmsgs.notice('jemfinch', 'supybot here') join = ircmsgs.join('#foo') who = ircmsgs.who('#foo') def testInit(self): q = irclib.IrcMsgQueue([self.msg, self.topic, self.ping]) self.assertEqual(len(q), 3) def testLen(self): q = irclib.IrcMsgQueue() q.enqueue(self.msg) self.assertEqual(len(q), 1) q.enqueue(self.mode) self.assertEqual(len(q), 2) q.enqueue(self.kick) self.assertEqual(len(q), 3) q.enqueue(self.topic) self.assertEqual(len(q), 4) q.dequeue() self.assertEqual(len(q), 3) q.dequeue() self.assertEqual(len(q), 2) q.dequeue() self.assertEqual(len(q), 1) q.dequeue() self.assertEqual(len(q), 0) def testContains(self): q = irclib.IrcMsgQueue() q.enqueue(self.msg) q.enqueue(self.msg) q.enqueue(self.msg) self.failUnless(self.msg in q) q.dequeue() self.failUnless(self.msg in q) q.dequeue() self.failUnless(self.msg in q) q.dequeue() self.failIf(self.msg in q) def testRepr(self): q = irclib.IrcMsgQueue() self.assertEqual(repr(q), 'IrcMsgQueue([])') q.enqueue(self.msg) try: repr(q) except Exception as e: self.fail('repr(q) raised an exception: %s' % utils.exnToString(e)) def testEmpty(self): q = irclib.IrcMsgQueue() self.failIf(q) def testEnqueueDequeue(self): q = irclib.IrcMsgQueue() q.enqueue(self.msg) self.failUnless(q) self.assertEqual(self.msg, q.dequeue()) self.failIf(q) q.enqueue(self.msg) q.enqueue(self.notice) self.assertEqual(self.msg, q.dequeue()) self.assertEqual(self.notice, q.dequeue()) for msg in self.msgs: q.enqueue(msg) for msg in self.msgs: self.assertEqual(msg, q.dequeue()) def testPrioritizing(self): q = irclib.IrcMsgQueue() q.enqueue(self.msg) q.enqueue(self.mode) self.assertEqual(self.mode, q.dequeue()) self.assertEqual(self.msg, q.dequeue()) q.enqueue(self.msg) q.enqueue(self.kick) self.assertEqual(self.kick, q.dequeue()) self.assertEqual(self.msg, q.dequeue()) q.enqueue(self.ping) q.enqueue(self.msgs[0]) q.enqueue(self.kick) q.enqueue(self.msgs[1]) q.enqueue(self.mode) self.assertEqual(self.kick, q.dequeue()) self.assertEqual(self.mode, q.dequeue()) self.assertEqual(self.ping, q.dequeue()) self.assertEqual(self.msgs[0], q.dequeue()) self.assertEqual(self.msgs[1], q.dequeue()) def testNoIdenticals(self): configVar = conf.supybot.protocols.irc.queuing.duplicates original = configVar() try: configVar.setValue(True) q = irclib.IrcMsgQueue() q.enqueue(self.msg) q.enqueue(self.msg) self.assertEqual(self.msg, q.dequeue()) self.failIf(q) finally: configVar.setValue(original) def testJoinBeforeWho(self): q = irclib.IrcMsgQueue() q.enqueue(self.join) q.enqueue(self.who) self.assertEqual(self.join, q.dequeue()) self.assertEqual(self.who, q.dequeue()) ## q.enqueue(self.who) ## q.enqueue(self.join) ## self.assertEqual(self.join, q.dequeue()) ## self.assertEqual(self.who, q.dequeue()) def testTopicBeforePrivmsg(self): q = irclib.IrcMsgQueue() q.enqueue(self.msg) q.enqueue(self.topic) self.assertEqual(self.topic, q.dequeue()) self.assertEqual(self.msg, q.dequeue()) def testModeBeforePrivmsg(self): q = irclib.IrcMsgQueue() q.enqueue(self.msg) q.enqueue(self.mode) self.assertEqual(self.mode, q.dequeue()) self.assertEqual(self.msg, q.dequeue()) q.enqueue(self.mode) q.enqueue(self.msg) self.assertEqual(self.mode, q.dequeue()) self.assertEqual(self.msg, q.dequeue())
def testErrorsWithoutOps(self): for s in 'op deop halfop dehalfop voice devoice kick invite'.split(): self.assertError('%s foo' % s) self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) self.assertNotError('%s foo' % s) self.irc.feedMsg(ircmsgs.deop(self.channel, self.nick))
def testWontDeItself(self): for s in 'deop dehalfop devoice'.split(): self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) self.assertError('%s %s' % (s, self.nick))
def testCanDevoiceSelf(self): self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) self.assertNotError('devoice %s' % self.nick)