cerrado @ v0.0.18

 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 http.HandlerFunc) http.HandlerFunc {
18	return func(w http.ResponseWriter, r *http.Request) {
19		ctx := r.Context()
20		ctx = context.WithValue(ctx, "disableAuthentication", true)
21		next(w, r.WithContext(ctx))
22	}
23}
24
25func VerifyRespository(
26	config *serverconfig.ConfigurationRepository,
27) func(next http.HandlerFunc) http.HandlerFunc {
28	return func(next http.HandlerFunc) http.HandlerFunc {
29		return func(w http.ResponseWriter, r *http.Request) {
30			name := r.PathValue("name")
31			if name != "" {
32				repo := config.GetByName(name)
33				if repo != nil && !repo.Public && !IsLoggedIn(r.Context()) {
34					NotFound(w, r)
35					return
36				}
37			}
38
39			next(w, r)
40		}
41	}
42}
43
44func Authenticate(auth authService) func(next http.HandlerFunc) http.HandlerFunc {
45	return func(next http.HandlerFunc) http.HandlerFunc {
46		return func(w http.ResponseWriter, r *http.Request) {
47			cookie, err := r.Cookie("auth")
48			if err != nil {
49				if !errors.Is(err, http.ErrNoCookie) {
50					slog.Error("Error loading cookie", "error", err)
51				}
52
53				next(w, r)
54				return
55			}
56
57			value, err := base64.StdEncoding.DecodeString(cookie.Value)
58			if err != nil {
59				slog.Error("Error decoding", "error", err)
60				next(w, r)
61				return
62			}
63
64			valid, err := auth.ValidateToken(value)
65			if err != nil {
66				slog.Error("Error validating token", "error", err, "cookie", cookie.Value)
67				next(w, r)
68				return
69			}
70
71			ctx := r.Context()
72			ctx = context.WithValue(ctx, "logged", valid)
73
74			slog.Info("Validated token", "valid?", valid)
75			next(w, r.WithContext(ctx))
76		}
77	}
78}
79
80func IsLoggedIn(ctx context.Context) bool {
81	t, ok := ctx.Value("logged").(bool)
82	return ok && t
83}