mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 20:59:27 +01:00
NickAuth: First commit.
This commit is contained in:
parent
6ea2d062b7
commit
659f6ebceb
6
plugins/NickAuth/README.txt
Normal file
6
plugins/NickAuth/README.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
This plugin allows users to use their network services account to
|
||||||
|
authenticate to the bot.
|
||||||
|
|
||||||
|
They first have to use @nickauth nick add <the nick>, then use @auth
|
||||||
|
every time they want to be authenticated.
|
||||||
|
|
66
plugins/NickAuth/__init__.py
Normal file
66
plugins/NickAuth/__init__.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
###
|
||||||
|
# Copyright (c) 2012, Valentin Lorentz
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Add a description of the plugin (to be presented to the user inside the wizard)
|
||||||
|
here. This should describe *what* the plugin does.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import supybot
|
||||||
|
import supybot.world as world
|
||||||
|
|
||||||
|
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||||
|
# in here if you're keeping the plugin in CVS or some similar system.
|
||||||
|
__version__ = ""
|
||||||
|
|
||||||
|
# XXX Replace this with an appropriate author or supybot.Author instance.
|
||||||
|
__author__ = supybot.authors.unknown
|
||||||
|
|
||||||
|
# This is a dictionary mapping supybot.Author instances to lists of
|
||||||
|
# contributions.
|
||||||
|
__contributors__ = {}
|
||||||
|
|
||||||
|
# This is a url where the most recent plugin package can be downloaded.
|
||||||
|
__url__ = '' # 'http://supybot.com/Members/yourname/NickAuth/download'
|
||||||
|
|
||||||
|
import config
|
||||||
|
import plugin
|
||||||
|
reload(plugin) # In case we're being reloaded.
|
||||||
|
# Add more reloads here if you add third-party modules and want them to be
|
||||||
|
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||||
|
|
||||||
|
if world.testing:
|
||||||
|
import test
|
||||||
|
|
||||||
|
Class = plugin.Class
|
||||||
|
configure = config.configure
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
52
plugins/NickAuth/config.py
Normal file
52
plugins/NickAuth/config.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
###
|
||||||
|
# Copyright (c) 2012, Valentin Lorentz
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
import supybot.conf as conf
|
||||||
|
import supybot.registry as registry
|
||||||
|
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||||
|
|
||||||
|
_ = PluginInternationalization('NickAuth')
|
||||||
|
|
||||||
|
def configure(advanced):
|
||||||
|
# This will be called by supybot to configure this module. advanced is
|
||||||
|
# a bool that specifies whether the user identified himself as an advanced
|
||||||
|
# user or not. You should effect your configuration by manipulating the
|
||||||
|
# registry as appropriate.
|
||||||
|
from supybot.questions import expect, anything, something, yn
|
||||||
|
conf.registerPlugin('NickAuth', True)
|
||||||
|
|
||||||
|
|
||||||
|
NickAuth = conf.registerPlugin('NickAuth')
|
||||||
|
# This is where your configuration variables (if any) should go. For example:
|
||||||
|
# conf.registerGlobalValue(NickAuth, 'someConfigVariableName',
|
||||||
|
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
1
plugins/NickAuth/local/__init__.py
Normal file
1
plugins/NickAuth/local/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Stub so local is a module, used for third-party modules
|
166
plugins/NickAuth/plugin.py
Normal file
166
plugins/NickAuth/plugin.py
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
###
|
||||||
|
# Copyright (c) 2012, Valentin Lorentz
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
import supybot.conf as conf
|
||||||
|
import supybot.utils as utils
|
||||||
|
import supybot.ircdb as ircdb
|
||||||
|
from supybot.commands import *
|
||||||
|
import supybot.ircmsgs as ircmsgs
|
||||||
|
import supybot.plugins as plugins
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.callbacks as callbacks
|
||||||
|
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||||
|
|
||||||
|
_ = PluginInternationalization('NickAuth')
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
class NickAuth(callbacks.Plugin):
|
||||||
|
"""Support authentication based on nicks and network services."""
|
||||||
|
def __init__(self, irc):
|
||||||
|
super(NickAuth, self).__init__(irc)
|
||||||
|
self._requests = {}
|
||||||
|
class nick(callbacks.Commands):
|
||||||
|
def _check_auth(self, irc, msg, user):
|
||||||
|
if user is None:
|
||||||
|
irc.error(_('You are not authenticated.'), Raise=True)
|
||||||
|
if not user.checkHostmask(msg.prefix):
|
||||||
|
try:
|
||||||
|
u = ircdb.users.getUser(msg.prefix)
|
||||||
|
except KeyError:
|
||||||
|
irc.error(_('You are not authenticated.'),
|
||||||
|
Raise=True)
|
||||||
|
if not u._checkCapability('owner'):
|
||||||
|
irc.error(_('You must be owner to do that.'),
|
||||||
|
Raise=True)
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def add(self, irc, msg, args, network, user, nick):
|
||||||
|
"""[<network>] <user> <nick>
|
||||||
|
|
||||||
|
Add <nick> to the list of nicks owned by the <user> on the
|
||||||
|
<network>. You have to register this nick to the network
|
||||||
|
services to be authenticated.
|
||||||
|
<network> defaults to the current network.
|
||||||
|
"""
|
||||||
|
network = network.network or irc.network
|
||||||
|
user = user or ircdb.users.getUser(msg.prefix)
|
||||||
|
self._check_auth(irc, msg, user)
|
||||||
|
try:
|
||||||
|
user.addNick(network, nick)
|
||||||
|
except KeyError:
|
||||||
|
irc.error(_('This nick is already used by someone on this '
|
||||||
|
'network.'), Raise=True)
|
||||||
|
irc.replySuccess()
|
||||||
|
add = wrap(add, [optional('networkIrc'),
|
||||||
|
optional('otherUser'),
|
||||||
|
'nick'])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def remove(self, irc, msg, args, network, user, nick):
|
||||||
|
"""[<network>] <user> <nick>
|
||||||
|
|
||||||
|
Remove <nick> from the list of nicks owned by the <user> on the
|
||||||
|
<network>.
|
||||||
|
<network> defaults to the current network.
|
||||||
|
"""
|
||||||
|
network = network.network or irc.network
|
||||||
|
user = user or ircdb.users.getUser(msg.prefix)
|
||||||
|
self._check_auth(user, irc, msg)
|
||||||
|
try:
|
||||||
|
user.removeNick(network, nick)
|
||||||
|
except KeyError:
|
||||||
|
irc.error(_('This nick is not registered to you on this '
|
||||||
|
'network.'), Raise=True)
|
||||||
|
irc.replySuccess()
|
||||||
|
remove = wrap(remove, [optional('networkIrc'),
|
||||||
|
optional('otherUser'),
|
||||||
|
'nick'])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def list(self, irc, msg, args, network, user):
|
||||||
|
"""[<network>] [<user>]
|
||||||
|
|
||||||
|
Lists nicks of the <user> on the network.
|
||||||
|
<network> defaults to the current network.
|
||||||
|
"""
|
||||||
|
network = network.network or irc.network
|
||||||
|
user = user or ircdb.users.getUser(msg.prefix)
|
||||||
|
self._check_auth(irc, msg, user)
|
||||||
|
try:
|
||||||
|
list_ = user.nicks[network]
|
||||||
|
if list_:
|
||||||
|
irc.reply(format('%L', list_))
|
||||||
|
else:
|
||||||
|
raise KeyError
|
||||||
|
except KeyError:
|
||||||
|
irc.error(_('You have no recognized nick on this '
|
||||||
|
'network.'), Raise=True)
|
||||||
|
list = wrap(list, [optional('networkIrc'),
|
||||||
|
optional('otherUser')])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def auth(self, irc, msg, args):
|
||||||
|
"""takes no argument
|
||||||
|
|
||||||
|
Tries to authenticate you using network services.
|
||||||
|
If you get no reply, it means you are not authenticated to the
|
||||||
|
network services."""
|
||||||
|
nick = ircutils.toLower(msg.nick)
|
||||||
|
self._requests[(irc.network, msg.nick)] = (time.time(), msg.prefix, irc)
|
||||||
|
irc.queueMsg(ircmsgs.whois(nick, nick))
|
||||||
|
auth = wrap(auth, [])
|
||||||
|
|
||||||
|
def do330(self, irc, msg):
|
||||||
|
mynick, theirnick, theiraccount, garbage = msg.args
|
||||||
|
# I would like to use a dict comprehension, but we have to support
|
||||||
|
# Python 2.6 :(
|
||||||
|
self._requests = dict([(x,y) for x,y in self._requests.items()
|
||||||
|
if y[0]+60>time.time()])
|
||||||
|
try:
|
||||||
|
(timestamp, prefix, irc) = self._requests.pop((irc.network, theirnick))
|
||||||
|
except KeyError:
|
||||||
|
return
|
||||||
|
user = ircdb.users.getUserFromNick(irc.network, theiraccount)
|
||||||
|
if not user:
|
||||||
|
user = ircdb.users.getUserFromNick(irc.network, theirnick)
|
||||||
|
if user:
|
||||||
|
user.addAuth(prefix)
|
||||||
|
ircdb.users.setUser(user, flush=False)
|
||||||
|
irc.reply(_('You are now authenticated as %s.') % user.name)
|
||||||
|
else:
|
||||||
|
irc.error(_('No user has this nick on this network.'))
|
||||||
|
|
||||||
|
|
||||||
|
Class = NickAuth
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
92
plugins/NickAuth/test.py
Normal file
92
plugins/NickAuth/test.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
###
|
||||||
|
# Copyright (c) 2012, Valentin Lorentz
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
import supybot.ircdb as ircdb
|
||||||
|
from supybot.test import *
|
||||||
|
|
||||||
|
class NickAuthTestCase(PluginTestCase):
|
||||||
|
plugins = ('NickAuth', 'User')
|
||||||
|
|
||||||
|
prefix1 = 'something!user@host.tld'
|
||||||
|
def _procedure(self, nickserv_reply):
|
||||||
|
self.assertNotError('register foobar 123')
|
||||||
|
self.assertResponse('user list', 'foobar')
|
||||||
|
self.assertNotError('hostmask remove foobar %s' % self.prefix)
|
||||||
|
self.assertNotError('identify foobar 123')
|
||||||
|
self.assertNotError('nick add foobar baz')
|
||||||
|
self.assertNotError('unidentify')
|
||||||
|
self.prefix = self.prefix1
|
||||||
|
self.assertError('nick add foobar qux')
|
||||||
|
self.nick = self.prefix.split('!')[0]
|
||||||
|
|
||||||
|
self.assertError('hostmask list')
|
||||||
|
self.irc.feedMsg(ircmsgs.privmsg(self.irc.nick,
|
||||||
|
'auth',
|
||||||
|
prefix=self.prefix))
|
||||||
|
self.assertIs(self.irc.takeMsg().command, 'WHOIS')
|
||||||
|
self.assertError('hostmask list')
|
||||||
|
|
||||||
|
self.irc.feedMsg(ircmsgs.privmsg(self.irc.nick,
|
||||||
|
'auth',
|
||||||
|
prefix=self.prefix))
|
||||||
|
self.assertEqual(self.irc.takeMsg().command, 'WHOIS')
|
||||||
|
if nickserv_reply:
|
||||||
|
self.irc.feedMsg(ircmsgs.IrcMsg(':leguin.freenode.net 330 pgjrgrg '
|
||||||
|
'%s baz :is logged in as' % self.nick))
|
||||||
|
msg = self.irc.takeMsg()
|
||||||
|
self.assertNotEqual(msg, None)
|
||||||
|
self.assertEqual(msg.args[1], 'You are now authenticated as foobar.')
|
||||||
|
self.assertResponse('hostmask list',
|
||||||
|
'foobar has no registered hostmasks.')
|
||||||
|
else:
|
||||||
|
msg = self.irc.takeMsg()
|
||||||
|
self.assertEqual(msg, None)
|
||||||
|
self.assertError('hostmask list')
|
||||||
|
|
||||||
|
def testAuth(self):
|
||||||
|
self._procedure(True)
|
||||||
|
def testNoAuth(self):
|
||||||
|
self._procedure(False)
|
||||||
|
|
||||||
|
def testList(self):
|
||||||
|
self.assertNotError('register foobar 123')
|
||||||
|
self.assertRegexp('nick list', 'You have no recognized nick')
|
||||||
|
self.assertNotError('nick add foo')
|
||||||
|
self.assertRegexp('nick list', 'foo')
|
||||||
|
self.assertNotError('nick add %s bar' % self.nick)
|
||||||
|
self.assertRegexp('nick list', 'foo and bar')
|
||||||
|
self.assertNotError('nick add %s %s baz' % (self.irc.network, self.nick))
|
||||||
|
self.assertRegexp('nick list', 'foo, bar, and baz')
|
||||||
|
self.assertRegexp('nick list %s' % self.irc.network, 'foo, bar, and baz')
|
||||||
|
self.assertRegexp('nick list %s foobar' % self.irc.network,
|
||||||
|
'foo, bar, and baz')
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Loading…
Reference in New Issue
Block a user