robespierre_models/
permissions_utils.rs

1use crate::{
2    channels::{
3        Channel, ChannelPermissions, GroupChannel, ServerChannel, TextChannel, VoiceChannel,
4    },
5    id::{RoleId, UserId},
6    servers::{Member, Role, Server, ServerPermissions},
7};
8
9fn perms_or(server: &Server, roles: &[RoleId]) -> (ServerPermissions, ChannelPermissions) {
10    if let Some(ref roles_obj) = server.roles {
11        roles_obj.iter().filter(|it| roles.contains(it.0)).fold(
12            server.default_permissions,
13            |p, (_, Role { permissions, .. })| (p.0 | permissions.0, p.1 | permissions.1),
14        )
15    } else {
16        server.default_permissions
17    }
18}
19
20fn perms_or_in_channel(
21    server: &Server,
22    roles: &[RoleId],
23    channel: &Channel,
24) -> (ServerPermissions, ChannelPermissions) {
25    let base = perms_or(server, roles);
26
27    match channel {
28        Channel::TextChannel(TextChannel {
29            server_channel:
30                ServerChannel {
31                    default_permissions,
32                    role_permissions,
33                    ..
34                },
35            ..
36        })
37        | Channel::VoiceChannel(VoiceChannel {
38            server_channel:
39                ServerChannel {
40                    default_permissions,
41                    role_permissions,
42                    ..
43                },
44            ..
45        }) => {
46            let new = (
47                base.0,
48                base.1 | default_permissions.unwrap_or(ChannelPermissions::empty()),
49            );
50
51            let new = role_permissions
52                .iter()
53                .filter(|it| roles.contains(it.0))
54                .fold(new, |p, (_, new)| (p.0, p.1 | *new));
55
56            new
57        }
58
59        _ => unreachable!(),
60    }
61}
62
63pub fn member_has_permissions(
64    member: &Member,
65    server_permissions: ServerPermissions,
66    server: &Server,
67) -> bool {
68    if server.owner == member.id.user {
69        // owner has all perms
70        return true;
71    }
72
73    perms_or(server, &member.roles)
74        .0
75        .contains(server_permissions)
76}
77
78pub fn member_has_permissions_in_channel(
79    member: &Member,
80    server_permissions: ServerPermissions,
81    server: &Server,
82    channel_permissions: ChannelPermissions,
83    channel: &Channel,
84) -> bool {
85    if server.owner == member.id.user {
86        // owner has all perms
87        return true;
88    }
89
90    let (sp, cp) = perms_or_in_channel(server, &member.roles, channel);
91
92    sp.contains(server_permissions) && cp.contains(channel_permissions)
93}
94
95pub fn user_has_permissions_in_group(
96    user: UserId,
97    group: &Channel,
98    check_permissions: ChannelPermissions,
99) -> bool {
100    match group {
101        Channel::Group(GroupChannel {
102            owner, permissions, ..
103        }) => {
104            if user == *owner {
105                // owner has all perms
106                return true;
107            }
108
109            permissions
110                .unwrap_or(ChannelPermissions::empty())
111                .contains(check_permissions)
112        }
113        _ => false,
114    }
115}