package auth import ( "encoding/base64" "net/http" "time" "git.gabrielgio.me/cerrado/pkg/ext" "git.gabrielgio.me/cerrado/templates" ) type ( LoginHandler struct { auth authService } authService interface { CheckAuth(username, password string) bool IssueToken() ([]byte, error) } ) func NewLoginHandler(auth authService) *LoginHandler { return &LoginHandler{ auth: auth, } } func (g *LoginHandler) Logout(w http.ResponseWriter, r *http.Request) error { cookie := &http.Cookie{ Name: "auth", Value: "", Path: "/", Expires: time.Unix(0, 0), } referer := r.Header.Get("Referer") if referer == "" { referer = "/" } http.SetCookie(w, cookie) ext.Redirect(w, referer) return nil } func (g *LoginHandler) Login(w http.ResponseWriter, r *http.Request) error { referer := r.URL.Query().Get("referer") // if query value is empty tries to get from header if referer == "" { referer = r.Header.Get("Referer") } if r.Method == "GET" { ext.SetHTML(w) login := &templates.LoginPage{ Referer: referer, } templates.WritePageTemplate(w, login, r.Context()) } else if r.Method == "POST" { username := r.FormValue("username") password := r.FormValue("password") if !g.auth.CheckAuth(username, password) { login := &templates.LoginPage{ Referer: referer, ErrorMessage: "Invalid login", } templates.WritePageTemplate(w, login, r.Context()) } else { bytes, err := g.auth.IssueToken() if err != nil { return err } cookie := &http.Cookie{ Name: "auth", Value: base64.StdEncoding.EncodeToString(bytes), Path: "/", MaxAge: 3600, HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode, } http.SetCookie(w, cookie) ext.Redirect(w, referer) } } return nil }