Documentation
¶
Overview ¶
Package guard is authorization: the question "may this caller do this?", asked once per route, before the handler runs.
A guard returns nil to allow and an *errs.Error to refuse, and the refusal carries its own status — so a guard that needs to answer 402 rather than 403 just says so.
Why a guard and not an `if` at the top of the handler: a route is declared in one line, and the guards on it are part of that line. A reviewer reading the module's Register function can see what protects each route without opening six handlers, and a route added without protection is visibly different from its neighbours.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Authenticated = Of("authenticated", func(c fiber.Ctx) error { if ctxkit.ActorOf(c.Context()).UserID.String() == "00000000-0000-0000-0000-000000000000" { return errs.Unauthorized("authentication required").WithCode("UNAUTHENTICATED") } return nil })
Authenticated refuses a request that carries no actor.
It reads what the authentication middleware put on the context; it does not itself verify a token. Keeping the two apart means a test can establish an actor without minting a credential.
var Operator = Of("operator", func(c fiber.Ctx) error { if !ctxkit.TenantOf(c.Context()).Operator { return errs.Forbidden("not permitted").WithCode("OPERATOR_ONLY") } return nil })
Operator allows only a platform super-admin.
var Tenanted = Of("tenanted", func(c fiber.Ctx) error { if ctxkit.TenantOf(c.Context()).Zero() { return errs.Unauthorized("no account context on this request").WithCode("NO_TENANT") } return nil })
Tenanted refuses a request that is not scoped to an account.
Every tenant-owned read and write depends on this having run: a zero account id reaching a repository is the bug that returns another customer's rows.
Functions ¶
func Use ¶
Use returns a fiber handler that runs the guards in order and stops at the first refusal.
Order is yours to choose and it matters: put the cheap checks first. An authentication guard that reads a cached token should run before a quota guard that queries a database, so an unauthenticated flood costs a map lookup rather than a connection.
Types ¶
type Func ¶
Func adapts a plain function to Guard.
func (Func) CanActivate ¶
CanActivate implements Guard.
type Guard ¶
type Guard interface {
// Name identifies the guard in logs and in the route table.
Name() string
CanActivate(c fiber.Ctx) error
}
Guard decides whether a request may proceed.
Returning nil allows it. Returning an error refuses it, and the error's kind picks the status — use errs.Unauthorized for "who are you", errs.Forbidden for "not you", errs.PaymentRequired or errs.Exhausted where those fit.
func All ¶
All passes only when every guard passes. It is the same as listing them, and exists so a set of guards can be named once and reused.
func Any ¶
Any passes when at least one guard passes, and reports the LAST refusal when none do.
Use it for "an owner or an admin may do this". Do not use it to paper over a guard that is failing for a reason you have not understood.