1
1
use std:: sync:: Arc ;
2
2
3
3
use twilight_model:: guild:: Permissions ;
4
- use twilight_model:: id:: UserId ;
4
+ use twilight_model:: id:: { ChannelId , GuildId , UserId } ;
5
5
6
6
use super :: BotContext ;
7
7
use crate :: cache:: { CachedGuild , CachedMember } ;
8
8
use crate :: commands:: meta:: nodes:: { CommandNode , GearBotPermissions } ;
9
9
use crate :: commands:: ROOT_NODE ;
10
10
use crate :: core:: guild_config:: { GuildConfig , PermissionGroup } ;
11
+ use twilight_model:: channel:: permission_overwrite:: PermissionOverwriteType ;
11
12
12
13
impl BotContext {
13
- pub fn get_guild_permissions_for ( & self , member : & Arc < CachedMember > , guild : & Arc < CachedGuild > ) -> Permissions {
14
+ pub fn get_guild_permissions_for_member (
15
+ & self ,
16
+ member : & Arc < CachedMember > ,
17
+ guild : & Arc < CachedGuild > ,
18
+ ) -> Permissions {
14
19
//owners can do whatever they want
15
20
if guild. owner_id == member. user_id {
16
21
return Permissions :: all ( ) ;
@@ -31,6 +36,76 @@ impl BotContext {
31
36
}
32
37
}
33
38
39
+ pub fn get_guild_permissions_for ( & self , guild_id : & GuildId , user_id : & UserId ) -> Permissions {
40
+ match self . cache . get_guild ( guild_id) {
41
+ Some ( guild) => match self . cache . get_member ( guild_id, user_id) {
42
+ Some ( member) => self . get_guild_permissions_for_member ( & member, & guild) ,
43
+ None => Permissions :: empty ( ) ,
44
+ } ,
45
+ None => Permissions :: empty ( ) ,
46
+ }
47
+ }
48
+
49
+ pub fn get_channel_permissions_for ( & self , user_id : UserId , channel_id : ChannelId ) -> Permissions {
50
+ if let Some ( channel) = self . cache . get_channel ( channel_id) {
51
+ if channel. is_dm ( ) {
52
+ return Permissions :: SEND_MESSAGES
53
+ | Permissions :: EMBED_LINKS
54
+ | Permissions :: ATTACH_FILES
55
+ | Permissions :: USE_EXTERNAL_EMOJIS
56
+ | Permissions :: ADD_REACTIONS
57
+ | Permissions :: READ_MESSAGE_HISTORY ;
58
+ }
59
+
60
+ let mut permissions = self . get_guild_permissions_for ( & channel. get_guild_id ( ) . unwrap ( ) , & user_id) ;
61
+ //admins don't give a **** about overrides
62
+ if permissions. contains ( Permissions :: ADMINISTRATOR ) {
63
+ return Permissions :: all ( ) ;
64
+ }
65
+ if let Some ( member) = & self . cache . get_member ( & channel. get_guild_id ( ) . unwrap ( ) , & user_id) {
66
+ let overrides = channel. get_permission_overrides ( ) ;
67
+ let mut everyone_allowed = Permissions :: empty ( ) ;
68
+ let mut everyone_denied = Permissions :: empty ( ) ;
69
+ let mut user_allowed = Permissions :: empty ( ) ;
70
+ let mut user_denied = Permissions :: empty ( ) ;
71
+ let mut role_allowed = Permissions :: empty ( ) ;
72
+ let mut role_denied = Permissions :: empty ( ) ;
73
+ for o in overrides {
74
+ match o. kind {
75
+ PermissionOverwriteType :: Member ( member_id) => {
76
+ if member_id == user_id {
77
+ user_allowed |= o. allow ;
78
+ user_denied |= o. deny ;
79
+ }
80
+ }
81
+ PermissionOverwriteType :: Role ( role_id) => {
82
+ if role_id. 0 == channel. get_guild_id ( ) . unwrap ( ) . 0 {
83
+ everyone_allowed |= o. allow ;
84
+ everyone_denied |= o. deny
85
+ } else if member. roles . contains ( & role_id) {
86
+ role_allowed |= o. allow ;
87
+ role_denied |= o. deny ;
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ permissions &= !everyone_denied;
94
+ permissions |= everyone_allowed;
95
+
96
+ permissions &= !role_denied;
97
+ permissions |= role_allowed;
98
+
99
+ permissions &= !user_denied;
100
+ permissions |= user_allowed;
101
+ } ;
102
+
103
+ permissions
104
+ } else {
105
+ Permissions :: empty ( )
106
+ }
107
+ }
108
+
34
109
pub fn get_permissions_for (
35
110
& self ,
36
111
guild : & Arc < CachedGuild > ,
@@ -40,7 +115,7 @@ impl BotContext {
40
115
let mut permissions = GearBotPermissions :: empty ( ) ;
41
116
let mut not_negated_denies = GearBotPermissions :: empty ( ) ;
42
117
43
- let discord_permissions = self . get_guild_permissions_for ( member, guild) ;
118
+ let discord_permissions = self . get_guild_permissions_for_member ( member, guild) ;
44
119
45
120
//these are already sorted by priority upon loading
46
121
for group in & config. permission_groups {
@@ -120,7 +195,7 @@ fn cascade_node(
120
195
// also when the parent is not available
121
196
// unless we have an explicit grant
122
197
let denied = not_negated_denies. contains ( node. command_permission )
123
- || !parent_available && !permissions. contains ( node. command_permission ) ;
198
+ || !parent_available & & !permissions. contains ( node. command_permission ) ;
124
199
125
200
if !denied {
126
201
permissions. insert ( node. command_permission )
@@ -133,7 +208,7 @@ fn cascade_node(
133
208
}
134
209
}
135
210
// we did not have this command, we do have one of it's subcommands and this command does not do anything itself, grant access as it only gives help info
136
- if denied && !not_negated_denies. contains ( node. command_permission ) && any_granted && node. handler . is_none ( ) {
211
+ if denied & & !not_negated_denies. contains ( node. command_permission ) & & any_granted & & node. handler . is_none ( ) {
137
212
permissions. insert ( node. command_permission )
138
213
}
139
214
}
0 commit comments