mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-23 19:19:31 +01:00
permissions, automode: work on default permissions & add example permissions config (#190)
- Fix possible type errors in add/removeDefaultPermissions by converting permlist values to sets. - Fix wrong permission string being checked in automode.<command>.#channel - automode: register and unregister default permissions on load/unload. - permissions: add an 'also_show' argument to checkPermissions(), to display alternative permissions that weren't directly checked.
This commit is contained in:
parent
03a780f397
commit
f890ddac1b
@ -7,7 +7,7 @@ import threading
|
|||||||
|
|
||||||
# Global variables: these store mappings of hostmasks/exttargets to lists of permissions each target has.
|
# Global variables: these store mappings of hostmasks/exttargets to lists of permissions each target has.
|
||||||
default_permissions = defaultdict(set)
|
default_permissions = defaultdict(set)
|
||||||
permissions = defaultdict(set)
|
permissions = defaultdict(set, {'$pylinkacc': {'*'}})
|
||||||
|
|
||||||
# Only allow one thread to change the permissions index at once.
|
# Only allow one thread to change the permissions index at once.
|
||||||
permissions_lock = threading.Lock()
|
permissions_lock = threading.Lock()
|
||||||
@ -23,7 +23,12 @@ def resetPermissions():
|
|||||||
with permissions_lock:
|
with permissions_lock:
|
||||||
global permissions
|
global permissions
|
||||||
log.debug('permissions.resetPermissions: old perm list: %s', permissions)
|
log.debug('permissions.resetPermissions: old perm list: %s', permissions)
|
||||||
permissions = conf.conf.get('permissions', default_permissions)
|
|
||||||
|
if not conf.conf.get('permissions_merge_defaults', True):
|
||||||
|
log.debug('permissions.resetPermissions: clearing perm list due to permissions_merge_defaults set False.')
|
||||||
|
permissions.clear()
|
||||||
|
|
||||||
|
permissions.update(conf.conf.get('permissions', default_permissions))
|
||||||
log.debug('permissions.resetPermissions: new perm list: %s', permissions)
|
log.debug('permissions.resetPermissions: new perm list: %s', permissions)
|
||||||
|
|
||||||
def addDefaultPermissions(perms):
|
def addDefaultPermissions(perms):
|
||||||
@ -31,16 +36,16 @@ def addDefaultPermissions(perms):
|
|||||||
with permissions_lock:
|
with permissions_lock:
|
||||||
global permissions
|
global permissions
|
||||||
for target, permlist in perms.items():
|
for target, permlist in perms.items():
|
||||||
permissions[target] |= permlist
|
permissions[target] |= set(permlist)
|
||||||
|
|
||||||
def removeDefaultPermissions(perms):
|
def removeDefaultPermissions(perms):
|
||||||
"""Remove default permissions from the index."""
|
"""Remove default permissions from the index."""
|
||||||
with permissions_lock:
|
with permissions_lock:
|
||||||
global permissions
|
global permissions
|
||||||
for target, permlist in perms.items():
|
for target, permlist in perms.items():
|
||||||
permissions[target] -= permlist
|
permissions[target] -= set(permlist)
|
||||||
|
|
||||||
def checkPermissions(irc, uid, perms):
|
def checkPermissions(irc, uid, perms, also_show=[]):
|
||||||
"""
|
"""
|
||||||
Checks permissions of the caller. If the caller has any of the permissions listed in perms,
|
Checks permissions of the caller. If the caller has any of the permissions listed in perms,
|
||||||
this function returns True. Otherwise, NotAuthorizedError is raised.
|
this function returns True. Otherwise, NotAuthorizedError is raised.
|
||||||
@ -58,7 +63,7 @@ def checkPermissions(irc, uid, perms):
|
|||||||
if any(irc.matchHost(perm, p) for p in perms):
|
if any(irc.matchHost(perm, p) for p in perms):
|
||||||
return True
|
return True
|
||||||
raise utils.NotAuthorizedError("You are missing one of the following permissions: %s" %
|
raise utils.NotAuthorizedError("You are missing one of the following permissions: %s" %
|
||||||
(', '.join(perms)))
|
(', '.join(perms+also_show)))
|
||||||
|
|
||||||
|
|
||||||
# This is called on first import.
|
# This is called on first import.
|
||||||
|
35
example-permissions.yml
Normal file
35
example-permissions.yml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# This file is an example of the permissions system in PyLink. Should you wish,
|
||||||
|
# you may copy the contents of this file and paste it into the configuration you're
|
||||||
|
# using.
|
||||||
|
# Permissions work by mapping hostmasks or exttargets to list of permissions, allowing
|
||||||
|
# you to fine tune which users have access to which commands.
|
||||||
|
|
||||||
|
# The permissions API is new, and optional for plugins. Currently, only Automode uses it.
|
||||||
|
|
||||||
|
# If you do not specify any permissions block in your configuration, PyLink will default to a
|
||||||
|
# permission set defined by plugins, which usually correspond to the list below, but can be
|
||||||
|
# changed on every release.
|
||||||
|
|
||||||
|
# This determines whether we should merge the plugin-default permissions with the ones specified
|
||||||
|
# in the permissions: block. Disabling this allows you greater control over the permissions
|
||||||
|
# PyLink gives, but you should check this file on every major update to see if any new permissions
|
||||||
|
# were added for commands. Otherwise, commands that were available before may cease to function!
|
||||||
|
permissions_merge_defaults: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
# Note: It is a good idea to quote any exttargets or hostmasks so the configuration parser knows
|
||||||
|
# they are raw strings.
|
||||||
|
|
||||||
|
"$ircop":
|
||||||
|
# The default set of Automode permissions allow you to manage any channels you own in Relay.
|
||||||
|
# If Relay is not loaded, this check will fail. This has the ability of allowing local opers
|
||||||
|
# to manage their channels, but not abusing Automode to hack modes in other networks' relay
|
||||||
|
# channels.
|
||||||
|
- automode.manage.relay_owned
|
||||||
|
- automode.sync.relay_owned
|
||||||
|
"*!*@*":
|
||||||
|
# Everyone can use /msg Automode list on any channel.
|
||||||
|
- automode.list
|
||||||
|
"$pylinkacc":
|
||||||
|
# Those with an admin login in PyLink can do anything.
|
||||||
|
- "*"
|
@ -24,6 +24,10 @@ exportdb_timer = None
|
|||||||
|
|
||||||
save_delay = conf.conf['bot'].get('save_delay', 300)
|
save_delay = conf.conf['bot'].get('save_delay', 300)
|
||||||
|
|
||||||
|
# The default set of Automode permissions.
|
||||||
|
default_permissions = {"$ircop": ['automode.manage.relay_owned', 'automode.sync.relay_owned'],
|
||||||
|
"*!*@*": ['automode.list']}
|
||||||
|
|
||||||
def loadDB():
|
def loadDB():
|
||||||
"""Loads the Automode database, silently creating a new one if this fails."""
|
"""Loads the Automode database, silently creating a new one if this fails."""
|
||||||
global db
|
global db
|
||||||
@ -66,6 +70,9 @@ def main(irc=None):
|
|||||||
# Schedule periodic exports of the automode database.
|
# Schedule periodic exports of the automode database.
|
||||||
scheduleExport(starting=True)
|
scheduleExport(starting=True)
|
||||||
|
|
||||||
|
# Register our permissions.
|
||||||
|
permissions.addDefaultPermissions(default_permissions)
|
||||||
|
|
||||||
# Queue joins to all channels where Automode has entries.
|
# Queue joins to all channels where Automode has entries.
|
||||||
for entry in db:
|
for entry in db:
|
||||||
netname, channel = entry.split('#', 1)
|
netname, channel = entry.split('#', 1)
|
||||||
@ -94,6 +101,7 @@ def die(sourceirc):
|
|||||||
log.debug("Automode: cancelling exportDB timer thread %s due to die()", threading.get_ident())
|
log.debug("Automode: cancelling exportDB timer thread %s due to die()", threading.get_ident())
|
||||||
exportdb_timer.cancel()
|
exportdb_timer.cancel()
|
||||||
|
|
||||||
|
permissions.removeDefaultPermissions(default_permissions)
|
||||||
utils.unregisterService('automode')
|
utils.unregisterService('automode')
|
||||||
|
|
||||||
def checkAccess(irc, uid, channel, command):
|
def checkAccess(irc, uid, channel, command):
|
||||||
@ -111,10 +119,11 @@ def checkAccess(irc, uid, channel, command):
|
|||||||
baseperm = 'automode.%s' % command
|
baseperm = 'automode.%s' % command
|
||||||
try:
|
try:
|
||||||
# First, check the catch all and channel permissions.
|
# First, check the catch all and channel permissions.
|
||||||
return permissions.checkPermissions(irc, uid, [baseperm, baseperm+'.*', '%s.%s' % (command, channel)])
|
perms = [baseperm, baseperm+'.*', '%s.%s' % (baseperm, channel)]
|
||||||
|
return permissions.checkPermissions(irc, uid, perms)
|
||||||
except utils.NotAuthorizedError:
|
except utils.NotAuthorizedError:
|
||||||
log.debug('(%s) Automode: falling back to automode.%s.relay_owned', irc.name, command)
|
log.debug('(%s) Automode: falling back to automode.%s.relay_owned', irc.name, command)
|
||||||
permissions.checkPermissions(irc, uid, [baseperm+'.relay_owned'])
|
permissions.checkPermissions(irc, uid, [baseperm+'.relay_owned'], also_show=perms)
|
||||||
|
|
||||||
relay = world.plugins.get('relay')
|
relay = world.plugins.get('relay')
|
||||||
if relay is None:
|
if relay is None:
|
||||||
|
Loading…
Reference in New Issue
Block a user