Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"github.com/go-logr/logr"
)

var UIDAttr CtxKey = "uid"

const (
LogKeySID = "session.sid"
LogKeyRQID = "session.rqud"
Expand All @@ -33,15 +31,14 @@ type sessionService struct {

/*

Create implementation of SessionServiceInterface to work with session
NewService Create implementation of Service to work with session

logr.Logger may be useful only for debugging purposes.
All messages will be logged as logr.V = 10
and none of errors will be logged as logr.Error.
logr.Logger may be useful only for debugging purposes,
Nnone of errors will be logged as logr.Error.
It's up to service that call these methods
to decide what is really error in terms of application and what is not.

reqIdKey is key to extract request id from context
reqIDKey is key to extract request id from the context

*/
func NewService(s Store, l logr.Logger, reqIDKey interface{}) Service {
Expand All @@ -53,6 +50,8 @@ func NewService(s Store, l logr.Logger, reqIDKey interface{}) Service {
return &ss
}

// CreateAnonymSession create new anonym session, store it based on provided implementation of Store and return
// keyAndValues attributes which should be added to a session during creation
func (ss *sessionService) CreateAnonymSession(ctx context.Context, cc CookieConf, sc Conf, keyAndValues ...interface{}) (*Session, error) {
ss.Logger.V(0).Info(
"session.CreateAnonymSession() started",
Expand Down Expand Up @@ -108,6 +107,8 @@ func (ss *sessionService) CreateAnonymSession(ctx context.Context, cc CookieConf
return svdS, nil
}

// CreateUserSession create new session, store it based on provided implementation of Store and return
// keyAndValues attributes which should be added to a session during creation
func (ss *sessionService) CreateUserSession(ctx context.Context, uid string, cc CookieConf, sc Conf, keyAndValues ...interface{}) (*Session, error) {
ss.Logger.V(0).Info("session.CreateUserSession() started", LogKeyRQID, ctx.Value(ss.CtxReqIDKey))
defer ss.Logger.V(0).Info("session.CreateUserSession() finished", LogKeyRQID, ctx.Value(ss.CtxReqIDKey))
Expand Down Expand Up @@ -140,6 +141,7 @@ func (ss *sessionService) CreateUserSession(ctx context.Context, uid string, cc
return svdS, nil
}

// LoadSession return session loaded from storage based on implementation of Store
func (ss *sessionService) LoadSession(ctx context.Context, sid string) (*Session, error) {
ss.Logger.V(0).Info("session.LoadSession() started", LogKeySID, sid, LogKeyRQID, ctx.Value(ss.CtxReqIDKey))
defer ss.Logger.V(0).Info("session.LoadSession() finished", LogKeySID, sid, LogKeyRQID, ctx.Value(ss.CtxReqIDKey))
Expand All @@ -162,6 +164,7 @@ func (ss *sessionService) LoadSession(ctx context.Context, sid string) (*Session
return s, nil
}

// InvalidateSession invalidate session in storage based on implementation of Store
func (ss *sessionService) InvalidateSession(ctx context.Context, sid string) error {
ss.Logger.V(0).Info("session.InvalidateSession() started", LogKeySID, sid, LogKeyRQID, ctx.Value(ss.CtxReqIDKey))
defer ss.Logger.V(0).Info("session.InvalidateSession() finished", LogKeySID, sid, LogKeyRQID, ctx.Value(ss.CtxReqIDKey))
Expand Down
29 changes: 29 additions & 0 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ import (
"time"
)

// Session is representation of session in terms of current module.
// Data - should be used to store any data within a session.
//
// IdleTimeout and LastAccessedAt will be used to expire session based
// on user activity within the session.
//
// AbsTimeout and CreatedAt will be used to expire session based
// on full session lifetime.
//
// UID is supposed to store user identity who session belongs to.
//
// Anonym is supposed to use during authentication process.
type Session struct {
ID string
Data map[CtxKey]interface{}
Expand All @@ -34,6 +46,7 @@ const (
SameSiteNoneMode
)

// CookieConf contains cookie parameters
type CookieConf struct {
Path string
Domain string
Expand All @@ -43,11 +56,13 @@ type CookieConf struct {
SameSite SameSite
}

// Conf contains session parameters
type Conf struct {
IdleTimeout time.Duration
AbsTimout time.Duration
}

// CtxKey type alias for session data attributes keys
type CtxKey string

var (
Expand All @@ -72,6 +87,12 @@ func DefaultSessionConf() Conf {
}
}

// NewSession return new session with default configuration
// IdleTimeout = 24h
// AbsTimeout = 7d
// Anonym = true
// Active = true
// Opts: Secure, HTTPOnly, Strict
func NewSession() (Session, error) {
id, err := generateSessionID()
if err != nil {
Expand All @@ -89,29 +110,36 @@ func NewSession() (Session, error) {
return s, nil
}

// WithUserID add user identity to the session
func (s *Session) WithUserID(uid string) {
s.UID = uid
s.Anonym = false
}

// WithCookieConf add cookie to the session
func (s *Session) WithCookieConf(cc CookieConf) {
s.Opts = cc
}

// WithSessionConf configure session timeouts
func (s *Session) WithSessionConf(sc Conf) {
s.IdleTimeout = sc.IdleTimeout
s.AbsTimeout = sc.AbsTimout
}

// AddAttribute add a new attribute to the session
func (s *Session) AddAttribute(k CtxKey, v interface{}) {
s.Data[k] = v
}

// GetAttribute return a value from the session
// It return nill and false if attribute doesn't exists
func (s *Session) GetAttribute(k CtxKey) (interface{}, bool) {
v, ok := s.Data[k]
return v, ok
}

// IsExpired check if session is expired
func (s *Session) IsExpired() bool {
if !s.Active {
return true
Expand All @@ -130,6 +158,7 @@ func (s *Session) IsExpired() bool {
return false
}

// ValidateSessionID validate session id format
func ValidateSessionID(sid string) error {
if len(sid) != base32enc.EncodedLen(keyLen) {
return fmt.Errorf("error validating session: wrong session id length")
Expand Down
4 changes: 4 additions & 0 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
)

type Store interface {
// Save store session and return its updated copy
Save(ctx context.Context, s *Session) (*Session, error)
// Update session and return its updated copy
Update(ctx context.Context, s *Session) (*Session, error)
// Load session by its id
Load(ctx context.Context, sid string) (*Session, error)
// Invalidate session by its id
Invalidate(ctx context.Context, sid string) error
}