github.com/Axway/agent-sdk@v1.1.101/pkg/traceability/redaction/redaction_test.go (about) 1 package redaction 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 ) 11 12 var requestHeaders = map[string]string{ 13 "request": "value", 14 "x-amplify-something": "random", 15 "x-amplify-somethingelse": "else", 16 } 17 18 var responseHeaders = map[string]string{ 19 "response": "value", 20 "x-response": "random", 21 "x-value": "test", 22 } 23 24 var queryParams = map[string][]string{ 25 "param1": {"date"}, 26 "param2": {"day", "time"}, 27 } 28 29 var jmsProperties = map[string]string{ 30 "jmsMessageID": "messageid", 31 "jmsDestination": "queue://test-queue", 32 "jmsReplyTo": "queue://reply-queue", 33 } 34 35 func TestDefaultRedaction(t *testing.T) { 36 redactionCfg := DefaultConfig() 37 38 SetupGlobalRedaction(redactionCfg) 39 40 // URI redaction 41 redactedPath, err := URIRedaction("https://apicentral.axway.com/test/the/path/redaction") 42 assert.Nil(t, err) 43 assert.NotNil(t, redactedPath) 44 assert.Equal(t, "/{*}/{*}/{*}/{*}", redactedPath) 45 46 // Only send path to URI redaction 47 redactedPath, err = URIRedaction("/test/the/path/redaction") 48 assert.Nil(t, err) 49 assert.NotNil(t, redactedPath) 50 assert.Equal(t, "/{*}/{*}/{*}/{*}", redactedPath) 51 52 // Query args redaction 53 queryArgString := "" 54 for key, val := range queryParams { 55 if queryArgString != "" { 56 queryArgString += "&" 57 } 58 queryArgString += fmt.Sprintf("%s=%s", key, strings.Join(val, ",")) 59 } 60 redactedQueryParamsString, err := QueryArgsRedactionString(queryArgString) 61 assert.Nil(t, err) 62 assert.Empty(t, redactedQueryParamsString) 63 var redactedQueryParams map[string][]string 64 json.Unmarshal([]byte(redactedQueryParamsString), &redactedQueryParams) 65 assert.Len(t, redactedQueryParams, 0) 66 67 // Request Header redaction 68 redactedRequestHeaders, err := RequestHeadersRedaction(requestHeaders) 69 assert.Nil(t, err) 70 assert.NotNil(t, redactedRequestHeaders) 71 assert.Len(t, redactedRequestHeaders, 0) 72 73 // Response Header redaction 74 redactedResponseHeaders, err := ResponseHeadersRedaction(responseHeaders) 75 assert.Nil(t, err) 76 assert.NotNil(t, redactedResponseHeaders) 77 assert.Len(t, redactedResponseHeaders, 0) 78 79 // JMS Property redaction 80 redactedJMSProperties, err := JMSPropertiesRedaction(jmsProperties) 81 assert.Nil(t, err) 82 assert.NotNil(t, redactedJMSProperties) 83 assert.Len(t, redactedJMSProperties, 0) 84 } 85 86 func TestBadSetupRedaction(t *testing.T) { 87 testCases := []struct { 88 name string 89 config Config 90 }{ 91 { 92 name: "PathRegex", 93 config: Config{ 94 Path: Path{ 95 Allowed: []Show{ 96 { 97 KeyMatch: "*test", 98 }, 99 }, 100 }, 101 }, 102 }, 103 { 104 name: "QueryArgsAllowRegex", 105 config: Config{ 106 Args: Filter{ 107 Allowed: []Show{ 108 { 109 KeyMatch: "*test", 110 }, 111 }, 112 }, 113 }, 114 }, 115 { 116 name: "QueryArgsSanitizeRegex", 117 config: Config{ 118 Args: Filter{ 119 Sanitize: []Sanitize{ 120 { 121 KeyMatch: "test", 122 ValueMatch: "*test", 123 }, 124 }, 125 }, 126 }, 127 }, 128 { 129 name: "ResponseHeadersSanitizeRegex", 130 config: Config{ 131 ResponseHeaders: Filter{ 132 Sanitize: []Sanitize{ 133 { 134 KeyMatch: "*test", 135 ValueMatch: "*test", 136 }, 137 }, 138 }, 139 }, 140 }, 141 { 142 name: "ResponseHeadersRegex", 143 config: Config{ 144 ResponseHeaders: Filter{ 145 Allowed: []Show{ 146 { 147 KeyMatch: "*test", 148 }, 149 }, 150 }, 151 }, 152 }, 153 { 154 name: "RequesteHeadersSanitizeRegex", 155 config: Config{ 156 RequestHeaders: Filter{ 157 Sanitize: []Sanitize{ 158 { 159 KeyMatch: "*test", 160 ValueMatch: "*test", 161 }, 162 }, 163 }, 164 }, 165 }, 166 { 167 name: "RequestHeadersRegex", 168 config: Config{ 169 RequestHeaders: Filter{ 170 Allowed: []Show{ 171 { 172 KeyMatch: "*test", 173 }, 174 }, 175 }, 176 }, 177 }, 178 { 179 name: "JMSPropertiesSanitizeRegex", 180 config: Config{ 181 RequestHeaders: Filter{ 182 Sanitize: []Sanitize{ 183 { 184 KeyMatch: "*test", 185 ValueMatch: "*test", 186 }, 187 }, 188 }, 189 }, 190 }, 191 { 192 name: "JMSPropertiesRegex", 193 config: Config{ 194 RequestHeaders: Filter{ 195 Allowed: []Show{ 196 { 197 KeyMatch: "*test", 198 }, 199 }, 200 }, 201 }, 202 }, 203 } 204 205 for _, test := range testCases { 206 t.Run(test.name, func(t *testing.T) { 207 err := SetupGlobalRedaction(test.config) 208 assert.NotNil(t, err) 209 }) 210 } 211 212 } 213 214 func TestURIRedaction(t *testing.T) { 215 testCases := []struct { 216 name string 217 pathConfig []Show 218 input string 219 output string 220 maskingCharacters string 221 }{ 222 { 223 name: "SingleWord", 224 pathConfig: []Show{ 225 { 226 KeyMatch: "test", 227 }, 228 }, 229 input: "https://apicentral.axway.com/test/the/path/redaction", 230 output: "/test/{*}/{*}/{*}", 231 }, 232 { 233 name: "TwoWords", 234 pathConfig: []Show{ 235 { 236 KeyMatch: "test", 237 }, 238 { 239 KeyMatch: "redaction", 240 }, 241 }, 242 maskingCharacters: "{#}", 243 input: "https://apicentral.axway.com/test/the/path/redaction", 244 output: "/test/{#}/{#}/redaction", 245 }, 246 { 247 name: "Regex - invalid masking character", 248 pathConfig: []Show{ 249 { 250 KeyMatch: ".*th.*", 251 }, 252 }, 253 maskingCharacters: "{$}", // invalid masking character 254 input: "https://apicentral.axway.com/test/the/path/redaction", 255 output: "/{*}/the/path/{*}", 256 }, 257 { 258 name: "Regex - overriding masking character", 259 pathConfig: []Show{ 260 { 261 KeyMatch: ".*th.*", 262 }, 263 }, 264 maskingCharacters: "{^}", // invalid masking character 265 input: "https://apicentral.axway.com/test/the/path/redaction", 266 output: "/{^}/the/path/{^}", 267 }, 268 } 269 270 for _, test := range testCases { 271 t.Run(test.name, func(t *testing.T) { 272 defConfig := DefaultConfig() 273 defConfig.Path.Allowed = test.pathConfig // update to the test config 274 if test.maskingCharacters != "" { 275 defConfig.MaskingCharacters = test.maskingCharacters 276 } 277 278 err := SetupGlobalRedaction(defConfig) 279 assert.Nil(t, err) 280 281 // URI redaction 282 redactedPath, err := URIRedaction(test.input) 283 assert.Nil(t, err) 284 assert.NotNil(t, redactedPath) 285 assert.Equal(t, test.output, redactedPath) 286 }) 287 } 288 } 289 290 func TestQueryParamsRedaction(t *testing.T) { 291 testCases := []struct { 292 name string 293 qpConfig Filter 294 input map[string][]string 295 output map[string][]string 296 }{ 297 { 298 name: "SingleParam", 299 qpConfig: Filter{ 300 Allowed: []Show{ 301 { 302 KeyMatch: "param1", 303 }, 304 }, 305 }, 306 input: queryParams, 307 output: map[string][]string{ 308 "param1": {"date"}, 309 }, 310 }, 311 { 312 name: "TwoParas", 313 qpConfig: Filter{ 314 Allowed: []Show{ 315 { 316 KeyMatch: "param1", 317 }, 318 { 319 KeyMatch: "param2", 320 }, 321 }, 322 }, 323 input: queryParams, 324 output: map[string][]string{ 325 "param1": {"date"}, 326 "param2": {"day", "time"}, 327 }, 328 }, 329 { 330 name: "AllowRegex", 331 qpConfig: Filter{ 332 Allowed: []Show{ 333 { 334 KeyMatch: "param\\d", 335 }, 336 }, 337 }, 338 input: queryParams, 339 output: map[string][]string{ 340 "param1": {"date"}, 341 "param2": {"day", "time"}, 342 }, 343 }, 344 { 345 name: "Sanitize1", 346 qpConfig: Filter{ 347 Allowed: []Show{ 348 { 349 KeyMatch: "param1", 350 }, 351 { 352 KeyMatch: "param2", 353 }, 354 }, 355 Sanitize: []Sanitize{ 356 { 357 KeyMatch: "param2", 358 ValueMatch: "time", 359 }, 360 }, 361 }, 362 input: queryParams, 363 output: map[string][]string{ 364 "param1": {"date"}, 365 "param2": {"day", "{*}"}, 366 }, 367 }, 368 { 369 name: "SanitizeButNotAllowed", 370 qpConfig: Filter{ 371 Allowed: []Show{ 372 { 373 KeyMatch: "param1", 374 }, 375 }, 376 Sanitize: []Sanitize{ 377 { 378 KeyMatch: "param2", 379 ValueMatch: "time", 380 }, 381 }, 382 }, 383 input: queryParams, 384 output: map[string][]string{ 385 "param1": {"date"}, 386 }, 387 }, 388 } 389 390 for _, test := range testCases { 391 t.Run(test.name, func(t *testing.T) { 392 393 defConfig := DefaultConfig() 394 defConfig.Args = test.qpConfig // update to the test config 395 396 err := SetupGlobalRedaction(defConfig) 397 assert.Nil(t, err) 398 399 // QueryParams redaction 400 redactedQueryParams, err := QueryArgsRedaction(queryParams) 401 assert.Nil(t, err) 402 assert.NotNil(t, redactedQueryParams) 403 assert.Equal(t, test.output, redactedQueryParams) 404 }) 405 } 406 } 407 408 func TestHeadersRedaction(t *testing.T) { 409 testCases := []struct { 410 name string 411 responseConfig Filter 412 requestConfig Filter 413 inputResponse map[string]string 414 inputRequest map[string]string 415 outputResponse map[string]string 416 outputRequest map[string]string 417 }{ 418 { 419 name: "SingleParam", 420 responseConfig: Filter{ 421 Allowed: []Show{ 422 { 423 KeyMatch: "x-value", 424 }, 425 }, 426 }, 427 requestConfig: Filter{ 428 Allowed: []Show{ 429 { 430 KeyMatch: "request", 431 }, 432 }, 433 }, 434 inputResponse: responseHeaders, 435 inputRequest: requestHeaders, 436 outputResponse: map[string]string{ 437 "x-value": "test", 438 }, 439 outputRequest: map[string]string{ 440 "request": "value", 441 }, 442 }, 443 { 444 name: "TwoParams", 445 responseConfig: Filter{ 446 Allowed: []Show{ 447 { 448 KeyMatch: "x-value", 449 }, 450 { 451 KeyMatch: "x-response", 452 }, 453 }, 454 }, 455 requestConfig: Filter{ 456 Allowed: []Show{ 457 { 458 KeyMatch: "request", 459 }, 460 { 461 KeyMatch: "x-amplify-somethingelse", 462 }, 463 }, 464 }, 465 inputResponse: responseHeaders, 466 inputRequest: requestHeaders, 467 outputResponse: map[string]string{ 468 "x-value": "test", 469 "x-response": "random", 470 }, 471 outputRequest: map[string]string{ 472 "request": "value", 473 "x-amplify-somethingelse": "else", 474 }, 475 }, 476 { 477 name: "Regex", 478 responseConfig: Filter{ 479 Allowed: []Show{ 480 { 481 KeyMatch: "^.*response", 482 }, 483 }, 484 }, 485 requestConfig: Filter{ 486 Allowed: []Show{ 487 { 488 KeyMatch: "^x-amplify.*$", 489 }, 490 }, 491 }, 492 inputResponse: responseHeaders, 493 inputRequest: requestHeaders, 494 outputResponse: map[string]string{ 495 "response": "value", 496 "x-response": "random", 497 }, 498 outputRequest: map[string]string{ 499 "x-amplify-something": "random", 500 "x-amplify-somethingelse": "else", 501 }, 502 }, 503 { 504 name: "Sanitize", 505 responseConfig: Filter{ 506 Allowed: []Show{ 507 { 508 KeyMatch: "^x-.*", 509 }, 510 }, 511 Sanitize: []Sanitize{ 512 { 513 KeyMatch: "^x-value.*$", 514 ValueMatch: "^tes", 515 }, 516 }, 517 }, 518 requestConfig: Filter{ 519 Allowed: []Show{ 520 { 521 KeyMatch: "^x-amplify.*$", 522 }, 523 }, 524 Sanitize: []Sanitize{ 525 { 526 KeyMatch: "^x-amplify.*$", 527 ValueMatch: "^ran", 528 }, 529 }, 530 }, 531 inputResponse: responseHeaders, 532 inputRequest: requestHeaders, 533 outputResponse: map[string]string{ 534 "x-response": "random", 535 "x-value": "{*}t", 536 }, 537 outputRequest: map[string]string{ 538 "x-amplify-something": "{*}dom", 539 "x-amplify-somethingelse": "else", 540 }, 541 }, 542 { 543 name: "SanitizeNoShow", 544 responseConfig: Filter{ 545 Allowed: []Show{ 546 { 547 KeyMatch: "x-response", 548 }, 549 }, 550 Sanitize: []Sanitize{ 551 { 552 KeyMatch: "^x-value", 553 ValueMatch: "^tes", 554 }, 555 }, 556 }, 557 requestConfig: Filter{ 558 Allowed: []Show{ 559 { 560 KeyMatch: "^x-amplify-somethingelse", 561 }, 562 }, 563 Sanitize: []Sanitize{ 564 { 565 KeyMatch: "^x-amplify-something", 566 ValueMatch: "^ran", 567 }, 568 }, 569 }, 570 inputResponse: responseHeaders, 571 inputRequest: requestHeaders, 572 outputResponse: map[string]string{ 573 "x-response": "random", 574 }, 575 outputRequest: map[string]string{ 576 "x-amplify-somethingelse": "else", 577 }, 578 }, 579 } 580 581 for _, test := range testCases { 582 t.Run(test.name, func(t *testing.T) { 583 584 defConfig := DefaultConfig() 585 defConfig.RequestHeaders = test.requestConfig // update to the test config 586 defConfig.ResponseHeaders = test.responseConfig // update to the test config 587 588 err := SetupGlobalRedaction(defConfig) 589 assert.Nil(t, err) 590 591 // Request Header redaction 592 redactedRequestHeaders, err := RequestHeadersRedaction(test.inputRequest) 593 assert.Nil(t, err) 594 assert.NotNil(t, redactedRequestHeaders) 595 assert.Equal(t, test.outputRequest, redactedRequestHeaders) 596 597 // Response Header redaction 598 redactedResponseHeaders, err := ResponseHeadersRedaction(test.inputResponse) 599 assert.Nil(t, err) 600 assert.NotNil(t, redactedResponseHeaders) 601 assert.Equal(t, test.outputResponse, redactedResponseHeaders) 602 }) 603 } 604 }