robespierre_models/
permissions_utils.rs1use 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 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 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 return true;
107 }
108
109 permissions
110 .unwrap_or(ChannelPermissions::empty())
111 .contains(check_permissions)
112 }
113 _ => false,
114 }
115}