Module twilight_util::permission_calculator

source ·
Available on crate feature permission-calculator only.
Expand description

Calculate the permissions of a member on a guild-level or a channel-level.

§Examples

§Calculating member permissions in a channel

Take a scenario where a member has two roles: the @everyone role (with the same ID as the guild) that grants the View Channel permission across the whole guild, and a second role that grants the Send Messages permission across the whole guild. This means that - across the server - the member will have the View Channel and Send Messages permissions, unless denied or expanded by channel-specific permission overwrites.

In a given channel, there are two permission overwrites: one for the @everyone role and one for the member itself. These overwrites look like:

Taking into account the guild root-level permissions and the permission overwrites, the end result is that in the specified channel the user has the View Channel, Embed Links, and Add Reactions permission, but is denied the Send Messages permission that their second role was granted on a root level.

Let’s see that in code:

use twilight_model::{
    channel::{
        permission_overwrite::{PermissionOverwrite, PermissionOverwriteType},
        ChannelType,
    },
    guild::Permissions,
    id::Id,
};
use twilight_util::permission_calculator::PermissionCalculator;

let guild_id = Id::new(1);
let user_id = Id::new(3);

// Guild-level @everyone role that, by default, allows everyone to view
// channels.
let everyone_role = Permissions::VIEW_CHANNEL;

// Roles that the member has assigned to them and their permissions. This
// should not include the `@everyone` role.
let member_roles = &[
    // Guild-level permission that grants members with the role the Send
    // Messages permission.
    (Id::new(2), Permissions::SEND_MESSAGES),
];

let channel_overwrites = &[
    // All members are given the Add Reactions and Embed Links members via
    // the `@everyone` role.
    PermissionOverwrite {
        allow: Permissions::ADD_REACTIONS | Permissions::EMBED_LINKS,
        deny: Permissions::empty(),
        id: Id::new(1),
        kind: PermissionOverwriteType::Role,
    },
    // Member is denied the Send Messages permission.
    PermissionOverwrite {
        allow: Permissions::empty(),
        deny: Permissions::SEND_MESSAGES,
        id: user_id.cast(),
        kind: PermissionOverwriteType::Member,
    },
];

let calculator = PermissionCalculator::new(guild_id, user_id, everyone_role, member_roles);
let calculated_permissions = calculator.in_channel(ChannelType::GuildText, channel_overwrites);

// Now that we've got the member's permissions in the channel, we can
// check that they have the server-wide View Channel permission and
// the Add Reactions permission granted, but their guild-wide Send Messages
// permission was denied. Additionally, since the user can't send messages,
// their Embed Links permission was removed.

let expected = Permissions::ADD_REACTIONS | Permissions::VIEW_CHANNEL;
assert!(!calculated_permissions.contains(Permissions::EMBED_LINKS));
assert!(!calculated_permissions.contains(Permissions::SEND_MESSAGES));
assert_eq!(expected, calculated_permissions);

Structs§