package main
import (
"net/http"
"net/url"
"time"
"git.neuromancer.ovh/bastien-mrq/gitfed/internal/store"
)
const sessionCookieName = "gitfed_session"
func setSessionCookie(w http.ResponseWriter, token string) {
http.SetCookie(w, &http.Cookie{
Name: sessionCookieName,
Value: token,
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteLaxMode,
Expires: time.Now().Add(7 * 24 * time.Hour), // matches admin.sessionTTL
})
}
func clearSessionCookie(w http.ResponseWriter) {
http.SetCookie(w, &http.Cookie{
Name: sessionCookieName,
Value: "",
Path: "/",
MaxAge: -1,
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteLaxMode,
})
}
// currentSession returns the caller's session, if any. A missing, invalid
// or expired cookie is just "not logged in" — never an error the caller
// needs to handle specially.
func (s *server) currentSession(r *http.Request) (store.Session, bool) {
c, err := r.Cookie(sessionCookieName)
if err != nil || c.Value == "" {
return store.Session{}, false
}
sess, err := s.ops.GetSession(c.Value)
if err != nil {
return store.Session{}, false
}
return sess, true
}
func (s *server) requireLogin(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, ok := s.currentSession(r); !ok {
http.Redirect(w, r, "/login?next="+url.QueryEscape(r.URL.RequestURI()), http.StatusSeeOther)
return
}
next(w, r)
}
}
func (s *server) requireAdmin(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
sess, ok := s.currentSession(r)
if !ok {
http.Redirect(w, r, "/login?next="+url.QueryEscape(r.URL.RequestURI()), http.StatusSeeOther)
return
}
if !sess.IsAdmin {
http.Error(w, "admin access required", http.StatusForbidden)
return
}
next(w, r)
}
}