@@ -220,6 +220,7 @@ impl Message {
220
220
///
221
221
/// This may return `None` if:
222
222
/// - The [`Cache`] does not have the current [`Guild`]
223
+ /// - The [`Guild`] does not have the current channel cached (should never happen).
223
224
/// - This message is not from [`MessageCreateEvent`] and the author's [`Member`] cannot be
224
225
/// found in [`Guild#structfield.members`].
225
226
#[ cfg( feature = "cache" ) ]
@@ -229,10 +230,18 @@ impl Message {
229
230
} ;
230
231
231
232
let guild = cache. as_ref ( ) . guild ( guild_id) ?;
233
+ let channel = if let Some ( channel) = guild. channels . get ( & self . channel_id ) {
234
+ channel
235
+ } else if let Some ( thread) = guild. threads . iter ( ) . find ( |th| th. id == self . channel_id ) {
236
+ thread
237
+ } else {
238
+ return None ;
239
+ } ;
240
+
232
241
if let Some ( member) = & self . member {
233
- Some ( guild. partial_member_permissions ( self . author . id , member) )
242
+ Some ( guild. partial_member_permissions_in ( channel , self . author . id , member) )
234
243
} else {
235
- Some ( guild. member_permissions ( guild. members . get ( & self . author . id ) ?) )
244
+ Some ( guild. user_permissions_in ( channel , guild. members . get ( & self . author . id ) ?) )
236
245
}
237
246
}
238
247
@@ -1443,3 +1452,75 @@ pub struct PollAnswerCount {
1443
1452
pub count : u64 ,
1444
1453
pub me_voted : bool ,
1445
1454
}
1455
+
1456
+ // all tests here require cache, move if non-cache test is added
1457
+ #[ cfg( all( test, feature = "cache" ) ) ]
1458
+ mod tests {
1459
+ use std:: collections:: HashMap ;
1460
+
1461
+ use dashmap:: DashMap ;
1462
+
1463
+ use super :: {
1464
+ Guild ,
1465
+ GuildChannel ,
1466
+ Member ,
1467
+ Message ,
1468
+ PermissionOverwrite ,
1469
+ PermissionOverwriteType ,
1470
+ Permissions ,
1471
+ User ,
1472
+ UserId ,
1473
+ } ;
1474
+ use crate :: cache:: wrappers:: MaybeMap ;
1475
+ use crate :: cache:: Cache ;
1476
+
1477
+ /// Test that author_permissions checks the permissions in a channel, not just the guild.
1478
+ #[ test]
1479
+ fn author_permissions_respects_overwrites ( ) {
1480
+ // Author of the message, with a random ID that won't collide with defaults.
1481
+ let author = User {
1482
+ id : UserId :: new ( 50778944701071 ) ,
1483
+ ..Default :: default ( )
1484
+ } ;
1485
+
1486
+ // Channel with the message, with SEND_MESSAGES on.
1487
+ let channel = GuildChannel {
1488
+ permission_overwrites : vec ! [ PermissionOverwrite {
1489
+ allow: Permissions :: SEND_MESSAGES ,
1490
+ deny: Permissions :: default ( ) ,
1491
+ kind: PermissionOverwriteType :: Member ( author. id) ,
1492
+ } ] ,
1493
+ ..Default :: default ( )
1494
+ } ;
1495
+ let channel_id = channel. id ;
1496
+
1497
+ // Guild with the author and channel cached, default (empty) permissions.
1498
+ let guild = Guild {
1499
+ channels : HashMap :: from ( [ ( channel. id , channel) ] ) ,
1500
+ members : HashMap :: from ( [ ( author. id , Member {
1501
+ user : author. clone ( ) ,
1502
+ ..Default :: default ( )
1503
+ } ) ] ) ,
1504
+ ..Default :: default ( )
1505
+ } ;
1506
+
1507
+ // Message, tied to the guild and the channel.
1508
+ let message = Message {
1509
+ author,
1510
+ channel_id,
1511
+ guild_id : Some ( guild. id ) ,
1512
+ ..Default :: default ( )
1513
+ } ;
1514
+
1515
+ // Cache, with the guild setup.
1516
+ let mut cache = Cache :: new ( ) ;
1517
+ cache. guilds = MaybeMap ( Some ( {
1518
+ let guilds = DashMap :: default ( ) ;
1519
+ guilds. insert ( guild. id , guild) ;
1520
+ guilds
1521
+ } ) ) ;
1522
+
1523
+ // The author should only have the one permission, SEND_MESSAGES.
1524
+ assert_eq ! ( message. author_permissions( & cache) , Some ( Permissions :: SEND_MESSAGES ) ) ;
1525
+ }
1526
+ }
0 commit comments