proxy-pool/internal/domain/authorization/authorization.go

64 lines
1.6 KiB
Go

// Package authorization owns the fixed, low-cardinality permission vocabulary
// used by HTTP authentication and endpoint handlers.
package authorization
import (
"errors"
"strings"
)
const (
All = "*"
AdminRead = "admin:read"
AdminWrite = "admin:write"
DistributionExtract = "distribution:extract"
)
var ErrInvalidPermissions = errors.New("invalid permissions")
// Validate accepts an omitted permission set for backwards-compatible full
// access. An explicit set is strict, finite, duplicate-free, and cannot mix
// the global permission with narrower grants.
func Validate(permissions []string) error {
if len(permissions) == 0 {
return nil
}
seen := make(map[string]struct{}, len(permissions))
for _, permission := range permissions {
if strings.TrimSpace(permission) != permission || !known(permission) {
return ErrInvalidPermissions
}
if _, exists := seen[permission]; exists {
return ErrInvalidPermissions
}
seen[permission] = struct{}{}
}
if _, hasAll := seen[All]; hasAll && len(seen) != 1 {
return ErrInvalidPermissions
}
return nil
}
// Allows reports whether one authenticated identity can invoke an endpoint.
// Empty permissions preserve pre-scope configurations as full access.
func Allows(permissions []string, required string) bool {
if len(permissions) == 0 {
return true
}
for _, permission := range permissions {
if permission == All || permission == required {
return true
}
}
return false
}
func known(permission string) bool {
switch permission {
case All, AdminRead, AdminWrite, DistributionExtract:
return true
default:
return false
}
}