119 lines
3.1 KiB
Go
119 lines
3.1 KiB
Go
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
|
|
}
|