feat: /v1/role list, get, create, update and delete. Reassign members on delete. Write-time validation (ValidateGrants, duplicates, typed keys against real content types). Name uniqueness (role_name_taken), role_locked, role_has_members, role_conflict on version mismatch. No-escalation: nobody grants a permission they don't hold, and roles.edit_owner_only guards the Owner role. Activity events for role changes. Typed-key exposure in /auth/me. Cleanup of typed rows when a content type is deleted. | Backend only. Will carry the deferred ListGrants decision.
This commit is contained in:
1 parent
a043f7f41a
commit
094df63a7f
51 files changed
+4822
-115
No files matched your search
@@ -3,6 +3,7 @@ package role
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -14,6 +15,18 @@ var (
|
||||
ErrDuplicateGrant = errors.New("permission granted more than once")
|
||||
|
||||
ErrMissingPermission = errors.New("missing permission")
|
||||
|
||||
ErrRoleHasMembers = errors.New("role still has members")
|
||||
ErrRoleNameTaken = errors.New("role name already used")
|
||||
ErrRoleLocked = errors.New("role is locked")
|
||||
ErrBuiltInRole = errors.New("role is built in")
|
||||
ErrBuiltInName = errors.New("built-in role cannot be renamed")
|
||||
ErrOwnRole = errors.New("cannot change the role you hold")
|
||||
ErrInvalidRoleName = errors.New("invalid role name")
|
||||
ErrUnknownContentType = errors.New("unknown content type")
|
||||
ErrNotBuiltIn = errors.New("role is not built in")
|
||||
ErrInvalidReassign = errors.New("invalid reassign target")
|
||||
ErrEscalation = errors.New("grants more than the caller holds")
|
||||
)
|
||||
|
||||
type Scope string
|
||||
@@ -30,13 +43,15 @@ type Grant struct {
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
ID uint32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
BuiltIn bool `json:"built_in"`
|
||||
Locked bool `json:"locked"`
|
||||
Version uint32 `json:"version"`
|
||||
Grants []Grant `json:"grants"`
|
||||
ID uint32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
BuiltIn bool `json:"built_in"`
|
||||
Locked bool `json:"locked"`
|
||||
Version uint32 `json:"version"`
|
||||
Grants []Grant `json:"grants"`
|
||||
UpdatedAt time.Time `json:"-"`
|
||||
UpdatedBy *uint32 `json:"-"`
|
||||
}
|
||||
|
||||
func resolveGrantKey(key string) (Permission, error) {
|
||||
|
||||
Reference in new issue
Block a user