mirror of
https://github.com/jlu5/PyLink.git
synced 2025-02-09 02:54:14 +01:00
core: move isOper, checkAuthenticated to Irc (#199)
This commit is contained in:
parent
4bd4c23a08
commit
2fe2e9c8c4
37
classes.py
37
classes.py
@ -15,6 +15,7 @@ import threading
|
|||||||
import ssl
|
import ssl
|
||||||
import hashlib
|
import hashlib
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
import inspect
|
||||||
|
|
||||||
from log import *
|
from log import *
|
||||||
import world
|
import world
|
||||||
@ -26,6 +27,13 @@ import structures
|
|||||||
class ProtocolError(Exception):
|
class ProtocolError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class NotAuthenticatedError(Exception):
|
||||||
|
"""
|
||||||
|
Exception raised by checkAuthenticated() when a user fails authentication
|
||||||
|
requirements.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
### Internal classes (users, servers, channels)
|
### Internal classes (users, servers, channels)
|
||||||
|
|
||||||
class Irc():
|
class Irc():
|
||||||
@ -469,7 +477,7 @@ class Irc():
|
|||||||
for func in world.commands[cmd]:
|
for func in world.commands[cmd]:
|
||||||
try:
|
try:
|
||||||
func(self, source, cmd_args)
|
func(self, source, cmd_args)
|
||||||
except utils.NotAuthenticatedError:
|
except NotAuthenticatedError:
|
||||||
self.msg(self.called_by or source, 'Error: You are not authorized to perform this operation.')
|
self.msg(self.called_by or source, 'Error: You are not authorized to perform this operation.')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception('Unhandled exception caught in command %r', cmd)
|
log.exception('Unhandled exception caught in command %r', cmd)
|
||||||
@ -848,6 +856,33 @@ class Irc():
|
|||||||
|
|
||||||
return '%s!%s@%s' % (nick, ident, host)
|
return '%s!%s@%s' % (nick, ident, host)
|
||||||
|
|
||||||
|
def isOper(self, uid, allowAuthed=True, allowOper=True):
|
||||||
|
"""
|
||||||
|
Returns whether the given user has operator status on PyLink. This can be achieved
|
||||||
|
by either identifying to PyLink as admin (if allowAuthed is True),
|
||||||
|
or having user mode +o set (if allowOper is True). At least one of
|
||||||
|
allowAuthed or allowOper must be True for this to give any meaningful
|
||||||
|
results.
|
||||||
|
"""
|
||||||
|
if uid in self.users:
|
||||||
|
if allowOper and ("o", None) in self.users[uid].modes:
|
||||||
|
return True
|
||||||
|
elif allowAuthed and self.users[uid].identified:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def checkAuthenticated(self, uid, allowAuthed=True, allowOper=True):
|
||||||
|
"""
|
||||||
|
Checks whether the given user has operator status on PyLink, raising
|
||||||
|
NotAuthenticatedError and logging the access denial if not.
|
||||||
|
"""
|
||||||
|
lastfunc = inspect.stack()[1][3]
|
||||||
|
if not self.isOper(uid, allowAuthed=allowAuthed, allowOper=allowOper):
|
||||||
|
log.warning('(%s) Access denied for %s calling %r', self.name,
|
||||||
|
self.getHostmask(uid), lastfunc)
|
||||||
|
raise NotAuthenticatedError("You are not authenticated!")
|
||||||
|
return True
|
||||||
|
|
||||||
class IrcUser():
|
class IrcUser():
|
||||||
"""PyLink IRC user class."""
|
"""PyLink IRC user class."""
|
||||||
def __init__(self, nick, ts, uid, ident='null', host='null',
|
def __init__(self, nick, ts, uid, ident='null', host='null',
|
||||||
|
@ -221,7 +221,7 @@ def shutdown(irc, source, args):
|
|||||||
"""takes no arguments.
|
"""takes no arguments.
|
||||||
|
|
||||||
Exits PyLink by disconnecting all networks."""
|
Exits PyLink by disconnecting all networks."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
u = irc.users[source]
|
u = irc.users[source]
|
||||||
|
|
||||||
log.info('(%s) SHUTDOWN requested by "%s!%s@%s", exiting...', irc.name, u.nick,
|
log.info('(%s) SHUTDOWN requested by "%s!%s@%s", exiting...', irc.name, u.nick,
|
||||||
@ -233,7 +233,7 @@ def load(irc, source, args):
|
|||||||
"""<plugin name>.
|
"""<plugin name>.
|
||||||
|
|
||||||
Loads a plugin from the plugin folder."""
|
Loads a plugin from the plugin folder."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
name = args[0]
|
name = args[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -262,7 +262,7 @@ def unload(irc, source, args):
|
|||||||
"""<plugin name>.
|
"""<plugin name>.
|
||||||
|
|
||||||
Unloads a currently loaded plugin."""
|
Unloads a currently loaded plugin."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
name = args[0]
|
name = args[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -386,7 +386,7 @@ def rehash(irc, source, args):
|
|||||||
|
|
||||||
Reloads the configuration file for PyLink, (dis)connecting added/removed networks.
|
Reloads the configuration file for PyLink, (dis)connecting added/removed networks.
|
||||||
Plugins must be manually reloaded."""
|
Plugins must be manually reloaded."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
_rehash()
|
_rehash()
|
||||||
except Exception as e: # Something went wrong, abort.
|
except Exception as e: # Something went wrong, abort.
|
||||||
|
@ -16,7 +16,7 @@ def spawnclient(irc, source, args):
|
|||||||
|
|
||||||
Admin-only. Spawns the specified PseudoClient on the PyLink server.
|
Admin-only. Spawns the specified PseudoClient on the PyLink server.
|
||||||
Note: this doesn't check the validity of any fields you give it!"""
|
Note: this doesn't check the validity of any fields you give it!"""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
nick, ident, host = args[:3]
|
nick, ident, host = args[:3]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -29,7 +29,7 @@ def quit(irc, source, args):
|
|||||||
"""<target> [<reason>]
|
"""<target> [<reason>]
|
||||||
|
|
||||||
Admin-only. Quits the PyLink client with nick <target>, if one exists."""
|
Admin-only. Quits the PyLink client with nick <target>, if one exists."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nick = args[0]
|
nick = args[0]
|
||||||
@ -55,7 +55,7 @@ def joinclient(irc, source, args):
|
|||||||
"""[<target>] <channel1>,[<channel2>], etc.
|
"""[<target>] <channel1>,[<channel2>], etc.
|
||||||
|
|
||||||
Admin-only. Joins <target>, the nick of a PyLink client, to a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
|
Admin-only. Joins <target>, the nick of a PyLink client, to a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Check if the first argument is an existing PyLink client. If it is not,
|
# Check if the first argument is an existing PyLink client. If it is not,
|
||||||
@ -100,7 +100,7 @@ def nick(irc, source, args):
|
|||||||
"""[<target>] <newnick>
|
"""[<target>] <newnick>
|
||||||
|
|
||||||
Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>. If <target> is not given, it defaults to the main PyLink client."""
|
Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>. If <target> is not given, it defaults to the main PyLink client."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nick = args[0]
|
nick = args[0]
|
||||||
@ -134,7 +134,7 @@ def part(irc, source, args):
|
|||||||
"""[<target>] <channel1>,[<channel2>],... [<reason>]
|
"""[<target>] <channel1>,[<channel2>],... [<reason>]
|
||||||
|
|
||||||
Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
|
Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nick = args[0]
|
nick = args[0]
|
||||||
@ -180,7 +180,7 @@ def msg(irc, source, args):
|
|||||||
"""[<source>] <target> <text>
|
"""[<source>] <target> <text>
|
||||||
|
|
||||||
Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client. If <source> is not given, it defaults to the main PyLink client."""
|
Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client. If <source> is not given, it defaults to the main PyLink client."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
# Because we want the source nick to be optional, this argument parsing gets a bit tricky.
|
# Because we want the source nick to be optional, this argument parsing gets a bit tricky.
|
||||||
try:
|
try:
|
||||||
|
@ -18,7 +18,7 @@ def status(irc, source, args):
|
|||||||
irc.reply('You are identified as \x02%s\x02.' % identified)
|
irc.reply('You are identified as \x02%s\x02.' % identified)
|
||||||
else:
|
else:
|
||||||
irc.reply('You are not identified as anyone.')
|
irc.reply('You are not identified as anyone.')
|
||||||
irc.reply('Operator access: \x02%s\x02' % bool(utils.isOper(irc, source)))
|
irc.reply('Operator access: \x02%s\x02' % bool(irc.isOper(source)))
|
||||||
|
|
||||||
def listcommands(irc, source, args):
|
def listcommands(irc, source, args):
|
||||||
"""takes no arguments.
|
"""takes no arguments.
|
||||||
@ -81,7 +81,7 @@ def showuser(irc, source, args):
|
|||||||
u = irc.nickToUid(target) or target
|
u = irc.nickToUid(target) or target
|
||||||
# Only show private info if the person is calling 'showuser' on themselves,
|
# Only show private info if the person is calling 'showuser' on themselves,
|
||||||
# or is an oper.
|
# or is an oper.
|
||||||
verbose = utils.isOper(irc, source) or u == source
|
verbose = irc.isOper(source) or u == source
|
||||||
if u not in irc.users:
|
if u not in irc.users:
|
||||||
irc.reply('Error: Unknown user %r.' % target)
|
irc.reply('Error: Unknown user %r.' % target)
|
||||||
return
|
return
|
||||||
@ -127,7 +127,7 @@ def showchan(irc, source, args):
|
|||||||
f = lambda s: irc.msg(source, s)
|
f = lambda s: irc.msg(source, s)
|
||||||
c = irc.channels[channel]
|
c = irc.channels[channel]
|
||||||
# Only show verbose info if caller is oper or is in the target channel.
|
# Only show verbose info if caller is oper or is in the target channel.
|
||||||
verbose = source in c.users or utils.isOper(irc, source)
|
verbose = source in c.users or irc.isOper(source)
|
||||||
secret = ('s', None) in c.modes
|
secret = ('s', None) in c.modes
|
||||||
if secret and not verbose:
|
if secret and not verbose:
|
||||||
# Hide secret channels from normal users.
|
# Hide secret channels from normal users.
|
||||||
@ -178,7 +178,7 @@ def loglevel(irc, source, args):
|
|||||||
|
|
||||||
Sets the log level to the given <level>. <level> must be either DEBUG, INFO, WARNING, ERROR, or CRITICAL.
|
Sets the log level to the given <level>. <level> must be either DEBUG, INFO, WARNING, ERROR, or CRITICAL.
|
||||||
If no log level is given, shows the current one."""
|
If no log level is given, shows the current one."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
level = args[0].upper()
|
level = args[0].upper()
|
||||||
try:
|
try:
|
||||||
|
@ -21,7 +21,7 @@ def _exec(irc, source, args):
|
|||||||
|
|
||||||
Admin-only. Executes <code> in the current PyLink instance. This command performs backslash escaping of characters, so things like \\n and \\ will work.
|
Admin-only. Executes <code> in the current PyLink instance. This command performs backslash escaping of characters, so things like \\n and \\ will work.
|
||||||
\x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
|
\x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
# Allow using \n in the code, while escaping backslashes correctly otherwise.
|
# Allow using \n in the code, while escaping backslashes correctly otherwise.
|
||||||
args = bytes(' '.join(args), 'utf-8').decode("unicode_escape")
|
args = bytes(' '.join(args), 'utf-8').decode("unicode_escape")
|
||||||
@ -40,7 +40,7 @@ def _eval(irc, source, args):
|
|||||||
|
|
||||||
Admin-only. Evaluates the given Python expression and returns the result.
|
Admin-only. Evaluates the given Python expression and returns the result.
|
||||||
\x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
|
\x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
args = ' '.join(args)
|
args = ' '.join(args)
|
||||||
if not args.strip():
|
if not args.strip():
|
||||||
@ -58,7 +58,7 @@ def raw(irc, source, args):
|
|||||||
|
|
||||||
Admin-only. Sends raw text to the uplink IRC server.
|
Admin-only. Sends raw text to the uplink IRC server.
|
||||||
\x02**WARNING: THIS CAN BREAK YOUR NETWORK IF USED IMPROPERLY!**\x02"""
|
\x02**WARNING: THIS CAN BREAK YOUR NETWORK IF USED IMPROPERLY!**\x02"""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
args = ' '.join(args)
|
args = ' '.join(args)
|
||||||
if not args.strip():
|
if not args.strip():
|
||||||
@ -77,7 +77,7 @@ def inject(irc, source, args):
|
|||||||
|
|
||||||
Admin-only. Injects raw text into the running PyLink protocol module, replying with the hook data returned.
|
Admin-only. Injects raw text into the running PyLink protocol module, replying with the hook data returned.
|
||||||
\x02**WARNING: THIS CAN BREAK YOUR NETWORK IF USED IMPROPERLY!**\x02"""
|
\x02**WARNING: THIS CAN BREAK YOUR NETWORK IF USED IMPROPERLY!**\x02"""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
args = ' '.join(args)
|
args = ' '.join(args)
|
||||||
if not args.strip():
|
if not args.strip():
|
||||||
|
@ -16,7 +16,7 @@ def disconnect(irc, source, args):
|
|||||||
|
|
||||||
Disconnects the network <network>. When all networks are disconnected, PyLink will automatically exit.
|
Disconnects the network <network>. When all networks are disconnected, PyLink will automatically exit.
|
||||||
Note: This does not affect the autoreconnect settings of any network, so the network will likely just reconnect unless autoconnect is disabled (see the 'autoconnect' command)."""
|
Note: This does not affect the autoreconnect settings of any network, so the network will likely just reconnect unless autoconnect is disabled (see the 'autoconnect' command)."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
netname = args[0]
|
netname = args[0]
|
||||||
network = world.networkobjects[netname]
|
network = world.networkobjects[netname]
|
||||||
@ -39,7 +39,7 @@ def connect(irc, source, args):
|
|||||||
"""<network>
|
"""<network>
|
||||||
|
|
||||||
Initiates a connection to the network <network>."""
|
Initiates a connection to the network <network>."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
netname = args[0]
|
netname = args[0]
|
||||||
network = world.networkobjects[netname]
|
network = world.networkobjects[netname]
|
||||||
@ -69,7 +69,7 @@ def autoconnect(irc, source, args):
|
|||||||
|
|
||||||
Sets the autoconnect time for <network> to <seconds>.
|
Sets the autoconnect time for <network> to <seconds>.
|
||||||
You can disable autoconnect for a network by setting <seconds> to a negative value."""
|
You can disable autoconnect for a network by setting <seconds> to a negative value."""
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
try:
|
try:
|
||||||
netname = args[0]
|
netname = args[0]
|
||||||
seconds = float(args[1])
|
seconds = float(args[1])
|
||||||
@ -91,7 +91,7 @@ def remote(irc, source, args):
|
|||||||
"""<network> <command>
|
"""<network> <command>
|
||||||
|
|
||||||
Runs <command> on the remote network <network>. No replies are sent back due to protocol limitations."""
|
Runs <command> on the remote network <network>. No replies are sent back due to protocol limitations."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
netname = args[0]
|
netname = args[0]
|
||||||
|
@ -22,7 +22,7 @@ def checkban(irc, source, args):
|
|||||||
"""<banmask (nick!user@host or user@host)> [<nick or hostmask to check>]
|
"""<banmask (nick!user@host or user@host)> [<nick or hostmask to check>]
|
||||||
|
|
||||||
Oper only. If a nick or hostmask is given, return whether the given banmask will match it. Otherwise, returns a list of connected users that would be affected by such a ban, up to 50 results."""
|
Oper only. If a nick or hostmask is given, return whether the given banmask will match it. Otherwise, returns a list of connected users that would be affected by such a ban, up to 50 results."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
if ircmatch is None:
|
if ircmatch is None:
|
||||||
irc.reply("Error: missing ircmatch module (install it via 'pip install ircmatch').")
|
irc.reply("Error: missing ircmatch module (install it via 'pip install ircmatch').")
|
||||||
@ -87,7 +87,7 @@ def jupe(irc, source, args):
|
|||||||
Oper-only, jupes the given server."""
|
Oper-only, jupes the given server."""
|
||||||
|
|
||||||
# Check that the caller is either opered or logged in as admin.
|
# Check that the caller is either opered or logged in as admin.
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
servername = args[0]
|
servername = args[0]
|
||||||
@ -114,7 +114,7 @@ def kick(irc, source, args):
|
|||||||
"""<source> <channel> <user> [<reason>]
|
"""<source> <channel> <user> [<reason>]
|
||||||
|
|
||||||
Admin only. Kicks <user> from <channel> via <source>, where <source> is either the nick of a PyLink client or the SID of a PyLink server."""
|
Admin only. Kicks <user> from <channel> via <source>, where <source> is either the nick of a PyLink client or the SID of a PyLink server."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
sourcenick = args[0]
|
sourcenick = args[0]
|
||||||
channel = args[1]
|
channel = args[1]
|
||||||
@ -155,7 +155,7 @@ def kill(irc, source, args):
|
|||||||
"""<source> <target> [<reason>]
|
"""<source> <target> [<reason>]
|
||||||
|
|
||||||
Admin only. Kills <target> via <source>, where <source> is either the nick of a PyLink client or the SID of a PyLink server."""
|
Admin only. Kills <target> via <source>, where <source> is either the nick of a PyLink client or the SID of a PyLink server."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
sourcenick = args[0]
|
sourcenick = args[0]
|
||||||
target = args[1]
|
target = args[1]
|
||||||
@ -194,7 +194,7 @@ def mode(irc, source, args):
|
|||||||
Oper-only, sets modes <modes> on the target channel."""
|
Oper-only, sets modes <modes> on the target channel."""
|
||||||
|
|
||||||
# Check that the caller is either opered or logged in as admin.
|
# Check that the caller is either opered or logged in as admin.
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
target, modes = args[0], args[1:]
|
target, modes = args[0], args[1:]
|
||||||
@ -232,7 +232,7 @@ def topic(irc, source, args):
|
|||||||
"""<channel> <topic>
|
"""<channel> <topic>
|
||||||
|
|
||||||
Admin only. Updates the topic in a channel."""
|
Admin only. Updates the topic in a channel."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
channel = args[0]
|
channel = args[0]
|
||||||
topic = ' '.join(args[1:])
|
topic = ' '.join(args[1:])
|
||||||
|
@ -1235,7 +1235,7 @@ def create(irc, source, args):
|
|||||||
if source not in irc.channels[channel].users:
|
if source not in irc.channels[channel].users:
|
||||||
irc.reply('Error: You must be in %r to complete this operation.' % channel)
|
irc.reply('Error: You must be in %r to complete this operation.' % channel)
|
||||||
return
|
return
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
|
|
||||||
# Check to see whether the channel requested is already part of a different
|
# Check to see whether the channel requested is already part of a different
|
||||||
# relay.
|
# relay.
|
||||||
@ -1276,10 +1276,10 @@ def destroy(irc, source, args):
|
|||||||
|
|
||||||
if network == irc.name:
|
if network == irc.name:
|
||||||
# If we're destroying a channel on the current network, only oper is needed.
|
# If we're destroying a channel on the current network, only oper is needed.
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
else:
|
else:
|
||||||
# Otherwise, we'll need to be logged in as admin.
|
# Otherwise, we'll need to be logged in as admin.
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
irc.checkAuthenticated(source, allowOper=False)
|
||||||
|
|
||||||
entry = (network, channel)
|
entry = (network, channel)
|
||||||
|
|
||||||
@ -1320,7 +1320,7 @@ def link(irc, source, args):
|
|||||||
if source not in irc.channels[localchan].users:
|
if source not in irc.channels[localchan].users:
|
||||||
irc.reply('Error: You must be in %r to complete this operation.' % localchan)
|
irc.reply('Error: You must be in %r to complete this operation.' % localchan)
|
||||||
return
|
return
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
if remotenet not in world.networkobjects:
|
if remotenet not in world.networkobjects:
|
||||||
irc.reply('Error: No network named %r exists.' % remotenet)
|
irc.reply('Error: No network named %r exists.' % remotenet)
|
||||||
return
|
return
|
||||||
@ -1363,7 +1363,7 @@ def delink(irc, source, args):
|
|||||||
remotenet = args[1]
|
remotenet = args[1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
remotenet = None
|
remotenet = None
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
if not utils.isChannel(channel):
|
if not utils.isChannel(channel):
|
||||||
irc.reply('Error: Invalid channel %r.' % channel)
|
irc.reply('Error: Invalid channel %r.' % channel)
|
||||||
return
|
return
|
||||||
@ -1421,7 +1421,7 @@ def linked(irc, source, args):
|
|||||||
if ('s', None) in c.modes or ('p', None) in c.modes:
|
if ('s', None) in c.modes or ('p', None) in c.modes:
|
||||||
# Only show secret channels to opers, and tag them with
|
# Only show secret channels to opers, and tag them with
|
||||||
# [secret].
|
# [secret].
|
||||||
if utils.isOper(irc, source):
|
if irc.isOper(source):
|
||||||
s += '\x02[secret]\x02 '
|
s += '\x02[secret]\x02 '
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
@ -1434,7 +1434,7 @@ def linked(irc, source, args):
|
|||||||
|
|
||||||
irc.msg(source, s)
|
irc.msg(source, s)
|
||||||
|
|
||||||
if utils.isOper(irc, source):
|
if irc.isOper(source):
|
||||||
s = ''
|
s = ''
|
||||||
|
|
||||||
# If the caller is an oper, we can show the hostmasks of people
|
# If the caller is an oper, we can show the hostmasks of people
|
||||||
@ -1460,7 +1460,7 @@ def linkacl(irc, source, args):
|
|||||||
Allows blocking / unblocking certain networks from linking to a relay, based on a blacklist.
|
Allows blocking / unblocking certain networks from linking to a relay, based on a blacklist.
|
||||||
LINKACL LIST returns a list of blocked networks for a channel, while the ALLOW and DENY subcommands allow manipulating this blacklist."""
|
LINKACL LIST returns a list of blocked networks for a channel, while the ALLOW and DENY subcommands allow manipulating this blacklist."""
|
||||||
missingargs = "Error: Not enough arguments. Needs 2-3: subcommand (ALLOW/DENY/LIST), channel, remote network (for ALLOW/DENY)."
|
missingargs = "Error: Not enough arguments. Needs 2-3: subcommand (ALLOW/DENY/LIST), channel, remote network (for ALLOW/DENY)."
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
try:
|
try:
|
||||||
cmd = args[0].lower()
|
cmd = args[0].lower()
|
||||||
channel = utils.toLower(irc, args[1])
|
channel = utils.toLower(irc, args[1])
|
||||||
@ -1530,7 +1530,7 @@ def showuser(irc, source, args):
|
|||||||
relay = getRelay((irc.name, ch))
|
relay = getRelay((irc.name, ch))
|
||||||
if relay:
|
if relay:
|
||||||
relaychannels.append(''.join(relay))
|
relaychannels.append(''.join(relay))
|
||||||
if relaychannels and (utils.isOper(irc, source) or u == source):
|
if relaychannels and (irc.isOper(source) or u == source):
|
||||||
irc.msg(source, "\x02Relay channels\x02: %s" % ' '.join(relaychannels))
|
irc.msg(source, "\x02Relay channels\x02: %s" % ' '.join(relaychannels))
|
||||||
|
|
||||||
@utils.add_cmd
|
@utils.add_cmd
|
||||||
@ -1538,7 +1538,7 @@ def save(irc, source, args):
|
|||||||
"""takes no arguments.
|
"""takes no arguments.
|
||||||
|
|
||||||
Saves the relay database to disk."""
|
Saves the relay database to disk."""
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
exportDB()
|
exportDB()
|
||||||
irc.reply('Done.')
|
irc.reply('Done.')
|
||||||
|
|
||||||
@ -1549,7 +1549,7 @@ def claim(irc, source, args):
|
|||||||
Sets the CLAIM for a channel to a case-sensitive list of networks. If no list of networks is given, shows which networks have claim over the channel. A single hyphen (-) can also be given as a list of networks to remove claim from the channel entirely.
|
Sets the CLAIM for a channel to a case-sensitive list of networks. If no list of networks is given, shows which networks have claim over the channel. A single hyphen (-) can also be given as a list of networks to remove claim from the channel entirely.
|
||||||
|
|
||||||
CLAIM is a way of enforcing network ownership for a channel, similarly to Janus. Unless the list is empty, only networks on the CLAIM list for a channel (plus the creating network) are allowed to override kicks, mode changes, and topic changes in it - attempts from other networks' opers to do this are simply blocked or reverted."""
|
CLAIM is a way of enforcing network ownership for a channel, similarly to Janus. Unless the list is empty, only networks on the CLAIM list for a channel (plus the creating network) are allowed to override kicks, mode changes, and topic changes in it - attempts from other networks' opers to do this are simply blocked or reverted."""
|
||||||
utils.checkAuthenticated(irc, source)
|
irc.checkAuthenticated(source)
|
||||||
try:
|
try:
|
||||||
channel = utils.toLower(irc, args[0])
|
channel = utils.toLower(irc, args[0])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
35
utils.py
35
utils.py
@ -7,7 +7,6 @@ framework.
|
|||||||
|
|
||||||
import string
|
import string
|
||||||
import re
|
import re
|
||||||
import inspect
|
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -15,13 +14,6 @@ from log import log
|
|||||||
import world
|
import world
|
||||||
import conf
|
import conf
|
||||||
|
|
||||||
class NotAuthenticatedError(Exception):
|
|
||||||
"""
|
|
||||||
Exception raised by checkAuthenticated() when a user fails authentication
|
|
||||||
requirements.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class IncrementalUIDGenerator():
|
class IncrementalUIDGenerator():
|
||||||
"""
|
"""
|
||||||
Incremental UID Generator module, adapted from InspIRCd source:
|
Incremental UID Generator module, adapted from InspIRCd source:
|
||||||
@ -132,33 +124,6 @@ def applyModes(irc, target, changedmodes):
|
|||||||
log.warning("(%s) utils.applyModes is deprecated. Use irc.applyModes() instead!", irc.name)
|
log.warning("(%s) utils.applyModes is deprecated. Use irc.applyModes() instead!", irc.name)
|
||||||
return irc.applyModes(target, changedmodes)
|
return irc.applyModes(target, changedmodes)
|
||||||
|
|
||||||
def isOper(irc, uid, allowAuthed=True, allowOper=True):
|
|
||||||
"""
|
|
||||||
Returns whether the given user has operator status on PyLink. This can be achieved
|
|
||||||
by either identifying to PyLink as admin (if allowAuthed is True),
|
|
||||||
or having user mode +o set (if allowOper is True). At least one of
|
|
||||||
allowAuthed or allowOper must be True for this to give any meaningful
|
|
||||||
results.
|
|
||||||
"""
|
|
||||||
if uid in irc.users:
|
|
||||||
if allowOper and ("o", None) in irc.users[uid].modes:
|
|
||||||
return True
|
|
||||||
elif allowAuthed and irc.users[uid].identified:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def checkAuthenticated(irc, uid, allowAuthed=True, allowOper=True):
|
|
||||||
"""
|
|
||||||
Checks whether the given user has operator status on PyLink, raising
|
|
||||||
NotAuthenticatedError and logging the access denial if not.
|
|
||||||
"""
|
|
||||||
lastfunc = inspect.stack()[1][3]
|
|
||||||
if not isOper(irc, uid, allowAuthed=allowAuthed, allowOper=allowOper):
|
|
||||||
log.warning('(%s) Access denied for %s calling %r', irc.name,
|
|
||||||
getHostmask(irc, uid), lastfunc)
|
|
||||||
raise NotAuthenticatedError("You are not authenticated!")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def loadModuleFromFolder(name, folder):
|
def loadModuleFromFolder(name, folder):
|
||||||
"""
|
"""
|
||||||
Imports and returns a module, if existing, from a specific folder.
|
Imports and returns a module, if existing, from a specific folder.
|
||||||
|
Loading…
Reference in New Issue
Block a user