summaryrefslogtreecommitdiff
path: root/internal/auth/middleware.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-20 11:34:33 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-20 11:34:33 -1000
commit08bbcf18b1207153983261652b4a43a9b36f386c (patch)
treee6665608c7c8a87d6c789cf8b4c56d466df6bb8b /internal/auth/middleware.go
parent07ba815e8517ee2d3a5fa531361bbd09bdfcbaa7 (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.go50
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())
+}