-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathparam_logger.go
133 lines (110 loc) · 2.83 KB
/
param_logger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package paramlogger
import (
"encoding/json"
"mime/multipart"
"net/url"
"strings"
"github.com/gobuffalo/buffalo"
"github.com/pkg/errors"
)
// ParameterExclusionList is the list of parameter names that will be filtered
// from the application logs (see maskSecrets).
// Important: this list will be used in case insensitive.
var ParameterExclusionList = []string{
"Password",
"PasswordConfirmation",
"CreditCard",
"CVC",
}
var filteredIndicator = []string{"[FILTERED]"}
// ParameterLogger logs form and parameter values to the logger
type parameterLogger struct {
excluded []string
}
// ParameterLogger logs form and parameter values to the loggers
func ParameterLogger(next buffalo.Handler) buffalo.Handler {
pl := parameterLogger{
excluded: ParameterExclusionList,
}
return pl.Middleware(next)
}
// Middleware is a buffalo middleware function to connect this parameter filterer with buffalo
func (pl parameterLogger) Middleware(next buffalo.Handler) buffalo.Handler {
return func(c buffalo.Context) error {
defer func() {
req := c.Request()
if req.Method != "GET" {
if err := pl.logForm(c); err != nil {
c.Logger().Error(err)
}
}
params, ok := c.Params().(url.Values)
if ok {
params = pl.maskSecrets(params)
}
b, err := json.Marshal(params)
if err != nil {
c.Logger().Error(err)
}
c.LogField("params", string(b))
}()
return next(c)
}
}
func (pl parameterLogger) logForm(c buffalo.Context) error {
req := c.Request()
mp := req.MultipartForm
if mp != nil {
return pl.multipartParamLogger(mp, c)
}
if err := pl.addFormFieldTo(c, req.Form); err != nil {
return errors.WithStack(err)
}
return nil
}
func (pl parameterLogger) multipartParamLogger(mp *multipart.Form, c buffalo.Context) error {
uv := url.Values{}
for k, v := range mp.Value {
for _, vv := range v {
uv.Add(k, vv)
}
}
for k, v := range mp.File {
for _, vv := range v {
uv.Add(k, vv.Filename)
}
}
if err := pl.addFormFieldTo(c, uv); err != nil {
return errors.WithStack(err)
}
return nil
}
func (pl parameterLogger) addFormFieldTo(c buffalo.Context, form url.Values) error {
maskedForm := pl.maskSecrets(form)
b, err := json.Marshal(maskedForm)
if err != nil {
return err
}
c.LogField("form", string(b))
return nil
}
// maskSecrets matches ParameterExclusionList against parameters passed in the
// request, and returns a copy of the request parameters replacing excluded params
// with [FILTERED].
func (pl parameterLogger) maskSecrets(form url.Values) url.Values {
if len(pl.excluded) == 0 {
pl.excluded = ParameterExclusionList
}
copy := url.Values{}
for key, values := range form {
blcheck:
for _, excluded := range pl.excluded {
copy[key] = values
if strings.ToUpper(key) == strings.ToUpper(excluded) {
copy[key] = filteredIndicator
break blcheck
}
}
}
return copy
}