2026-10-03 10:30:07 -04:00
|
|
|
package auth
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"slices"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Actor is the signed-in household member a request acts for. Handlers
|
|
|
|
|
// record Actor.Subject as updated_by on edits.
|
|
|
|
|
type Actor struct {
|
|
|
|
|
Subject string
|
|
|
|
|
Email string
|
|
|
|
|
Name string
|
|
|
|
|
Groups []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Actor returns the household member s belongs to.
|
|
|
|
|
func (s Session) Actor() Actor {
|
|
|
|
|
return Actor{Subject: s.Subject, Email: s.Email, Name: s.Name, Groups: slices.Clone(s.Groups)}
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-03 10:51:26 -04:00
|
|
|
type sessionKey struct{}
|
2026-10-03 10:30:07 -04:00
|
|
|
|
2026-10-03 10:51:26 -04:00
|
|
|
// WithSession returns a copy of ctx carrying s. The session middleware calls
|
|
|
|
|
// it for every authenticated request.
|
|
|
|
|
func WithSession(ctx context.Context, s Session) context.Context {
|
|
|
|
|
return context.WithValue(ctx, sessionKey{}, s)
|
2026-10-03 10:30:07 -04:00
|
|
|
}
|
|
|
|
|
|
2026-10-03 10:51:26 -04:00
|
|
|
// SessionFrom returns the session WithSession stored in ctx. ok is false when
|
|
|
|
|
// ctx has none, which behind the session middleware means a wiring bug.
|
|
|
|
|
func SessionFrom(ctx context.Context) (s Session, ok bool) {
|
|
|
|
|
s, ok = ctx.Value(sessionKey{}).(Session)
|
|
|
|
|
return s, ok
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ActorFrom returns the actor of the session WithSession stored in ctx. ok is
|
|
|
|
|
// false when ctx has none.
|
2026-10-03 10:30:07 -04:00
|
|
|
func ActorFrom(ctx context.Context) (actor Actor, ok bool) {
|
2026-10-03 10:51:26 -04:00
|
|
|
s, ok := SessionFrom(ctx)
|
|
|
|
|
if !ok {
|
|
|
|
|
return Actor{}, false
|
|
|
|
|
}
|
|
|
|
|
return s.Actor(), true
|
2026-10-03 10:30:07 -04:00
|
|
|
}
|