Documentation
¶
Overview ¶
Package permission defines the Permission entity and its store interface.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckAction ¶ added in v1.7.0
CheckAction refuses an action that contains ':' with an *ActionColonError. Every write path that creates a permission, or sets a new action on one, calls it before writing. Stores do not: a permission already stored with ':' in its action still loads, checks and deletes.
func CheckWritable ¶ added in v1.7.0
func CheckWritable(p *Permission) error
CheckWritable refuses, with a *SystemPermissionError, an update or delete of a system permission. The REST API and the dashboard contract both call it before they write one. The dashboard's schema.plan and schema.apply refuse the same writes through dsl.ApplyOptions.ProtectSystem; `warden apply` and DeclarativeOnStart leave that off on purpose, since they are operator tooling, and can change or delete one. No store checks IsSystem, so code that writes through the store directly checks nothing. A nil permission passes.
Types ¶
type ActionColonError ¶ added in v1.7.0
type ActionColonError struct {
Action string
}
ActionColonError refuses a permission action that contains ':'.
The engine checks a role's grant by joining the permission's resource and action with ':' into one string, and compares that with the request's resource and action joined the same way. An action with a ':' would make (warden, role:manage) and (warden:role, manage) the same grant. A resource may contain ':' (warden:role); only the action may not.
func (*ActionColonError) Error ¶ added in v1.7.0
func (e *ActionColonError) Error() string
type ListFilter ¶
type ListFilter struct {
TenantID string `json:"tenant_id,omitempty"`
NamespacePath *string `json:"namespace_path,omitempty"`
NamespacePrefix string `json:"namespace_prefix,omitempty"`
Resource string `json:"resource,omitempty"`
Action string `json:"action,omitempty"`
IsSystem *bool `json:"is_system,omitempty"`
Search string `json:"search,omitempty"`
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
}
ListFilter contains filters for listing permissions.
type NameGetter ¶ added in v1.7.0
type NameGetter interface {
GetPermissionByName(ctx context.Context, tenantID, namespacePath, name string) (*Permission, error)
}
NameGetter is the one store read LookupRef needs.
type Permission ¶
type Permission struct {
ID id.PermissionID `json:"id" db:"id"`
TenantID string `json:"tenant_id" db:"tenant_id"`
NamespacePath string `json:"namespace_path,omitempty" db:"namespace_path"`
AppID string `json:"app_id" db:"app_id"`
Name string `json:"name" db:"name"`
Description string `json:"description,omitempty" db:"description"`
Resource string `json:"resource" db:"resource"`
Action string `json:"action" db:"action"`
IsSystem bool `json:"is_system" db:"is_system"`
Metadata map[string]any `json:"metadata,omitempty" db:"metadata"`
CreatedBy string `json:"created_by,omitempty" db:"created_by"`
UpdatedBy string `json:"updated_by,omitempty" db:"updated_by"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
Permission represents a specific action allowed on a resource type.
NamespacePath locates the permission within the tenant's namespace tree. Empty string is the tenant root. Permissions defined at an ancestor namespace are visible from descendants.
func LookupRef ¶ added in v1.7.0
func LookupRef(ctx context.Context, s NameGetter, tenantID string, ref Ref) (*Permission, error)
LookupRef returns the permission ref names in tenantID, or a *RefNotFoundError when there is none. The REST API and the dashboard contract both call it before they attach a grant: a store records a grant for a name that is not there, and the role then appears to grant something and grants nothing, because the evaluator resolves grants by joining against the permissions. A store failure is returned as is.
type Ref ¶
Ref is a natural-key reference to a permission within a tenant.
Used by the role-permission junction (after Phase A.5) and the natural-key store API. NamespacePath locates the permission in the namespace tree; Name is the `<resource>:<action>` string that's unique per (tenant_id, namespace_path).
type RefNotFoundError ¶ added in v1.7.0
type RefNotFoundError struct {
Name string
}
RefNotFoundError refuses a grant of a permission that does not exist. It wraps wardenerr.ErrPermissionNotFound, so the REST API answers it with 404 and the dashboard with NOT_FOUND.
func (*RefNotFoundError) Error ¶ added in v1.7.0
func (e *RefNotFoundError) Error() string
func (*RefNotFoundError) Unwrap ¶ added in v1.7.0
func (e *RefNotFoundError) Unwrap() error
type Store ¶
type Store interface {
// CreatePermission persists a new permission.
CreatePermission(ctx context.Context, p *Permission) error
// GetPermission retrieves a permission by ID within a tenant.
GetPermission(ctx context.Context, tenantID string, permID id.PermissionID) (*Permission, error)
// GetPermissionByName retrieves a permission by tenant, namespace, and name.
// Names are unique per (tenant_id, namespace_path); the namespace argument
// disambiguates permissions sharing a name across different namespaces.
GetPermissionByName(ctx context.Context, tenantID, namespacePath, name string) (*Permission, error)
// UpdatePermission persists changes to a permission. The row is matched
// on both the ID and p.TenantID, and tenant_id is never written.
UpdatePermission(ctx context.Context, p *Permission) error
// DeletePermission removes a permission by ID within a tenant, along with
// the role junction rows that grant it, matched on
// (tenant_id, namespace_path, name).
DeletePermission(ctx context.Context, tenantID string, permID id.PermissionID) error
// ListPermissions returns permissions matching the filter.
ListPermissions(ctx context.Context, filter *ListFilter) ([]*Permission, error)
// CountPermissions returns the number of permissions matching the filter.
CountPermissions(ctx context.Context, filter *ListFilter) (int64, error)
// ListPermissionsByRole returns all permissions attached to a role
// within a tenant.
ListPermissionsByRole(ctx context.Context, tenantID string, roleID id.RoleID) ([]*Permission, error)
// ListPermissionsBySubject returns all permissions granted to a subject
// through their assigned roles.
ListPermissionsBySubject(ctx context.Context, tenantID, subjectKind, subjectID string) ([]*Permission, error)
// DeletePermissionsByTenant removes all permissions for a tenant.
DeletePermissionsByTenant(ctx context.Context, tenantID string) error
}
Store defines persistence operations for permissions.
Every by-ID operation takes the tenant as a mandatory parameter and filters on it alongside the primary key. A call whose tenant does not own the row returns ErrPermissionNotFound and changes nothing.
type SystemPermissionError ¶ added in v1.7.0
type SystemPermissionError struct {
Name string
}
SystemPermissionError refuses a write that would change or delete a system permission. It wraps wardenerr.ErrSystemPermissionImmutable (warden.ErrSystemPermissionImmutable).
func (*SystemPermissionError) Error ¶ added in v1.7.0
func (e *SystemPermissionError) Error() string
func (*SystemPermissionError) Unwrap ¶ added in v1.7.0
func (e *SystemPermissionError) Unwrap() error