54 lines
1.4 KiB
Go
54 lines
1.4 KiB
Go
package synthetic
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const (
|
|
requestBodyKey = "bell.synthetic.request-body"
|
|
requestBodyErrorKey = "bell.synthetic.request-body-error"
|
|
)
|
|
|
|
var redactedRequestBody = []byte(`{"redacted":true}`)
|
|
|
|
// RedactRequestBody runs before GoAdmin's operation logger. It keeps the real
|
|
// body only in the request context for the handler and exposes a fixed marker
|
|
// to the generic audit middleware so event payloads never enter sys_opera_log.
|
|
func RedactRequestBody() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
if c.Request.Method != http.MethodPost || c.Request.URL.Path != "/api/v1/bell/synthetic-events" {
|
|
c.Next()
|
|
return
|
|
}
|
|
body, err := io.ReadAll(io.LimitReader(c.Request.Body, maxRequestBytes+1))
|
|
if err != nil {
|
|
c.Set(requestBodyErrorKey, err)
|
|
} else if len(body) > maxRequestBytes {
|
|
c.Set(requestBodyErrorKey, errors.New("request body too large"))
|
|
} else {
|
|
c.Set(requestBodyKey, body)
|
|
}
|
|
_ = c.Request.Body.Close()
|
|
c.Request.Body = io.NopCloser(bytes.NewReader(redactedRequestBody))
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func restoreRequestBody(c *gin.Context) error {
|
|
if value, ok := c.Get(requestBodyErrorKey); ok {
|
|
return value.(error)
|
|
}
|
|
value, ok := c.Get(requestBodyKey)
|
|
if !ok {
|
|
return errors.New("synthetic request body was not captured")
|
|
}
|
|
body := value.([]byte)
|
|
c.Request.Body = io.NopCloser(bytes.NewReader(body))
|
|
return nil
|
|
}
|