Added redis backend, backend selection mechanism
This commit is contained in:
71
backend/interface.go
Normal file
71
backend/interface.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserType string
|
||||
|
||||
var (
|
||||
UtPerson UserType = "person"
|
||||
UtHost UserType = "host"
|
||||
UtService UserType = "service"
|
||||
|
||||
ErrTooManyAttempts error = errors.New("too many attempts")
|
||||
ErrReservationSniped error = errors.New("session ID reservation expired and was sniped")
|
||||
ErrBackendData error = errors.New("invalid data from backend")
|
||||
)
|
||||
|
||||
// Session holds info about the logged-in user that won't change
|
||||
type Session struct {
|
||||
SessionID string
|
||||
Expiration time.Time
|
||||
UserID string
|
||||
UserType UserType
|
||||
LdapDN string
|
||||
}
|
||||
|
||||
// SessionCache holds volatile information about the logged-in user
|
||||
type SessionCache struct {
|
||||
Valid bool
|
||||
Groups []string
|
||||
DisplayName string
|
||||
GivenName string
|
||||
SurName string
|
||||
Email string
|
||||
}
|
||||
|
||||
type Backend interface {
|
||||
PutSession(ctx context.Context, session Session, cache SessionCache) error
|
||||
GetSession(ctx context.Context, id string) (Session, *SessionCache, error)
|
||||
EndSession(ctx context.Context, id string)
|
||||
// ReserveSessionID attempts to reserve a session ID. If the ID was successfully reserved, return true
|
||||
// A reserved session ID should time out no sooner than 60s from the reservation.
|
||||
// Ergo, once reserved, a session ID should be used within 60s
|
||||
ReserveSessionID(ctx context.Context, sessionID string) (bool, error)
|
||||
DoMaintenance(ctx context.Context)
|
||||
Ping(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewSessionID(ctx context.Context, backend Backend) (string, error) {
|
||||
var data = make([]byte, 18)
|
||||
for i := 0; i < 10; i++ {
|
||||
_, err := rand.Read(data[2:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
encoded := base64.URLEncoding.EncodeToString(data)
|
||||
success, err := backend.ReserveSessionID(ctx, encoded)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if success {
|
||||
return encoded, nil
|
||||
}
|
||||
}
|
||||
return "", ErrTooManyAttempts
|
||||
}
|
||||
Reference in New Issue
Block a user