cerrado @ 3739c9e14b0c65a59a520dbfefa459e43af3bf20

 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}