230 lines
7.8 KiB
Markdown
230 lines
7.8 KiB
Markdown
# Permission Checking
|
|
|
|
Now that we can fetch member info, we can use permissions to restrict commands to only members who have the right access. Valour has two types of permission checks — planet-level and channel-level.
|
|
|
|
### How permissions work
|
|
|
|
Permissions in Valour are stored as flags on roles. When you call `member.HasPermission()` it calculates the combined permissions from all of the member's roles and checks if the requested permission is included.
|
|
|
|
> **Note:** You do not need to separately check if a member is the planet owner or has an admin role. `HasPermission()` handles both of these automatically — it always returns `true` for the planet owner and for any member with an admin role.
|
|
|
|
### Planet permissions
|
|
|
|
Planet permissions are server-wide — they apply regardless of which channel the command is used in. To check one, call `member.HasPermission()` with a `PlanetPermissions` value.
|
|
|
|
```c#
|
|
// Check if the member has the Kick planet permission
|
|
// This also returns true for planet owners and members with an admin role
|
|
if (!member.HasPermission(PlanetPermissions.Kick))
|
|
{
|
|
await channel.SendMessageAsync("You do not have permission to use this command!");
|
|
return;
|
|
}
|
|
```
|
|
|
|
Here are all the available planet permissions:
|
|
|
|
| Permission | Description |
|
|
|---|---|
|
|
| `PlanetPermissions.Kick` | Can kick members |
|
|
| `PlanetPermissions.Ban` | Can ban members |
|
|
| `PlanetPermissions.Manage` | Can edit planet settings |
|
|
| `PlanetPermissions.Invite` | Can send invites |
|
|
| `PlanetPermissions.CreateChannels` | Can create channels |
|
|
| `PlanetPermissions.ManageRoles` | Can manage roles |
|
|
| `PlanetPermissions.MentionAll` | Can @mention all roles |
|
|
| `PlanetPermissions.BypassAutomod` | Bypasses automod |
|
|
| `PlanetPermissions.FullControl` | Full owner-level control |
|
|
|
|
### Channel permissions
|
|
|
|
Channel permissions are specific to a single channel — a member may have different permissions in different channels depending on their role overrides. To check one, call `await member.HasPermission(channel, ...)` with a `ChatChannelPermissions` value. Note that this one is `async` so needs `await`.
|
|
|
|
```c#
|
|
// Check if the member has the ManageMessages permission in this specific channel
|
|
if (!await member.HasPermission(channel, ChatChannelPermissions.ManageMessages))
|
|
{
|
|
await channel.SendMessageAsync("You do not have permission to manage messages in this channel!");
|
|
return;
|
|
}
|
|
```
|
|
|
|
Here are all the available channel permissions:
|
|
|
|
| Permission | Description |
|
|
|---|---|
|
|
| `ChatChannelPermissions.View` | Can see the channel in the list |
|
|
| `ChatChannelPermissions.ViewMessages` | Can read messages |
|
|
| `ChatChannelPermissions.PostMessages` | Can send messages |
|
|
| `ChatChannelPermissions.ManageMessages` | Can delete/manage messages |
|
|
| `ChatChannelPermissions.ManageChannel` | Can edit channel settings |
|
|
| `ChatChannelPermissions.ManagePermissions` | Can manage channel permission overrides |
|
|
| `ChatChannelPermissions.Embed` | Can post embedded content |
|
|
| `ChatChannelPermissions.AttachContent` | Can upload files |
|
|
| `ChatChannelPermissions.UseReactions` | Can use reactions |
|
|
|
|
### Putting it together
|
|
|
|
Here are both commands using everything above:
|
|
|
|
```c#
|
|
else if (command == "planetperms")
|
|
{
|
|
// Fetch the member object for the message author
|
|
PlanetMember member = await message.FetchAuthorMemberAsync();
|
|
|
|
if (member is null)
|
|
{
|
|
await channel.SendMessageAsync("Could not find your member info!");
|
|
return;
|
|
}
|
|
|
|
// Check if the member has the Kick planet permission
|
|
// This also returns true for planet owners and members with an admin role
|
|
if (!member.HasPermission(PlanetPermissions.Kick))
|
|
{
|
|
await channel.SendMessageAsync("You do not have permission to use this command!");
|
|
return;
|
|
}
|
|
|
|
await channel.SendMessageAsync("Hello, you have permission to kick members!");
|
|
}
|
|
else if (command == "channelperms")
|
|
{
|
|
// Fetch the member object for the message author
|
|
PlanetMember member = await message.FetchAuthorMemberAsync();
|
|
|
|
if (member is null)
|
|
{
|
|
await channel.SendMessageAsync("Could not find your member info!");
|
|
return;
|
|
}
|
|
|
|
// Check if the member has the ManageMessages permission in this specific channel
|
|
if (!await member.HasPermission(channel, ChatChannelPermissions.ManageMessages))
|
|
{
|
|
await channel.SendMessageAsync("You do not have permission to manage messages in this channel!");
|
|
return;
|
|
}
|
|
|
|
await channel.SendMessageAsync("Hello, you can manage messages in this channel!");
|
|
}
|
|
```
|
|
|
|
<br><br>
|
|
### Full code below
|
|
|
|
```c#
|
|
using Valour.Sdk.Client;
|
|
using Valour.Shared;
|
|
using DotNetEnv;
|
|
using Valour.Sdk.Models;
|
|
using Valour.Shared.Models;
|
|
using Valour.Shared.Authorization;
|
|
|
|
ValourClient client = new ValourClient("https://api.valour.gg/");
|
|
client.SetupHttpClient();
|
|
|
|
Env.Load();
|
|
|
|
string token = Environment.GetEnvironmentVariable("TOKEN") ?? string.Empty;
|
|
|
|
Dictionary<long, Channel> channelCache = new();
|
|
|
|
if (string.IsNullOrWhiteSpace(token))
|
|
{
|
|
Console.WriteLine($"Token invalid. Please make sure you set a valid token in your .env");
|
|
return;
|
|
}
|
|
|
|
TaskResult loginResult = await client.InitializeUser(token);
|
|
if (!loginResult.Success)
|
|
{
|
|
Console.WriteLine($"Login failed: {loginResult.Message}");
|
|
}
|
|
|
|
Console.WriteLine($"Logged in as {client.Me.Name} (ID: {client.Me.Id})");
|
|
|
|
foreach (Planet planet in client.PlanetService.JoinedPlanets)
|
|
{
|
|
await planet.EnsureReadyAsync();
|
|
await planet.FetchInitialDataAsync();
|
|
|
|
foreach (Channel chan in planet.Channels)
|
|
{
|
|
channelCache[chan.Id] = chan;
|
|
|
|
if (chan.ChannelType == ChannelTypeEnum.PlanetChat)
|
|
{
|
|
await chan.OpenWithResult("YourBotName");
|
|
}
|
|
}
|
|
}
|
|
|
|
client.MessageService.MessageReceived += onMessageReceived;
|
|
|
|
async Task onMessageReceived(Message message)
|
|
{
|
|
string prefix = "bg/";
|
|
string content = message.Content;
|
|
|
|
if (!channelCache.TryGetValue(message.ChannelId, out var channel)) return;
|
|
if (!content.StartsWith(prefix)) return;
|
|
|
|
string withoutPrefix = content.Substring(prefix.Length);
|
|
string[] parts = withoutPrefix.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (parts.Length == 0) return;
|
|
|
|
string command = parts[0].ToLower();
|
|
string[] args = parts.Skip(1).ToArray();
|
|
|
|
if (command == "ping")
|
|
{
|
|
await channel.SendMessageAsync("Pong!");
|
|
}
|
|
else if (command == "planetperms")
|
|
{
|
|
// Fetch the member object for the message author
|
|
PlanetMember member = await message.FetchAuthorMemberAsync();
|
|
|
|
if (member is null)
|
|
{
|
|
await channel.SendMessageAsync("Could not find your member info!");
|
|
return;
|
|
}
|
|
|
|
// Check if the member has the Kick planet permission
|
|
// This also returns true for planet owners and members with a role with the Administrator Permission
|
|
if (!member.HasPermission(PlanetPermissions.Kick))
|
|
{
|
|
await channel.SendMessageAsync("You do not have permission to use this command!");
|
|
return;
|
|
}
|
|
|
|
await channel.SendMessageAsync("Hello, you have permission to kick members!");
|
|
}
|
|
else if (command == "channelperms")
|
|
{
|
|
// Fetch the member object for the message author
|
|
PlanetMember member = await message.FetchAuthorMemberAsync();
|
|
|
|
if (member is null)
|
|
{
|
|
await channel.SendMessageAsync("Could not find your member info!");
|
|
return;
|
|
}
|
|
|
|
// Check if the member has the ManageMessages permission in this specific channel
|
|
if (!await member.HasPermission(channel, ChatChannelPermissions.ManageMessages))
|
|
{
|
|
await channel.SendMessageAsync("You do not have permission to manage messages in this channel!");
|
|
return;
|
|
}
|
|
|
|
await channel.SendMessageAsync("Hello, you can manage messages in this channel!");
|
|
}
|
|
}
|
|
|
|
await Task.Delay(Timeout.Infinite);
|
|
``` |