mirror of
https://codeberg.org/angestoepselt/homepage.git
synced 2026-03-21 22:32:17 +00:00
56 lines
1.7 KiB
Go
56 lines
1.7 KiB
Go
// Package antispam defines HTML templates and the corresponding server-side
|
|
// logic for integrating captcha providers.
|
|
package antispam
|
|
|
|
import (
|
|
"context"
|
|
"html/template"
|
|
"log/slog"
|
|
"net/http"
|
|
"os"
|
|
)
|
|
|
|
type Antispam interface {
|
|
// Script contains HTML `<script>` tag(s) that need to be injected into the
|
|
// form content or document head.
|
|
Script() template.HTML
|
|
// FormField is the template that needs to be injected into the `<form>`.
|
|
FormField() template.HTML
|
|
// CheckRequest uses the captcha provider to determine if request should be
|
|
// allowed to proceed.
|
|
//
|
|
// Implementations using HTTP forms may require r.ParseForm() to have been
|
|
// called.
|
|
CheckRequest(r *http.Request) (bool, error)
|
|
}
|
|
|
|
type antispamKey struct{}
|
|
|
|
// GetAntispam returns the active antispam implementation from request context.
|
|
func GetAntispam(r *http.Request) Antispam {
|
|
if antispam, ok := r.Context().Value(antispamKey{}).(Antispam); ok {
|
|
return antispam
|
|
}
|
|
return NewNoop()
|
|
}
|
|
|
|
// WithAntispam chooses a suitable antispam implementation sets up request
|
|
// context accordingly.
|
|
func WithAntispam(next http.Handler) http.HandlerFunc {
|
|
hCaptchaSiteKey := os.Getenv("HCAPTCHA_SITE_KEY")
|
|
hCaptchaSecretKey := os.Getenv("HCAPTCHA_SECRET_KEY")
|
|
if hCaptchaSiteKey != "" && hCaptchaSecretKey != "" {
|
|
slog.Info("antispam: using hCaptcha implementation")
|
|
return withAntispam(next, NewHcaptcha(hCaptchaSiteKey, hCaptchaSecretKey))
|
|
}
|
|
|
|
slog.Info("antispam: falling back to noop implementation")
|
|
return next.ServeHTTP
|
|
}
|
|
|
|
func withAntispam(next http.Handler, impl Antispam) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := context.WithValue(r.Context(), antispamKey{}, impl)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
}
|
|
}
|