auth

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2026 License: GPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package auth handles authentication and session tickets.

Package auth provides local accounts, platform sessions, CSRF, and WebSocket tickets. OIDC is behind an interface from day one (implementation later).

Index

Constants

View Source
const (
	// SessionCookieName carries the signed stateless browser session JWT.
	SessionCookieName = "shellcn_session"
	// CSRFHeader is where state-changing HTTP requests echo the CSRF token.
	CSRFHeader = "X-CSRF-Token"
	// DefaultSessionTTL is how long a platform session lives.
	DefaultSessionTTL = 24 * time.Hour
	// MFAChallengeTTL bounds how long a password-verified user has to complete the
	// second factor before they must sign in again.
	MFAChallengeTTL = 5 * time.Minute
)
View Source
const DefaultTicketTTL = 30 * time.Second

DefaultTicketTTL is the short lifetime of a WS ticket.

Variables

View Source
var (
	// ErrInvalidCredentials is returned for a bad username/password pair.
	ErrInvalidCredentials = errors.New("auth: invalid credentials")
	// ErrAccountDisabled is returned when the account exists but is disabled.
	ErrAccountDisabled = errors.New("auth: account disabled")
	// ErrNotImplemented is returned by an authenticator that is not yet available.
	ErrNotImplemented = errors.New("auth: not implemented")
)
View Source
var ErrInvalidHash = errors.New("auth: invalid password hash")

ErrInvalidHash is returned when a stored password hash is malformed.

View Source
var ErrTicketInvalid = errors.New("auth: invalid ticket")

ErrTicketInvalid is returned for any ticket failure (unknown, expired, used, or scope mismatch) — deliberately undifferentiated so it leaks nothing.

Functions

func CheckWSOrigin

func CheckWSOrigin(r *http.Request, allowed []string) bool

CheckWSOrigin reports whether the request's Origin header is same-site with the Host (or matches an explicit allowlist). A missing Origin is rejected for cross-origin safety on the WS upgrade path.

func ClearSessionCookie

func ClearSessionCookie(w http.ResponseWriter)

ClearSessionCookie expires the session cookie on logout.

func HashPassword

func HashPassword(password string) (string, error)

HashPassword returns a PHC-formatted argon2id hash of password.

func SetSessionCookie

func SetSessionCookie(w http.ResponseWriter, s Session, secure bool)

SetSessionCookie writes the HttpOnly, SameSite=Lax session cookie. Secure is set when the request is served over TLS.

func VerifyPassword

func VerifyPassword(encoded, password string) (bool, error)

VerifyPassword reports whether password matches the encoded argon2id hash, using a constant-time comparison.

Types

type Authenticator

type Authenticator interface {
	Authenticate(ctx context.Context, username, password string) (models.User, error)
}

Authenticator verifies a principal and returns the authenticated user. Local accounts and OIDC implement the same interface.

type LocalAuthenticator

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

LocalAuthenticator verifies username/password against the user store.

func NewLocalAuthenticator

func NewLocalAuthenticator(users store.UserStore) *LocalAuthenticator

func (*LocalAuthenticator) Authenticate

func (a *LocalAuthenticator) Authenticate(ctx context.Context, username, password string) (models.User, error)

Authenticate looks up the user, verifies the password, and rejects disabled accounts. It returns ErrInvalidCredentials for both unknown users and wrong passwords (no user-enumeration signal).

type MFAVerifier

type MFAVerifier interface {
	Verify(ctx context.Context, userID, code string) (bool, error)
}

MFAVerifier is the optional second-factor (TOTP) hook.

type OIDCAuthenticator

type OIDCAuthenticator struct{}

OIDCAuthenticator holds the OIDC interface in place; it has no implementation.

func (OIDCAuthenticator) Authenticate

Authenticate always reports not-implemented.

type Session

type Session struct {
	ID             string
	UserID         string
	CSRFToken      string
	SessionVersion int
	ExpiresAt      time.Time
}

Session is one authenticated browser session.

func (Session) ValidateCSRF

func (s Session) ValidateCSRF(r *http.Request) bool

ValidateCSRF reports whether the request carries the session's CSRF token.

type SessionManager

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

SessionManager signs and verifies stateless browser session JWTs.

func NewSessionManager

func NewSessionManager(ttl time.Duration) *SessionManager

NewSessionManager returns a manager with an ephemeral signing key. Production code should use NewSessionManagerWithKey so sessions survive process restarts.

func NewSessionManagerWithKey

func NewSessionManagerWithKey(ttl time.Duration, key []byte) *SessionManager

NewSessionManagerWithKey returns a JWT session manager with a stable HMAC key.

func (*SessionManager) Create

func (m *SessionManager) Create(userID string, sessionVersion ...int) Session

Create starts a new stateless session for userID, returning its signed JWT.

func (*SessionManager) CreateMFAChallenge

func (m *SessionManager) CreateMFAChallenge(userID string) (string, time.Time)

CreateMFAChallenge issues a short-lived token proving a user passed the password step; it carries no CSRF token, so it can never be used as a session.

func (*SessionManager) Destroy

func (m *SessionManager) Destroy(tokenString string)

Destroy revokes one browser session token for the remainder of its lifetime.

func (*SessionManager) Get

func (m *SessionManager) Get(tokenString string) (Session, bool)

Get validates a signed session JWT.

func (*SessionManager) ParseMFAChallenge

func (m *SessionManager) ParseMFAChallenge(tokenString string) (string, bool)

ParseMFAChallenge validates a challenge token and returns the pending user id.

type TicketScope

type TicketScope struct {
	ConnectionID string
	RouteID      string
	Params       map[string]string
	UserID       string
}

TicketScope binds a ticket to exactly one resource + acting user. Binding the params means a ticket minted for pod-A can't be replayed against pod-B.

type TicketStore

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

TicketStore mints and redeems single-use, short-lived WS tickets. Browsers can't set Authorization on a WS upgrade, so tickets are mandatory. The store is in-memory and not shared across instances.

func NewTicketStore

func NewTicketStore(ttl time.Duration) *TicketStore

NewTicketStore returns a store with the given TTL (0 = default).

func (*TicketStore) Mint

func (s *TicketStore) Mint(scope TicketScope) (token string, expiresAt time.Time)

Mint issues a token bound to scope, expiring after the store's TTL.

func (*TicketStore) Redeem

func (s *TicketStore) Redeem(token string, want TicketScope) error

Redeem validates a token against the request's scope and consumes it (single-use). Any mismatch, expiry, or reuse returns ErrTicketInvalid.

Jump to

Keyboard shortcuts

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