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
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))
|
|
})
|
|
}
|
|
}
|