/
permissions.go
126 lines (101 loc) · 3.63 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package v2
import (
"encoding/binary"
"sort"
)
// Permission represents a permission that can be set to a user or user group
type Permission = uint32
const (
// PermissionNothing represents the permission to do nothing
PermissionNothing = Permission(0b000000)
// PermissionWrite identifies users that can create content inside the subspace
PermissionWrite = Permission(0b000001)
// PermissionModerateContent allows users to moderate contents of other users (e.g. deleting it)
PermissionModerateContent = Permission(0b000010)
// PermissionChangeInfo allows to change the information of the subspace
PermissionChangeInfo = Permission(0b000100)
// PermissionManageGroups allows users to manage user groups and members
PermissionManageGroups = Permission(0b001000)
// PermissionSetPermissions allows users to set other users' permissions (except PermissionSetPermissions).
// This includes managing user groups and the associated permissions
PermissionSetPermissions = Permission(0b010000)
// PermissionDeleteSubspace allows users to delete the subspace.
PermissionDeleteSubspace = Permission(0b100000)
// PermissionEverything allows to do everything.
// This should usually be reserved only to the owner (which has it by default)
PermissionEverything = Permission(0b111111)
)
var (
permissionsMap = map[Permission]string{
PermissionNothing: "Nothing",
PermissionWrite: "Write",
PermissionModerateContent: "ModerateContent",
PermissionChangeInfo: "ChangeInfo",
PermissionManageGroups: "ManageGroups",
PermissionSetPermissions: "SetUserPermissions",
PermissionDeleteSubspace: "DeleteSubspace",
PermissionEverything: "Everything",
}
)
// MarshalPermission marshals the given permission to a byte array
func MarshalPermission(permission Permission) (permissionBytes []byte) {
permissionBytes = make([]byte, 4)
binary.BigEndian.PutUint32(permissionBytes, permission)
return
}
// UnmarshalPermission reads the given byte array as a Permission object
func UnmarshalPermission(bz []byte) (permission Permission) {
if len(bz) < 4 {
return PermissionNothing
}
return binary.BigEndian.Uint32(bz)
}
// CombinePermissions combines all the given permissions into a single Permission object using the OR operator
func CombinePermissions(permissions ...Permission) Permission {
result := PermissionNothing
for _, permission := range permissions {
result |= permission
}
return result
}
// getValidPermissions returns the valid permissions slice
func getValidPermissions() []Permission {
validPermissions := make([]Permission, len(permissionsMap))
i := 0
for perm := range permissionsMap {
validPermissions[i] = perm
i++
}
// Sort the permissions
sort.Slice(validPermissions, func(i, j int) bool {
return validPermissions[i] < validPermissions[j]
})
return validPermissions
}
// SplitPermissions splits the given combined permission value into its individual values
func SplitPermissions(permission Permission) []Permission {
if permission == PermissionNothing {
return nil
}
if permission == PermissionEverything {
return []Permission{PermissionEverything}
}
var permissions []Permission
for _, perm := range getValidPermissions() {
if perm == PermissionNothing || perm == PermissionEverything {
continue
}
if (permission & perm) == perm {
permissions = append(permissions, perm)
}
}
return permissions
}
// SanitizePermission sanitizes the given permission to remove any unwanted bits set to 1
func SanitizePermission(permission Permission) Permission {
mask := PermissionNothing
for perm := range permissionsMap {
mask = CombinePermissions(mask, perm)
}
return permission & mask
}