package panelui import ( "context" "net" "net/http" ) type ctxKey int const ( keyUser = iota ) //HeaderAuth is a Negroni-compatible Middleware type HeaderAuth struct { AllowedNames []string AllowedIPs []net.IP RequireUser bool } func _getSourceIP(req *http.Request) (net.IP, error) { ip, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { return net.IP{}, err } userIP := net.ParseIP(ip) if userIP == nil { return net.IP{}, err } return userIP, nil } func (ha HeaderAuth) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { srcIP, err := _getSourceIP(r) if err != nil { rw.WriteHeader(501) return } found := false if len(ha.AllowedNames) == 0 && len(ha.AllowedIPs) == 0 { found = true } if !found && len(ha.AllowedIPs) > 0 { for _, allowedIP := range ha.AllowedIPs { if allowedIP.Equal(srcIP) { found = true break } } } if !found && len(ha.AllowedNames) > 0 { for _, name := range ha.AllowedNames { nameips, err := net.LookupIP(name) if err != nil { continue } for _, allowedIP := range nameips { if allowedIP.Equal(srcIP) { found = true break } } } } user := r.Header.Get("X-Forwarded-User") if !found || (ha.RequireUser && user == "") { rw.WriteHeader(http.StatusUnauthorized) return } ctx := r.Context() ctx = context.WithValue(ctx, keyUser, user) next(rw, r.WithContext(ctx)) return }