Documentation
¶
Overview ¶
Package auth provides the single-user credential, token store, and cookie session machinery shared by the Reader API and the htmx web UI.
Two front doors share one credential:
- Reader API (Google ClientLogin): clients POST username+password, receive an opaque Auth=<token>; subsequent requests send `Authorization: GoogleLogin auth=<token>` (Reeder also sends T=<token> as a write-token after a `/reader/api/0/token` call).
- Web UI: a standard cookie session set on POST /ui/login.
Tokens are random opaque strings (32 bytes, hex-encoded). They are persisted to tokens.json so they survive restarts.
Index ¶
- Constants
- Variables
- func ClearSessionCookie(w http.ResponseWriter)
- func ExtractAPIToken(r *http.Request) string
- func HashPassword(plain string) (string, error)
- func SessionFromRequest(r *http.Request) string
- func SetSessionCookie(w http.ResponseWriter, tok string, secure bool)
- type Config
- type Store
- func (s *Store) CheckAPIToken(tok string) bool
- func (s *Store) CheckSession(tok string) bool
- func (s *Store) IssueAPIToken(username, password string) (string, error)
- func (s *Store) IssueSession(username, password string) (string, error)
- func (s *Store) RevokeAllSessions() error
- func (s *Store) RevokeSession(tok string) error
- func (s *Store) SetPasswordHash(h string)
- func (s *Store) Verify(username, password string) error
Constants ¶
const CookieName = "harborrs_session"
CookieName is the HTTP cookie name for the UI session.
const HashIterations = 100_000
HashIterations is the number of SHA-256 rounds applied to the salted password. Tuned to ~50ms on a recent laptop.
const TokenLifetime = 30 * 24 * time.Hour
TokenLifetime governs how long tokens are valid. v0.1: 30 days.
Variables ¶
var ErrInvalidCredentials = errors.New("invalid credentials")
ErrInvalidCredentials is returned on a bad username/password pair.
Functions ¶
func ClearSessionCookie ¶
func ClearSessionCookie(w http.ResponseWriter)
ClearSessionCookie writes an expired session cookie to w.
func ExtractAPIToken ¶
ExtractAPIToken pulls a Reader-API token from an http.Request: either `Authorization: GoogleLogin auth=<token>` or a `T=<token>` form value.
func HashPassword ¶
HashPassword returns a salted-and-stretched SHA-256 hash for password.
func SessionFromRequest ¶
SessionFromRequest returns the session value from the cookie, or "".
func SetSessionCookie ¶
func SetSessionCookie(w http.ResponseWriter, tok string, secure bool)
SetSessionCookie writes a session cookie to w.
Types ¶
type Config ¶
Config is the single-user credential configuration. The on-disk format for PasswordHash is "sha256$<hex-salt>$<hex-hash>" where hash is computed over (salt || password) repeatedly (HashIterations rounds). This is not bcrypt-grade; for v0.1 single-user with a strong password it is acceptable, and it keeps the dep surface stdlib-only.
type Store ¶
type Store struct {
Path string // tokens.json
Cfg Config
// contains filtered or unexported fields
}
Store holds API tokens and cookie sessions.
func (*Store) CheckAPIToken ¶
CheckAPIToken returns true if token is valid (exists + not expired).
func (*Store) CheckSession ¶
CheckSession returns true if a session cookie value is valid.
func (*Store) IssueAPIToken ¶
IssueAPIToken authenticates and returns a new opaque token. The token is also persisted to disk so it survives restarts.
func (*Store) IssueSession ¶
IssueSession authenticates and returns a new opaque session cookie value.
func (*Store) RevokeAllSessions ¶ added in v0.3.0
RevokeAllSessions drops every session cookie, forcing all browsers to re-authenticate. Used after a password change. API tokens are kept (clients re-authenticate with the new password lazily).
func (*Store) RevokeSession ¶
RevokeSession deletes a session token (logout).
func (*Store) SetPasswordHash ¶ added in v0.3.0
SetPasswordHash atomically replaces the stored password hash. Callers are responsible for also persisting the new hash to config.json — the auth store has no knowledge of where the Config lives on disk.