-
Notifications
You must be signed in to change notification settings - Fork 2
Users Behavior
A Behavior that manages known user accounts in a cross-Environment friendly manner. Originally inspired by Eggdrop.
Each user account correlates the following information:
- A unique, human-readable handle which can be used to identify the account (essentially this is the username of the account).
- A list of Environment names and user ID regular expression patterns that effectively identify the owner of the account. Users doesn't have an independent mechanism for authentication, and relies on
Environment.isAuthenticated
. - A list of permissions. A permission is a freeform string that can be tested by other Behaviors (for locking or unlocking features).
- A map of metadata. Behaviors can store and retrieve information in user accounts without managing their own data storage (data is shared across all Behaviors).
The following commands are provided (assuming the Commands Behavior is loaded) for manipulating user accounts directly:
-
!user
- Add/remove/list accounts. -
!id
- Add/remove/list user IDs in an account. -
!perm
- Add/remove/list permissions in an account. -
!meta
- Add/remove metadata in an account. -
!whois
- Describes the contents of the user account with a given handle.
The optional configuration parameters defaultpermadmin
and defaultpermadmin
can be used to modify the names of permissions that grant administrator or moderator access to many of the built-in Behaviors.
Behavior developers can use these permissions in their own Behaviors by retrieving them from:
this.be("Users").defaultPermAdmin
this.be("Users").defaultPermMod
The commands listed above for managing user accounts require the permission set in the defaultpermadmin
parameter, which is by default administrator
; they can't be used unless an account already exists. In order to create the first administrator account, a bootstrap
object can be added to the Users config. It will cause Users to copy its contents into an account when Rowboat runs.
Example:
- type: Users
bootstrap:
handle: "Protected"
environment: "Discord" # This is the instance name of an Environment from your config file
idpattern: "^1234567890912345678909$" # Don't forget to anchor the regular expression
permissions: ["administrator"] # List the permissions for the account here
In addition to assigning manual (static) permissions to user accounts using !perm
(or programmatically with this.be("Users").addPerms(...)
), Users support dynamic permissions providers. These are checked when a user is being tested for permissions, but the permissions aren't permanently associated with the account.
There are two ways to create permission providers:
You can create Behaviors whose sole purpose is to be permissions providers. The advantage of this setup is that you can easily add or remove permission providers from your configuration by adding or removing the Behaviors from the configuration file.
Begin by importing PermissionProvider
from Users.js
and extending it, then override async permissionProvider({env, userid, channelid, permissions})
.
The permissions
argument contains a list of permissions that are being tested for. The method should filter this list and return a list of those permissions that your provider has determined that the user should have. If no permissions can be confirmed by your provider, an empty list should be returned.
The following built-in permission providers come ready for you to use and can also be used as examples:
- DiscordRole - Grants each user the names of all their Discord roles as permissions in each Discord Environment.
- DiscordRoleID - Grants each user the ID of all their Discord roles as permissions in each Discord Environment.
- GenericRole - Grants each user each of their Environment roles as permissions in each Environment.
- UserID - Grants each user their own ID as a permission in each Environment.
Alternatively, an unrelated Behavior can register a permission provider directly with Users:
this.be('Users').registerPermissionProvider(async ({env, userid, channelid, permissions}) => {
...
}):
These function like stand alone permission providers, and are ideal when you don't want to separate the provider from a parent Behavior with associated functionality.
Behaviors can test for permissions using the testPermissions method:
this.be("Users").testPermissions(env, userid, channelid, permissions, requireall, handle)
-
env
is the environment name; -
userid
is the ID of the user in the environment; -
channelid
is the ID of a channel in the environment (optional); -
handle
is the handle of the user account. It's optional, since the user account is identified usingenv
anduserid
, but can help resolve the user if multiple accounts contain the same ID pattern. -
permissions
is the list of permissions to test for; -
requireall
, if true, means testPermissions will only return true if the user has all of the listed permissions. Otherwise, one of the listed permissions is enough.
Even if Users is not being used as a manual account system, Behaviors can make use of its features by implicitly generating user accounts, using the following method:
this.be("Users").getEnvUser(env, userid)
This returns an existing user account object for the given environment name and user ID. If the user account doesn't exist, it's created.
SelfService is a Behavior add-on to Users that provides commands that allow non-administrators to register their own accounts manually.