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}