|
21 | 21 | import java.util.List; |
22 | 22 | import java.util.Properties; |
23 | 23 | import java.util.Set; |
| 24 | + |
24 | 25 | import javax.mail.MessagingException; |
25 | 26 |
|
26 | 27 | import static org.hamcrest.Matchers.containsInAnyOrder; |
@@ -68,6 +69,31 @@ public void testSend() throws Exception { |
68 | 69 | assertThat(sent.account(), is("account1")); |
69 | 70 | } |
70 | 71 |
|
| 72 | + public void testDomainAndRecipientAllowCantBeSetAtSameTime() { |
| 73 | + Settings settings = Settings.builder() |
| 74 | + .putList("xpack.notification.email.account.domain_allowlist", "bar.com") |
| 75 | + . putList( "xpack.notification.email.recipient_allowlist", "*[email protected]") |
| 76 | + .build(); |
| 77 | + |
| 78 | + IllegalArgumentException e = expectThrows( |
| 79 | + IllegalArgumentException.class, |
| 80 | + () -> new EmailService( |
| 81 | + settings, |
| 82 | + null, |
| 83 | + mock(SSLService.class), |
| 84 | + new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())) |
| 85 | + ) |
| 86 | + ); |
| 87 | + |
| 88 | + assertThat( |
| 89 | + e.getMessage(), |
| 90 | + containsString( |
| 91 | + "Cannot set both [xpack.notification.email.recipient_allowlist] and " |
| 92 | + + "[xpack.notification.email.account.domain_allowlist] to a non [\"*\"] value at the same time." |
| 93 | + ) |
| 94 | + ); |
| 95 | + } |
| 96 | + |
71 | 97 | public void testAccountSmtpPropertyConfiguration() { |
72 | 98 | Settings settings = Settings.builder() |
73 | 99 | .put("xpack.notification.email.account.account1.smtp.host", "localhost") |
@@ -321,6 +347,264 @@ public void testChangeDomainAllowListSetting() throws UnsupportedEncodingExcepti |
321 | 347 | assertThat(e2.getMessage(), containsString("port out of range")); |
322 | 348 | } |
323 | 349 |
|
| 350 | + public void testRecipientAddressInAllowList_EmptyAllowedPatterns() throws UnsupportedEncodingException { |
| 351 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 352 | + Set<String> allowedPatterns = Set.of(); |
| 353 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(false)); |
| 354 | + } |
| 355 | + |
| 356 | + public void testRecipientAddressInAllowList_WildcardPattern() throws UnsupportedEncodingException { |
| 357 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 358 | + Set<String> allowedPatterns = Set.of("*"); |
| 359 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(true)); |
| 360 | + } |
| 361 | + |
| 362 | + public void testRecipientAddressInAllowList_SpecificPattern() throws UnsupportedEncodingException { |
| 363 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 364 | + Set< String> allowedPatterns = Set. of( "[email protected]"); |
| 365 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(false)); |
| 366 | + } |
| 367 | + |
| 368 | + public void testRecipientAddressInAllowList_MultiplePatterns() throws UnsupportedEncodingException { |
| 369 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 370 | + Set< String> allowedPatterns = Set. of( "[email protected]", "[email protected]"); |
| 371 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(true)); |
| 372 | + } |
| 373 | + |
| 374 | + public void testRecipientAddressInAllowList_MixedCasePatterns() throws UnsupportedEncodingException { |
| 375 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 376 | + Set< String> allowedPatterns = Set. of( "[email protected]", "[email protected]"); |
| 377 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(true)); |
| 378 | + } |
| 379 | + |
| 380 | + public void testRecipientAddressInAllowList_PartialWildcardPrefixPattern() throws UnsupportedEncodingException { |
| 381 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 382 | + Set<String> allowedPatterns = Set.of("foo@*", "baz@*"); |
| 383 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(true)); |
| 384 | + } |
| 385 | + |
| 386 | + public void testRecipientAddressInAllowList_PartialWildcardSuffixPattern() throws UnsupportedEncodingException { |
| 387 | + Email email = createTestEmail( "[email protected]", "[email protected]"); |
| 388 | + Set<String> allowedPatterns = Set.of("*@bar.com", "*@potato.com"); |
| 389 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(true)); |
| 390 | + } |
| 391 | + |
| 392 | + public void testRecipientAddressInAllowList_DisallowedCCAddressesFails() throws UnsupportedEncodingException { |
| 393 | + Email email = new Email( |
| 394 | + "id", |
| 395 | + new Email. Address( "[email protected]", "Sender"), |
| 396 | + createAddressList( "[email protected]"), |
| 397 | + randomFrom(Email.Priority.values()), |
| 398 | + ZonedDateTime.now(), |
| 399 | + createAddressList( "[email protected]"), |
| 400 | + |
| 401 | + null, |
| 402 | + "subject", |
| 403 | + "body", |
| 404 | + "htmlbody", |
| 405 | + Collections.emptyMap() |
| 406 | + ); |
| 407 | + Set< String> allowedPatterns = Set. of( "[email protected]", "[email protected]"); |
| 408 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(false)); |
| 409 | + } |
| 410 | + |
| 411 | + public void testRecipientAddressInAllowList_DisallowedBCCAddressesFails() throws UnsupportedEncodingException { |
| 412 | + Email email = new Email( |
| 413 | + "id", |
| 414 | + new Email. Address( "[email protected]", "Sender"), |
| 415 | + createAddressList( "[email protected]"), |
| 416 | + randomFrom(Email.Priority.values()), |
| 417 | + ZonedDateTime.now(), |
| 418 | + createAddressList( "[email protected]"), |
| 419 | + null, |
| 420 | + |
| 421 | + "subject", |
| 422 | + "body", |
| 423 | + "htmlbody", |
| 424 | + Collections.emptyMap() |
| 425 | + ); |
| 426 | + Set< String> allowedPatterns = Set. of( "[email protected]", "[email protected]"); |
| 427 | + assertThat(EmailService.recipientAddressInAllowList(email, allowedPatterns), is(false)); |
| 428 | + } |
| 429 | + |
| 430 | + public void testAllowedRecipient() throws Exception { |
| 431 | + Email email = new Email( |
| 432 | + "id", |
| 433 | + new Email. Address( "[email protected]", "Mr. Foo Man"), |
| 434 | + |
| 435 | + randomFrom(Email.Priority.values()), |
| 436 | + ZonedDateTime.now(), |
| 437 | + createAddressList( "[email protected]"), |
| 438 | + null, |
| 439 | + null, |
| 440 | + "subject", |
| 441 | + "body", |
| 442 | + "htmlbody", |
| 443 | + Collections.emptyMap() |
| 444 | + ); |
| 445 | + assertTrue(EmailService.recipientAddressInAllowList(email, Set.of("*"))); |
| 446 | + assertFalse(EmailService.recipientAddressInAllowList(email, Set.of())); |
| 447 | + assertFalse(EmailService.recipientAddressInAllowList(email, Set.of(""))); |
| 448 | + assertTrue( EmailService. recipientAddressInAllowList( email, Set. of( "[email protected]", "*[email protected]"))); |
| 449 | + assertTrue( EmailService. recipientAddressInAllowList( email, Set. of( "[email protected]", "*.com"))); |
| 450 | + assertTrue(EmailService.recipientAddressInAllowList(email, Set.of("*.CoM"))); |
| 451 | + |
| 452 | + // Invalid email in CC doesn't blow up |
| 453 | + email = new Email( |
| 454 | + "id", |
| 455 | + new Email. Address( "[email protected]", "Mr. Foo Man"), |
| 456 | + |
| 457 | + randomFrom(Email.Priority.values()), |
| 458 | + ZonedDateTime.now(), |
| 459 | + createAddressList( "[email protected]"), |
| 460 | + createAddressList("badEmail"), |
| 461 | + null, |
| 462 | + "subject", |
| 463 | + "body", |
| 464 | + "htmlbody", |
| 465 | + Collections.emptyMap() |
| 466 | + ); |
| 467 | + assertFalse( EmailService. recipientAddressInAllowList( email, Set. of( "*@other.com", "*[email protected]"))); |
| 468 | + |
| 469 | + // Check CC |
| 470 | + email = new Email( |
| 471 | + "id", |
| 472 | + new Email. Address( "[email protected]", "Mr. Foo Man"), |
| 473 | + |
| 474 | + randomFrom(Email.Priority.values()), |
| 475 | + ZonedDateTime.now(), |
| 476 | + createAddressList( "[email protected]"), |
| 477 | + createAddressList( "[email protected]"), |
| 478 | + null, |
| 479 | + "subject", |
| 480 | + "body", |
| 481 | + "htmlbody", |
| 482 | + Collections.emptyMap() |
| 483 | + ); |
| 484 | + assertTrue(EmailService.recipientAddressInAllowList(email, Set.of("*@other.com", "*@bar.com"))); |
| 485 | + assertFalse( EmailService. recipientAddressInAllowList( email, Set. of( "*[email protected]"))); |
| 486 | + |
| 487 | + // Check BCC |
| 488 | + email = new Email( |
| 489 | + "id", |
| 490 | + new Email. Address( "[email protected]", "Mr. Foo Man"), |
| 491 | + |
| 492 | + randomFrom(Email.Priority.values()), |
| 493 | + ZonedDateTime.now(), |
| 494 | + createAddressList( "[email protected]"), |
| 495 | + null, |
| 496 | + createAddressList( "[email protected]"), |
| 497 | + "subject", |
| 498 | + "body", |
| 499 | + "htmlbody", |
| 500 | + Collections.emptyMap() |
| 501 | + ); |
| 502 | + assertTrue(EmailService.recipientAddressInAllowList(email, Set.of("*@other.com", "*@bar.com"))); |
| 503 | + assertFalse( EmailService. recipientAddressInAllowList( email, Set. of( "*[email protected]"))); |
| 504 | + } |
| 505 | + |
| 506 | + public void testSendEmailWithRecipientNotInAllowList() throws Exception { |
| 507 | + service.updateAllowedRecipientPatterns(Collections.singletonList(randomFrom("*@bar.*", "*@bar.com", "*b*"))); |
| 508 | + Email email = new Email( |
| 509 | + "id", |
| 510 | + new Email. Address( "[email protected]", "Mr. Foo Man"), |
| 511 | + |
| 512 | + randomFrom(Email.Priority.values()), |
| 513 | + ZonedDateTime.now(), |
| 514 | + |
| 515 | + null, |
| 516 | + null, |
| 517 | + "subject", |
| 518 | + "body", |
| 519 | + "htmlbody", |
| 520 | + Collections.emptyMap() |
| 521 | + ); |
| 522 | + when(account.name()).thenReturn("account1"); |
| 523 | + Authentication auth = new Authentication("user", new Secret("passwd".toCharArray())); |
| 524 | + Profile profile = randomFrom(Profile.values()); |
| 525 | + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> service.send(email, auth, profile, "account1")); |
| 526 | + assertThat( |
| 527 | + e.getMessage(), |
| 528 | + containsString( |
| 529 | + "failed to send email with subject [subject] and recipients [[email protected], [email protected]], " |
| 530 | + + "one or more recipients is not specified in the domain allow list setting " |
| 531 | + + "[xpack.notification.email.recipient_allowlist]." |
| 532 | + ) |
| 533 | + ); |
| 534 | + } |
| 535 | + |
| 536 | + public void testChangeRecipientAllowListSetting() throws UnsupportedEncodingException, MessagingException { |
| 537 | + Settings settings = Settings.builder() |
| 538 | + .put("xpack.notification.email.account.account1.foo", "bar") |
| 539 | + // Setting a random SMTP server name and an invalid port so that sending emails is guaranteed to fail: |
| 540 | + .put("xpack.notification.email.account.account1.smtp.host", randomAlphaOfLength(10)) |
| 541 | + .put("xpack.notification.email.account.account1.smtp.port", -100) |
| 542 | + . putList( "xpack.notification.email.recipient_allowlist", "*[email protected]") |
| 543 | + .build(); |
| 544 | + ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())); |
| 545 | + EmailService emailService = new EmailService(settings, null, mock(SSLService.class), clusterSettings); |
| 546 | + Email email = new Email( |
| 547 | + "id", |
| 548 | + new Email. Address( "[email protected]", "Mr. Foo Man"), |
| 549 | + |
| 550 | + randomFrom(Email.Priority.values()), |
| 551 | + ZonedDateTime.now(), |
| 552 | + |
| 553 | + null, |
| 554 | + null, |
| 555 | + "subject", |
| 556 | + "body", |
| 557 | + "htmlbody", |
| 558 | + Collections.emptyMap() |
| 559 | + ); |
| 560 | + when(account.name()).thenReturn("account1"); |
| 561 | + Authentication auth = new Authentication("user", new Secret("passwd".toCharArray())); |
| 562 | + Profile profile = randomFrom(Profile.values()); |
| 563 | + |
| 564 | + // This send will fail because one of the recipients ("[email protected]") is in a domain that is not in the allowed list |
| 565 | + IllegalArgumentException e1 = expectThrows( |
| 566 | + IllegalArgumentException.class, |
| 567 | + () -> emailService.send(email, auth, profile, "account1") |
| 568 | + ); |
| 569 | + assertThat( |
| 570 | + e1.getMessage(), |
| 571 | + containsString( |
| 572 | + "failed to send email with subject [subject] and recipients [[email protected], [email protected]], " |
| 573 | + + "one or more recipients is not specified in the domain allow list setting " |
| 574 | + + "[xpack.notification.email.recipient_allowlist]." |
| 575 | + ) |
| 576 | + ); |
| 577 | + |
| 578 | + // Now dynamically add "invalid.com" to the list of allowed domains: |
| 579 | + Settings newSettings = Settings.builder() |
| 580 | + .putList("xpack.notification.email.recipient_allowlist", "*@bar.com", "*@invalid.com") |
| 581 | + .build(); |
| 582 | + clusterSettings.applySettings(newSettings); |
| 583 | + // Still expect an exception because we're not actually sending the email, but it's no longer because the domain isn't allowed: |
| 584 | + IllegalArgumentException e2 = expectThrows( |
| 585 | + IllegalArgumentException.class, |
| 586 | + () -> emailService.send(email, auth, profile, "account1") |
| 587 | + ); |
| 588 | + assertThat(e2.getMessage(), containsString("port out of range")); |
| 589 | + } |
| 590 | + |
| 591 | + private Email createTestEmail(String... recipients) throws UnsupportedEncodingException { |
| 592 | + return new Email( |
| 593 | + "id", |
| 594 | + new Email. Address( "[email protected]", "Sender"), |
| 595 | + createAddressList(recipients), |
| 596 | + randomFrom(Email.Priority.values()), |
| 597 | + ZonedDateTime.now(), |
| 598 | + createAddressList(recipients), |
| 599 | + null, |
| 600 | + null, |
| 601 | + "subject", |
| 602 | + "body", |
| 603 | + "htmlbody", |
| 604 | + Collections.emptyMap() |
| 605 | + ); |
| 606 | + } |
| 607 | + |
324 | 608 | private static Email.AddressList createAddressList(String... emails) throws UnsupportedEncodingException { |
325 | 609 | List<Email.Address> addresses = new ArrayList<>(); |
326 | 610 | for (String email : emails) { |
|
0 commit comments