mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-17 23:52:49 +01:00
Relay: rework to use the permission system
This defines the following permissions: Granted to opers by default: - relay.create - relay.destroy - relay.claim - relay.link - relay.delink - relay.linkacl.view - relay.linkacl Granted to all users by default: - relay.linked And the following which is not explicitly granted: - relay.savedb Closes #325.
This commit is contained in:
parent
93ca62aa49
commit
2d20256ed8
17
docs/relay-permissions.md
Normal file
17
docs/relay-permissions.md
Normal file
@ -0,0 +1,17 @@
|
||||
## Relay Permissions
|
||||
|
||||
Relay defines the following permissions, which can be customized by defining the `permissions:` configuration block (see [example-permissions.yml](../example-permissions.yml) for examples).
|
||||
|
||||
By default, the following permissions are given to opers:
|
||||
|
||||
- `relay.create`
|
||||
- `relay.destroy`
|
||||
- `relay.claim`
|
||||
- `relay.link`
|
||||
- `relay.delink`
|
||||
- `relay.linkacl.view`
|
||||
- `relay.linkacl`
|
||||
|
||||
The following permissions are given to all users:
|
||||
|
||||
- `relay.linked`
|
@ -4,14 +4,14 @@
|
||||
# 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.
|
||||
# The permissions API is new, and optional for plugins. Currently, only Automode and Relay use 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
|
||||
# This determines whether we should merge plugins' built-in default permissions with the ones specified
|
||||
# in the following 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
|
||||
@ -28,6 +28,10 @@ permissions:
|
||||
- automode.manage.relay_owned
|
||||
- automode.sync.relay_owned
|
||||
- automode.list
|
||||
|
||||
# These allow opers to manage Relay links on their network.
|
||||
|
||||
|
||||
"$pylinkacc":
|
||||
# Those with an admin login in PyLink can do anything.
|
||||
- "*"
|
||||
|
@ -8,6 +8,7 @@ from collections import defaultdict
|
||||
from pylinkirc import utils, world, conf
|
||||
from pylinkirc.log import log
|
||||
from pylinkirc.coremods import control
|
||||
from pylinkirc.coremods import permissions
|
||||
|
||||
### GLOBAL (statekeeping) VARIABLES
|
||||
relayusers = defaultdict(dict)
|
||||
@ -20,6 +21,11 @@ save_delay = conf.conf['bot'].get('save_delay', 300)
|
||||
db = {}
|
||||
dbname = utils.getDatabaseName('pylinkrelay')
|
||||
|
||||
default_permissions = {"*!*@*": ['relay.linked'],
|
||||
"$ircop": ['relay.create', 'relay.linkacl*',
|
||||
'relay.destroy', 'relay.link', 'relay.delink',
|
||||
'relay.claim']}
|
||||
|
||||
### INTERNAL FUNCTIONS
|
||||
|
||||
def initializeAll(irc):
|
||||
@ -53,6 +59,8 @@ def main(irc=None):
|
||||
|
||||
log.debug('relay.main: scheduling export loop')
|
||||
|
||||
permissions.addDefaultPermissions(default_permissions)
|
||||
|
||||
if irc is not None:
|
||||
# irc is defined when the plugin is reloaded. Otherwise, it means that we've just started the
|
||||
# server. Iterate over all connected networks and initialize their relay users.
|
||||
@ -77,10 +85,13 @@ def die(sourceirc):
|
||||
relayservers.clear()
|
||||
relayusers.clear()
|
||||
|
||||
# 3) Export the relay links database.
|
||||
# 3) Unload our permissions.
|
||||
permissions.removeDefaultPermissions(default_permissions)
|
||||
|
||||
# 4) Export the relay links database.
|
||||
exportDB()
|
||||
|
||||
# 4) Kill the scheduling for any other exports.
|
||||
# 5) Kill the scheduling for any other exports.
|
||||
global exportdb_timer
|
||||
if exportdb_timer:
|
||||
log.debug("Relay: cancelling exportDB timer thread %s due to die()", threading.get_ident())
|
||||
@ -1562,7 +1573,7 @@ def create(irc, source, args):
|
||||
irc.reply('Error: You must be in %r to complete this operation.' % channel)
|
||||
return
|
||||
|
||||
irc.checkAuthenticated(source)
|
||||
permissions.checkPermissions(irc, source, ['relay.create'])
|
||||
|
||||
# Check to see whether the channel requested is already part of a different
|
||||
# relay.
|
||||
@ -1601,12 +1612,12 @@ def destroy(irc, source, args):
|
||||
irc.reply('Error: Invalid channel %r.' % channel)
|
||||
return
|
||||
|
||||
# Check for different permissions based on whether we're destroying a local channel or
|
||||
# a remote one.
|
||||
if network == irc.name:
|
||||
# If we're destroying a channel on the current network, only oper is needed.
|
||||
irc.checkAuthenticated(source)
|
||||
permissions.checkPermissions(irc, source, ['relay.destroy'])
|
||||
else:
|
||||
# Otherwise, we'll need to be logged in as admin.
|
||||
irc.checkAuthenticated(source, allowOper=False)
|
||||
permissions.checkPermissions(irc, source, ['relay.destroy.remote'])
|
||||
|
||||
entry = (network, channel)
|
||||
|
||||
@ -1670,7 +1681,7 @@ def link(irc, source, args):
|
||||
irc.reply('Error: You must be in %r to complete this operation.' % localchan)
|
||||
return
|
||||
|
||||
irc.checkAuthenticated(source)
|
||||
permissions.checkPermissions(irc, source, ['relay.link'])
|
||||
|
||||
if remotenet not in world.networkobjects:
|
||||
irc.reply('Error: No network named %r exists.' % remotenet)
|
||||
@ -1727,7 +1738,9 @@ def delink(irc, source, args):
|
||||
remotenet = args[1]
|
||||
except IndexError:
|
||||
remotenet = None
|
||||
irc.checkAuthenticated(source)
|
||||
|
||||
permissions.checkPermissions(irc, source, ['relay.delink'])
|
||||
|
||||
if not utils.isChannel(channel):
|
||||
irc.reply('Error: Invalid channel %r.' % channel)
|
||||
return
|
||||
@ -1843,7 +1856,7 @@ def linkacl(irc, source, args):
|
||||
Allows blocking / unblocking certain networks from linking to a relayed channel, 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."""
|
||||
missingargs = "Error: Not enough arguments. Needs 2-3: subcommand (ALLOW/DENY/LIST), channel, remote network (for ALLOW/DENY)."
|
||||
irc.checkAuthenticated(source)
|
||||
|
||||
try:
|
||||
cmd = args[0].lower()
|
||||
channel = irc.toLower(args[1])
|
||||
@ -1858,10 +1871,12 @@ def linkacl(irc, source, args):
|
||||
irc.reply('Error: No such relay %r exists.' % channel)
|
||||
return
|
||||
if cmd == 'list':
|
||||
permissions.checkPermissions(irc, source, ['relay.linkacl.view'])
|
||||
s = 'Blocked networks for \x02%s\x02: \x02%s\x02' % (channel, ', '.join(db[relay]['blocked_nets']) or '(empty)')
|
||||
irc.reply(s)
|
||||
return
|
||||
|
||||
permissions.checkPermissions(irc, source, ['relay.linkacl'])
|
||||
try:
|
||||
remotenet = args[2]
|
||||
except IndexError:
|
||||
@ -1922,7 +1937,7 @@ def save(irc, source, args):
|
||||
"""takes no arguments.
|
||||
|
||||
Saves the relay database to disk."""
|
||||
irc.checkAuthenticated(source)
|
||||
permissions.checkPermissions(irc, source, ['relay.savedb'])
|
||||
exportDB()
|
||||
irc.reply('Done.')
|
||||
|
||||
@ -1933,13 +1948,14 @@ 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.
|
||||
|
||||
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."""
|
||||
irc.checkAuthenticated(source)
|
||||
try:
|
||||
channel = irc.toLower(args[0])
|
||||
except IndexError:
|
||||
irc.reply("Error: Not enough arguments. Needs 1-2: channel, list of networks (optional).")
|
||||
return
|
||||
|
||||
permissions.checkPermissions(irc, source, ['relay.claim'])
|
||||
|
||||
# We override getRelay() here to limit the search to the current network.
|
||||
relay = (irc.name, channel)
|
||||
if relay not in db:
|
||||
|
Loading…
Reference in New Issue
Block a user