internal: cleanup duplicate and redundant code, properly set sentry SDK scope settings
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
		| @ -60,6 +60,7 @@ type FlowExecutor struct { | ||||
|  | ||||
| func NewFlowExecutor(ctx context.Context, flowSlug string, refConfig *api.Configuration, logFields log.Fields) *FlowExecutor { | ||||
| 	rsp := sentry.StartSpan(ctx, "authentik.outposts.flow_executor") | ||||
| 	rsp.Description = flowSlug | ||||
|  | ||||
| 	l := log.WithField("flow", flowSlug).WithFields(logFields) | ||||
| 	jar, err := cookiejar.New(nil) | ||||
| @ -153,8 +154,8 @@ func (fe *FlowExecutor) solveFlowChallenge(depth int) (bool, error) { | ||||
| 	} | ||||
| 	ch := challenge.GetActualInstance().(ChallengeInt) | ||||
| 	fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got challenge") | ||||
| 	gcsp.SetTag("ak_challenge", string(ch.GetType())) | ||||
| 	gcsp.SetTag("ak_component", ch.GetComponent()) | ||||
| 	gcsp.SetTag("authentik.flow.challenge", string(ch.GetType())) | ||||
| 	gcsp.SetTag("authentik.flow.component", ch.GetComponent()) | ||||
| 	gcsp.Finish() | ||||
| 	FlowTimingGet.With(prometheus.Labels{ | ||||
| 		"stage":  ch.GetComponent(), | ||||
| @ -202,8 +203,8 @@ func (fe *FlowExecutor) solveFlowChallenge(depth int) (bool, error) { | ||||
| 	response, _, err := responseReq.Execute() | ||||
| 	ch = response.GetActualInstance().(ChallengeInt) | ||||
| 	fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got response") | ||||
| 	scsp.SetTag("ak_challenge", string(ch.GetType())) | ||||
| 	scsp.SetTag("ak_component", ch.GetComponent()) | ||||
| 	scsp.SetTag("authentik.flow.challenge", string(ch.GetType())) | ||||
| 	scsp.SetTag("authentik.flow.component", ch.GetComponent()) | ||||
| 	scsp.Finish() | ||||
|  | ||||
| 	switch ch.GetComponent() { | ||||
|  | ||||
| @ -23,9 +23,14 @@ type Request struct { | ||||
| func NewRequest(bindDN string, bindPW string, conn net.Conn) (*Request, *sentry.Span) { | ||||
| 	span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.bind", | ||||
| 		sentry.TransactionName("authentik.providers.ldap.bind")) | ||||
| 	span.Description = bindDN | ||||
| 	rid := uuid.New().String() | ||||
| 	span.SetTag("request_uid", rid) | ||||
| 	span.SetTag("user.username", bindDN) | ||||
| 	sentry.GetHubFromContext(span.Context()).Scope().SetUser(sentry.User{ | ||||
| 		Username:  bindDN, | ||||
| 		ID:        bindDN, | ||||
| 		IPAddress: utils.GetIP(conn.RemoteAddr()), | ||||
| 	}) | ||||
|  | ||||
| 	bindDN = strings.ToLower(bindDN) | ||||
| 	return &Request{ | ||||
|  | ||||
| @ -2,6 +2,7 @@ package search | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"strings" | ||||
|  | ||||
| @ -27,10 +28,15 @@ func NewRequest(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (*Re | ||||
| 	bindDN = strings.ToLower(bindDN) | ||||
| 	searchReq.BaseDN = strings.ToLower(searchReq.BaseDN) | ||||
| 	span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.search", sentry.TransactionName("authentik.providers.ldap.search")) | ||||
| 	span.Description = fmt.Sprintf("%s (%s)", searchReq.BaseDN, ldap.ScopeMap[searchReq.Scope]) | ||||
| 	span.SetTag("request_uid", rid) | ||||
| 	span.SetTag("user.username", bindDN) | ||||
| 	span.SetTag("ak_filter", searchReq.Filter) | ||||
| 	span.SetTag("ak_base_dn", searchReq.BaseDN) | ||||
| 	sentry.GetHubFromContext(span.Context()).Scope().SetUser(sentry.User{ | ||||
| 		Username:  bindDN, | ||||
| 		ID:        bindDN, | ||||
| 		IPAddress: utils.GetIP(conn.RemoteAddr()), | ||||
| 	}) | ||||
| 	span.SetTag("ldap_filter", searchReq.Filter) | ||||
| 	span.SetTag("ldap_base_dn", searchReq.BaseDN) | ||||
| 	return &Request{ | ||||
| 		SearchRequest: searchReq, | ||||
| 		BindDN:        bindDN, | ||||
|  | ||||
| @ -12,6 +12,8 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 	"github.com/getsentry/sentry-go" | ||||
| 	sentryhttp "github.com/getsentry/sentry-go/http" | ||||
| 	"github.com/gorilla/mux" | ||||
| 	"github.com/gorilla/sessions" | ||||
| 	"github.com/pkg/errors" | ||||
| @ -109,6 +111,11 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore | ||||
| 			user := "" | ||||
| 			if c != nil { | ||||
| 				user = c.PreferredUsername | ||||
| 				sentry.GetHubFromContext(r.Context()).Scope().SetUser(sentry.User{ | ||||
| 					Username:  user, | ||||
| 					ID:        c.Sub, | ||||
| 					IPAddress: r.RemoteAddr, | ||||
| 				}) | ||||
| 			} | ||||
| 			before := time.Now() | ||||
| 			inner.ServeHTTP(rw, r) | ||||
| @ -124,6 +131,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore | ||||
| 			}).Observe(float64(after)) | ||||
| 		}) | ||||
| 	}) | ||||
| 	mux.Use(sentryhttp.New(sentryhttp.Options{}).Handle) | ||||
|  | ||||
| 	// Support /start and /sign_in for backwards compatibility | ||||
| 	mux.HandleFunc("/akprox/start", a.handleRedirect) | ||||
|  | ||||
| @ -10,6 +10,7 @@ import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	sentryhttp "github.com/getsentry/sentry-go/http" | ||||
| 	"github.com/gorilla/mux" | ||||
| 	"github.com/pires/go-proxyproto" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| @ -52,6 +53,7 @@ func NewProxyServer(ac *ak.APIController, portOffset int) *ProxyServer { | ||||
|  | ||||
| 	globalMux := rootMux.NewRoute().Subrouter() | ||||
| 	globalMux.Use(web.NewLoggingHandler(l.WithField("logger", "authentik.outpost.proxyv2.http"), nil)) | ||||
| 	globalMux.Use(sentryhttp.New(sentryhttp.Options{}).Handle) | ||||
| 	s := &ProxyServer{ | ||||
| 		Listen:     "0.0.0.0:%d", | ||||
| 		PortOffset: portOffset, | ||||
|  | ||||
| @ -99,8 +99,8 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { | ||||
| 	h.handler.ServeHTTP(responseLogger, req) | ||||
| 	duration := float64(time.Since(t)) / float64(time.Millisecond) | ||||
| 	h.afterHandler(h.logger.WithFields(log.Fields{ | ||||
| 		"host":              req.RemoteAddr, | ||||
| 		"vhost":             GetHost(req), | ||||
| 		"remote":            req.RemoteAddr, | ||||
| 		"host":              GetHost(req), | ||||
| 		"request_protocol":  req.Proto, | ||||
| 		"runtime":           fmt.Sprintf("%0.3f", duration), | ||||
| 		"method":            req.Method, | ||||
|  | ||||
| @ -1,29 +0,0 @@ | ||||
| package web | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/getsentry/sentry-go" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| 	"goauthentik.io/internal/utils/web" | ||||
| ) | ||||
|  | ||||
| func loggingMiddleware(l *log.Entry) func(next http.Handler) http.Handler { | ||||
| 	return func(next http.Handler) http.Handler { | ||||
| 		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 			span := sentry.StartSpan(r.Context(), "authentik.go.request") | ||||
| 			before := time.Now() | ||||
| 			// Call the next handler, which can be another middleware in the chain, or the final handler. | ||||
| 			next.ServeHTTP(w, r) | ||||
| 			after := time.Now() | ||||
| 			l.WithFields(log.Fields{ | ||||
| 				"remote": r.RemoteAddr, | ||||
| 				"method": r.Method, | ||||
| 				"took":   after.Sub(before), | ||||
| 				"host":   web.GetHost(r), | ||||
| 			}).Info(r.RequestURI) | ||||
| 			span.Finish() | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -1,44 +0,0 @@ | ||||
| package web | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"net/http" | ||||
|  | ||||
| 	sentryhttp "github.com/getsentry/sentry-go/http" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
|  | ||||
| func recoveryMiddleware() func(next http.Handler) http.Handler { | ||||
| 	sentryHandler := sentryhttp.New(sentryhttp.Options{}) | ||||
| 	l := log.WithField("logger", "authentik.router.sentry") | ||||
| 	return func(next http.Handler) http.Handler { | ||||
| 		sentryHandler.Handle(next) | ||||
| 		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 			next.ServeHTTP(w, r) | ||||
| 			defer func() { | ||||
| 				re := recover() | ||||
| 				if re == nil { | ||||
| 					return | ||||
| 				} | ||||
| 				err := re.(error) | ||||
| 				if err != nil { | ||||
| 					l.WithError(err).Warning("global panic handler") | ||||
| 					jsonBody, _ := json.Marshal(struct { | ||||
| 						Successful bool | ||||
| 						Error      string | ||||
| 					}{ | ||||
| 						Successful: false, | ||||
| 						Error:      err.Error(), | ||||
| 					}) | ||||
|  | ||||
| 					w.Header().Set("Content-Type", "application/json") | ||||
| 					w.WriteHeader(http.StatusInternalServerError) | ||||
| 					_, err := w.Write(jsonBody) | ||||
| 					if err != nil { | ||||
| 						l.WithError(err).Warning("Failed to write sentry error body") | ||||
| 					} | ||||
| 				} | ||||
| 			}() | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -6,6 +6,7 @@ import ( | ||||
| 	"net" | ||||
| 	"net/http" | ||||
|  | ||||
| 	sentryhttp "github.com/getsentry/sentry-go/http" | ||||
| 	"github.com/gorilla/handlers" | ||||
| 	"github.com/gorilla/mux" | ||||
| 	"github.com/pires/go-proxyproto" | ||||
| @ -13,6 +14,7 @@ import ( | ||||
| 	"goauthentik.io/internal/config" | ||||
| 	"goauthentik.io/internal/gounicorn" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2" | ||||
| 	"goauthentik.io/internal/utils/web" | ||||
| ) | ||||
|  | ||||
| type WebServer struct { | ||||
| @ -34,13 +36,11 @@ type WebServer struct { | ||||
| func NewWebServer(g *gounicorn.GoUnicorn) *WebServer { | ||||
| 	l := log.WithField("logger", "authentik.router") | ||||
| 	mainHandler := mux.NewRouter() | ||||
| 	if config.G.ErrorReporting.Enabled { | ||||
| 		mainHandler.Use(recoveryMiddleware()) | ||||
| 	} | ||||
| 	mainHandler.Use(sentryhttp.New(sentryhttp.Options{}).Handle) | ||||
| 	mainHandler.Use(handlers.ProxyHeaders) | ||||
| 	mainHandler.Use(handlers.CompressHandler) | ||||
| 	logginRouter := mainHandler.NewRoute().Subrouter() | ||||
| 	logginRouter.Use(loggingMiddleware(l)) | ||||
| 	logginRouter.Use(web.NewLoggingHandler(l, nil)) | ||||
|  | ||||
| 	ws := &WebServer{ | ||||
| 		LegacyProxy: true, | ||||
| @ -72,7 +72,7 @@ func (ws *WebServer) Shutdown() { | ||||
| func (ws *WebServer) listenPlain() { | ||||
| 	ln, err := net.Listen("tcp", config.G.Web.Listen) | ||||
| 	if err != nil { | ||||
| 		ws.log.WithError(err).Fatalf("failed to listen") | ||||
| 		ws.log.WithError(err).Fatal("failed to listen") | ||||
| 	} | ||||
| 	ws.log.WithField("listen", config.G.Web.Listen).Info("Listening") | ||||
|  | ||||
| @ -83,7 +83,7 @@ func (ws *WebServer) listenPlain() { | ||||
|  | ||||
| 	err = http.ListenAndServe(config.G.Web.Listen, ws.m) | ||||
| 	if err != nil && !errors.Is(err, http.ErrServerClosed) { | ||||
| 		ws.log.Errorf("ERROR: http.Serve() - %s", err) | ||||
| 		ws.log.WithError(err).Error("failed to listen") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -100,14 +100,14 @@ func (ws *WebServer) serve(listener net.Listener) { | ||||
| 		// We received an interrupt signal, shut down. | ||||
| 		if err := srv.Shutdown(context.Background()); err != nil { | ||||
| 			// Error from closing listeners, or context timeout: | ||||
| 			ws.log.Printf("HTTP server Shutdown: %v", err) | ||||
| 			ws.log.WithError(err).Warning("HTTP server Shutdown") | ||||
| 		} | ||||
| 		close(idleConnsClosed) | ||||
| 	}() | ||||
|  | ||||
| 	err := srv.Serve(listener) | ||||
| 	if err != nil && !errors.Is(err, http.ErrServerClosed) { | ||||
| 		ws.log.Errorf("ERROR: http.Serve() - %s", err) | ||||
| 		ws.log.WithError(err).Error("ERROR: http.Serve()") | ||||
| 	} | ||||
| 	<-idleConnsClosed | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer