-
-
Notifications
You must be signed in to change notification settings - Fork 271
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#297: Improved the new Recipients API. S/MIME encryption now on both …
…Recipient and Recipients level on top of Email and Mailer level. Updated both Recipient and Recipients APIs to include S/MIME encryption as a feature. This adds to the existing levels for S/MIME encryption which were Email and Mailer. The changes ensure a flexible, layered approach to managing S/MIME encryption, offering specific controls at each level. Order of precedence has now been established to clarify encryption priority.
- Loading branch information
Showing
22 changed files
with
504 additions
and
373 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,27 +7,21 @@ | |
import java.security.cert.X509Certificate; | ||
|
||
/** | ||
* Produces immutable recipient object, with a name, emailaddress and recipient type (eg {@link Message.RecipientType#BCC}), | ||
* and optionally an S/MIME certificate for encrypting messages on a per-user basis. | ||
* Produces immutable recipient object, with a name, emailaddress and recipient type (eg {@link Message.RecipientType#BCC}), and optionally an S/MIME | ||
* certificate for encrypting messages on a per-user basis. | ||
*/ | ||
public interface IRecipientBuilder { | ||
|
||
/** | ||
* @param name Optional explicit name of the recipient, otherwise taken from inside the address (if provided) (for example "Joe Sixpack <[email protected]>"). | ||
* @see #clearingName() | ||
* @param name Optional explicit name of the recipient, otherwise taken from inside the address (if provided, for example "Joe Sixpack | ||
* <[email protected]>"). Note that in {@link Recipients}, this can still be overridden by the {@code defaultName} and | ||
* {@code overridingName} fields. | ||
*/ | ||
IRecipientBuilder withName(@NotNull String name); | ||
|
||
/** | ||
* Clears the name, in which case the name from inside the provided address is used (if provided), or else the address is used as-is. | ||
* So in email clients you won't see a name, just the address. | ||
* | ||
* @see #withName(String) | ||
*/ | ||
IRecipientBuilder clearingName(); | ||
|
||
/** | ||
* @param address The email address of the recipient, can contain a name, but is ignored if a name was seperately provided. | ||
* @param address The email address of the recipient, can contain a name, but is ignored if a name was seperately provided, this includes names possibly | ||
* provided by {@link Recipients}. | ||
*/ | ||
IRecipientBuilder withAddress(@NotNull String address); | ||
|
||
|
@@ -37,20 +31,33 @@ public interface IRecipientBuilder { | |
IRecipientBuilder withType(@NotNull Message.RecipientType type); | ||
|
||
/** | ||
* @param smimeCertificate Optional S/MIME certificate for this recipient, used for encrypting messages on a per-user basis. Overrides certificate provided | ||
* on {@link Email} level and {@link org.simplejavamail.api.mailer.Mailer} level (if provided). | ||
* @param smimeCertificate Optional S/MIME certificate for this recipient, used for encrypting S/MIME messages on a per-user basis. Overrides certificate | ||
* provided on {@link Email} level and {@link org.simplejavamail.api.mailer.Mailer} level (if provided). | ||
* <p></p> | ||
* So, the order of precedence is: | ||
* <ol> | ||
* <li>Mailer level (override value)</li> | ||
* <li>Recipient level (specific value)</li> | ||
* <li>Recipients level (default value)</li> | ||
* <li>Email level (default value)</li> | ||
* <li>Mailer level (default value)</li> | ||
* </ol> | ||
* @see #clearingSmimeCertificate() | ||
* @see IRecipientsBuilder#withDefaultSmimeCertificate(X509Certificate) | ||
*/ | ||
IRecipientBuilder withSmimeCertificate(@NotNull X509Certificate smimeCertificate); | ||
|
||
/** | ||
* Clears the S/MIME certificate used for encrypting S/MIME messages for this recipient. In this case, if available, the S/MIME certificate from | ||
* the {@link Email} object is used and from the {@link org.simplejavamail.api.mailer.Mailer} otherwise (if provided). | ||
* Clears the S/MIME certificate used for encrypting S/MIME messages for this recipient. In this case, if available, the S/MIME certificate from the | ||
* {@link Email} object is used and from the {@link org.simplejavamail.api.mailer.Mailer} otherwise (if provided). | ||
* | ||
* @see #withSmimeCertificate(X509Certificate) | ||
*/ | ||
IRecipientBuilder clearingSmimeCertificate(); | ||
|
||
/** | ||
* Creates a new {@link Recipient} instance, but first checks if address is set and throws an exception if not. | ||
*/ | ||
@NotNull Recipient build(); | ||
|
||
/** | ||
|
@@ -72,4 +79,4 @@ public interface IRecipientBuilder { | |
* @see #withSmimeCertificate(X509Certificate) | ||
*/ | ||
@Nullable X509Certificate getSmimeCertificate(); | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
modules/core-module/src/main/java/org/simplejavamail/api/email/IRecipientsBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package org.simplejavamail.api.email; | ||
|
||
import jakarta.mail.Message; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.security.cert.X509Certificate; | ||
import java.util.List; | ||
|
||
/** | ||
* Produces immutable recipients object, with an optional default/overriding name. | ||
*/ | ||
public interface IRecipientsBuilder { | ||
|
||
/** | ||
* Default explicit name of the recipient, otherwise taken from inside the {@link Recipient}'s explicitly set name, or otherwise from the nested address (if | ||
* provided). | ||
* <p> | ||
* The reason for this option is due to the natur of an email address on the string level, where we don't always control the value of the name part of the | ||
* address. This is especially true when the address is provided by a user, where the name part can be anything, including a name that is not a name at all, | ||
* or perhaps previously set defaults in a properties configuration. | ||
* </p> | ||
*/ | ||
IRecipientsBuilder withDefaultName(@Nullable String defaultName); | ||
|
||
/** | ||
* Similar to {@link #withDefaultName(String)}, but this field is used to override the name of all recipients in this object. The nested name of each | ||
* recipient is simply ignored if this field is set, including explicitly set names or implicitly derived names from the address. | ||
*/ | ||
IRecipientsBuilder withOverridingName(@Nullable String overridingName); | ||
|
||
IRecipientsBuilder withRecipient(@NotNull Recipient recipient); | ||
|
||
IRecipientsBuilder withRecipients(@NotNull Recipient... recipient); | ||
|
||
/** | ||
* @param defaultSmimeCertificate Optional S/MIME certificate for all recipients in this object, used for encrypting messages on a per-user basis. Overrides | ||
* certificate provided on {@link Email} level and {@link org.simplejavamail.api.mailer.Mailer} level (if provided). If | ||
* overridden by a specific recipient, that recipient's certificate is used instead. The only exception is when a | ||
* {@code Mailer} level override is set, in which case that is used for all recipients. | ||
* <p></p> | ||
* So, the order of precedence is: | ||
* <ol> | ||
* <li>Mailer level (override value)</li> | ||
* <li>Recipient level (specific value)</li> | ||
* <li>Recipients level (default value)</li> | ||
* <li>Email level (default value)</li> | ||
* <li>Mailer level (default value)</li> | ||
* </ol> | ||
* @see IRecipientBuilder#withSmimeCertificate(X509Certificate) | ||
*/ | ||
IRecipientsBuilder withDefaultSmimeCertificate(@NotNull X509Certificate defaultSmimeCertificate); | ||
|
||
/** | ||
* @return An immutable {@link Recipients} object, with an optional default/overriding name and an optional default S/MIME certificate. | ||
*/ | ||
@NotNull Recipients build(); | ||
|
||
/** | ||
* @see #withDefaultName(String) | ||
*/ | ||
@Nullable String getDefaultName(); | ||
|
||
/** | ||
* @see #withOverridingName(String) | ||
*/ | ||
@Nullable String getOverridingName(); | ||
|
||
/** | ||
* @see #withRecipient(Recipient) | ||
* @see #withRecipients(Recipient...) | ||
*/ | ||
@NotNull List<Recipient> getRecipients(); | ||
|
||
/** | ||
* @see #withDefaultSmimeCertificate(X509Certificate) | ||
*/ | ||
@Nullable X509Certificate getDefaultSmimeCertificate(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,112 +2,41 @@ | |
|
||
import jakarta.mail.Message; | ||
import jakarta.mail.Message.RecipientType; | ||
import lombok.Value; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.io.Serializable; | ||
import java.security.cert.X509Certificate; | ||
import java.util.Objects; | ||
|
||
import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument; | ||
|
||
/** | ||
* An immutable recipient object, with a name, emailaddress and recipient type (eg {@link Message.RecipientType#BCC}), | ||
* and optionally an S/MIME certificate for encrypting messages on a per-user basis. | ||
* An immutable recipient object, with a name, emailaddress and recipient type (eg {@link Message.RecipientType#BCC}), and optionally an S/MIME certificate for | ||
* encrypting messages on a per-user basis. | ||
* | ||
* @see IRecipientBuilder | ||
*/ | ||
public final class Recipient implements Serializable { | ||
|
||
private static final long serialVersionUID = 1234567L; | ||
|
||
@Nullable | ||
private final String name; | ||
@NotNull | ||
private final String address; | ||
@Nullable | ||
private final RecipientType type; | ||
@Nullable | ||
private final X509Certificate smimeCertificate; | ||
|
||
/** | ||
* Constructor; initializes this recipient object. | ||
* | ||
* @param name Optional explicit name of the recipient, otherwise taken from inside the address (if provided) (for example "Joe Sixpack <[email protected]>"). | ||
* @param address The email address of the recipient, can contain a name, but is ignored if a name was seperately provided. | ||
* @param type The recipient type (e.g. {@link RecipientType#TO}), optional for {@code from} and {@code replyTo} fields. | ||
* @param smimeCertificate Optional S/MIME certificate for this recipient, used for encrypting messages on a per-user basis. Overrides certificate provided | ||
* on {@link Email} level and {@link org.simplejavamail.api.mailer.Mailer} level (if provided). | ||
* @see IRecipientBuilder | ||
*/ | ||
public Recipient(@Nullable final String name, @NotNull final String address, @Nullable final RecipientType type, @Nullable final X509Certificate smimeCertificate) { | ||
this.name = name; | ||
this.address = checkNonEmptyArgument(address, "address"); | ||
this.type = type; | ||
this.smimeCertificate = smimeCertificate; | ||
} | ||
|
||
/** | ||
* Checks equality based on {@link #name}, {@link #address} and {@link #type}. | ||
*/ | ||
@Override | ||
public boolean equals(@Nullable final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final Recipient recipient = (Recipient) o; | ||
return Objects.equals(name, recipient.name) && | ||
Objects.equals(address, recipient.address) && | ||
Objects.equals(type, recipient.type); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(name, address, type); | ||
} | ||
|
||
@NotNull | ||
@Override public String toString() { | ||
return "Recipient{" + | ||
"name='" + name + '\'' + | ||
", address='" + address + '\'' + | ||
", type=" + type + | ||
", smimeCertificate=" + smimeCertificate + | ||
'}'; | ||
} | ||
|
||
/** | ||
* @see IRecipientBuilder#withName(String) | ||
*/ | ||
@Nullable | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
/** | ||
* @see IRecipientBuilder#withAddress(String) | ||
*/ | ||
@NotNull | ||
public String getAddress() { | ||
return address; | ||
} | ||
|
||
/** | ||
* @see IRecipientBuilder#withType(RecipientType) | ||
*/ | ||
@Nullable | ||
public RecipientType getType() { | ||
return type; | ||
} | ||
|
||
/** | ||
* @see IRecipientBuilder#withSmimeCertificate(X509Certificate) | ||
*/ | ||
@Nullable | ||
public X509Certificate getSmimeCertificate() { | ||
return smimeCertificate; | ||
} | ||
@Value | ||
public class Recipient implements Serializable { | ||
|
||
private static final long serialVersionUID = 1234567L; | ||
|
||
/** | ||
* @see IRecipientBuilder#withName(String) | ||
*/ | ||
@Nullable String name; | ||
|
||
/** | ||
* @see IRecipientBuilder#withAddress(String) | ||
*/ | ||
@NotNull String address; | ||
|
||
/** | ||
* @see IRecipientBuilder#withType(RecipientType) | ||
*/ | ||
@Nullable RecipientType type; | ||
|
||
/** | ||
* @see IRecipientBuilder#withSmimeCertificate(X509Certificate) | ||
*/ | ||
@Nullable X509Certificate smimeCertificate; | ||
} |
58 changes: 29 additions & 29 deletions
58
modules/core-module/src/main/java/org/simplejavamail/api/email/Recipients.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,41 @@ | ||
package org.simplejavamail.api.email; | ||
|
||
import jakarta.mail.Message.RecipientType; | ||
import lombok.Value; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.io.Serializable; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.security.cert.X509Certificate; | ||
import java.util.List; | ||
|
||
/** | ||
* An immutable recipient object, with a name, emailaddress and recipient type (eg {@link RecipientType#BCC}), | ||
* and optionally an S/MIME certificate for encrypting messages on a per-user basis. | ||
* An immutable recipients object, with an optional default or overriding name. | ||
* | ||
* @see IRecipientBuilder | ||
* @see IRecipientsBuilder | ||
*/ | ||
public final class Recipients implements Serializable { | ||
|
||
private static final long serialVersionUID = 1234567L; | ||
|
||
@NotNull | ||
private final List<Recipient> recipients = new ArrayList<>(); | ||
@Nullable | ||
private final String defaultName; | ||
@Nullable | ||
private final String overridingName; | ||
|
||
/** | ||
* Constructor; initializes this recipient object. | ||
* | ||
* @param defaultName Optional explicit name of the recipient, otherwise taken from inside the address (if provided) (for example "Joe Sixpack < | ||
* @param overridingName The email address of the recipient, can contain a name, but is ignored if a name was seperately provided. | ||
* @see IRecipientBuilder | ||
*/ | ||
public Recipients(@Nullable final String defaultName, @Nullable final String overridingName, @NotNull final Recipient... recipients) { | ||
this.recipients.addAll(Arrays.asList(recipients)); | ||
this.defaultName = defaultName; | ||
this.overridingName = overridingName; | ||
} | ||
@Value | ||
public class Recipients implements Serializable { | ||
|
||
private static final long serialVersionUID = 1234567L; | ||
|
||
/** | ||
* @see IRecipientsBuilder#withRecipient(Recipient) | ||
* @see IRecipientsBuilder#withRecipients(Recipient...) | ||
*/ | ||
@NotNull List<Recipient> recipients; | ||
|
||
/** | ||
* @see IRecipientsBuilder#withDefaultName(String) | ||
*/ | ||
@Nullable String defaultName; | ||
|
||
/** | ||
* @see IRecipientsBuilder#withOverridingName(String) | ||
*/ | ||
@Nullable String overridingName; | ||
|
||
/** | ||
* @see IRecipientsBuilder#withDefaultSmimeCertificate(X509Certificate) | ||
*/ | ||
@Nullable X509Certificate defaultSmimeCertificate; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.