Viewing:
package serve
import (
"context"
"log/slog"
"net"
"net/http"
"strings"
"gopkg.awl.red/bizdex/db"
)
// TODO: fix
const specialLocal = "[::1]"
func mkMiddlewareSession(d *db.DB) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Session")
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
slog.Info("no session cookie", "err", err)
return
}
session, err := d.GetSession(cookie.Value, d.GetConfig())
if err != nil || session == nil {
w.WriteHeader(http.StatusUnauthorized)
slog.Info("error middleware session", "err", err)
return
}
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "auth", *session)))
})
}
}
func mkMiddlewareAllows(d *db.DB) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cfg := d.GetConfig()
lenPolicies := len(cfg.UsagePolicies)
slog.Info("policies", "count", lenPolicies, "plcystruct", cfg.UsagePolicies)
if lenPolicies == 0 {
next.ServeHTTP(w, r)
return
}
slog.Info(r.RemoteAddr)
lastCol := strings.LastIndex(r.RemoteAddr, ":")
remoteIp := r.RemoteAddr
if lastCol != -1 {
remoteIp = r.RemoteAddr[:lastCol]
}
parsedRemote := net.ParseIP(remoteIp)
isSpecialIp6Local := remoteIp == specialLocal
if parsedRemote == nil && !isSpecialIp6Local {
slog.Error("bad remote ip", "remote_ip", remoteIp)
return
}
for _, policy := range cfg.UsagePolicies {
if policy.ExtraType != "allow_blocks" {
continue
}
for extra := range strings.SplitSeq(policy.Extra, ",") {
if isSpecialIp6Local && extra == remoteIp {
next.ServeHTTP(w, r)
return
}
_, cidr, err := net.ParseCIDR(extra)
if err != nil {
slog.Error("bad allow block in usage limits config", "block", extra)
continue
}
if cidr.Contains(parsedRemote) {
slog.Info("allowed ip", "ip", remoteIp, "block", cidr.String())
next.ServeHTTP(w, r)
return
}
}
}
slog.Info("dropped", "ip", remoteIp)
w.WriteHeader(http.StatusTooManyRequests)
// TODO: its not that they can request later successfully
// its that the policy says never to serve the user
// see what convention is in this case
})
}
}
// func (m middlewares) Srv(next http.Handler) http.Handler {
// return http.HandlerFunc(func(w http.ResponseWriter, rOrig *http.Request) {
// func compose(mws ...func(next http.Handler) http.HandlerFunc) func(next http.Handler) {
// if len(mws) == 0 {
// panic("compose called with no handlers")
// }
// // if len(mws) == 1 {
// // return mws[0]
// // }
// var acc func(next http.Handler)
// for i, elt := range slices.Backward(mws) {
// if i == 0 {
// acc = elt
// }
// acc = elt(acc)
// }
// return acc
// }