2014-01-20 11:54:27 +01:00
|
|
|
.. _capabilities:
|
|
|
|
|
2011-06-30 16:49:28 +02:00
|
|
|
************
|
2011-06-30 16:21:24 +02:00
|
|
|
Capabilities
|
2011-06-30 16:49:28 +02:00
|
|
|
************
|
2011-06-30 16:21:24 +02:00
|
|
|
|
|
|
|
Introduction
|
|
|
|
------------
|
|
|
|
|
|
|
|
Ok, some explanation of the capabilities system is probably in order. With
|
|
|
|
most IRC bots (including the ones I've written myself prior to this one) "what
|
|
|
|
a user can do" is set in one of two ways. On the *really* simple bots, each
|
|
|
|
user has a numeric "level" and commands check to see if a user has a "high
|
|
|
|
enough level" to perform some operation. On bots that are slightly more
|
|
|
|
complicated, users have a list of "flags" whose meanings are hardcoded, and the
|
|
|
|
bot checks to see if a user possesses the necessary flag before performing some
|
|
|
|
operation. Both methods, IMO, are rather arbitrary, and force the user and the
|
|
|
|
programmer to be unduly confined to less expressive constructs.
|
|
|
|
|
|
|
|
This bot is different. Every user has a set of "capabilities" that is
|
|
|
|
consulted every time they give the bot a command. Commands, rather than
|
|
|
|
checking for a user level of 100, or checking if the user has an 'o' flag, are
|
|
|
|
instead able to check if a user has the 'owner' capability. At this point such
|
|
|
|
a difference might not seem revolutionary, but at least we can already tell
|
|
|
|
that this method is self-documenting, and easier for users and developers to
|
|
|
|
understand what's truly going on.
|
|
|
|
|
|
|
|
User Capabilities
|
|
|
|
-----------------
|
|
|
|
What the heck can these capabilities DO?
|
|
|
|
|
|
|
|
If that was all, well, the capability system would be *cool*, but not many
|
|
|
|
people would say it was *awesome*. But it **is** awesome! Several things are
|
|
|
|
happening behind the scenes that make it awesome, and these are things that
|
|
|
|
couldn't happen if the bot was using numeric userlevels or single-character
|
|
|
|
flags. First, whenever a user issues the bot a command, the command dispatcher
|
|
|
|
checks to make sure the user doesn't have the "anticapability" for that
|
|
|
|
command. An anticapability is a capability that, instead of saying "what a
|
|
|
|
user can do", says what a user *cannot* do. It's formed rather simply by
|
|
|
|
adding a dash ('-') to the beginning of a capability; 'rot13' is a capability,
|
|
|
|
and '-rot13' is an anticapability.
|
|
|
|
|
|
|
|
Anyway, when a user issues the bot a command, perhaps 'calc' or 'help', the bot
|
|
|
|
first checks to make sure the user doesn't have the '-calc' or the '-help'
|
|
|
|
(anti)capabilities before even considering responding to the user. So commands
|
|
|
|
can be turned on or off on a *per user* basis, offering fine-grained control
|
|
|
|
not often (if at all!) seen in other bots. This can be further refined by
|
|
|
|
limiting the (anti)capability to a command in a specific plugin or even an
|
|
|
|
entire plugin. For example, the rot13 command is in the Filter plugin. If a
|
|
|
|
user should be able to use another rot13 command, but not the one in the Format
|
|
|
|
plugin, they would simply need to be given '-Format.rot13' anticapability.
|
|
|
|
Similarly, if a user were to be banned from using the Filter plugin altogether,
|
|
|
|
they would simply need to be given the '-Filter' anticapability.
|
|
|
|
|
|
|
|
Channel Capabilities
|
|
|
|
--------------------
|
|
|
|
What if #linux wants completely different capabilities from #windows?
|
|
|
|
|
|
|
|
But that's not all! The capabilities system also supports *channel*
|
|
|
|
capabilities, which are capabilities that only apply to a specific channel;
|
|
|
|
they're of the form '#channel,capability'. Whenever a user issues a command to
|
|
|
|
the bot in a channel, the command dispatcher also checks to make sure the user
|
|
|
|
doesn't have the anticapability for that command *in that channel*, and if the
|
|
|
|
user does, the bot won't respond to the user in the channel. Thus now, in
|
|
|
|
addition to having the ability to turn individual commands on or off for an
|
|
|
|
individual user, we can now turn commands on or off for an individual user on
|
|
|
|
an individual channel!
|
|
|
|
|
|
|
|
So when a user 'foo' sends a command 'bar' to the bot on channel '#baz', first
|
|
|
|
the bot checks to see if the user has the anticapability for the command by
|
|
|
|
itself, '-bar'. If so, it errors right then and there, telling the user that
|
2020-05-13 19:56:44 +02:00
|
|
|
they lacks the 'bar' capability. If the user doesn't have that anticapability,
|
2011-06-30 16:21:24 +02:00
|
|
|
then the bot checks to see if the user issued the command over a channel, and
|
|
|
|
if so, checks to see if the user has the antichannelcapability for that
|
2014-08-28 13:43:41 +02:00
|
|
|
command, '#baz,-bar'. If so, again, it tells the user that they lack the 'bar'
|
2011-06-30 16:21:24 +02:00
|
|
|
capability. If neither of these anticapabilities are present, then the bot
|
|
|
|
just responds to the user like normal.
|
|
|
|
|
|
|
|
Default Capabilities
|
|
|
|
--------------------
|
|
|
|
So what capabilities am I dealing with already?
|
|
|
|
|
|
|
|
There are several default capabilities the bot uses. The most important of
|
|
|
|
these is the 'owner' capability. This capability allows the person having it
|
|
|
|
to use *any* command. It's best to keep this capability reserved to people who
|
|
|
|
actually have access to the shell the bot is running on. It's so important, in
|
|
|
|
fact, that the bot will not allow you to add it with a command--you'll have you
|
|
|
|
edit the users file directly to give it to someone.
|
|
|
|
|
|
|
|
There is also the 'admin' capability for non-owners that are highly trusted to
|
|
|
|
administer the bot appropriately. They can do things such as change the bot's
|
|
|
|
nick, cause the bot to ignore a given user, make the bot join or part channels,
|
|
|
|
etc. They generally cannot do administration related to channels, which is
|
|
|
|
reserved for people with the next capability.
|
|
|
|
|
|
|
|
People who are to administer channels with the bot should have the
|
|
|
|
'#channel,op' capability--whatever channel they are to administrate, they
|
|
|
|
should have that channel capability for 'op'. For example, since I want
|
2014-08-28 13:43:41 +02:00
|
|
|
inkedmn to be an administrator in #supybot, I'll give them the '#supybot,op'
|
|
|
|
capability. This is in addition to their 'admin' capability, since the 'admin'
|
2011-06-30 16:21:24 +02:00
|
|
|
capability doesn't give the person having it control over channels.
|
|
|
|
'#channel,op' is used for such things as giving/receiving ops, kickbanning
|
|
|
|
people, lobotomizing the bot, ignoring users in the channel, and managing the
|
|
|
|
channel capabilities. The '#channel,op' capability is also basically the
|
|
|
|
equivalent of the 'owner' capability for capabilities involving
|
|
|
|
#channel--basically anyone with the #channel,op capability is considered to
|
|
|
|
have all positive capabilities and no negative capabilities for #channel.
|
|
|
|
|
|
|
|
One other globally important capability exists: 'trusted'. This is a command
|
|
|
|
that basically says "This user can be trusted not to try and crash the bot." It
|
|
|
|
allows users to call commands like 'icalc' in the 'Math' plugin, which can
|
|
|
|
cause the bot to begin a calculation that could potentially never return (a
|
|
|
|
calculation like '10**10**10**10'). Another command that requires the 'trusted'
|
|
|
|
capability is the 're' command in the 'Utilities' plugin, which (due to the
|
|
|
|
regular expression implementation in Python (and any other language that uses
|
|
|
|
NFA regular expressions, like Perl or Ruby or Lua or ...) which can allow a
|
|
|
|
regular expression to take exponential time to process). Consider what would
|
|
|
|
happen if someone gave the bot the command 're [format join "" s/./ [dict go]
|
|
|
|
/] [dict go]' It would basically replace every character in the output of
|
|
|
|
'dict go' (14,896 characters!) with the entire output of 'dict go', resulting
|
|
|
|
in 221MB of memory allocated! And that's not even the worst example!
|
|
|
|
|
2020-05-13 20:48:04 +02:00
|
|
|
|
2014-08-28 15:09:16 +02:00
|
|
|
Managing capabilities
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
User Capabilities
|
|
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
User capabilities are controlled with the ``admin capability <add|remove>``
|
|
|
|
and ``channel capability <add|remove>``. Their difference is that the
|
|
|
|
first one is only restricted to those who have the admin capability.
|
|
|
|
|
|
|
|
To make user1 admin, I would run::
|
|
|
|
|
|
|
|
admin capability add user1 admin
|
|
|
|
|
|
|
|
If the bot joins on a channel where there should be ops who should't have
|
|
|
|
power over any other channel, I would run::
|
|
|
|
|
|
|
|
channel capability add #channel user2 op
|
|
|
|
|
|
|
|
Note that admins cannot give anyone capability which they don't have by
|
|
|
|
themselves first, so user1 couldn't use ``channel capability add`` unless
|
|
|
|
they were made #channel,op first. The command::
|
|
|
|
|
|
|
|
admin capability add user2 #channel,op
|
|
|
|
|
|
|
|
has the same effect as ``channel capability add``, but it requires user
|
|
|
|
to have the admin capability in addition to #channel,op.
|
|
|
|
|
|
|
|
If there is abusive user who shouldn't have op capability but still does
|
|
|
|
for one reason or another, I could run either::
|
|
|
|
|
|
|
|
channel capability add user3 -op
|
|
|
|
|
|
|
|
or::
|
|
|
|
|
|
|
|
channel capability remove user3 op
|
|
|
|
|
|
|
|
Anticapabilities are checked before normal capabilities so the first
|
|
|
|
command would work even if user3 still had the op capability. Removing
|
|
|
|
capability which isn't given to user or channel adds anti-capability
|
|
|
|
automatically.
|
|
|
|
|
|
|
|
User capabilities can be viewed with ``user capabilities`` command.
|
|
|
|
|
|
|
|
Channel
|
|
|
|
^^^^^^^
|
|
|
|
|
|
|
|
Channel capabilities affect everyone on the current channel including
|
|
|
|
unidentified users. They are controlled with the ``channel capability <set|unset>`` commands.
|
|
|
|
|
|
|
|
If I wanted to make everyone on the channel able to voice themselves or get
|
|
|
|
automatically voiced by the AutoMode plugin, I would start by unsetting the
|
|
|
|
default anticapability and setting the capability.::
|
|
|
|
|
|
|
|
channel capability unset -voice
|
|
|
|
channel capability set voice
|
|
|
|
|
|
|
|
Now anyone on the channel can voice themselves or if AutoMode plugin is
|
|
|
|
configured to voice voiced people, the will automatically get voiced on
|
|
|
|
join.
|
|
|
|
|
|
|
|
If there was unwanted plugin or plugin which output was causing spam, Games
|
|
|
|
for example, I could add anticapability for it and prevent the whole plugin
|
|
|
|
from being used.::
|
|
|
|
|
|
|
|
channel capability set -Games
|
|
|
|
|
|
|
|
Note that I didn't specify any separate command after Games.
|
|
|
|
|
|
|
|
Default
|
|
|
|
^^^^^^^
|
|
|
|
|
|
|
|
Default capabilities affect everyone whether they are identified or not.
|
|
|
|
They are controlled by the ``owner defaultcapability <add|remove>`` command
|
|
|
|
and they arecommonly used for preventing users from adding/removing akas,
|
|
|
|
using Unix Progstats which disabling is asked about in supybot-wizard or
|
|
|
|
registering to the bot using anticapabilities.::
|
|
|
|
|
|
|
|
defaultcapability add -aka.add
|
|
|
|
defaultcapability add -aka.remove
|
|
|
|
defaultcapability add -user.register
|
|
|
|
defaultcapability add -unix.progstats
|
|
|
|
|
|
|
|
To undo this I would simply do the opposite.::
|
|
|
|
|
|
|
|
defaultcapability remove -aka.add
|
|
|
|
defaultcapability remove -aka.remove
|
|
|
|
defaultcapability remove -user.register
|
|
|
|
defaultcapability remove -unix.progstats
|
|
|
|
|
2020-05-13 19:56:44 +02:00
|
|
|
Defaultcapabilities can be restored with either of these two commands::
|
2014-08-28 15:09:16 +02:00
|
|
|
|
|
|
|
config setdefault capabilities
|
|
|
|
config capabilities [config default capabilities]
|
|
|
|
|
2020-05-13 19:57:09 +02:00
|
|
|
|
|
|
|
Example
|
|
|
|
-------
|
|
|
|
|
|
|
|
To make all this less abstract, here is a popular example of what
|
|
|
|
capabilities are used for: disabling a plugin or command for everyone
|
|
|
|
but a select group of people
|
|
|
|
|
|
|
|
Allowing only user ``foo`` to use the ``Games`` plugin, globally::
|
|
|
|
|
|
|
|
defaultcapability add -games
|
|
|
|
admin capability add foo games
|
|
|
|
|
|
|
|
And to undo it::
|
|
|
|
|
|
|
|
defaultcapability remove -Games
|
|
|
|
admin capability remove foo Games
|
|
|
|
|
|
|
|
Same, but only on ``#channel``::
|
|
|
|
|
|
|
|
channel capability set #channel -games
|
|
|
|
channel capability add #channel foo games
|
|
|
|
|
|
|
|
channel capability unset #channel -games
|
|
|
|
channel capability remove #channel foo games
|
|
|
|
|
|
|
|
|
|
|
|
And to forbid only the ``dice`` command of the ``Games`` plugin instead of the
|
|
|
|
entire plugin, you would use the same commands, but with ``-games.dice`` and
|
|
|
|
``games.dice`` instead of ``-games`` and ``games``.
|
|
|
|
|
|
|
|
|
2011-06-30 16:21:24 +02:00
|
|
|
Final Word
|
|
|
|
----------
|
|
|
|
|
2020-05-13 19:56:44 +02:00
|
|
|
From a programmer's perspective, capabilities are flexible and easy to use. Any
|
2011-06-30 16:21:24 +02:00
|
|
|
command can check if a user has any capability, even ones not thought of when
|
|
|
|
the bot was originally written. Plugins can easily add their own
|
|
|
|
capabilities--it's as easy as just checking for a capability and documenting
|
|
|
|
somewhere that a user needs that capability to do something.
|
|
|
|
|
|
|
|
From an user's perspective, capabilities remove a lot of the mystery and
|
|
|
|
esotery of bot control, in addition to giving a bot owner absolutely
|
|
|
|
finegrained control over what users are allowed to do with the bot.
|
|
|
|
Additionally, defaults can be set by the bot owner for both individual channels
|
2014-08-28 13:43:41 +02:00
|
|
|
and for the bot as a whole, letting an end-user set the policy they want the bot
|
|
|
|
to follow for users that haven't yet registered in their user database. It's
|
2011-06-30 16:21:24 +02:00
|
|
|
really a revolution!
|