package handlers import ( "net/http" "git.eeqj.de/sneak/webhooker/internal/database" ) // HandleLoginPage returns a handler for the login page (GET) func (h *Handlers) HandleLoginPage() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Check if already logged in sess, err := h.session.Get(r) if err == nil && h.session.IsAuthenticated(sess) { http.Redirect(w, r, "/", http.StatusSeeOther) return } // Render login page data := map[string]interface{}{ "Error": "", } h.renderTemplate(w, r, []string{"templates/base.html", "templates/login.html"}, data) } } // HandleLoginSubmit handles the login form submission (POST) func (h *Handlers) HandleLoginSubmit() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Parse form data if err := r.ParseForm(); err != nil { h.log.Error("failed to parse form", "error", err) http.Error(w, "Bad request", http.StatusBadRequest) return } username := r.FormValue("username") password := r.FormValue("password") // Validate input if username == "" || password == "" { data := map[string]interface{}{ "Error": "Username and password are required", } w.WriteHeader(http.StatusBadRequest) h.renderTemplate(w, r, []string{"templates/base.html", "templates/login.html"}, data) return } // Find user in database var user database.User if err := h.db.DB().Where("username = ?", username).First(&user).Error; err != nil { h.log.Debug("user not found", "username", username) data := map[string]interface{}{ "Error": "Invalid username or password", } w.WriteHeader(http.StatusUnauthorized) h.renderTemplate(w, r, []string{"templates/base.html", "templates/login.html"}, data) return } // Verify password valid, err := database.VerifyPassword(password, user.Password) if err != nil { h.log.Error("failed to verify password", "error", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } if !valid { h.log.Debug("invalid password", "username", username) data := map[string]interface{}{ "Error": "Invalid username or password", } w.WriteHeader(http.StatusUnauthorized) h.renderTemplate(w, r, []string{"templates/base.html", "templates/login.html"}, data) return } // Create session sess, err := h.session.Get(r) if err != nil { h.log.Error("failed to get session", "error", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } // Set user in session h.session.SetUser(sess, user.ID, user.Username) // Save session if err := h.session.Save(r, w, sess); err != nil { h.log.Error("failed to save session", "error", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } h.log.Info("user logged in", "username", username, "user_id", user.ID) // Redirect to home page http.Redirect(w, r, "/", http.StatusSeeOther) } } // HandleLogout handles user logout func (h *Handlers) HandleLogout() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { sess, err := h.session.Get(r) if err != nil { h.log.Error("failed to get session", "error", err) http.Redirect(w, r, "/pages/login", http.StatusSeeOther) return } // Destroy session h.session.Destroy(sess) // Save the destroyed session if err := h.session.Save(r, w, sess); err != nil { h.log.Error("failed to save destroyed session", "error", err) } // Redirect to login page http.Redirect(w, r, "/pages/login", http.StatusSeeOther) } }