3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 09:19:23 +01:00

Move checkAuthenticated() to utils, and give it and isOper() toggles for allowing oper/PyLink logins

This commit is contained in:
James Lu 2015-08-25 20:38:32 -07:00
parent 090fa85a46
commit 3d621b00df
3 changed files with 42 additions and 29 deletions

View File

@ -12,9 +12,6 @@ import utils
### Exceptions ### Exceptions
class NotAuthenticatedError(Exception):
pass
class ProtocolError(Exception): class ProtocolError(Exception):
pass pass

View File

@ -1,28 +1,17 @@
# admin.py: PyLink administrative commands # admin.py: PyLink administrative commands
import sys import sys
import os import os
import inspect
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import utils import utils
from log import log from log import log
class NotAuthenticatedError(Exception):
pass
def checkauthenticated(irc, source):
lastfunc = inspect.stack()[1][3]
if not irc.users[source].identified:
log.warning('(%s) Access denied for %s calling %r', irc.name,
utils.getHostmask(irc, source), lastfunc)
raise NotAuthenticatedError("You are not authenticated!")
def _exec(irc, source, args): def _exec(irc, source, args):
"""<code> """<code>
Admin-only. Executes <code> in the current PyLink instance. Admin-only. Executes <code> in the current PyLink instance.
\x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02""" \x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
args = ' '.join(args) args = ' '.join(args)
if not args.strip(): if not args.strip():
utils.msg(irc, source, 'No code entered!') utils.msg(irc, source, 'No code entered!')
@ -37,7 +26,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!"""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
nick, ident, host = args[:3] nick, ident, host = args[:3]
except ValueError: except ValueError:
@ -50,7 +39,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."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
nick = args[0] nick = args[0]
except IndexError: except IndexError:
@ -68,7 +57,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.""" Admin-only. Joins <target>, the nick of a PyLink client, to a comma-separated list of channels."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
nick = args[0] nick = args[0]
clist = args[1].split(',') clist = args[1].split(',')
@ -93,7 +82,7 @@ def nick(irc, source, args):
"""<target> <newnick> """<target> <newnick>
Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>.""" Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
nick = args[0] nick = args[0]
newnick = args[1] newnick = args[1]
@ -114,7 +103,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.""" Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
nick = args[0] nick = args[0]
clist = args[1].split(',') clist = args[1].split(',')
@ -135,7 +124,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 the nick of a PyLink client.""" Admin-only. Kicks <user> from <channel> via <source>, where <source> is the nick of a PyLink client."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
nick = args[0] nick = args[0]
channel = args[1] channel = args[1]
@ -160,7 +149,7 @@ def showuser(irc, source, args):
"""<user> """<user>
Admin-only. Shows information about <user>.""" Admin-only. Shows information about <user>."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
target = args[0] target = args[0]
except IndexError: except IndexError:
@ -179,7 +168,7 @@ def showchan(irc, source, args):
"""<channel> """<channel>
Admin-only. Shows information about <channel>.""" Admin-only. Shows information about <channel>."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
channel = args[0].lower() channel = args[0].lower()
except IndexError: except IndexError:
@ -197,7 +186,7 @@ def mode(irc, source, args):
"""<source> <target> <modes> """<source> <target> <modes>
Admin-only. Sets modes <modes> on <target> from <source>, where <source> is either the nick of a PyLink client, or the SID of a PyLink server.""" Admin-only. Sets modes <modes> on <target> from <source>, where <source> is either the nick of a PyLink client, or the SID of a PyLink server."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
modesource, target, modes = args[0], args[1], args[2:] modesource, target, modes = args[0], args[1], args[2:]
except IndexError: except IndexError:
@ -226,7 +215,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.""" Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client."""
checkauthenticated(irc, source) utils.checkAuthenticated(irc, source, allowOper=False)
try: try:
msgsource, target, text = args[0], args[1], ' '.join(args[2:]) msgsource, target, text = args[0], args[1], ' '.join(args[2:])
except IndexError: except IndexError:

View File

@ -2,9 +2,9 @@ import string
import re import re
from collections import defaultdict from collections import defaultdict
import threading import threading
import inspect
from log import log from log import log
global bot_commands, command_hooks global bot_commands, command_hooks
# This should be a mapping of command names to functions # This should be a mapping of command names to functions
bot_commands = {} bot_commands = {}
@ -15,6 +15,10 @@ plugins = []
whois_handlers = [] whois_handlers = []
started = threading.Event() started = threading.Event()
# This is separate from classes.py to prevent import loops.
class NotAuthenticatedError(Exception):
pass
class TS6UIDGenerator(): class TS6UIDGenerator():
"""TS6 UID Generator module, adapted from InspIRCd source """TS6 UID Generator module, adapted from InspIRCd source
https://github.com/inspircd/inspircd/blob/f449c6b296ab/src/server.cpp#L85-L156 https://github.com/inspircd/inspircd/blob/f449c6b296ab/src/server.cpp#L85-L156
@ -350,15 +354,38 @@ def isInternalServer(irc, sid):
""" """
return (sid in irc.servers and irc.servers[sid].internal) return (sid in irc.servers and irc.servers[sid].internal)
def isOper(irc, uid): def isOper(irc, uid, allowAuthed=True, allowOper=True):
"""<irc object> <UID> """<irc object> <UID>
Returns whether <UID> has operator status on PyLink. This can be achieved Returns whether <UID> has operator status on PyLink. This can be achieved
by either identifying to PyLink as admin, or having user mode +o set. 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.
""" """
return (uid in irc.users and (("o", None) in irc.users[uid].modes or irc.users[uid].identified)) 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):
"""<irc object> <UID>
Checks whether user <UID> 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 getHostmask(irc, user): def getHostmask(irc, user):
"""<irc object> <UID>
Gets the hostmask of user <UID>, if present."""
userobj = irc.users.get(user) userobj = irc.users.get(user)
if userobj is None: if userobj is None:
return '<user object not found>' return '<user object not found>'