2626import java .util .ArrayList ;
2727import java .util .Arrays ;
2828import java .util .HashSet ;
29+ import java .util .Iterator ;
2930import java .util .List ;
31+ import java .util .Map ;
3032import java .util .Optional ;
3133import java .util .Set ;
3234import java .util .function .Predicate ;
3335import java .util .stream .Collectors ;
3436import java .util .stream .Stream ;
35-
3637import javax .mail .MessagingException ;
3738import javax .mail .internet .InternetAddress ;
3839import javax .net .ssl .SSLSocketFactory ;
@@ -56,9 +57,72 @@ public class EmailService extends NotificationService<Account> {
5657 (key ) -> Setting .simpleString (key , Property .Dynamic , Property .NodeScope )
5758 );
5859
60+ private static final List <String > ALLOW_ALL_DEFAULT = List .of ("*" );
61+
5962 private static final Setting <List <String >> SETTING_DOMAIN_ALLOWLIST = Setting .stringListSetting (
6063 "xpack.notification.email.account.domain_allowlist" ,
61- List .of ("*" ),
64+ ALLOW_ALL_DEFAULT ,
65+ new Setting .Validator <>() {
66+ @ Override
67+ public void validate (List <String > value ) {
68+ // Ignored
69+ }
70+
71+ @ Override
72+ @ SuppressWarnings ("unchecked" )
73+ public void validate (List <String > value , Map <Setting <?>, Object > settings ) {
74+ List <String > recipientAllowPatterns = (List <String >) settings .get (SETTING_RECIPIENT_ALLOW_PATTERNS );
75+ if (value .equals (ALLOW_ALL_DEFAULT ) == false && recipientAllowPatterns .equals (ALLOW_ALL_DEFAULT ) == false ) {
76+ throw new IllegalArgumentException (
77+ "Cannot set both ["
78+ + SETTING_RECIPIENT_ALLOW_PATTERNS .getKey ()
79+ + "] and ["
80+ + SETTING_DOMAIN_ALLOWLIST .getKey ()
81+ + "] to a non [\" *\" ] value at the same time."
82+ );
83+ }
84+ }
85+
86+ @ Override
87+ public Iterator <Setting <?>> settings () {
88+ List <Setting <?>> settingRecipientAllowPatterns = List .of (SETTING_RECIPIENT_ALLOW_PATTERNS );
89+ return settingRecipientAllowPatterns .iterator ();
90+ }
91+ },
92+ Property .Dynamic ,
93+ Property .NodeScope
94+ );
95+
96+ private static final Setting <List <String >> SETTING_RECIPIENT_ALLOW_PATTERNS = Setting .stringListSetting (
97+ "xpack.notification.email.recipient_allowlist" ,
98+ ALLOW_ALL_DEFAULT ,
99+ new Setting .Validator <>() {
100+ @ Override
101+ public void validate (List <String > value ) {
102+ // Ignored
103+ }
104+
105+ @ Override
106+ @ SuppressWarnings ("unchecked" )
107+ public void validate (List <String > value , Map <Setting <?>, Object > settings ) {
108+ List <String > domainAllowList = (List <String >) settings .get (SETTING_DOMAIN_ALLOWLIST );
109+ if (value .equals (ALLOW_ALL_DEFAULT ) == false && domainAllowList .equals (ALLOW_ALL_DEFAULT ) == false ) {
110+ throw new IllegalArgumentException (
111+ "Connect set both ["
112+ + SETTING_RECIPIENT_ALLOW_PATTERNS .getKey ()
113+ + "] and ["
114+ + SETTING_DOMAIN_ALLOWLIST .getKey ()
115+ + "] to a non [\" *\" ] value at the same time."
116+ );
117+ }
118+ }
119+
120+ @ Override
121+ public Iterator <Setting <?>> settings () {
122+ List <Setting <?>> settingDomainAllowlist = List .of (SETTING_DOMAIN_ALLOWLIST );
123+ return settingDomainAllowlist .iterator ();
124+ }
125+ },
62126 Property .Dynamic ,
63127 Property .NodeScope
64128 );
@@ -167,6 +231,7 @@ public class EmailService extends NotificationService<Account> {
167231 private final CryptoService cryptoService ;
168232 private final SSLService sslService ;
169233 private volatile Set <String > allowedDomains ;
234+ private volatile Set <String > allowedRecipientPatterns ;
170235
171236 @ SuppressWarnings ("this-escape" )
172237 public EmailService (Settings settings , @ Nullable CryptoService cryptoService , SSLService sslService , ClusterSettings clusterSettings ) {
@@ -192,7 +257,9 @@ public EmailService(Settings settings, @Nullable CryptoService cryptoService, SS
192257 clusterSettings .addAffixUpdateConsumer (SETTING_SMTP_SEND_PARTIAL , (s , o ) -> {}, (s , o ) -> {});
193258 clusterSettings .addAffixUpdateConsumer (SETTING_SMTP_WAIT_ON_QUIT , (s , o ) -> {}, (s , o ) -> {});
194259 this .allowedDomains = new HashSet <>(SETTING_DOMAIN_ALLOWLIST .get (settings ));
260+ this .allowedRecipientPatterns = new HashSet <>(SETTING_RECIPIENT_ALLOW_PATTERNS .get (settings ));
195261 clusterSettings .addSettingsUpdateConsumer (SETTING_DOMAIN_ALLOWLIST , this ::updateAllowedDomains );
262+ clusterSettings .addSettingsUpdateConsumer (SETTING_RECIPIENT_ALLOW_PATTERNS , this ::updateAllowedRecipientPatterns );
196263 // do an initial load
197264 reload (settings );
198265 }
@@ -201,6 +268,10 @@ void updateAllowedDomains(List<String> newDomains) {
201268 this .allowedDomains = new HashSet <>(newDomains );
202269 }
203270
271+ void updateAllowedRecipientPatterns (List <String > newPatterns ) {
272+ this .allowedRecipientPatterns = new HashSet <>(newPatterns );
273+ }
274+
204275 @ Override
205276 protected Account createAccount (String name , Settings accountSettings ) {
206277 Account .Config config = new Account .Config (name , accountSettings , getSmtpSslSocketFactory (), logger );
@@ -304,6 +375,7 @@ private static List<Setting<?>> getDynamicSettings() {
304375 return Arrays .asList (
305376 SETTING_DEFAULT_ACCOUNT ,
306377 SETTING_DOMAIN_ALLOWLIST ,
378+ SETTING_RECIPIENT_ALLOW_PATTERNS ,
307379 SETTING_PROFILE ,
308380 SETTING_EMAIL_DEFAULTS ,
309381 SETTING_SMTP_AUTH ,
0 commit comments