Skip to content

Commit c1b266d

Browse files
committed
#447: Added value-defaulting control for individual properties, to make sure they don't get a default value
#447: Added value-overriding control for individual properties, to make sure they don't get overridden #297: Streamlined how defaults/overrides are determined by EmailGovernance and MiscUtil #297: Removed the signByDefault methods from Mailer; signWithSmime on Email already works on for the defaults Email reference #446: Added missing config properties for DKIM
1 parent 619a910 commit c1b266d

File tree

25 files changed

+589
-379
lines changed

25 files changed

+589
-379
lines changed

modules/core-module/src/main/java/org/simplejavamail/api/email/Email.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.simplejavamail.api.email.config.DkimConfig;
88
import org.simplejavamail.api.internal.smimesupport.model.PlainSmimeDetails;
99
import org.simplejavamail.api.mailer.config.Pkcs12Config;
10+
import org.simplejavamail.internal.config.EmailProperty;
1011
import org.simplejavamail.internal.util.MiscUtil;
1112

1213
import java.io.InputStream;
@@ -40,6 +41,16 @@ public class Email implements Serializable {
4041

4142
private static final long serialVersionUID = 1234567L;
4243

44+
/**
45+
* @see EmailPopulatingBuilder#dontApplyDefaultValueFor(EmailProperty...)
46+
*/
47+
private final Set<EmailProperty> propertiesNotToApplyDefaultValueFor;
48+
49+
/**
50+
* @see EmailPopulatingBuilder#dontApplyOverrideValueFor(EmailProperty...)
51+
*/
52+
private final Set<EmailProperty> propertiesNotToApplyOverrideValueFor;
53+
4354
/**
4455
* @see EmailPopulatingBuilder#fixingMessageId(String)
4556
*/
@@ -207,6 +218,8 @@ public class Email implements Serializable {
207218
public Email(@NotNull final EmailPopulatingBuilder builder) {
208219
checkNonEmptyArgument(builder, "builder");
209220

221+
propertiesNotToApplyDefaultValueFor = builder.getPropertiesNotToApplyDefaultValueFor();
222+
propertiesNotToApplyOverrideValueFor = builder.getPropertiesNotToApplyOverrideValueFor();
210223
smimeSignedEmail = builder.getSmimeSignedEmail();
211224

212225
final boolean smimeMerge = builder.isMergeSingleSMIMESignedAttachment() && smimeSignedEmail != null;
@@ -375,6 +388,22 @@ private String formatDate(@Nullable Date date) {
375388
return sdf.format(date);
376389
}
377390

391+
/**
392+
* @see EmailPopulatingBuilder#dontApplyDefaultValueFor(EmailProperty...)
393+
*/
394+
@Nullable
395+
public Set<EmailProperty> getPropertiesNotToApplyDefaultValueFor() {
396+
return propertiesNotToApplyDefaultValueFor;
397+
}
398+
399+
/**
400+
* @see EmailPopulatingBuilder#dontApplyOverrideValueFor(EmailProperty...)
401+
*/
402+
@Nullable
403+
public Set<EmailProperty> getPropertiesNotToApplyOverrideValueFor() {
404+
return propertiesNotToApplyOverrideValueFor;
405+
}
406+
378407
/**
379408
* @see EmailPopulatingBuilder#fixingMessageId(String)
380409
*/

modules/core-module/src/main/java/org/simplejavamail/api/email/EmailPopulatingBuilder.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.simplejavamail.api.internal.clisupport.model.Cli;
1212
import org.simplejavamail.api.internal.clisupport.model.CliBuilderApiType;
1313
import org.simplejavamail.api.mailer.config.Pkcs12Config;
14+
import org.simplejavamail.internal.config.EmailProperty;
1415

1516
import java.io.File;
1617
import java.io.InputStream;
@@ -47,6 +48,28 @@ public interface EmailPopulatingBuilder {
4748
*/
4849
@Cli.ExcludeApi(reason = "This API is specifically for Java use")
4950
Email buildEmail();
51+
52+
/**
53+
* Allows you to prevent a property to be configured with default values. This might be useful if you have defined defaults (either through (system) properties,
54+
* config files, or on mailer level on the {@link org.simplejavamail.api.mailer.config.EmailGovernance}), but for a specific case or under certain conditions
55+
* you might want to have this email untouched by the defaults.
56+
* <br>
57+
* <strong>Note:</strong> This is irrelevant for Email instances used to set on {@link org.simplejavamail.api.mailer.config.EmailGovernance}
58+
* as defaults or overrides reference.
59+
*
60+
* @param configProperties The properties that should not be configured with default values, if any, when sending the email.
61+
* @see EmailStartingBuilder#ignoringDefaults()
62+
*/
63+
EmailPopulatingBuilder dontApplyDefaultValueFor(@NotNull EmailProperty @NotNull ...configProperties);
64+
65+
/**
66+
* Allows you to prevent a property to be configured with override values. This might be useful if you have defined overrides on mailer level on the
67+
* {@link org.simplejavamail.api.mailer.config.EmailGovernance}), but for a specific case or under certain conditions you might want
68+
* to have this email untouched by the overrides.
69+
*
70+
* @param configProperties The properties that should not be overridden when sending the email.
71+
*/
72+
EmailPopulatingBuilder dontApplyOverrideValueFor(@NotNull EmailProperty @NotNull ...configProperties);
5073

5174
/**
5275
* Sets optional ID to a fixed value, which is otherwise generated by the underlying JavaMail framework when sending the email.
@@ -1174,7 +1197,6 @@ public interface EmailPopulatingBuilder {
11741197
*
11751198
* @see <a href="https://en.wikipedia.org/wiki/S/MIME">S/MIME on Wikipedia</a>
11761199
* @see <a href="https://www.globalsign.com/en/blog/what-is-s-mime/">Primer on S/MIME</a>
1177-
* @see org.simplejavamail.api.mailer.MailerGenericBuilder#signByDefaultWithSmime(Pkcs12Config)
11781200
*/
11791201
@Cli.ExcludeApi(reason = "delegated method contains CLI compatible arguments")
11801202
EmailPopulatingBuilder signWithSmime(@NotNull Pkcs12Config pkcs12Config);
@@ -1514,6 +1536,18 @@ public interface EmailPopulatingBuilder {
15141536
*/
15151537
EmailPopulatingBuilder clearSMIMESignedAttachmentMergingBehavior();
15161538

1539+
/**
1540+
* @see #dontApplyDefaultValueFor(EmailProperty...)
1541+
*/
1542+
@Nullable
1543+
Set<EmailProperty> getPropertiesNotToApplyDefaultValueFor();
1544+
1545+
/**
1546+
* @see #dontApplyOverrideValueFor(EmailProperty...)
1547+
*/
1548+
@Nullable
1549+
Set<EmailProperty> getPropertiesNotToApplyOverrideValueFor();
1550+
15171551
/**
15181552
* @see #fixingMessageId(String)
15191553
*/

modules/core-module/src/main/java/org/simplejavamail/api/email/EmailStartingBuilder.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.jetbrains.annotations.NotNull;
55
import org.simplejavamail.api.internal.clisupport.model.Cli;
66
import org.simplejavamail.api.internal.clisupport.model.CliBuilderApiType;
7+
import org.simplejavamail.internal.config.EmailProperty;
78

89
import java.util.regex.Pattern;
910

@@ -36,7 +37,13 @@ public interface EmailStartingBuilder {
3637
"1cm\">%s</blockquote>";
3738

3839
/**
39-
* Configures this builder to create an email ignoring the normal (optional) defaults that apply from property config files.
40+
* Configures this builder to create an email ignoring the all defaults from (System) properties, config files or defaults email on
41+
* Mailer level in the {@link org.simplejavamail.api.mailer.config.EmailGovernance}.
42+
* <br>
43+
* <strong>Note:</strong> This is irrelevant for Email instances used to set on {@link org.simplejavamail.api.mailer.config.EmailGovernance}
44+
* as defaults or overrides reference.
45+
*
46+
* @see EmailPopulatingBuilder#dontApplyDefaultValueFor(EmailProperty...)
4047
*/
4148
EmailStartingBuilder ignoringDefaults();
4249

modules/core-module/src/main/java/org/simplejavamail/api/mailer/MailerGenericBuilder.java

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@
99
import org.simplejavamail.api.internal.clisupport.model.Cli;
1010
import org.simplejavamail.api.internal.clisupport.model.CliBuilderApiType;
1111
import org.simplejavamail.api.mailer.config.LoadBalancingStrategy;
12-
import org.simplejavamail.api.mailer.config.Pkcs12Config;
1312
import org.simplejavamail.api.mailer.config.TransportStrategy;
1413

15-
import java.io.File;
16-
import java.io.InputStream;
1714
import java.util.List;
1815
import java.util.Map;
1916
import java.util.Properties;
@@ -268,53 +265,6 @@ public interface MailerGenericBuilder<T extends MailerGenericBuilder<?>> {
268265
*/
269266
T withMaximumEmailSize(int maximumEmailSize);
270267

271-
/**
272-
* Signs this <em>all emails by default</em> with an <a href="https://tools.ietf.org/html/rfc5751">S/MIME</a> signature, so the receiving client
273-
* can verify whether the email content was tampered with.
274-
* <p>
275-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
276-
*
277-
* @see <a href="https://en.wikipedia.org/wiki/S/MIME">S/MIME on Wikipedia</a>
278-
* @see <a href="https://www.globalsign.com/en/blog/what-is-s-mime/">Primer on S/MIME</a>
279-
* @see org.simplejavamail.api.email.EmailPopulatingBuilder#signWithSmime(Pkcs12Config)
280-
* @see #clearSignByDefaultWithSmime()
281-
*/
282-
@Cli.ExcludeApi(reason = "delegated method contains CLI compatible arguments")
283-
T signByDefaultWithSmime(@NotNull Pkcs12Config pkcs12Config);
284-
285-
/**
286-
* Delegates to {@link #signByDefaultWithSmime(InputStream, String, String, String)}.
287-
* <p>
288-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
289-
*
290-
* @param pkcs12StoreFile The key store file to use to find the indicated key
291-
* @param storePassword The store's password
292-
* @param keyAlias The name of the certificate in the key store to use
293-
* @param keyPassword The password of the certificate
294-
*/
295-
T signByDefaultWithSmime(@NotNull File pkcs12StoreFile, @NotNull String storePassword, @NotNull String keyAlias, @NotNull String keyPassword);
296-
297-
/**
298-
* Delegates to {@link #signByDefaultWithSmime(byte[], String, String, String)}.
299-
* <p>
300-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
301-
*/
302-
@Cli.ExcludeApi(reason = "Is duplicate API from CLI point of view")
303-
T signByDefaultWithSmime(@NotNull InputStream pkcs12StoreStream, @NotNull String storePassword, @NotNull String keyAlias, @NotNull String keyPassword);
304-
305-
/**
306-
* Delegates to {@link #signByDefaultWithSmime(Pkcs12Config)}.
307-
* <p>
308-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
309-
*
310-
* @param pkcs12StoreData The key store file to use to find the indicated key
311-
* @param storePassword The store's password
312-
* @param keyAlias The name of the certificate in the key store to use
313-
* @param keyPassword The password of the certificate
314-
*/
315-
@Cli.ExcludeApi(reason = "Is duplicate API from CLI point of view")
316-
T signByDefaultWithSmime(@NotNull byte[] pkcs12StoreData, @NotNull String storePassword, @NotNull String keyAlias, @NotNull String keyPassword);
317-
318268
/**
319269
* <strong>For advanced use cases.</strong>
320270
* <p>
@@ -700,13 +650,6 @@ public interface MailerGenericBuilder<T extends MailerGenericBuilder<?>> {
700650
*/
701651
T clearMaximumEmailSize();
702652

703-
/**
704-
* Removes S/MIME signing, so emails won't be signed by default.
705-
*
706-
* @see #signByDefaultWithSmime(Pkcs12Config)
707-
*/
708-
T clearSignByDefaultWithSmime();
709-
710653
/**
711654
* Removes all trusted hosts from the list.
712655
*
@@ -801,13 +744,6 @@ public interface MailerGenericBuilder<T extends MailerGenericBuilder<?>> {
801744
@Nullable
802745
Integer getMaximumEmailSize();
803746

804-
/**
805-
* @see #signByDefaultWithSmime(Pkcs12Config)
806-
* @see #signByDefaultWithSmime(InputStream, String, String, String)
807-
*/
808-
@Nullable
809-
Pkcs12Config getPkcs12ConfigForSmimeSigning();
810-
811747
/**
812748
* Returns the user set ExecutorService or else null as the default ExecutorService is not created until the {@link org.simplejavamail.api.mailer.config.OperationalConfig} is created for the
813749
* new {@link Mailer} instance.
Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,58 @@
11
package org.simplejavamail.api.mailer.config;
22

33
import com.sanctionco.jmail.EmailValidator;
4-
import lombok.AllArgsConstructor;
5-
import lombok.Getter;
6-
import lombok.ToString;
4+
import org.jetbrains.annotations.NotNull;
75
import org.jetbrains.annotations.Nullable;
86
import org.simplejavamail.api.email.Email;
9-
import org.simplejavamail.api.email.EmailPopulatingBuilder;
107
import org.simplejavamail.api.mailer.MailerGenericBuilder;
8+
import org.simplejavamail.internal.config.EmailProperty;
119

12-
import java.io.InputStream;
10+
import java.util.Collection;
11+
import java.util.List;
12+
import java.util.Map;
1313

1414
/**
1515
* Governance for all emails being sent through the current {@link org.simplejavamail.api.mailer.Mailer} instance. That is, this class represents actions
1616
* taken or configuration used by default for each individual email sent through the current mailer. For example, you might want to S/MIME sign all emails
1717
* by default. You <em>can</em> do it manually on each email of course, but then the keystore used for this is not reused.
1818
* <p>
19-
* Also, you can supply a custom {@link org.simplejavamail.api.email.Email email} instance which will be used for defaults. For example,
20-
* you can set a default from address or subject.
21-
* <p>
22-
* You can set this on the {@code MailerBuilder} using {@code MailerBuilder.withEmailGovernance(EmailGovernance)}.
19+
* Also, you can supply a custom {@link org.simplejavamail.api.email.Email email} instance which will be used for <em>defaults</em> or <em>overrides</em>. For example,
20+
* you can set a default from address or subject. Any fields that are not set on the email will be taken from the defaults (properties). Any fields that are set on the
21+
* email will be used instead of the defaults.
2322
*/
24-
@ToString
25-
@AllArgsConstructor
26-
@Getter()
27-
public class EmailGovernance {
28-
29-
public static final EmailGovernance NO_GOVERNANCE = new EmailGovernance(null, null, null, null, null);
30-
31-
/**
32-
* The effective email validator used for email validation. Can be <code>null</code> if no validation should be done.
33-
* @see MailerGenericBuilder#withEmailValidator(EmailValidator)
34-
* @see EmailValidator
35-
*/
36-
@Nullable private final EmailValidator emailValidator;
37-
38-
/**
39-
* @see EmailPopulatingBuilder#signWithSmime(Pkcs12Config)
40-
* @see EmailPopulatingBuilder#signWithSmime(InputStream, String, String, String)
41-
* @see MailerGenericBuilder#signByDefaultWithSmime(Pkcs12Config)
42-
* @see MailerGenericBuilder#signByDefaultWithSmime(InputStream, String, String, String)
43-
*/
44-
@Nullable private final Pkcs12Config pkcs12ConfigForSmimeSigning;
45-
46-
/**
47-
* Reference email used for defaults if no fields are not filled in the email but are on this instance.
48-
* Can be <code>null</code> if no defaults should be used.
49-
* @see MailerGenericBuilder#withEmailDefaults(Email)
50-
*/
51-
@Nullable private final Email emailDefaults;
52-
53-
/**
54-
* Reference email used for overrides. Values from this email will trump the incoming email.
55-
* Can be <code>null</code> if no overrides should be used.
56-
* @see MailerGenericBuilder#withEmailOverrides(Email)
57-
*/
58-
@Nullable private final Email emailOverrides;
59-
60-
/**
61-
* Determines at what size Simple Java Mail should reject a MimeMessage. Useful if you know your SMTP server has a limit.
62-
* @see MailerGenericBuilder#withMaximumEmailSize(int)
63-
*/
64-
@Nullable private final Integer maximumEmailSize;
23+
public interface EmailGovernance {
24+
/**
25+
* @return The effective email validator used for email validation. Can be <code>null</code> if no validation should be done.
26+
* @see MailerGenericBuilder#withEmailValidator(EmailValidator)
27+
* @see EmailValidator
28+
*/
29+
@Nullable EmailValidator getEmailValidator();
30+
31+
/**
32+
* @return Determines at what size Simple Java Mail should reject a MimeMessage. Useful if you know your SMTP server has a limit.
33+
* @see MailerGenericBuilder#withMaximumEmailSize(int)
34+
*/
35+
@Nullable Integer getMaximumEmailSize();
36+
37+
/**
38+
* Resolves a property by first checking overrides (if the override wasn't disabled globally, or for this property specifically), then checking the email itself, and finally
39+
* checking the defaults (again checking if it was disabled). If the property is not set on any of these, <code>null</code> is returned.
40+
*/
41+
@Nullable <T> T resolveEmailProperty(@Nullable Email email, @NotNull EmailProperty emailProperty);
42+
43+
/**
44+
* Resolves a collection property by first checking overrides (if the override wasn't disabled globally, or for this property specifically), then checking the email itself, and finally
45+
* checking the defaults (again checking if it was disabled). If the property is not set on any of these, an empty <code>List</code> is returned.
46+
* <br>
47+
* The collections are merged from these sources, with the overrides taking precedence.
48+
*/
49+
@NotNull <T> List<T> resolveEmailCollectionProperty(@Nullable Email email, @NotNull EmailProperty emailProperty);
50+
51+
/**
52+
* Specifically resolves the headers by first checking overrides (if the override wasn't disabled globally, or for this property specifically), then checking the email itself, and finally
53+
* checking the defaults (again checking if it was disabled). If the property is not set on any of these, an empty <code>List</code> is returned.
54+
* <br>
55+
* The header maps are merged from these sources, with the overrides taking precedence. The keys are added to the map, but their associated value collections are not merged, but replaced.
56+
*/
57+
Map<String, Collection<String>> resolveEmailHeadersProperty(@Nullable Email email);
6558
}

modules/core-module/src/main/java/org/simplejavamail/config/ConfigLoader.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@
7979
* <li>simplejavamail.smime.signing.key_alias</li>
8080
* <li>simplejavamail.smime.signing.key_password</li>
8181
* <li>simplejavamail.smime.encryption.certificate</li>
82+
* <li>simplejavamail.dkim.signing.private_key_file_or_data</li>
83+
* <li>simplejavamail.dkim.signing.selector</li>
84+
* <li>simplejavamail.dkim.signing.signing_domain</li>
85+
* <li>simplejavamail.dkim.signing.excluded_headers_from_default_signing_list</li>
8286
* <li>simplejavamail.embeddedimages.dynamicresolution.enable.dir</li>
8387
* <li>simplejavamail.embeddedimages.dynamicresolution.enable.url</li>
8488
* <li>simplejavamail.embeddedimages.dynamicresolution.enable.classpath</li>
@@ -171,6 +175,10 @@ public enum Property {
171175
SMIME_SIGNING_KEYSTORE_PASSWORD("simplejavamail.smime.signing.keystore_password"),
172176
SMIME_SIGNING_KEY_ALIAS("simplejavamail.smime.signing.key_alias"),
173177
SMIME_SIGNING_KEY_PASSWORD("simplejavamail.smime.signing.key_password"),
178+
DKIM_PRIVATE_KEY_FILE_OR_DATA("simplejavamail.dkim.signing.private_key_file_or_data"),
179+
DKIM_SELECTOR("simplejavamail.dkim.signing.selector"),
180+
DKIM_SIGNING_DOMAIN("simplejavamail.dkim.signing.signing_domain"),
181+
DKIM_EXCLUDED_HEADERS_FROM_DEFAULT_SIGNING_LIST("simplejavamail.dkim.signing.excluded_headers_from_default_signing_list"),
174182
SMIME_ENCRYPTION_CERTIFICATE("simplejavamail.smime.encryption.certificate"),
175183
EMBEDDEDIMAGES_DYNAMICRESOLUTION_ENABLE_DIR("simplejavamail.embeddedimages.dynamicresolution.enable.dir"),
176184
EMBEDDEDIMAGES_DYNAMICRESOLUTION_ENABLE_CLASSPATH("simplejavamail.embeddedimages.dynamicresolution.enable.classpath"),

0 commit comments

Comments
 (0)