-
Notifications
You must be signed in to change notification settings - Fork 0
Permissions
Halpbot provides support for three different ways of determining if a member has permission to use a command. These three different ways can all be used in conjunction with each other in the @Permissions
decorator. These are summarised below:
- Using JDA's built-in
Permission
enum to check the member's permissions. - Defining permission suppliers which verifies if a member has the permission by calling a custom method.
- Binding roles to permissions and checking if the member has the necessary roles.
For basic usage of the @Permissions
decorator and some examples, refer to the documentation here.
Permission suppliers are methods annotated with @PermissionSupplier
that only take in a Guild
and Member
(In that order) and return a boolean
, defining if the member has the specified permission within that guild. The class these methods are defined in must be annotated with @Service
for them to be automatically registered. Halpbot comes with two permission suppliers built-in:
Permission | Description |
---|---|
HalpbotPermissions.BOT_OWNER |
Returns true if the member is the owner of the bot defined in the bot-config. |
HalpbotPermissions.GUILD_OWNER |
Returns true if the member is the owner of the guild that the action was invoked in. |
NOTE: Permission suppliers will be automatically registered on startup. If they don't match the requirements defined previously, then a warning will be logged into the console and the permission supplier ignored.
Consider the permission suppliers for the built-in BOT_OWNER
and GUILD_OWNER
permissions. Notice that you can inject dependencies into the class if needed.
Show Imports
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import org.dockbox.hartshorn.core.annotations.stereotype.Service;
import javax.inject.Inject;
import nz.pumbas.halpbot.HalpbotCore;
@Service
public class HalpbotPermissions
{
@Inject private HalpbotCore halpbotCore;
public static final String BOT_OWNER = "halpbot.bot.owner";
public static final String GUILD_OWNER = "halpbot.guild.owner";
@PermissionSupplier(GUILD_OWNER)
public boolean isGuildOwner(Guild guild, Member member) {
return guild.getOwnerIdLong() == member.getIdLong();
}
@PermissionSupplier(BOT_OWNER)
public boolean isBotOwner(Guild guild, Member member) {
return this.halpbotCore.ownerId() == member.getIdLong();
}
}
They can then be used in the permissions
field of the annotation like so:
Show Imports
import nz.pumbas.halpbot.commands.annotations.Command;
import nz.pumbas.halpbot.permissions.HalpbotPermissions;
import nz.pumbas.halpbot.permissions.Permissions;
@Permissions(permissions = HalpbotPermissions.GUILD_OWNER)
@Command(description = "Tests the @Permissions decorator")
public String permission() {
return "This command is restricted to people who own the guild this command was invoked in";
}
Role binding allows you to create custom string-based permissions that must be bound to a discord role. When checking if someone has a bound permission, it then just needs to check if they have the appropriate role. This means you can easily assign permissions to groups of individuals within a discord without having to manually assign the permission to each person, or store the individual users with the permission. By default, role binding is disabled as it requires creating an embedded Derby database to keep track of the role bindings for each guild. To enable it, add the following to your bot-config.properties
file:
useRoleBinding=true
This will automatically generate the database and handle all the role binding without you needing to install any additional software. If you want to use a different database (Or other persistent solution) you can override the PermissionService
with a custom implementation. You can read more about creating custom implementations here.
NOTE: If you have role binding disabled in your bot-config but have custom permissions specified in your
@Permissions
decorators an error will be raised during startup.
Any permissions that you specify in @Permissions#permissions
which aren't permission suppliers are automatically treated as bindable roles, for example, in the following commands, the bindable permissions are halpbot.example.testA
and halpbot.example.testB
.
Show Imports
import nz.pumbas.halpbot.commands.annotations.Command;
import nz.pumbas.halpbot.permissions.Permissions;
@Permissions(permissions = "halpbot.example.testA")
@Command(description = "Tests custom permissions")
public String customPermissions() {
return "This command is restricted to people with the *halpbot.example.testA* permission";
}
// Note: This combination of permissions doesn't really make sense and is only for demonstration purposes.
@Permissions(permissions = {"halpbot.example.testB", HalpbotPermissions.GUILD_OWNER})
@Command(description = "Tests multiple custom permissions")
public String multipleCustomPermissions() {
return "This command is restricted to people with the *halpbot.example.testB* permission and are the guild owner";
}
The next step is to actually bind the permissions to roles. This can be achieved by using the built-in guildPermissions
and bind
permissions. Both of these permissions require the MANAGE_PERMISSIONS
permission.
The guildPermissions
command allows you to see the current role buildings for a guild. By default, all the permissions will be Unbound
:
bind <permission> <role>
allows you to bind a permission to a role:
Now when you check the guildPermissions
again, you'll see the permissions have been successfully bound:
If you remove a custom permission from the permissions field of @Permissions
, then it will automatically be deleted from the database during the next startup to prevent unnecessary storage of deprecated permissions. The deleted permissions will be logged to the console for your information:
23:41:09.558 [ main ] @ 19848 -> n.p.h.p.HalpbotPermissionService INFO - Deleting the following deprecated permissions from the database: halpbot.example.testA
The PermissionService
is an interface that abstracts away the specific implementation and can be safely injected as a dependency where necessary. The service is responsible for managing/storing the permissions suppliers and bindable permissions previously mentioned. The permission service is not responsible for locating the permission suppliers as this is automatically done by the PermissionSupplierServicePreProcessor
. If you wish to tell if a member has one of JDA's built-in Permission
s then you should use the appropriate Member#hasPermission
method.
The PermissionService
also allows you to check if a string is a permission, whether a User
or Member
has that permission(s) along with the methods to save, update or delete GuildPermissions
(The entity containing a bound permission for a guild).
If you want to create your own PermissionService
implementation, that can easily be done as described by the documentation here.
- Built-in Commands
- @Command Parameters
- Arguments
- Annotations
- Custom Objects
- Custom TypeParsers
- Slash Commands - W.I.P.
- Pagination - W.I.P