Files
contracts/security/security_bag.go
T

56 lines
1.9 KiB
Go
Raw Permalink Normal View History

package security
// SecurityBag is the request-scoped security context for a single request.
// It carries the authenticated [Identity] alongside any additional attributes
// injected during the enrichment phase (hardware IDs, grant codes, etc.).
//
// SecurityBag is a value type — all mutation methods return a new value without
// modifying the receiver. The attribute map is copied on every [SecurityBag.With]
// call to preserve this guarantee.
//
// The framework defines no string key constants for bag attributes — all
// framework-known fields live as typed fields on [Identity]. Callers define
// their own constants to avoid collisions:
//
// const KeyHardwareID = "hardware_id"
//
// bag.With(KeyHardwareID, hwID)
// val, ok := bag.Get(KeyHardwareID)
type SecurityBag struct {
identity Identity
attributes map[string]any
}
// NewSecurityBag creates a SecurityBag wrapping id with an empty attribute map.
func NewSecurityBag(id Identity) SecurityBag {
return SecurityBag{identity: id}
}
// Identity returns the authenticated Identity stored in the bag.
func (b SecurityBag) Identity() Identity {
return b.identity
}
// WithIdentity returns a copy of the bag with the Identity replaced by id.
// Used by bag enrichers that modify the Identity (e.g., [authmw.WithTenantHeader]).
func (b SecurityBag) WithIdentity(id Identity) SecurityBag {
return SecurityBag{identity: id, attributes: b.attributes}
}
// Get returns the attribute stored under key and true, or (nil, false) if absent.
func (b SecurityBag) Get(key string) (any, bool) {
v, ok := b.attributes[key]
return v, ok
}
// With returns a copy of the bag with key set to value.
// The receiver is not modified — safe to call from concurrent middleware chains.
func (b SecurityBag) With(key string, value any) SecurityBag {
attrs := make(map[string]any, len(b.attributes)+1)
for k, v := range b.attributes {
attrs[k] = v
}
attrs[key] = value
return SecurityBag{identity: b.identity, attributes: attrs}
}