This is an automated email from the ASF dual-hosted git repository. juanpablo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jspwiki.git
commit 8cdd18796d2a74da7e100597348b99d6055b6c99 Author: Juan Pablo Santos RodrÃguez <[email protected]> AuthorDate: Sat Apr 27 15:52:41 2024 +0200 MailUtil now uses every mail.smtp / mail.smtps property provided through your jspwiki(-custom).properties file --- jspwiki-main/pom.xml | 5 -- jspwiki-util/pom.xml | 13 ++- .../main/java/org/apache/wiki/util/MailUtil.java | 98 ++++++++++++---------- .../java/org/apache/wiki/util/MailUtilTest.java | 55 ++++-------- pom.xml | 22 +++-- 5 files changed, 95 insertions(+), 98 deletions(-) diff --git a/jspwiki-main/pom.xml b/jspwiki-main/pom.xml index 669661619..1ec40cadb 100644 --- a/jspwiki-main/pom.xml +++ b/jspwiki-main/pom.xml @@ -91,11 +91,6 @@ <artifactId>jstl</artifactId> </dependency> - <dependency> - <groupId>javax.mail</groupId> - <artifactId>mail</artifactId> - </dependency> - <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> diff --git a/jspwiki-util/pom.xml b/jspwiki-util/pom.xml index 19ac84435..81258ff96 100644 --- a/jspwiki-util/pom.xml +++ b/jspwiki-util/pom.xml @@ -31,13 +31,18 @@ <dependencies> <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> + <groupId>com.sun.mail</groupId> + <artifactId>logging-mailhandler</artifactId> </dependency> <dependency> - <groupId>javax.mail</groupId> - <artifactId>mail</artifactId> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + </dependency> + + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> </dependency> <dependency> diff --git a/jspwiki-util/src/main/java/org/apache/wiki/util/MailUtil.java b/jspwiki-util/src/main/java/org/apache/wiki/util/MailUtil.java index 8e8ea9ac7..3c7fbb597 100644 --- a/jspwiki-util/src/main/java/org/apache/wiki/util/MailUtil.java +++ b/jspwiki-util/src/main/java/org/apache/wiki/util/MailUtil.java @@ -21,7 +21,12 @@ package org.apache.wiki.util; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import javax.mail.*; +import javax.mail.Authenticator; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; @@ -30,7 +35,9 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.Objects; import java.util.Properties; +import java.util.Set; /** @@ -196,6 +203,7 @@ public final class MailUtil { private static boolean c_useJndi = true; private static final String PROP_MAIL_AUTH = "mail.smtp.auth"; + private static final String PROP_MAILS_AUTH = "mail.smtps.auth"; static final Logger LOG = LogManager.getLogger(MailUtil.class); @@ -213,23 +221,32 @@ public final class MailUtil { static final String PROP_MAIL_JNDI_NAME = "jspwiki.mail.jndiname"; + static final String MAIL_PROPS = "mail.smtp"; + static final String PROP_MAIL_HOST = "mail.smtp.host"; + static final String PROP_MAILS_HOST = "mail.smtps.host"; static final String PROP_MAIL_PORT = "mail.smtp.port"; + static final String PROP_MAILS_PORT = "mail.smtps.port"; static final String PROP_MAIL_ACCOUNT = "mail.smtp.account"; + static final String PROP_MAILS_ACCOUNT = "mail.smtps.account"; static final String PROP_MAIL_PASSWORD = "mail.smtp.password"; + static final String PROP_MAILS_PASSWORD = "mail.smtps.password"; static final String PROP_MAIL_TIMEOUT = "mail.smtp.timeout"; + static final String PROP_MAILS_TIMEOUT = "mail.smtps.timeout"; static final String PROP_MAIL_CONNECTION_TIMEOUT = "mail.smtp.connectiontimeout"; + static final String PROP_MAILS_CONNECTION_TIMEOUT= "mail.smtps.connectiontimeout"; static final String PROP_MAIL_TRANSPORT = "smtp"; static final String PROP_MAIL_SENDER = "mail.from"; static final String PROP_MAIL_STARTTLS = "mail.smtp.starttls.enable"; + static final String PROP_MAILS_STARTTLS = "mail.smtps.starttls.enable"; private static String c_fromAddress; @@ -267,7 +284,7 @@ public final class MailUtil { throws AddressException, MessagingException { final Session session = getMailSession( props ); - getSenderEmailAddress(session, props); + setSenderEmailAddress(session, props); try { // Create and address the message @@ -294,11 +311,9 @@ public final class MailUtil { * from the jspwiki.properties or lastly the default value. * @param pSession <code>Session</code> * @param pProperties <code>Properties</code> - * @return <code>String</code> */ - static String getSenderEmailAddress(final Session pSession, final Properties pProperties) { - if( c_fromAddress == null ) - { + static void setSenderEmailAddress( final Session pSession, final Properties pProperties ) { + if( c_fromAddress == null ) { // First, attempt to get the email address from the JNDI Mail Session. if( pSession != null && c_useJndi ) { c_fromAddress = pSession.getProperty( MailUtil.PROP_MAIL_SENDER ); @@ -312,7 +327,6 @@ public final class MailUtil { LOG.debug( "Attempt to get the sender's mail address from the JNDI mail session was successful ({}).", c_fromAddress ); } } - return c_fromAddress; } /** @@ -348,40 +362,42 @@ public final class MailUtil { } /** - * Returns a stand-alone JavaMail Session by looking up the correct - * mail account, password and host from a supplied set of properties. - * If the JavaMail property {@value #PROP_MAIL_ACCOUNT} is set to - * a value that is non-<code>null</code> and of non-zero length, the - * Session will be initialized with an instance of + * Returns a stand-alone JavaMail Session by looking up the correct mail account, password, host and others from a + * supplied set of properties. If the JavaMail property {@value #PROP_MAIL_ACCOUNT} is set to a value that is + * non-<code>null</code> and of non-zero length, the Session will be initialized with an instance of * {@link javax.mail.Authenticator}. - * @param props the properties that contain mail session properties - * @return the initialized JavaMail Session + * + * @param props the properties that contain mail session properties. + * @return the initialized JavaMail Session. + * + * @see <a href="https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html#properties">SMTP Properties</a> + * for a list of valid <code>mail.smtp</code> / <code>mail.smtps</code> properties, used to create the JavaMail session. */ - static Session getStandaloneMailSession(final Properties props ) { + static Session getStandaloneMailSession( final Properties props ) { // Read the JSPWiki settings from the properties - final String host = props.getProperty( PROP_MAIL_HOST, DEFAULT_MAIL_HOST ); - final String port = props.getProperty( PROP_MAIL_PORT, DEFAULT_MAIL_PORT ); - final String account = props.getProperty( PROP_MAIL_ACCOUNT ); - final String password = props.getProperty( PROP_MAIL_PASSWORD ); - final String timeout = props.getProperty( PROP_MAIL_TIMEOUT, DEFAULT_MAIL_TIMEOUT); - final String conntimeout = props.getProperty( PROP_MAIL_CONNECTION_TIMEOUT, DEFAULT_MAIL_CONN_TIMEOUT ); - final boolean starttls = TextUtil.getBooleanProperty( props, PROP_MAIL_STARTTLS, true); - + final String host = Objects.toString( props.getProperty( PROP_MAIL_HOST, props.getProperty( PROP_MAILS_HOST, DEFAULT_MAIL_HOST ) ) ); + final String port = Objects.toString( props.getProperty( PROP_MAIL_PORT, props.getProperty( PROP_MAILS_PORT, DEFAULT_MAIL_PORT ) ) ); + final String account = Objects.toString( props.getProperty( PROP_MAIL_ACCOUNT ), props.getProperty( PROP_MAILS_ACCOUNT ) ); + final String password = Objects.toString( props.getProperty( PROP_MAIL_PASSWORD ),props.getProperty( PROP_MAILS_PASSWORD ) ); + final String timeout = Objects.toString( props.getProperty( PROP_MAIL_TIMEOUT, props.getProperty( PROP_MAILS_TIMEOUT, DEFAULT_MAIL_TIMEOUT ) ) ); + final String conntimeout = Objects.toString( props.getProperty( PROP_MAIL_CONNECTION_TIMEOUT, props.getProperty( PROP_MAILS_CONNECTION_TIMEOUT, DEFAULT_MAIL_CONN_TIMEOUT ) ) ); + final String starttls = Boolean.toString( TextUtil.getBooleanProperty( props, PROP_MAIL_STARTTLS, TextUtil.getBooleanProperty( props, PROP_MAILS_STARTTLS, true ) ) ); final boolean useAuthentication = account != null && !account.isEmpty(); - final Properties mailProps = new Properties(); - // Set JavaMail properties - mailProps.put( PROP_MAIL_HOST, host ); - mailProps.put( PROP_MAIL_PORT, port ); - mailProps.put( PROP_MAIL_TIMEOUT, timeout ); - mailProps.put( PROP_MAIL_CONNECTION_TIMEOUT, conntimeout ); - mailProps.put( PROP_MAIL_STARTTLS, starttls ? TRUE : FALSE ); + final Properties mailProps = new Properties(); + final Set< String > keys = props.stringPropertyNames(); + for( final String key : keys) { + if( key.startsWith( MAIL_PROPS ) ) { + mailProps.setProperty( key, props.getProperty( key ) ); + } + } // Add SMTP authentication if required final Session session; if ( useAuthentication ) { mailProps.put( PROP_MAIL_AUTH, TRUE ); + mailProps.put( PROP_MAILS_AUTH, TRUE ); // just in case, cover mail.stmps config as well final SmtpAuthenticator auth = new SmtpAuthenticator( account, password ); session = Session.getInstance( mailProps, auth ); @@ -396,7 +412,6 @@ public final class MailUtil { return session; } - /** * Returns a JavaMail Session instance from a JNDI container-managed factory. * @param jndiName the JNDI name for the resource. If <code>null</code>, the default value @@ -404,13 +419,12 @@ public final class MailUtil { * @return the initialized JavaMail Session * @throws NamingException if the Session cannot be obtained; for example, if the factory is not configured */ - static Session getJNDIMailSession(final String jndiName ) throws NamingException - { + static Session getJNDIMailSession( final String jndiName ) throws NamingException { final Session session; try { final Context initCtx = new InitialContext(); - final Context ctx = (Context) initCtx.lookup( JAVA_COMP_ENV ); - session = (Session) ctx.lookup( jndiName ); + final Context ctx = ( Context ) initCtx.lookup( JAVA_COMP_ENV ); + session = ( Session )ctx.lookup( jndiName ); } catch( final NamingException e ) { LOG.warn( "JNDI mail session initialization error: {}", e.getMessage() ); throw e; @@ -431,11 +445,11 @@ public final class MailUtil { /** * Constructs a new SmtpAuthenticator with a supplied username and password. + * * @param login the username * @param pass the password */ - public SmtpAuthenticator(final String login, final String pass) - { + public SmtpAuthenticator( final String login, final String pass ) { super(); m_login = login == null ? BLANK : login; m_pass = pass == null ? BLANK : pass; @@ -443,16 +457,14 @@ public final class MailUtil { /** * Returns the password used to authenticate to the SMTP server. - * @return <code>PasswordAuthentication</code> + * + * @return <code>PasswordAuthentication</code>. */ @Override - public PasswordAuthentication getPasswordAuthentication() - { - if ( BLANK.equals(m_pass) ) - { + public PasswordAuthentication getPasswordAuthentication() { + if( BLANK.equals( m_pass ) ) { return null; } - return new PasswordAuthentication( m_login, m_pass ); } diff --git a/jspwiki-util/src/test/java/org/apache/wiki/util/MailUtilTest.java b/jspwiki-util/src/test/java/org/apache/wiki/util/MailUtilTest.java index c6d770590..9a6c10806 100644 --- a/jspwiki-util/src/test/java/org/apache/wiki/util/MailUtilTest.java +++ b/jspwiki-util/src/test/java/org/apache/wiki/util/MailUtilTest.java @@ -19,16 +19,15 @@ package org.apache.wiki.util; -import java.net.ConnectException; -import java.util.Properties; - -import javax.mail.MessagingException; -import javax.net.ssl.SSLHandshakeException; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import javax.mail.MessagingException; +import javax.net.ssl.SSLHandshakeException; +import java.net.ConnectException; +import java.util.Properties; + /** * This test is not integrated into any TestSuite yet, because I don't know how * to really assert if a mail was sent etc. (setup would be to complicated yet). Therefore @@ -37,22 +36,12 @@ import org.junit.jupiter.api.Test; * * */ -public class MailUtilTest -{ +class MailUtilTest { + static Properties m_props = new Properties(); - static final String PAGE_NAME = "TestPage"; - - static final String TEST_HOST = "mail.mydomain.org"; - static final String TEST_PORT = "587"; - static final String TEST_ACCOUNT = "myaccount"; - static final String TEST_PASSWORD = "changeit"; - - static final String TEST_RECEIVER = "[email protected]"; - static final String TEST_SENDER = "[email protected]"; - @BeforeAll - public static void setUp() throws Exception { + static void setUp() { m_props = PropertyReader.getCombinedProperties( PropertyReader.CUSTOM_JSPWIKI_CONFIG ); } @@ -61,8 +50,7 @@ public class MailUtilTest * Three of them (account, password, jndi name) are commented out, so we expect null. */ @Test - public void testProperties() - { + void testProperties() { Assertions.assertEquals( "127.0.0.1", m_props.getProperty( MailUtil.PROP_MAIL_HOST ) ); Assertions.assertEquals( "25", m_props.getProperty( MailUtil.PROP_MAIL_PORT ) ); Assertions.assertEquals( "JSPWiki <JSPWiki@localhost>", m_props.getProperty( MailUtil.PROP_MAIL_SENDER ) ); @@ -79,42 +67,33 @@ public class MailUtilTest * the command line. */ @Test - public void testSendMail() - { + void testSendMail() { final String user = System.getProperty( "user.name" ) + "@localhost"; - try - { + try { MailUtil.sendMessage( m_props, user, "Mail test", "This is a test mail generated by MailUtilTest." ); - } - catch( final MessagingException e ) - { - if( e.getCause() instanceof ConnectException ) - { - // This can occur if you do not have a SMTP server set up. We just log this and don't Assertions.fail. + } catch( final MessagingException e ) { + if( e.getCause() instanceof ConnectException ) { + // This can occur if you do not have an SMTP server set up. We just log this and don't Assertions.fail. System.out.println("I could not test whether mail sending works, since I could not connect to your SMTP server."); System.out.println("Reason: "+e.getMessage()); return; } - if( e.getCause() instanceof SSLHandshakeException ) - { + if( e.getCause() instanceof SSLHandshakeException ) { // This can occur if you do not have the required cert in the JVM's keystore. We just log this // and don't Assertions.fail. System.out.println("I could not test whether mail sending works, since I don't have the required cert in my keystore."); System.out.println("Reason: "+e.getMessage()); return; } - if( e.getCause() == null ) - { + if( e.getCause() == null ) { System.out.println("Reason: "+e.getMessage()); System.out.println("I could not test whether mail sending works, we let the test pass anyway."); return; } e.printStackTrace(); Assertions.fail( "Unknown problem, cause=" + e.getCause() + " (check the console for error report)" ); - } - catch (final Exception e) - { + } catch (final Exception e) { e.printStackTrace(); Assertions.fail( "Could not send mail: " + e.getMessage() ); } diff --git a/pom.xml b/pom.xml index 6899f2ffa..ebc66d625 100644 --- a/pom.xml +++ b/pom.xml @@ -61,11 +61,11 @@ <jamm.version>0.4.0</jamm.version> <jaxen.version>2.0.0</jaxen.version> <javax-jstl.version>1.2</javax-jstl.version> - <javax-mail.version>1.4.7</javax-mail.version> + <javax-mail.version>1.6.2</javax-mail.version> <javax-jsp-api.version>2.3.3</javax-jsp-api.version> <javax-servlet-api.version>3.1.0</javax-servlet-api.version> <jdom2.version>2.0.6</jdom2.version> - <jetty.version>9.4.53.v20231009</jetty.version> + <jetty.version>9.4.54.v20240208</jetty.version> <jrcs-diff.version>0.4.2</jrcs-diff.version> <junit.version>5.10.2</junit.version> <log4j2.version>2.23.0</log4j2.version> @@ -159,6 +159,18 @@ <version>${selenide.version}</version> </dependency> + <dependency><!-- as of 1.6.2 not included by javax.mail-api, see https://javaee.github.io/javamail/docs/COMPAT.txt --> + <groupId>com.sun.mail</groupId> + <artifactId>logging-mailhandler</artifactId> + <version>${javax-mail.version}</version> + </dependency> + + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + <version>${javax-mail.version}</version> + </dependency> + <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> @@ -261,12 +273,6 @@ <version>${log4j2.version}</version> </dependency> - <dependency> - <groupId>javax.mail</groupId> - <artifactId>mail</artifactId> - <version>${javax-mail.version}</version> - </dependency> - <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId>
