71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
|
|
package handlers
|
||
|
|
|
||
|
|
import (
|
||
|
|
"net/http"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"crowdsec-dashy/internal/middleware"
|
||
|
|
)
|
||
|
|
|
||
|
|
// AuthHandler handles login and logout.
|
||
|
|
type AuthHandler struct {
|
||
|
|
renderer *Renderer
|
||
|
|
secret string
|
||
|
|
uiUsername string
|
||
|
|
verifyPassword func(string) bool
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewAuthHandler constructs an AuthHandler.
|
||
|
|
func NewAuthHandler(renderer *Renderer, secret, uiUsername string, verifyPassword func(string) bool) *AuthHandler {
|
||
|
|
return &AuthHandler{
|
||
|
|
renderer: renderer,
|
||
|
|
secret: secret,
|
||
|
|
uiUsername: uiUsername,
|
||
|
|
verifyPassword: verifyPassword,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// LoginData is passed to the login template.
|
||
|
|
type LoginData struct {
|
||
|
|
Title string
|
||
|
|
Error string
|
||
|
|
}
|
||
|
|
|
||
|
|
// Login handles GET (render form) and POST (verify credentials, set cookie).
|
||
|
|
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||
|
|
switch r.Method {
|
||
|
|
case http.MethodGet:
|
||
|
|
if _, err := r.Cookie("cs_session"); err == nil {
|
||
|
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
h.renderer.Render(w, "login", LoginData{Title: "Login"})
|
||
|
|
|
||
|
|
case http.MethodPost:
|
||
|
|
r.Body = http.MaxBytesReader(w, r.Body, 2048)
|
||
|
|
if err := r.ParseForm(); err != nil {
|
||
|
|
h.renderer.Render(w, "login", LoginData{Title: "Login", Error: "Invalid request."})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
username := strings.TrimSpace(r.FormValue("username"))
|
||
|
|
password := r.FormValue("password")
|
||
|
|
|
||
|
|
if username != h.uiUsername || !h.verifyPassword(password) {
|
||
|
|
h.renderer.Render(w, "login", LoginData{Title: "Login", Error: "Invalid credentials."})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
http.SetCookie(w, middleware.NewSessionCookie(h.secret, username))
|
||
|
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||
|
|
|
||
|
|
default:
|
||
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Logout clears the session cookie and redirects to /login.
|
||
|
|
func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||
|
|
http.SetCookie(w, middleware.ClearSessionCookie())
|
||
|
|
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||
|
|
}
|