-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgosecretfields_test.go
More file actions
154 lines (130 loc) · 4.01 KB
/
gosecretfields_test.go
File metadata and controls
154 lines (130 loc) · 4.01 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package gosecretfields
import (
"encoding/json"
"fmt"
"reflect"
"strings"
"testing"
)
func TestAsSecret(t *testing.T) {
type args struct {
value string
redactedValue []string
}
tests := []struct {
name string
args args
want Secret[string]
}{
{
name: "With default redacted value",
args: args{
value: "Hiro Protagonist",
redactedValue: []string{},
},
want: Secret[string]{SecretValue: "Hiro Protagonist", redactedValue: "", Settings: DefaultSettings()},
},
{
name: "With explicit redacted value",
args: args{
value: "Hiro Protagonist",
redactedValue: []string{"REDACTED"},
},
want: Secret[string]{SecretValue: "Hiro Protagonist", redactedValue: "REDACTED", Settings: DefaultSettings()},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := AsSecret(tt.args.value, tt.args.redactedValue...); !reflect.DeepEqual(got, tt.want) {
t.Errorf("AsSecret() = %v, want %v", got, tt.want)
}
})
}
}
type character struct {
Name Secret[string]
Age Secret[int]
Friend *character
}
type testCase struct {
name string
value character
redactJson bool
}
var sampleCharacterHiro = character{
Name: AsSecret("Hiro Protagonist"),
Age: AsSecret(30),
}
var sampleCharacterYT = character{
Name: AsSecret("YT"),
Age: AsSecret(15),
}
func containsSecrets(text string) bool {
return strings.Contains(text, sampleCharacterHiro.Name.SecretValue) ||
strings.Contains(text, fmt.Sprint(sampleCharacterHiro.Age.SecretValue)) ||
strings.Contains(text, sampleCharacterYT.Name.SecretValue) ||
strings.Contains(text, fmt.Sprint(sampleCharacterYT.Age.SecretValue))
}
func TestMarshallingAndStringer(t *testing.T) {
commonSettings := &MutableSettings{
EnabledClearTextJSON: true,
}
sampleCharacterHiro.Age.Settings = commonSettings
sampleCharacterHiro.Name.Settings = commonSettings
sampleCharacterYT.Age.Settings = commonSettings
sampleCharacterYT.Name.Settings = commonSettings
hiroWithFriend := sampleCharacterHiro
hiroWithFriend.Friend = &sampleCharacterYT
tests := []testCase{
{
name: "Redacting JSON",
value: sampleCharacterHiro,
redactJson: true,
},
{
name: "NOT Redacting JSON",
value: sampleCharacterHiro,
redactJson: false,
},
{
name: "Redacting JSON with references",
value: hiroWithFriend,
redactJson: true,
},
{
name: "NOT Redacting JSON with references",
value: hiroWithFriend,
redactJson: false,
},
}
for _, testCase := range tests {
t.Run(testCase.name, func(t *testing.T) {
if asString := fmt.Sprint(testCase.value); containsSecrets(asString) {
t.Errorf("Stringer interface implementation must prevent secrets from leaking:\n%s", asString)
}
commonSettings.EnabledClearTextJSON = !testCase.redactJson
var unmarshalled character
marshalled, _ := json.Marshal(testCase.value)
marshalledString := string(marshalled)
if testCase.redactJson && containsSecrets(marshalledString) {
t.Error("Marshalled JSON can't contain secret values when JSON redaction is enabled")
}
unmarshallingError := json.Unmarshal(marshalled, &unmarshalled)
if unmarshallingError != nil {
t.Errorf("Unmarshalling should not fail. Error: %s", unmarshallingError)
}
unmarshalled.Name.Settings = commonSettings
unmarshalled.Age.Settings = commonSettings
if maybeUnmarshalledFriend := unmarshalled.Friend; maybeUnmarshalledFriend != nil {
maybeUnmarshalledFriend.Name.Settings = commonSettings
maybeUnmarshalledFriend.Age.Settings = commonSettings
}
if !testCase.redactJson && !reflect.DeepEqual(unmarshalled, testCase.value) {
t.Errorf("Unmarshalled value doesn't match the value that generated the JSON\nUnmarshalled value:\n%v\nValue:\n%v", unmarshalled, testCase.value)
}
if testCase.redactJson && reflect.DeepEqual(unmarshalled, testCase.value) {
t.Errorf("It should not be possible to unmarshall the same value from secrets-hidden JSONs\n%s", marshalledString)
}
})
}
}