cerrado @ 1e45ae2ea3497958b2ea6a20137955cfc3bbc964

 1package auth
 2
 3import (
 4	"encoding/base64"
 5	"net/http"
 6	"time"
 7
 8	"git.gabrielgio.me/cerrado/pkg/ext"
 9	"git.gabrielgio.me/cerrado/templates"
10)
11
12type (
13	LoginHandler struct {
14		auth authService
15	}
16
17	authService interface {
18		CheckAuth(username, password string) bool
19		IssueToken() ([]byte, error)
20	}
21)
22
23func NewLoginHandler(auth authService) *LoginHandler {
24	return &LoginHandler{
25		auth: auth,
26	}
27}
28
29func (g *LoginHandler) Logout(w http.ResponseWriter, r *http.Request) error {
30	cookie := &http.Cookie{
31		Name:    "auth",
32		Value:   "",
33		Path:    "/",
34		Expires: time.Unix(0, 0),
35	}
36
37	referer := r.Header.Get("Referer")
38	if referer == "" {
39		referer = "/"
40	}
41
42	http.SetCookie(w, cookie)
43	ext.Redirect(w, referer)
44	return nil
45}
46
47func (g *LoginHandler) Login(w http.ResponseWriter, r *http.Request) error {
48	if r.Method == "GET" {
49		ext.SetHTML(w)
50
51		login := &templates.LoginPage{}
52		templates.WritePageTemplate(w, login, r.Context())
53	} else if r.Method == "POST" {
54
55		username := r.FormValue("username")
56		password := r.FormValue("password")
57
58		if !g.auth.CheckAuth(username, password) {
59			login := &templates.LoginPage{
60				ErrorMessage: "Invalid login",
61			}
62			templates.WritePageTemplate(w, login, r.Context())
63		} else {
64
65			bytes, err := g.auth.IssueToken()
66			if err != nil {
67				return err
68			}
69
70			cookie := &http.Cookie{
71				Name:     "auth",
72				Value:    base64.StdEncoding.EncodeToString(bytes),
73				Path:     "/",
74				MaxAge:   3600,
75				HttpOnly: true,
76				Secure:   true,
77				SameSite: http.SameSiteStrictMode,
78			}
79
80			http.SetCookie(w, cookie)
81			ext.Redirect(w, "/")
82		}
83
84	}
85
86	return nil
87}