-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add methods for computing permissions in a channel. (#29)
- Loading branch information
1 parent
82d8d50
commit c18a053
Showing
2 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import 'package:nyxx/nyxx.dart'; | ||
|
||
/// Compute the permissions for [member] in a given [channel]. | ||
/// | ||
/// {@template compute_permissions_detail} | ||
/// This method returns the permissions for [member] according to the | ||
/// permissions granted to them by their roles at a guild level as well as | ||
/// the permission overwrites for [channel]. | ||
/// | ||
/// Adapted from https://discord.com/developers/docs/topics/permissions#permission-overwrites | ||
/// {@endtemplate} | ||
Future<Permissions> computePermissions( | ||
GuildChannel channel, | ||
Member member, | ||
) async { | ||
final guild = await channel.guild.get(); | ||
|
||
Future<Permissions> computeBasePermissions() async { | ||
if (guild.ownerId == member.id) { | ||
return Permissions.allPermissions; | ||
} | ||
|
||
final everyoneRole = await guild.roles[guild.id].get(); | ||
Flags<Permissions> permissions = everyoneRole.permissions; | ||
|
||
for (final role in member.roles) { | ||
final rolePermissions = (await role.get()).permissions; | ||
|
||
permissions |= rolePermissions; | ||
} | ||
|
||
permissions = Permissions(permissions.value); | ||
permissions as Permissions; | ||
|
||
if (permissions.isAdministrator) { | ||
return Permissions.allPermissions; | ||
} | ||
|
||
return permissions; | ||
} | ||
|
||
Future<Permissions> computeOverwrites(Permissions basePermissions) async { | ||
if (basePermissions.isAdministrator) { | ||
return Permissions.allPermissions; | ||
} | ||
|
||
Flags<Permissions> permissions = basePermissions; | ||
|
||
final everyoneOverwrite = channel.permissionOverwrites.where((overwrite) => overwrite.id == guild.id).singleOrNull; | ||
if (everyoneOverwrite != null) { | ||
permissions &= ~everyoneOverwrite.deny; | ||
permissions |= everyoneOverwrite.allow; | ||
} | ||
|
||
Flags<Permissions> allow = Permissions(0); | ||
Flags<Permissions> deny = Permissions(0); | ||
|
||
for (final roleId in member.roleIds) { | ||
final roleOverwrite = channel.permissionOverwrites.where((overwrite) => overwrite.id == roleId).singleOrNull; | ||
if (roleOverwrite != null) { | ||
allow |= roleOverwrite.allow; | ||
deny |= roleOverwrite.deny; | ||
} | ||
} | ||
|
||
permissions &= ~deny; | ||
permissions |= allow; | ||
|
||
final memberOverwrite = channel.permissionOverwrites.where((overwrite) => overwrite.id == member.id).singleOrNull; | ||
if (memberOverwrite != null) { | ||
permissions &= ~memberOverwrite.deny; | ||
permissions |= memberOverwrite.allow; | ||
} | ||
|
||
return Permissions(permissions.value); | ||
} | ||
|
||
return computeOverwrites(await computeBasePermissions()); | ||
} | ||
|
||
/// Extensions for computing permissions in a [GuildChannel]. | ||
extension MemberComputePermissions on PartialMember { | ||
/// Compute this member's permissions in [channel]. | ||
/// | ||
/// {@macro compute_permissions_detail} | ||
Future<Permissions> computePermissionsIn(GuildChannel channel) async => await computePermissions(channel, await get()); | ||
} | ||
|
||
/// Extensions for computing a [Member]'s permissions. | ||
extension ChannelComputePermissions on GuildChannel { | ||
/// Compute [member]'s permissions in this channel. | ||
/// | ||
/// {@macro compute_permissions_detail} | ||
Future<Permissions> computePermissionsFor(PartialMember member) async => await computePermissions(this, await member.get()); | ||
} |