feat: add chi middleware stack

This commit is contained in:
Ruidy 2025-09-20 00:50:40 +02:00
parent 2c0ef46f18
commit 346678027f
No known key found for this signature in database
GPG key ID: 705C24D202990805
5 changed files with 56 additions and 14 deletions

View file

@ -4,12 +4,14 @@ import "net/http"
func (s *Server) dashboardHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !s.sessions.IsAuthenticated() {
state := sessionFromContext(r.Context())
if !state.Authenticated {
w.WriteHeader(http.StatusUnauthorized)
s.render(w, "unauthorized.html", newUnauthorizedData("Sign in to continue."))
return
}
s.render(w, "in.html", PageData{Email: s.sessions.CurrentAccount()})
s.render(w, "in.html", PageData{Email: state.Email})
}
}

View file

@ -4,6 +4,7 @@ import "net/http"
func (s *Server) indexHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
s.render(w, "index.html", newIndexData("", ""))
state := sessionFromContext(r.Context())
s.render(w, "index.html", newIndexData(state.Email, ""))
}
}

View file

@ -0,0 +1,30 @@
package server
import (
"context"
"net/http"
)
func (s *Server) sessionMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
state := s.sessions.Snapshot()
ctx := withSession(r.Context(), state)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
type sessionContextKey struct{}
func withSession(ctx context.Context, state SessionState) context.Context {
return context.WithValue(ctx, sessionContextKey{}, state)
}
func sessionFromContext(ctx context.Context) SessionState {
if ctx == nil {
return SessionState{}
}
if state, ok := ctx.Value(sessionContextKey{}).(SessionState); ok {
return state
}
return SessionState{}
}

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/rjnemo/auth/internal/auth"
"github.com/rjnemo/auth/web"
@ -52,6 +53,13 @@ func New() (*Server, error) {
// Router returns the configured HTTP router.
func (s *Server) Router() http.Handler {
r := chi.NewRouter()
r.Use(
middleware.RequestID,
middleware.RealIP,
middleware.Logger,
middleware.Recoverer,
s.sessionMiddleware,
)
s.registerRoutes(r)
return r
}

View file

@ -2,6 +2,12 @@ package server
import "sync"
// SessionState represents the snapshot of session metadata for a request.
type SessionState struct {
Authenticated bool
Email string
}
// SessionManager is a placeholder for future session persistence.
type SessionManager struct {
mu sync.RWMutex
@ -32,18 +38,13 @@ func (m *SessionManager) Clear() {
m.currentAccount = ""
}
// IsAuthenticated reports whether a user is currently considered logged in.
func (m *SessionManager) IsAuthenticated() bool {
// Snapshot captures the current session state for contextual use.
func (m *SessionManager) Snapshot() SessionState {
m.mu.RLock()
defer m.mu.RUnlock()
return m.authenticated
}
// CurrentAccount returns the email associated with the active session.
func (m *SessionManager) CurrentAccount() string {
m.mu.RLock()
defer m.mu.RUnlock()
return m.currentAccount
return SessionState{
Authenticated: m.authenticated,
Email: m.currentAccount,
}
}