1package ext
2
3import (
4 "context"
5 "encoding/base64"
6 "errors"
7 "log/slog"
8 "net/http"
9
10 serverconfig "git.gabrielgio.me/cerrado/pkg/config"
11)
12
13type authService interface {
14 ValidateToken(token []byte) (bool, error)
15}
16
17func DisableAuthentication(next HandlerFunc) HandlerFunc {
18 return func(w http.ResponseWriter, r *Request) {
19 ctx := r.Context()
20 ctx = context.WithValue(ctx, "disableAuthentication", true)
21 r.Request = r.WithContext(ctx)
22 next(w, r)
23 }
24}
25
26func VerifyRespository(
27 config *serverconfig.ConfigurationRepository,
28) func(next HandlerFunc) HandlerFunc {
29 return func(next HandlerFunc) HandlerFunc {
30 return func(w http.ResponseWriter, r *Request) {
31 name := r.PathValue("name")
32 if name != "" {
33 repo := config.GetByName(name)
34 if repo != nil && !repo.Public && !IsLoggedIn(r.Context()) {
35 NotFound(w, r)
36 return
37 }
38 }
39
40 next(w, r)
41 }
42 }
43}
44
45func Authenticate(auth authService) func(next HandlerFunc) HandlerFunc {
46 return func(next HandlerFunc) HandlerFunc {
47 return func(w http.ResponseWriter, r *Request) {
48 cookie, err := r.Cookie("auth")
49 if err != nil {
50 if !errors.Is(err, http.ErrNoCookie) {
51 slog.Error("Error loading cookie", "error", err)
52 }
53
54 next(w, r)
55 return
56 }
57
58 value, err := base64.StdEncoding.DecodeString(cookie.Value)
59 if err != nil {
60 slog.Error("Error decoding", "error", err)
61 next(w, r)
62 return
63 }
64
65 valid, err := auth.ValidateToken(value)
66 if err != nil {
67 slog.Error("Error validating token", "error", err, "cookie", cookie.Value)
68 next(w, r)
69 return
70 }
71
72 ctx := r.Context()
73 ctx = context.WithValue(ctx, "logged", valid)
74 r.Request = r.WithContext(ctx)
75
76 slog.Info("Validated token", "valid?", valid)
77 next(w, r)
78 }
79 }
80}
81
82func IsLoggedIn(ctx context.Context) bool {
83 t, ok := ctx.Value("logged").(bool)
84 return ok && t
85}