66 lines
1.9 KiB
Go
66 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
)
|
|
|
|
type ctxKey string
|
|
|
|
const uidKey ctxKey = "uid"
|
|
|
|
// torNet ist das interne Netz, über das TOR-Anfragen beim Backend ankommen:
|
|
// der Onion-Hidden-Service reicht über einen lokalen Proxy weiter, eine echte
|
|
// Client-IP gibt es dabei nicht -> die Anfragen erscheinen mit einer IP aus
|
|
// diesem Netz (siehe Impression-Log: 10.89.0.0). Beiträge von dort werden
|
|
// vorerst komplett abgewiesen; eine Moderations-/Freigabeseite kommt später.
|
|
// Per KVER_TOR_NET (CIDR) konfigurierbar; leer schaltet die Sperre ab.
|
|
var torNet *net.IPNet
|
|
|
|
func init() {
|
|
cidr := envOr("KVER_TOR_NET", "10.89.0.0/16")
|
|
if cidr == "" {
|
|
return
|
|
}
|
|
if _, n, err := net.ParseCIDR(cidr); err == nil {
|
|
torNet = n
|
|
} else {
|
|
log.Printf("KVER_TOR_NET ignoriert (ungültiges CIDR %q): %v", cidr, err)
|
|
}
|
|
}
|
|
|
|
// blockTOR weist Anfragen aus dem TOR-Netz ab (siehe torNet). Die volle IP wird
|
|
// hier nur für diese Zugriffsentscheidung geprüft, nicht gespeichert oder
|
|
// geloggt. Ist kein Netz konfiguriert, ist die Middleware ein No-op.
|
|
func blockTOR(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if torNet != nil {
|
|
if ip := clientIP(r.RemoteAddr); ip != nil && torNet.Contains(ip) {
|
|
writeError(w, http.StatusForbidden, "Beiträge über TOR sind derzeit nicht möglich.")
|
|
return
|
|
}
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// requireAuth lehnt Anfragen ohne gültige Session ab und legt die uid in den Context.
|
|
func requireAuth(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
s, ok := getSession(r)
|
|
if !ok {
|
|
writeError(w, http.StatusUnauthorized, "Nicht angemeldet")
|
|
return
|
|
}
|
|
ctx := context.WithValue(r.Context(), uidKey, s.UID)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
func uidFromContext(ctx context.Context) int64 {
|
|
uid, _ := ctx.Value(uidKey).(int64)
|
|
return uid
|
|
}
|