package ext import ( "context" "encoding/base64" "errors" "log/slog" "net/http" serverconfig "git.gabrielgio.me/cerrado/pkg/config" ) type authService interface { ValidateToken(token []byte) (bool, error) } func DisableAuthentication(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx = context.WithValue(ctx, "disableAuthentication", true) next(w, r.WithContext(ctx)) } } func VerifyRespository( config *serverconfig.ConfigurationRepository, ) func(next http.HandlerFunc) http.HandlerFunc { return func(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { name := r.PathValue("name") if name != "" { repo := config.GetByName(name) if repo != nil && !repo.Public && !IsLoggedIn(r.Context()) { NotFound(w, r) return } } next(w, r) } } } func Authenticate(auth authService) func(next http.HandlerFunc) http.HandlerFunc { return func(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("auth") if err != nil { if !errors.Is(err, http.ErrNoCookie) { slog.Error("Error loading cookie", "error", err) } next(w, r) return } value, err := base64.StdEncoding.DecodeString(cookie.Value) if err != nil { slog.Error("Error decoding", "error", err) next(w, r) return } valid, err := auth.ValidateToken(value) if err != nil { slog.Error("Error validating token", "error", err, "cookie", cookie.Value) next(w, r) return } ctx := r.Context() ctx = context.WithValue(ctx, "logged", valid) slog.Info("Validated token", "valid?", valid) next(w, r.WithContext(ctx)) } } } func IsLoggedIn(ctx context.Context) bool { t, ok := ctx.Value("logged").(bool) return ok && t }