The main server, and probably only repository in this org.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.7 KiB

package middlewares
import (
"net/http"
"strings"
"time"
"git.aiterp.net/lucifer/lucifer/internal/httperr"
"git.aiterp.net/lucifer/lucifer/models"
"github.com/gorilla/mux"
)
// Session is a middleware that adds a Session to the request context if there
// is one.
func Session(sessions models.SessionRepository, users models.UserRepository) mux.MiddlewareFunc {
clearCookie := &http.Cookie{
Name: "lucifer_session",
Value: "",
Path: "/",
Expires: time.Unix(0, 0),
HttpOnly: true,
}
redirectFailure := func(next http.Handler, w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.URL.Path, "/api/") || strings.HasPrefix(r.URL.Path, "/api/user/") {
next.ServeHTTP(w, r)
} else {
httperr.Respond(w, httperr.ErrLoginRequired)
}
}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Find cookie
cookie, err := r.Cookie("lucifer_session")
if err != nil || cookie == nil {
redirectFailure(next, w, r)
return
}
// Check session existence
session, err := sessions.FindByID(r.Context(), cookie.Value)
if err != nil {
http.SetCookie(w, clearCookie)
redirectFailure(next, w, r)
return
}
ctx = session.InContext(ctx)
user, err := users.FindByID(r.Context(), session.UserID)
if err != nil {
http.SetCookie(w, clearCookie)
redirectFailure(next, w, r)
return
}
ctx = user.InContext(ctx)
// Check if session has expired
if session.Expired() {
http.SetCookie(w, clearCookie)
redirectFailure(next, w, r)
return
}
// Proceed.
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}