84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
package entities
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
)
|
|
|
|
var permissionTokenSanitizer = regexp.MustCompile(`[^a-z0-9_-]+`)
|
|
|
|
// PermissionGroup represents a named group of permissions.
|
|
type PermissionGroup struct {
|
|
ID bson.ObjectID `bson:"_id,omitempty"`
|
|
Name string `bson:"name"`
|
|
NameKey string `bson:"name_key"`
|
|
Description string `bson:"description,omitempty"`
|
|
Permissions []string `bson:"permissions"`
|
|
IsSystem bool `bson:"is_system"`
|
|
CreatedAt time.Time `bson:"created_at"`
|
|
UpdatedAt time.Time `bson:"updated_at"`
|
|
}
|
|
|
|
// NormalizePermission lowercases and trims a permission string.
|
|
func NormalizePermission(permission string) string {
|
|
return strings.ToLower(strings.TrimSpace(permission))
|
|
}
|
|
|
|
// SpacePermissionToken converts a space name to a dot-safe permission token.
|
|
func SpacePermissionToken(spaceName string) string {
|
|
normalized := strings.ToLower(strings.TrimSpace(spaceName))
|
|
normalized = strings.ReplaceAll(normalized, " ", "_")
|
|
normalized = permissionTokenSanitizer.ReplaceAllString(normalized, "_")
|
|
normalized = strings.Trim(normalized, "_")
|
|
if normalized == "" {
|
|
return "space"
|
|
}
|
|
return normalized
|
|
}
|
|
|
|
// PermissionMatches reports whether a wildcard pattern matches a concrete permission.
|
|
func PermissionMatches(pattern, permission string) bool {
|
|
pattern = NormalizePermission(pattern)
|
|
permission = NormalizePermission(permission)
|
|
|
|
if pattern == "" || permission == "" {
|
|
return false
|
|
}
|
|
if pattern == "*" || pattern == permission {
|
|
return true
|
|
}
|
|
if !strings.Contains(pattern, "*") {
|
|
return false
|
|
}
|
|
|
|
parts := strings.Split(pattern, "*")
|
|
remaining := permission
|
|
|
|
if parts[0] != "" {
|
|
if !strings.HasPrefix(remaining, parts[0]) {
|
|
return false
|
|
}
|
|
remaining = remaining[len(parts[0]):]
|
|
}
|
|
|
|
for i := 1; i < len(parts); i++ {
|
|
part := parts[i]
|
|
if part == "" {
|
|
continue
|
|
}
|
|
idx := strings.Index(remaining, part)
|
|
if idx < 0 {
|
|
return false
|
|
}
|
|
remaining = remaining[idx+len(part):]
|
|
}
|
|
|
|
if parts[len(parts)-1] != "" {
|
|
return strings.HasSuffix(permission, parts[len(parts)-1])
|
|
}
|
|
return true
|
|
}
|