Umbau-Projekt (SSR und Rest)
This commit is contained in:
+35
-13
@@ -5,6 +5,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type ctxKey string
|
||||
@@ -20,7 +21,14 @@ const uidKey ctxKey = "uid"
|
||||
var torNet *net.IPNet
|
||||
|
||||
func init() {
|
||||
cidr := envOr("KVER_TOR_NET", "10.89.0.0/16")
|
||||
// LookupEnv statt envOr: envOr würde bei leer GESETZTER Variable den
|
||||
// Default liefern -- dann ließe sich die Sperre nie abschalten. Nur eine
|
||||
// UNgesetzte Variable fällt auf den Default zurück; KVER_TOR_NET= (leer)
|
||||
// deaktiviert die Sperre.
|
||||
cidr, ok := os.LookupEnv("KVER_TOR_NET")
|
||||
if !ok {
|
||||
cidr = "10.89.0.0/16"
|
||||
}
|
||||
if cidr == "" {
|
||||
return
|
||||
}
|
||||
@@ -34,24 +42,38 @@ func init() {
|
||||
// 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)
|
||||
})
|
||||
var blockTOR = guard(func(_ http.ResponseWriter, r *http.Request) error {
|
||||
if isTOR(r) {
|
||||
return errTORBlocked
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
var errTORBlocked = Forbidden("tor.blocked", "Beiträge über TOR sind derzeit nicht möglich.")
|
||||
|
||||
// isTOR erkennt Anfragen aus dem TOR-Netz. Ausgelagert, damit die
|
||||
// serverseitig gerenderten Seiten das Beitragsformular erst gar nicht anbieten,
|
||||
// statt es anzuzeigen und beim Absenden abzulehnen.
|
||||
func isTOR(r *http.Request) bool {
|
||||
if torNet == nil {
|
||||
return false
|
||||
}
|
||||
ip := clientIP(r.RemoteAddr)
|
||||
return ip != nil && torNet.Contains(ip)
|
||||
}
|
||||
|
||||
// requireAuth lehnt Anfragen ohne gültige Session ab und legt die uid in den Context.
|
||||
var errAuthRequired = Unauth("auth.required", "Nicht angemeldet")
|
||||
|
||||
// requireAuth lehnt Anfragen ohne gültige Session ab und legt die uid in den
|
||||
// Context. Nicht über guard, weil hier nicht nur geprüft, sondern auch der
|
||||
// Request angereichert wird.
|
||||
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")
|
||||
// Über failRequest: ohne JavaScript ist die Session-Abfrage sonst
|
||||
// eine JSON-Zeile mitten im Browser.
|
||||
failRequest(w, r, errAuthRequired)
|
||||
return
|
||||
}
|
||||
ctx := context.WithValue(r.Context(), uidKey, s.UID)
|
||||
|
||||
Reference in New Issue
Block a user