Skip to content

Users Behavior

Protected edited this page Nov 18, 2023 · 1 revision

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.

Default administrator and moderator

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

Bootstrapping

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

Permission providers

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:

PermissionProvider Behaviors

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.

registerPermissionProvider

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.

Other developer integrations

Testing permissions

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 using env and userid, 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.

Automatically generating accounts

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.

See also

SelfService is a Behavior add-on to Users that provides commands that allow non-administrators to register their own accounts manually.

Clone this wiki locally