feat: roles system backend
This commit is contained in:
1 parent
44cca46d5e
commit
8c6c6456da
50 files changed
+2578
-22
No files matched your search
@@ -0,0 +1,118 @@
|
||||
package role
|
||||
|
||||
import "strings"
|
||||
|
||||
type Kind string
|
||||
|
||||
const (
|
||||
KindScoped Kind = "scoped"
|
||||
KindToggle Kind = "toggle"
|
||||
)
|
||||
|
||||
const contentGroup = "content"
|
||||
|
||||
type Permission struct {
|
||||
Key string
|
||||
Group string
|
||||
Kind Kind
|
||||
OwnerOnly bool
|
||||
}
|
||||
|
||||
func (p Permission) PerType() bool {
|
||||
return strings.HasPrefix(p.Key, contentGroup+".")
|
||||
}
|
||||
|
||||
func scoped(group, key string) Permission {
|
||||
return Permission{Key: key, Group: group, Kind: KindScoped}
|
||||
}
|
||||
|
||||
func toggle(group, key string) Permission {
|
||||
return Permission{Key: key, Group: group, Kind: KindToggle}
|
||||
}
|
||||
|
||||
func ownerOnly(group, key string) Permission {
|
||||
return Permission{Key: key, Group: group, Kind: KindToggle, OwnerOnly: true}
|
||||
}
|
||||
|
||||
var catalogue = []Permission{
|
||||
scoped("content", "content.read"),
|
||||
toggle("content", "content.create"),
|
||||
scoped("content", "content.update"),
|
||||
scoped("content", "content.delete"),
|
||||
scoped("content", "content.publish"),
|
||||
toggle("schema", "schema.view"),
|
||||
toggle("schema", "schema.edit"),
|
||||
toggle("schema", "schema.delete"),
|
||||
toggle("media", "media.view"),
|
||||
toggle("media", "media.upload"),
|
||||
scoped("media", "media.delete"),
|
||||
toggle("authors", "authors.view"),
|
||||
toggle("authors", "authors.create"),
|
||||
scoped("authors", "authors.edit"),
|
||||
toggle("authors", "authors.delete"),
|
||||
scoped("activity", "activity.view"),
|
||||
toggle("activity", "activity.export"),
|
||||
toggle("users", "users.view"),
|
||||
toggle("users", "users.invite"),
|
||||
toggle("users", "users.change_role"),
|
||||
toggle("users", "users.remove"),
|
||||
toggle("settings", "settings.view"),
|
||||
toggle("settings", "settings.edit_general"),
|
||||
toggle("settings", "settings.manage_sites"),
|
||||
ownerOnly("settings", "settings.delete_site"),
|
||||
scoped("settings", "apikeys.view"),
|
||||
toggle("settings", "apikeys.create"),
|
||||
scoped("settings", "apikeys.revoke"),
|
||||
toggle("roles", "roles.view"),
|
||||
toggle("roles", "roles.manage"),
|
||||
ownerOnly("roles", "roles.edit_owner_only"),
|
||||
ownerOnly("system", "system.apply_updates"),
|
||||
ownerOnly("system", "system.edit_retention"),
|
||||
ownerOnly("system", "system.transfer_ownership"),
|
||||
}
|
||||
|
||||
func Catalogue() []Permission {
|
||||
return append([]Permission(nil), catalogue...)
|
||||
}
|
||||
|
||||
func Lookup(key string) (Permission, error) {
|
||||
for _, permission := range catalogue {
|
||||
if permission.Key == key {
|
||||
return permission, nil
|
||||
}
|
||||
}
|
||||
return Permission{}, ErrUnknownPermission
|
||||
}
|
||||
|
||||
func Groups() []string {
|
||||
groups := []string{}
|
||||
for _, permission := range catalogue {
|
||||
if len(groups) == 0 || groups[len(groups)-1] != permission.Group {
|
||||
groups = append(groups, permission.Group)
|
||||
}
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
const (
|
||||
typeSeparator = ":"
|
||||
maxKeyLength = 100
|
||||
typeKeyAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789_-"
|
||||
)
|
||||
|
||||
func ParseTypedKey(composite string) (string, string, error) {
|
||||
base, typeKey, found := strings.Cut(composite, typeSeparator)
|
||||
if !found || len(composite) > maxKeyLength || typeKey == "" {
|
||||
return "", "", ErrUnknownPermission
|
||||
}
|
||||
permission, err := Lookup(base)
|
||||
if err != nil || !permission.PerType() {
|
||||
return "", "", ErrUnknownPermission
|
||||
}
|
||||
for _, char := range typeKey {
|
||||
if !strings.ContainsRune(typeKeyAlphabet, char) {
|
||||
return "", "", ErrUnknownPermission
|
||||
}
|
||||
}
|
||||
return base, typeKey, nil
|
||||
}
|
||||
Reference in new issue
Block a user