Files
contracts/security/permission_mask.go
Rene Nochebuena 098a2098f8 feat(contracts): initial implementation (v1.0.0)
Introduces code.nochebuena.dev/einherjar/contracts — the zero-dependency
foundation of the Einherjar framework. Defines the interfaces and minimal
types consumed by every starter. Zero external dependencies. Zero Einherjar
dependencies. Nothing is above it in the dependency graph.

lifecycle:
- Component — OnInit, OnStart, OnStop three-phase lifecycle hooks

observability:
- Level (LevelCritical=0, LevelDegraded); zero value is the safe default
- Checkable — HealthCheck, Name, Priority
- Identifiable — ModulePath, ModuleVersion; implemented by all starters to
  surface module identity and version in the startup banner

logging:
- Logger — Debug, Info, Warn, Error, With, WithContext

errs:
- CodedError — ErrorCode() string; satisfied by core/xerrors.Err
- ContextualError — ErrorContext() map[string]any; satisfied by core/xerrors.Err

security:
- Identity value type — UID, TenantID, DisplayName, Email; NewIdentity, WithTenant
- Permission (int64), MaxPermission=62, PermissionMask — Has, Grant
- PermissionProvider — ResolveMask(ctx, uid, resource) (PermissionMask, error)
- SecurityBag value type — immutable request-scoped security context; carries
  Identity and arbitrary typed attributes (hardware IDs, grant codes, etc.);
  With copies the attribute map on every call to preserve receiver-invariant behaviour
- NewSecurityBag, Identity, WithIdentity, Get, With
- SetBagInContext / BagFromContext — full bag context storage
- SetInContext / FromContext — backed by SecurityBag; all four cross-function
  combinations (SetInContext+BagFromContext, SetBagInContext+FromContext) are valid

One file per type; CT-6 enforced by compliance test AST walk.
2026-05-29 15:43:08 +00:00

27 lines
855 B
Go

package security
// PermissionMask is a resolved bit-mask for a user on a specific resource.
// It is returned by PermissionProvider.ResolveMask and inspected with Has.
// A zero value means no permissions are granted.
type PermissionMask int64
// Has reports whether the given permission bit is set in the mask.
// Returns false for out-of-range values (p < 0 or p > MaxPermission).
func (m PermissionMask) Has(p Permission) bool {
if p < 0 || p >= 63 {
return false
}
return (int64(m) & (1 << uint(p))) != 0
}
// Grant returns a new mask with the bit for p set.
// The receiver is not modified — safe to use in builder chains:
//
// mask := security.PermissionMask(0).Grant(Read).Grant(Write)
func (m PermissionMask) Grant(p Permission) PermissionMask {
if p < 0 || p >= 63 {
return m
}
return PermissionMask(int64(m) | (1 << uint(p)))
}