-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathconfig_test.go
346 lines (292 loc) · 9.28 KB
/
config_test.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
// TestNewConfigLoader tests the creation of a new ConfigLoader instance.
package caddywaf
import (
"path/filepath"
"os"
"testing"
"time"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"go.uber.org/zap"
)
func TestNewConfigLoader(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
if cl.logger != logger {
t.Errorf("Expected logger to be set, got %v", cl.logger)
}
}
// TestParseMetricsEndpoint tests the parseMetricsEndpoint function.
func TestParseMetricsEndpoint(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
metrics_endpoint /metrics
`)
// Advance to the "metrics_endpoint" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err := cl.parseMetricsEndpoint(d, m)
if err != nil {
t.Fatalf("parseMetricsEndpoint failed: %v", err)
}
if m.MetricsEndpoint != "/metrics" {
t.Errorf("Expected metrics endpoint to be '/metrics', got '%s'", m.MetricsEndpoint)
}
}
// TestParseLogPath tests the parseLogPath function.
func TestParseLogPath(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
log_path /var/log/waf.log
`)
// Advance to the "log_path" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err := cl.parseLogPath(d, m)
if err != nil {
t.Fatalf("parseLogPath failed: %v", err)
}
if m.LogFilePath != "/var/log/waf.log" {
t.Errorf("Expected log path to be '/var/log/waf.log', got '%s'", m.LogFilePath)
}
}
// TestParseRateLimit tests the parseRateLimit function.
func TestParseRateLimit(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
rate_limit {
requests 100
window 10s
cleanup_interval 300s
paths /api /admin
match_all_paths true
}
`)
// Advance to the "rate_limit" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err := cl.parseRateLimit(d, m)
if err != nil {
t.Fatalf("parseRateLimit failed: %v", err)
}
if m.RateLimit.Requests != 100 {
t.Errorf("Expected requests to be 100, got %d", m.RateLimit.Requests)
}
if m.RateLimit.Window != 10*time.Second {
t.Errorf("Expected window to be 10s, got %v", m.RateLimit.Window)
}
if m.RateLimit.CleanupInterval != 300*time.Second {
t.Errorf("Expected cleanup interval to be 300s, got %v", m.RateLimit.CleanupInterval)
}
if len(m.RateLimit.Paths) != 2 || m.RateLimit.Paths[0] != "/api" || m.RateLimit.Paths[1] != "/admin" {
t.Errorf("Expected paths to be ['/api', '/admin'], got %v", m.RateLimit.Paths)
}
if !m.RateLimit.MatchAllPaths {
t.Errorf("Expected match_all_paths to be true, got %v", m.RateLimit.MatchAllPaths)
}
}
// TestParseRuleFile tests the parseRuleFile function.
func TestParseRuleFile(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
rule_file /etc/waf/rules.txt
`)
// Advance to the "rule_file" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err := cl.parseRuleFile(d, m)
if err != nil {
t.Fatalf("parseRuleFile failed: %v", err)
}
if len(m.RuleFiles) != 1 || m.RuleFiles[0] != "/etc/waf/rules.txt" {
t.Errorf("Expected rule file to be ['/etc/waf/rules.txt'], got %v", m.RuleFiles)
}
}
// TestParseCustomResponse tests the parseCustomResponse function.
func TestParseCustomResponse(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
// Create a temporary file for testing
tmpFile, err := os.CreateTemp("", "test-custom-response-*.txt")
if err != nil {
t.Fatalf("Failed to create temporary file: %v", err)
}
defer os.Remove(tmpFile.Name())
// Write test content to the file
testContent := `{"error":"Forbidden"}`
if _, err := tmpFile.WriteString(testContent); err != nil {
t.Fatalf("Failed to write to temporary file: %v", err)
}
tmpFile.Close()
d := caddyfile.NewTestDispenser(`
custom_response 403 "application/json" ` + tmpFile.Name() + `
`)
// Advance to the "custom_response" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err = cl.parseCustomResponse(d, m)
if err != nil {
t.Fatalf("parseCustomResponse failed: %v", err)
}
response, ok := m.CustomResponses[403]
if !ok {
t.Fatalf("Expected custom response for status code 403, got none")
}
if response.Headers["Content-Type"] != "application/json" {
t.Errorf("Expected content type to be 'application/json', got '%s'", response.Headers["Content-Type"])
}
if response.Body != testContent {
t.Errorf("Expected body to be '%s', got '%s'", testContent, response.Body)
}
}
// TestParseCountryBlock tests the parseCountryBlock function.
func TestParseCountryBlock(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
block_countries /etc/geoip/GeoIP.dat US CA
`)
// Advance to the "block_countries" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
handler := cl.parseCountryBlockDirective(true) // Get the directive handler
err := handler(d, m) // Execute the handler
if err != nil {
t.Fatalf("parseCountryBlockDirective failed: %v", err)
}
if !m.CountryBlock.Enabled {
t.Errorf("Expected country block to be enabled, got %v", m.CountryBlock.Enabled)
}
if m.CountryBlock.GeoIPDBPath != "/etc/geoip/GeoIP.dat" {
t.Errorf("Expected GeoIP DB path to be '/etc/geoip/GeoIP.dat', got '%s'", m.CountryBlock.GeoIPDBPath)
}
if len(m.CountryBlock.CountryList) != 2 || m.CountryBlock.CountryList[0] != "US" || m.CountryBlock.CountryList[1] != "CA" {
t.Errorf("Expected country list to be ['US', 'CA'], got %v", m.CountryBlock.CountryList)
}
}
// TestParseLogSeverity tests the parseLogSeverity function.
func TestParseLogSeverity(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
log_severity debug
`)
// Advance to the "log_severity" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err := cl.parseLogSeverity(d, m)
if err != nil {
t.Fatalf("parseLogSeverity failed: %v", err)
}
if m.LogSeverity != "debug" {
t.Errorf("Expected log severity to be 'debug', got '%s'", m.LogSeverity)
}
}
// TestParseBlacklistFile tests the parseBlacklistFile function.
func TestParseBlacklistFile(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
// Create a temporary directory for testing
tmpDir := t.TempDir()
tmpFile := filepath.Join(tmpDir, "ip_blacklist.txt")
d := caddyfile.NewTestDispenser(`
ip_blacklist_file ` + tmpFile + `
`)
// Advance to the "ip_blacklist_file" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
handler := cl.parseBlacklistFileDirective(true) // Get the directive handler for IP blacklist
err := handler(d, m) // Execute the handler
if err != nil {
t.Fatalf("parseBlacklistFileDirective failed: %v", err)
}
if m.IPBlacklistFile != tmpFile {
t.Errorf("Expected IP blacklist file to be '%s', got '%s'", tmpFile, m.IPBlacklistFile)
}
// Test dns_blacklist_file
tmpDNSFile := filepath.Join(tmpDir, "dns_blacklist.txt")
d = caddyfile.NewTestDispenser(`
dns_blacklist_file ` + tmpDNSFile + `
`)
if !d.Next() {
t.Fatal("Failed to advance to the dns_blacklist_file directive")
}
handler = cl.parseBlacklistFileDirective(false) // Get handler for DNS blacklist
err = handler(d, m)
if err != nil {
t.Fatalf("parseBlacklistFileDirective for dns failed: %v", err)
}
if m.DNSBlacklistFile != tmpDNSFile {
t.Errorf("Expected DNS blacklist file to be '%s', got '%s'", tmpDNSFile, m.DNSBlacklistFile)
}
}
// TestParseAnomalyThreshold tests the parseAnomalyThreshold function.
func TestParseAnomalyThreshold(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
anomaly_threshold 10
`)
// Advance to the "anomaly_threshold" directive
if !d.Next() {
t.Fatal("Failed to advance to the first directive")
}
err := cl.parseAnomalyThreshold(d, m)
if err != nil {
t.Fatalf("parseAnomalyThreshold failed: %v", err)
}
if m.AnomalyThreshold != 10 {
t.Errorf("Expected anomaly threshold to be 10, got %d", m.AnomalyThreshold)
}
}
func TestUnmarshalCaddyfile_InvalidRequests(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
rate_limit {
requests invalid
window 10s
}
rule_file /etc/waf/rules.txt
`)
err := cl.UnmarshalCaddyfile(d, m)
if err == nil {
t.Fatal("Expected error for invalid requests value, got nil")
}
}
func TestUnmarshalCaddyfile_MissingRuleFile(t *testing.T) {
logger := zap.NewNop()
cl := NewConfigLoader(logger)
m := &Middleware{}
d := caddyfile.NewTestDispenser(`
rate_limit {
requests 100
window 10s
}
`)
err := cl.UnmarshalCaddyfile(d, m)
if err == nil {
t.Fatal("Expected error for missing rule_file directive, got nil")
}
}