This repository has been archived by the owner on Mar 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpermissions.go
90 lines (74 loc) · 2.26 KB
/
permissions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package dstate
import "github.com/jonas747/discordgo"
const AllPermissions int64 = ^0
// Apply this mask to channel permissions to filter them out
// discord performs no server side validation so this is needed
// as to not run into some really weird situations
const ChannelPermsMask = ^(discordgo.PermissionAdministrator |
discordgo.PermissionManageServer |
discordgo.PermissionChangeNickname |
discordgo.PermissionManageServer |
discordgo.PermissionManageRoles |
discordgo.PermissionKickMembers |
discordgo.PermissionBanMembers)
// CalculatePermissions calculates a members permissions
func CalculatePermissions(g *GuildState, guildRoles []discordgo.Role, overwrites []discordgo.PermissionOverwrite, memberID int64, roles []int64) (perms int64) {
if g.OwnerID == memberID {
return AllPermissions
}
// Check guild scope permissions
// everyone role first
for _, role := range guildRoles {
if role.ID == g.ID {
perms |= int64(role.Permissions)
break
}
}
// member roles
for _, role := range guildRoles {
for _, roleID := range roles {
if role.ID == roleID {
perms |= int64(role.Permissions)
break
}
}
}
// Administrator bypasses channel overrides
if perms&discordgo.PermissionAdministrator == discordgo.PermissionAdministrator {
return AllPermissions
}
if len(overwrites) == 0 {
return perms
}
// Apply chanel overwrites
// Apply @everyone overrides from the channel.
for _, overwrite := range overwrites {
if g.ID == overwrite.ID {
perms &= ^int64(overwrite.Deny & ChannelPermsMask)
perms |= int64(overwrite.Allow & ChannelPermsMask)
break
}
}
denies := int64(0)
allows := int64(0)
// Member overwrites can override role overrides, so do two passes with roles first
for _, overwrite := range overwrites {
for _, roleID := range roles {
if overwrite.Type == "role" && roleID == overwrite.ID {
denies |= int64(overwrite.Deny & ChannelPermsMask)
allows |= int64(overwrite.Allow & ChannelPermsMask)
break
}
}
}
perms &= ^int64(denies)
perms |= int64(allows)
for _, overwrite := range overwrites {
if overwrite.Type == "member" && overwrite.ID == memberID {
perms &= ^int64(overwrite.Deny & ChannelPermsMask)
perms |= int64(overwrite.Allow & ChannelPermsMask)
break
}
}
return perms
}