diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-20 11:34:33 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-20 11:34:33 -1000 |
| commit | 08bbcf18b1207153983261652b4a43a9b36f386c (patch) | |
| tree | e6665608c7c8a87d6c789cf8b4c56d466df6bb8b /internal/auth/middleware.go | |
| parent | 07ba815e8517ee2d3a5fa531361bbd09bdfcbaa7 (diff) | |
Add session-based authentication
Implement secure authentication using scs session manager with SQLite
backing store and bcrypt password hashing.
- Add users and sessions tables (migration 004)
- Create internal/auth package with Service, Middleware, and Handlers
- Protect all routes except /login, /logout, /static/*
- Add login page template and logout button to dashboard
- Default credentials: admin/changeme (configurable via env vars)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/auth/middleware.go')
| -rw-r--r-- | internal/auth/middleware.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/internal/auth/middleware.go b/internal/auth/middleware.go new file mode 100644 index 0000000..7710328 --- /dev/null +++ b/internal/auth/middleware.go @@ -0,0 +1,50 @@ +package auth + +import ( + "net/http" + + "github.com/alexedwards/scs/v2" +) + +const SessionKeyUserID = "user_id" + +// Middleware provides authentication middleware +type Middleware struct { + sessions *scs.SessionManager +} + +// NewMiddleware creates a new auth middleware +func NewMiddleware(sessions *scs.SessionManager) *Middleware { + return &Middleware{sessions: sessions} +} + +// RequireAuth redirects to login if not authenticated +func (m *Middleware) RequireAuth(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !m.IsAuthenticated(r) { + http.Redirect(w, r, "/login", http.StatusSeeOther) + return + } + next.ServeHTTP(w, r) + }) +} + +// IsAuthenticated checks if the current request has a valid session +func (m *Middleware) IsAuthenticated(r *http.Request) bool { + return m.sessions.Exists(r.Context(), SessionKeyUserID) +} + +// GetUserID returns the authenticated user's ID from the session +func (m *Middleware) GetUserID(r *http.Request) int64 { + return m.sessions.GetInt64(r.Context(), SessionKeyUserID) +} + +// SetUserID sets the user ID in the session (called after successful login) +func (m *Middleware) SetUserID(r *http.Request, userID int64) { + m.sessions.Put(r.Context(), SessionKeyUserID, userID) +} + +// ClearSession removes the user ID from the session (called on logout) +func (m *Middleware) ClearSession(r *http.Request) error { + return m.sessions.Destroy(r.Context()) +} |
