revolt_permissions/
impl.rs

1use crate::{
2    ChannelPermission, ChannelType, PermissionQuery, PermissionValue, RelationshipStatus,
3    UserPermission, ALLOW_IN_TIMEOUT, DEFAULT_PERMISSION_DIRECT_MESSAGE,
4    DEFAULT_PERMISSION_SAVED_MESSAGES, DEFAULT_PERMISSION_VIEW_ONLY,
5};
6
7/// Calculate permissions against a user
8pub async fn calculate_user_permissions<P: PermissionQuery>(query: &mut P) -> PermissionValue {
9    if query.are_we_privileged().await {
10        return u64::MAX.into();
11    }
12
13    if query.are_the_users_same().await {
14        return u64::MAX.into();
15    }
16
17    let mut permissions = 0_u64;
18    match query.user_relationship().await {
19        RelationshipStatus::Friend => return u64::MAX.into(),
20        RelationshipStatus::Blocked | RelationshipStatus::BlockedOther => {
21            return (UserPermission::Access as u64).into()
22        }
23        RelationshipStatus::Incoming | RelationshipStatus::Outgoing => {
24            permissions = UserPermission::Access as u64;
25        }
26        _ => {}
27    }
28
29    if query.have_mutual_connection().await {
30        permissions = UserPermission::Access as u64 + UserPermission::ViewProfile as u64;
31
32        if query.user_is_bot().await || query.are_we_a_bot().await {
33            permissions += UserPermission::SendMessage as u64;
34        }
35
36        permissions.into()
37    } else {
38        permissions.into()
39    }
40
41    // TODO: add boolean switch for permission for users to globally message a user
42    // maybe an enum?
43    // PrivacyLevel { Private, Friends, Mutual, Public, Global }
44
45    // TODO: add boolean switch for permission for users to mutually DM a user
46}
47
48/// Calculate permissions against a server
49pub async fn calculate_server_permissions<P: PermissionQuery>(query: &mut P) -> PermissionValue {
50    if query.are_we_privileged().await || query.are_we_server_owner().await {
51        return ChannelPermission::GrantAllSafe.into();
52    }
53
54    if !query.are_we_a_member().await {
55        return 0_u64.into();
56    }
57
58    let mut permissions: PermissionValue = query.get_default_server_permissions().await.into();
59
60    for role_override in query.get_our_server_role_overrides().await {
61        permissions.apply(role_override);
62    }
63
64    if query.are_we_timed_out().await {
65        permissions.restrict(*ALLOW_IN_TIMEOUT);
66    }
67
68    permissions
69}
70
71/// Calculate permissions against a channel
72pub async fn calculate_channel_permissions<P: PermissionQuery>(query: &mut P) -> PermissionValue {
73    if query.are_we_privileged().await {
74        return ChannelPermission::GrantAllSafe.into();
75    }
76
77    match query.get_channel_type().await {
78        ChannelType::SavedMessages => {
79            if query.do_we_own_the_channel().await {
80                DEFAULT_PERMISSION_SAVED_MESSAGES.into()
81            } else {
82                0_u64.into()
83            }
84        }
85        ChannelType::DirectMessage => {
86            if query.are_we_part_of_the_channel().await {
87                query.set_recipient_as_user().await;
88
89                let permissions = calculate_user_permissions(query).await;
90                if permissions.has_user_permission(UserPermission::SendMessage) {
91                    (*DEFAULT_PERMISSION_DIRECT_MESSAGE).into()
92                } else {
93                    (*DEFAULT_PERMISSION_VIEW_ONLY).into()
94                }
95            } else {
96                0_u64.into()
97            }
98        }
99        ChannelType::Group => {
100            if query.do_we_own_the_channel().await {
101                ChannelPermission::GrantAllSafe.into()
102            } else if query.are_we_part_of_the_channel().await {
103                (*DEFAULT_PERMISSION_VIEW_ONLY
104                    | query.get_default_channel_permissions().await.allow)
105                    .into()
106            } else {
107                0_u64.into()
108            }
109        }
110        ChannelType::ServerChannel => {
111            query.set_server_from_channel().await;
112
113            if query.are_we_server_owner().await {
114                ChannelPermission::GrantAllSafe.into()
115            } else if query.are_we_a_member().await {
116                let mut permissions = calculate_server_permissions(query).await;
117                permissions.apply(query.get_default_channel_permissions().await);
118
119                for role_override in query.get_our_channel_role_overrides().await {
120                    permissions.apply(role_override);
121                }
122
123                if query.are_we_timed_out().await {
124                    permissions.restrict(*ALLOW_IN_TIMEOUT);
125                }
126
127                if !permissions.has_channel_permission(ChannelPermission::ViewChannel) {
128                    permissions.revoke_all();
129                }
130
131                permissions
132            } else {
133                0_u64.into()
134            }
135        }
136        ChannelType::Unknown => 0_u64.into(),
137    }
138}