49 lines
1.5 KiB
Go
49 lines
1.5 KiB
Go
package auth
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"log/slog"
|
||
|
|
"net/http"
|
||
|
|
)
|
||
|
|
|
||
|
|
const UserKey = "user"
|
||
|
|
const SessionKey = "session"
|
||
|
|
|
||
|
|
func (s *Service) NewMiddleware(sessionCookieName string) func(http.Handler) http.Handler {
|
||
|
|
return func(next http.Handler) http.Handler {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
cookie, err := r.Cookie(sessionCookieName)
|
||
|
|
if err != nil || cookie.Value == "" {
|
||
|
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
session, err := s.SessionByToken(r.Context(), cookie.Value)
|
||
|
|
if err != nil || !session.IsValid() {
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("session lookup", slog.String("op", "middleware.SessionByToken"), slog.Any("error", err))
|
||
|
|
}
|
||
|
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
user, err := s.u.UserById(r.Context(), session.UserId)
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("load user", slog.String("op", "middleware.UserById"), slog.Int64("user_id", session.UserId), slog.Any("error", err))
|
||
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
newSession, err := s.BumpSession(r.Context(), session)
|
||
|
|
if err != nil {
|
||
|
|
slog.Error("session bump", slog.String("op", "middleware.BumpSession"), slog.Int64("user_id", session.UserId), slog.Any("error", err))
|
||
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
ctx := context.WithValue(r.Context(), UserKey, user)
|
||
|
|
ctx = context.WithValue(ctx, SessionKey, newSession)
|
||
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|