session

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package session provides session management for authenticated users.

This package defines interfaces for session storage and OAuth state management, with implementations for different backends:

  • memory: In-memory storage for development/testing
  • redis: Redis-backed storage for production multi-instance deployments
  • file: File-based storage for CLI applications

Architecture

Sessions store user authentication data (access tokens, user info) with automatic expiration. The Store interface supports:

  • Get/Set/Delete operations
  • Automatic expiration checking
  • Cleanup of expired sessions

OAuth state tokens provide CSRF protection during the OAuth flow. The StateStore interface supports:

  • Token generation with TTL
  • Single-use validation (tokens are deleted after validation)

Usage

Create a session store:

// Development
store := memory.NewStore()

// Production
store, err := redis.NewStore(ctx, redis.Config{
    Addr: "localhost:6379",
})

// CLI
store, err := file.NewStore("")  // Uses ~/.config/stacktower/sessions/

Manage sessions:

// Create session
sess, err := session.New(accessToken, user, session.DefaultTTL)
if err != nil {
    return err
}
store.Set(ctx, sess)

// Retrieve session
sess, err := store.Get(ctx, sessionID)
if err != nil {
    return err
}
if sess == nil || sess.IsExpired() {
    // Session not found or expired
}

Index

Constants

View Source
const (
	// DefaultTTL is the default session duration.
	DefaultTTL = 24 * time.Hour

	// DefaultStateTTL is the default OAuth state token duration.
	DefaultStateTTL = 10 * time.Minute
)

Default durations.

Variables

View Source
var (
	// ErrNotFound is returned when a session does not exist.
	ErrNotFound = errors.New("not found")

	// ErrExpired is returned when a session has exceeded its TTL.
	ErrExpired = errors.New("expired")

	// ErrInvalidState is returned when an OAuth state token is invalid or already used.
	ErrInvalidState = errors.New("invalid or expired state token")
)

Sentinel errors for session operations.

Functions

func GenerateID

func GenerateID() (string, error)

GenerateID creates a cryptographically secure random session ID.

func GenerateState

func GenerateState() (string, error)

GenerateState creates a cryptographically secure random state token.

Types

type CLIStore

type CLIStore struct {
	// contains filtered or unexported fields
}

CLIStore wraps FileStore for simple CLI token storage.

func NewCLIStore

func NewCLIStore() (*CLIStore, error)

NewCLIStore creates a store for CLI token storage.

func (*CLIStore) DeleteSession

func (c *CLIStore) DeleteSession(ctx context.Context) error

DeleteSession removes the CLI session.

func (*CLIStore) GetSession

func (c *CLIStore) GetSession(ctx context.Context) (*Session, error)

GetSession retrieves the CLI session.

func (*CLIStore) Path

func (c *CLIStore) Path() string

Path returns the session file path.

func (*CLIStore) SaveSession

func (c *CLIStore) SaveSession(ctx context.Context, sess *Session) error

SaveSession stores the CLI session.

type FileStore

type FileStore struct {
	// contains filtered or unexported fields
}

FileStore is a file-based session store for CLI applications. Sessions are stored as JSON files in a config directory.

func NewFileStore

func NewFileStore(baseDir string) (*FileStore, error)

NewFileStore creates a new file-based session store. If baseDir is empty, defaults to ~/.config/stacktower/sessions/

func (*FileStore) Cleanup

func (s *FileStore) Cleanup(ctx context.Context) error

func (*FileStore) Close

func (s *FileStore) Close() error

func (*FileStore) Delete

func (s *FileStore) Delete(ctx context.Context, sessionID string) error

func (*FileStore) Get

func (s *FileStore) Get(ctx context.Context, sessionID string) (*Session, error)

func (*FileStore) Path

func (s *FileStore) Path() string

Path returns the base directory for session files.

func (*FileStore) Set

func (s *FileStore) Set(ctx context.Context, sess *Session) error

type Session

type Session struct {
	ID          string       `json:"id"`
	AccessToken string       `json:"access_token"`
	User        *github.User `json:"user"`
	ExpiresAt   time.Time    `json:"expires_at"`
	CreatedAt   time.Time    `json:"created_at"`
}

Session stores user session data.

func MockLocal

func MockLocal() *Session

MockLocal creates a mock session for local development without authentication. This is used when --no-auth is enabled in standalone mode. The mock user has ID "local" and no GitHub access token.

func New

func New(accessToken string, user *github.User, ttl time.Duration) (*Session, error)

New creates a new session with the given token and user.

func (*Session) IsExpired

func (s *Session) IsExpired() bool

IsExpired returns true if the session has expired.

func (*Session) UserID

func (s *Session) UserID() string

UserID returns a storage-compatible user identifier. Format: "github:{id}" to namespace by auth provider. This format is used in cache keys and document ownership.

type StateStore

type StateStore interface {
	// Generate creates a new state token and stores it with the given TTL.
	// Returns the generated state token.
	Generate(ctx context.Context, ttl time.Duration) (string, error)

	// Validate checks if a state token is valid and removes it (single-use).
	// Returns true if the token was valid and not expired.
	Validate(ctx context.Context, state string) (bool, error)

	// Cleanup removes expired state tokens (optional, may be no-op for Redis).
	Cleanup(ctx context.Context) error
}

StateStore manages OAuth state tokens for CSRF protection. State tokens are short-lived (typically 10 minutes) and single-use. For multi-instance deployments, use Redis to share state across instances.

type Store

type Store interface {
	// Get retrieves a session by ID.
	// Returns nil, nil if the session doesn't exist.
	// Returns nil, ErrExpired if the session exists but has expired.
	Get(ctx context.Context, sessionID string) (*Session, error)

	// Set stores a session.
	Set(ctx context.Context, session *Session) error

	// Delete removes a session.
	Delete(ctx context.Context, sessionID string) error

	// Cleanup removes expired sessions (optional, may be no-op for Redis).
	Cleanup(ctx context.Context) error
}

Store is the interface for session storage backends.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL