1
0
mirror of https://github.com/volatiletech/authboss.git synced 2024-12-10 10:40:07 +02:00
authboss/events.go
Aaron L ad5230a303 Bring back events
- Rename callbacks -> events
- Regenerate stringers.go with later version of stringer
2018-02-01 16:31:08 -08:00

114 lines
3.0 KiB
Go

package authboss
import "context"
//go:generate stringer -output stringers.go -type "Event,Interrupt"
// Event is used for callback registration.
type Event int
// Event values
const (
EventRegister Event = iota
EventAuth
EventOAuth
EventAuthFail
EventOAuthFail
EventRecoverStart
EventRecoverEnd
EventGetUser
EventGetUserSession
EventPasswordReset
)
// Interrupt is used to signal to callback mechanisms
// that the current process should not continue.
type Interrupt int
// Interrupt values
const (
// InterruptNone means there was no interrupt present and the process should continue.
InterruptNone Interrupt = iota
// InterruptAccountLocked occurs if a user's account has been locked
// by the lock module.
InterruptAccountLocked
// InterruptAccountNotConfirmed occurs if a user's account is not confirmed
// and therefore cannot be used yet.
InterruptAccountNotConfirmed
// InterruptSessionExpired occurs when the user's account has had no activity for the
// configured duration.
InterruptSessionExpired
)
// Before Events can interrupt the flow by returning an interrupt value.
// This is used to stop the callback chain and the original handler from
// continuing execution. The execution should also stopped if there is an error.
type Before func(context.Context) (Interrupt, error)
// After is a request callback that happens after the event.
type After func(context.Context) error
// Events is a collection of Events that fire before and after certain
// methods.
type Events struct {
before map[Event][]Before
after map[Event][]After
}
// NewEvents creates a new set of before and after Events.
// Called only by authboss internals and for testing.
func NewEvents() *Events {
return &Events{
before: make(map[Event][]Before),
after: make(map[Event][]After),
}
}
// Before event, call f.
func (c *Events) Before(e Event, f Before) {
Events := c.before[e]
Events = append(Events, f)
c.before[e] = Events
}
// After event, call f.
func (c *Events) After(e Event, f After) {
Events := c.after[e]
Events = append(Events, f)
c.after[e] = Events
}
// FireBefore event to all the Events with a context. The error
// should be passed up despite being logged once here already so it
// can write an error out to the HTTP Client. If err is nil then
// check the value of interrupted. If error is nil then the interrupt
// value should be checked. If it is not InterruptNone then there is a reason
// the current process should stop it's course of action.
func (c *Events) FireBefore(ctx context.Context, e Event) (interrupt Interrupt, err error) {
Events := c.before[e]
for _, fn := range Events {
interrupt, err = fn(ctx)
if err != nil {
return InterruptNone, err
}
if interrupt != InterruptNone {
return interrupt, nil
}
}
return InterruptNone, nil
}
// FireAfter event to all the Events with a context. The error can safely be
// ignored as it is logged.
func (c *Events) FireAfter(ctx context.Context, e Event) (err error) {
Events := c.after[e]
for _, fn := range Events {
if err = fn(ctx); err != nil {
return err
}
}
return nil
}