@@ -9,17 +9,17 @@ const (
99 tagName = "redact"
1010)
1111
12- type sanitizer func (string ) string
12+ type redactor func (string ) string
1313
14- var sanitizers = map [string ]sanitizer {}
14+ var redactors = map [string ]redactor {}
1515
16- // AddSanitizer associates a sanitizer with a key, which can be used in a Struct tag
17- func AddSanitizer (key string , s sanitizer ) {
18- sanitizers [key ] = s
16+ // AddRedactor allows for adding custom functionality based on tag values
17+ func AddRedactor (key string , r redactor ) {
18+ redactors [key ] = r
1919}
2020
21- // Strings conforms strings based on reflection tags
22- func Strings (iface interface {}) error {
21+ // Redact redacts all strings without the nonsecret tag
22+ func Redact (iface interface {}) error {
2323 ifv := reflect .ValueOf (iface )
2424 if ifv .Kind () != reflect .Ptr {
2525 return errors .New ("Not a pointer" )
@@ -40,9 +40,9 @@ func Strings(iface interface{}) error {
4040 str := ""
4141 if (elType .ConvertibleTo (reflect .TypeOf (str )) && reflect .TypeOf (str ).ConvertibleTo (elType )) ||
4242 (elType .ConvertibleTo (reflect .TypeOf (& str )) && reflect .TypeOf (& str ).ConvertibleTo (elType )) {
43- tags := v .Tag .Get (tagName )
43+ tagVal := v .Tag .Get (tagName )
4444 for i := 0 ; i < el .Len (); i ++ {
45- el .Index (i ).Set (transformValue (tags , el .Index (i )))
45+ el .Index (i ).Set (transformValue (tagVal , el .Index (i )))
4646 }
4747 } else {
4848 val := reflect .ValueOf (el .Interface ())
@@ -51,7 +51,7 @@ func Strings(iface interface{}) error {
5151 if elVal .Kind () != reflect .Ptr {
5252 elVal = elVal .Addr ()
5353 }
54- Strings (elVal .Interface ())
54+ Redact (elVal .Interface ())
5555 }
5656 }
5757 }
@@ -63,27 +63,20 @@ func Strings(iface interface{}) error {
6363 mapValuePtr := reflect .New (mapValue .Type ())
6464 mapValuePtr .Elem ().Set (mapValue )
6565 if mapValuePtr .Elem ().CanAddr () {
66- Strings (mapValuePtr .Elem ().Addr ().Interface ())
66+ Redact (mapValuePtr .Elem ().Addr ().Interface ())
6767 }
6868 val .SetMapIndex (key , reflect .Indirect (mapValuePtr ))
6969 }
7070 }
7171 case reflect .Struct :
7272 if el .CanAddr () && el .Addr ().CanInterface () {
73- // To handle "sql.NullString" we can assume that tags are added to a field of type struct rather than string
74- if tags := v .Tag .Get (tagName ); tags != "" && el .CanSet () {
75- field := el .FieldByName ("String" )
76- str := field .String ()
77- field .SetString (transformString (str , tags ))
78- } else {
79- Strings (el .Addr ().Interface ())
80- }
73+ Redact (el .Addr ().Interface ())
8174 }
8275 case reflect .String :
8376 if el .CanSet () {
84- tags := v .Tag .Get (tagName )
77+ tagVal := v .Tag .Get (tagName )
8578 input := el .String ()
86- el .SetString (transformString (input , tags ))
79+ el .SetString (transformString (input , tagVal ))
8780 }
8881 }
8982 }
@@ -130,11 +123,11 @@ func transformString(input, tagVal string) string {
130123 case "nonsecret" :
131124 return input
132125 default :
133- s , ok := sanitizers [tagVal ]
126+ redactor , ok := redactors [tagVal ]
134127 if ! ok {
135128 return "REDACTED"
136129 }
137130
138- return s (input )
131+ return redactor (input )
139132 }
140133}
0 commit comments