Pass down SignedUserName down to AccessLogger context (#16605)

* Pass down SignedUserName down to AccessLogger context

Unfortunately when the AccessLogger was moved back before the contexters the
SignedUserName reporting was lost. This is due to Request.WithContext leading to a
shallow copy of the Request and the modules/context/Context being within that request.

This PR adds a new context variable of a string pointer which is set and handled
in the contexters.

Fix #16600

Signed-off-by: Andrew Thornton <art27@cantab.net>

* handle nil ptr issue

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
zeripath 2021-08-04 18:26:30 +01:00 committed by GitHub
parent f03abe8fb1
commit 7c4172ef71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 4 deletions

View file

@ -6,6 +6,7 @@ package context
import ( import (
"bytes" "bytes"
"context"
"html/template" "html/template"
"net/http" "net/http"
"time" "time"
@ -22,6 +23,8 @@ type routerLoggerOptions struct {
Ctx map[string]interface{} Ctx map[string]interface{}
} }
var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey"
// AccessLogger returns a middleware to log access logger // AccessLogger returns a middleware to log access logger
func AccessLogger() func(http.Handler) http.Handler { func AccessLogger() func(http.Handler) http.Handler {
logger := log.GetLogger("access") logger := log.GetLogger("access")
@ -29,11 +32,10 @@ func AccessLogger() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
start := time.Now() start := time.Now()
next.ServeHTTP(w, req)
identity := "-" identity := "-"
if val := SignedUserName(req); val != "" { r := req.WithContext(context.WithValue(req.Context(), signedUserNameStringPointerKey, &identity))
identity = val
} next.ServeHTTP(w, r)
rw := w.(ResponseWriter) rw := w.(ResponseWriter)
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})

View file

@ -275,6 +275,17 @@ func APIContexter() func(http.Handler) http.Handler {
ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken()) ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken())
next.ServeHTTP(ctx.Resp, ctx.Req) next.ServeHTTP(ctx.Resp, ctx.Req)
// Handle adding signedUserName to the context for the AccessLogger
usernameInterface := ctx.Data["SignedUserName"]
identityPtrInterface := ctx.Req.Context().Value(signedUserNameStringPointerKey)
if usernameInterface != nil && identityPtrInterface != nil {
username := usernameInterface.(string)
identityPtr := identityPtrInterface.(*string)
if identityPtr != nil && username != "" {
*identityPtr = username
}
}
}) })
} }
} }

View file

@ -770,6 +770,17 @@ func Contexter() func(next http.Handler) http.Handler {
} }
next.ServeHTTP(ctx.Resp, ctx.Req) next.ServeHTTP(ctx.Resp, ctx.Req)
// Handle adding signedUserName to the context for the AccessLogger
usernameInterface := ctx.Data["SignedUserName"]
identityPtrInterface := ctx.Req.Context().Value(signedUserNameStringPointerKey)
if usernameInterface != nil && identityPtrInterface != nil {
username := usernameInterface.(string)
identityPtr := identityPtrInterface.(*string)
if identityPtr != nil && username != "" {
*identityPtr = username
}
}
}) })
} }
} }