diff --git a/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailConstants.java b/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailConstants.java index d2d816064..b4210efef 100644 --- a/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailConstants.java +++ b/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailConstants.java @@ -56,6 +56,9 @@ public final class EmailConstants { /** If set to true, tries to authenticate the user using the AUTH command. */ public static final String MAIL_SMTP_AUTH = "mail.smtp.auth"; + /** If set to true, tries to authenticate the user using an OAuth2 token. */ + public static final String MAIL_SMTP_AUTH_MECHANISMS = "mail.smtp.auth.mechanisms"; + /** The SMTP user name. */ public static final String MAIL_SMTP_USER = "mail.smtp.user"; diff --git a/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/Email.java b/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/Email.java index f4f67b57b..9c54fb0f7 100644 --- a/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/Email.java +++ b/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/Email.java @@ -214,6 +214,11 @@ public abstract class Email { */ private boolean startTlsRequired; + /** + * If true, uses OAuth2 token for authentication. + */ + private boolean oauth2Required; + /** * Does the current transport use SSL/TLS encryption upon connection? */ @@ -823,6 +828,10 @@ public Session getMailSession() throws EmailException { properties.setProperty(EmailConstants.MAIL_SMTP_AUTH, "true"); } + if (isOAuth2Required()) { + properties.put(EmailConstants.MAIL_SMTP_AUTH_MECHANISMS, "XOAUTH2"); + } + if (isSSLOnConnect()) { properties.setProperty(EmailConstants.MAIL_PORT, sslSmtpPort); properties.setProperty(EmailConstants.MAIL_SMTP_SOCKET_FACTORY_PORT, sslSmtpPort); @@ -1062,6 +1071,16 @@ public boolean isStartTLSRequired() { return startTlsRequired; } + /** + * Tests whether the client is configured to use OAuth2 authentication. + * + * @return true if using OAuth2 for authentication, false otherwise. + * @since 2.0 + */ + public boolean isOAuth2Required() { + return oauth2Required; + } + /** * Sends the email. Internally we build a MimeMessage which is afterwards sent to the SMTP server. * @@ -1640,6 +1659,20 @@ public Email setStartTLSRequired(final boolean startTlsRequired) { return this; } + /** + * Sets or disables OAuth2 authentication. + * + * @param oauth2Required true if OAUth2 authentication is required, false otherwise + * @return An Email. + * @throws IllegalStateException if the mail session is already initialized + * @since 2.0 + */ + public Email setOAuth2Required(final boolean oauth2Required) { + checkSessionAlreadyInitialized(); + this.oauth2Required = oauth2Required; + return this; + } + /** * Sets the email subject. Replaces end-of-line characters with spaces. * diff --git a/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/EmailTest.java b/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/EmailTest.java index 0ce1bb622..e734b0a62 100644 --- a/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/EmailTest.java +++ b/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/EmailTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -571,6 +572,17 @@ public void testGetSetAuthentication() { assertEquals(strPassword, retrievedAuth.getPasswordAuthentication().getPassword()); } + @Test + public void testSetOAuth2Required() throws EmailException { + email.setHostName(strTestMailServer); + email.setOAuth2Required(true); + final Session mailSession = email.getMailSession(); + + // tests + assertNotNull(mailSession); + assertEquals("XOAUTH2", mailSession.getProperties().getProperty("mail.smtp.auth.mechanisms")); + } + @Test public void testGetSetAuthenticator() { // setup diff --git a/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/Email.java b/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/Email.java index 1bea918c0..8150deff0 100644 --- a/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/Email.java +++ b/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/Email.java @@ -213,6 +213,11 @@ public abstract class Email { */ private boolean startTlsRequired; + /** + * If true, uses OAuth2 for authentication. + */ + private boolean oauth2Required; + /** * Does the current transport use SSL/TLS encryption upon connection? */ @@ -822,6 +827,10 @@ public Session getMailSession() throws EmailException { properties.setProperty(EmailConstants.MAIL_SMTP_AUTH, "true"); } + if (isOAuth2Required()) { + properties.put(EmailConstants.MAIL_SMTP_AUTH_MECHANISMS, "XOAUTH2"); + } + if (isSSLOnConnect()) { properties.setProperty(EmailConstants.MAIL_PORT, sslSmtpPort); properties.setProperty(EmailConstants.MAIL_SMTP_SOCKET_FACTORY_PORT, sslSmtpPort); @@ -1061,6 +1070,16 @@ public boolean isStartTLSRequired() { return startTlsRequired; } + /** + * Tests whether the client is configured to use OAuth2 authentication. + * + * @return true if using OAuth2 for authentication, false otherwise. + * @since 2.0 + */ + public boolean isOAuth2Required() { + return oauth2Required; + } + /** * Sends the email. Internally we build a MimeMessage which is afterwards sent to the SMTP server. * @@ -1639,6 +1658,20 @@ public Email setStartTLSRequired(final boolean startTlsRequired) { return this; } + /** + * Sets or disables OAuth2 authentication. + * + * @param oauth2Required true if OAUth2 authentication is required, false otherwise + * @return An Email. + * @throws IllegalStateException if the mail session is already initialized + * @since 2.0 + */ + public Email setOAuth2Required(final boolean oauth2Required) { + checkSessionAlreadyInitialized(); + this.oauth2Required = oauth2Required; + return this; + } + /** * Sets the email subject. Replaces end-of-line characters with spaces. * diff --git a/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/EmailTest.java b/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/EmailTest.java index 0e7af00be..b6940f704 100644 --- a/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/EmailTest.java +++ b/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/EmailTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -571,6 +572,17 @@ public void testGetSetAuthentication() { assertEquals(strPassword, retrievedAuth.getPasswordAuthentication().getPassword()); } + @Test + public void testSetOAuth2Required() throws EmailException { + email.setHostName(strTestMailServer); + email.setOAuth2Required(true); + final Session mailSession = email.getMailSession(); + + // tests + assertNotNull(mailSession); + assertEquals("XOAUTH2", mailSession.getProperties().getProperty("mail.smtp.auth.mechanisms")); + } + @Test public void testGetSetAuthenticator() { // setup diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 6e98fd333..57cbd3f43 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -24,6 +24,7 @@
+ Checklist provided by user mkomko to help future users of this feature +