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 referer := r.URL.Query().Get("referer")
49
50 // if query value is empty tries to get from header
51 if referer == "" {
52 referer = r.Header.Get("Referer")
53 }
54
55 if r.Method == "GET" {
56 ext.SetHTML(w)
57
58 login := &templates.LoginPage{
59 Referer: referer,
60 }
61 templates.WritePageTemplate(w, login, r.Context())
62 } else if r.Method == "POST" {
63
64 username := r.FormValue("username")
65 password := r.FormValue("password")
66
67 if !g.auth.CheckAuth(username, password) {
68 login := &templates.LoginPage{
69 Referer: referer,
70 ErrorMessage: "Invalid login",
71 }
72 templates.WritePageTemplate(w, login, r.Context())
73 } else {
74
75 bytes, err := g.auth.IssueToken()
76 if err != nil {
77 return err
78 }
79
80 cookie := &http.Cookie{
81 Name: "auth",
82 Value: base64.StdEncoding.EncodeToString(bytes),
83 Path: "/",
84 MaxAge: 3600,
85 HttpOnly: true,
86 Secure: true,
87 SameSite: http.SameSiteStrictMode,
88 }
89
90 http.SetCookie(w, cookie)
91 ext.Redirect(w, referer)
92 }
93
94 }
95
96 return nil
97}