mirror of
				https://github.com/jlu5/PyLink.git
				synced 2025-11-04 08:57:25 +01:00 
			
		
		
		
	Move checkAuthenticated() to utils, and give it and isOper() toggles for allowing oper/PyLink logins
This commit is contained in:
		
							parent
							
								
									090fa85a46
								
							
						
					
					
						commit
						3d621b00df
					
				@ -12,9 +12,6 @@ import utils
 | 
			
		||||
 | 
			
		||||
### Exceptions
 | 
			
		||||
 | 
			
		||||
class NotAuthenticatedError(Exception):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
class ProtocolError(Exception):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,28 +1,17 @@
 | 
			
		||||
# admin.py: PyLink administrative commands
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import inspect
 | 
			
		||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 | 
			
		||||
 | 
			
		||||
import utils
 | 
			
		||||
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):
 | 
			
		||||
    """<code>
 | 
			
		||||
 | 
			
		||||
    Admin-only. Executes <code> in the current PyLink instance.
 | 
			
		||||
    \x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    args = ' '.join(args)
 | 
			
		||||
    if not args.strip():
 | 
			
		||||
        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.
 | 
			
		||||
    Note: this doesn't check the validity of any fields you give it!"""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    try:
 | 
			
		||||
        nick, ident, host = args[:3]
 | 
			
		||||
    except ValueError:
 | 
			
		||||
@ -50,7 +39,7 @@ def quit(irc, source, args):
 | 
			
		||||
    """<target> [<reason>]
 | 
			
		||||
 | 
			
		||||
    Admin-only. Quits the PyLink client with nick <target>, if one exists."""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    try:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
    except IndexError:
 | 
			
		||||
@ -68,7 +57,7 @@ def joinclient(irc, source, args):
 | 
			
		||||
    """<target> <channel1>,[<channel2>], etc.
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
        clist = args[1].split(',')
 | 
			
		||||
@ -93,7 +82,7 @@ def nick(irc, source, args):
 | 
			
		||||
    """<target> <newnick>
 | 
			
		||||
 | 
			
		||||
    Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>."""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    try:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
        newnick = args[1]
 | 
			
		||||
@ -114,7 +103,7 @@ def part(irc, source, args):
 | 
			
		||||
    """<target> <channel1>,[<channel2>],... [<reason>]
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
        clist = args[1].split(',')
 | 
			
		||||
@ -135,7 +124,7 @@ def kick(irc, source, args):
 | 
			
		||||
    """<source> <channel> <user> [<reason>]
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
        channel = args[1]
 | 
			
		||||
@ -160,7 +149,7 @@ def showuser(irc, source, args):
 | 
			
		||||
    """<user>
 | 
			
		||||
 | 
			
		||||
    Admin-only. Shows information about <user>."""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    try:
 | 
			
		||||
        target = args[0]
 | 
			
		||||
    except IndexError:
 | 
			
		||||
@ -179,7 +168,7 @@ def showchan(irc, source, args):
 | 
			
		||||
    """<channel>
 | 
			
		||||
 | 
			
		||||
    Admin-only. Shows information about <channel>."""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    try:
 | 
			
		||||
        channel = args[0].lower()
 | 
			
		||||
    except IndexError:
 | 
			
		||||
@ -197,7 +186,7 @@ def mode(irc, source, args):
 | 
			
		||||
    """<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."""
 | 
			
		||||
    checkauthenticated(irc, source)
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
    try:
 | 
			
		||||
        modesource, target, modes = args[0], args[1], args[2:]
 | 
			
		||||
    except IndexError:
 | 
			
		||||
@ -226,7 +215,7 @@ def msg(irc, source, args):
 | 
			
		||||
    """<source> <target> <text>
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
        msgsource, target, text = args[0], args[1], ' '.join(args[2:])
 | 
			
		||||
    except IndexError:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								utils.py
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								utils.py
									
									
									
									
									
								
							@ -2,9 +2,9 @@ import string
 | 
			
		||||
import re
 | 
			
		||||
from collections import defaultdict
 | 
			
		||||
import threading
 | 
			
		||||
import inspect
 | 
			
		||||
 | 
			
		||||
from log import log
 | 
			
		||||
 | 
			
		||||
global bot_commands, command_hooks
 | 
			
		||||
# This should be a mapping of command names to functions
 | 
			
		||||
bot_commands = {}
 | 
			
		||||
@ -15,6 +15,10 @@ plugins = []
 | 
			
		||||
whois_handlers = []
 | 
			
		||||
started = threading.Event()
 | 
			
		||||
 | 
			
		||||
# This is separate from classes.py to prevent import loops.
 | 
			
		||||
class NotAuthenticatedError(Exception):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
class TS6UIDGenerator():
 | 
			
		||||
    """TS6 UID Generator module, adapted from InspIRCd source
 | 
			
		||||
    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)
 | 
			
		||||
 | 
			
		||||
def isOper(irc, uid):
 | 
			
		||||
def isOper(irc, uid, allowAuthed=True, allowOper=True):
 | 
			
		||||
    """<irc object> <UID>
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
    """<irc object> <UID>
 | 
			
		||||
 | 
			
		||||
    Gets the hostmask of user <UID>, if present."""
 | 
			
		||||
    userobj = irc.users.get(user)
 | 
			
		||||
    if userobj is None:
 | 
			
		||||
        return '<user object not found>'
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user