From 93ca9ea33b6d270b54b633548a28c6866d587b56 Mon Sep 17 00:00:00 2001 From: Odonax Date: Wed, 20 May 2026 15:57:09 +0200 Subject: [PATCH] Added session cookie and logout for admin --- auth/session.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ handlers/auth.go | 17 +++++++++++- main.go | 1 + 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 auth/session.go diff --git a/auth/session.go b/auth/session.go new file mode 100644 index 0000000..71160ae --- /dev/null +++ b/auth/session.go @@ -0,0 +1,69 @@ +package auth + +import ( + "crypto/rand" + "encoding/hex" + "net/http" + "sync" + "time" +) + +var ( + sessions = map[string]time.Time{} + mu sync.Mutex +) + +func GenerateSession() (string, error) { + bytes := make([]byte, 32) + _, err := rand.Read(bytes) + if err != nil { + return "", err + } + token := hex.EncodeToString(bytes) + + mu.Lock() + sessions[token] = time.Now() + mu.Unlock() + + return token, nil +} + +func IsLoggedIn(r *http.Request) bool { + cookie, err := r.Cookie("session") + if err != nil { + return false + } + + mu.Lock() + _, exists := sessions[cookie.Value] + mu.Unlock() + + return exists +} + +func SetSessionCookie(w http.ResponseWriter, token string) { + http.SetCookie(w, &http.Cookie{ + Name: "session", + Value: token, + Path: "/", + HttpOnly: true, + SameSite: http.SameSiteLaxMode, + }) +} + +func ClearSession(w http.ResponseWriter, r *http.Request) { + cookie, err := r.Cookie("session") + if err == nil { + mu.Lock() + delete(sessions, cookie.Value) + mu.Unlock() + } + + http.SetCookie(w, &http.Cookie{ + Name: "session", + Value: "", + Path: "/", + MaxAge: -1, + HttpOnly: true, + }) +} diff --git a/handlers/auth.go b/handlers/auth.go index 37bf03a..c8a750e 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -74,7 +74,22 @@ func Login(tmpl *template.Template) http.HandlerFunc { return } - // TODO: create a session so the admin stays logged in + token, err := auth.GenerateSession() + if err != nil { + tmpl.Execute(w, map[string]string{ + "SiteName": Cfg.SiteName, + "Error": "Something went wrong. Please try again.", + }) + return + } + auth.SetSessionCookie(w, token) http.Redirect(w, r, "/admin", http.StatusSeeOther) } } + +func Logout() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + auth.ClearSession(w, r) + http.Redirect(w, r, "/", http.StatusSeeOther) + } +} diff --git a/main.go b/main.go index bd6576b..061985f 100644 --- a/main.go +++ b/main.go @@ -40,6 +40,7 @@ func main() { http.HandleFunc("/setup", handlers.Setup(tmpl.Lookup("setup.html"))) http.HandleFunc("/login", handlers.Login(tmpl.Lookup("login.html"))) + http.HandleFunc("/logout", handlers.Logout()) log.Printf("Starting filehost on %s\n", cfg.Port) log.Fatal(http.ListenAndServe(cfg.Port, nil))