diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml index 22bbaa82..e0fe90bb 100644 --- a/libresonic-main/pom.xml +++ b/libresonic-main/pom.xml @@ -253,6 +253,12 @@ runtime + + javax.mail + javax.mail-api + 1.5.5 + + taglibs standard diff --git a/libresonic-main/src/main/java/org/libresonic/player/command/AdvancedSettingsCommand.java b/libresonic-main/src/main/java/org/libresonic/player/command/AdvancedSettingsCommand.java index bd3d7b08..5fe712af 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/command/AdvancedSettingsCommand.java +++ b/libresonic-main/src/main/java/org/libresonic/player/command/AdvancedSettingsCommand.java @@ -40,6 +40,12 @@ public class AdvancedSettingsCommand { private boolean isReloadNeeded; private boolean toast; + private String smtpServer; + private String smtpEncryption; + private int smtpPort; + private String smtpUser; + private String smtpPassword; + public String getDownloadLimit() { return downloadLimit; } @@ -127,4 +133,44 @@ public class AdvancedSettingsCommand { public void setToast(boolean toast) { this.toast = toast; } + + public String getSMTPServer() { + return smtpServer; + } + + public void setSMTPServer(String smtpServer) { + this.smtpServer = smtpServer; + } + + public String getSMTPEncryption() { + return smtpEncryption; + } + + public void setSMTPEncryption(String smtpEncryption) { + this.smtpEncryption = smtpEncryption; + } + + public int getSMTPPort() { + return smtpPort; + } + + public void setSMTPPort(int smtpPort) { + this.smtpPort = smtpPort; + } + + public String getSMTPUser() { + return smtpUser; + } + + public void setSMTPUser(String smtpUser) { + this.smtpUser = smtpUser; + } + + public String getSMTPPassword() { + return smtpPassword; + } + + public void setSMTPPassword(String smtpPassword) { + this.smtpPassword = smtpPassword; + } } diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/AdvancedSettingsController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/AdvancedSettingsController.java index 996a35fa..d5abaf24 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/AdvancedSettingsController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/AdvancedSettingsController.java @@ -47,6 +47,11 @@ public class AdvancedSettingsController extends SimpleFormController { command.setLdapAutoShadowing(settingsService.isLdapAutoShadowing()); command.setBrand(settingsService.getBrand()); + command.setSMTPServer(settingsService.getSMTPServer()); + command.setSMTPEncryption(settingsService.getSMTPEncryption()); + command.setSMTPPort(settingsService.getSMTPPort()); + command.setSMTPUser(settingsService.getSMTPUser()); + return command; } @@ -74,6 +79,15 @@ public class AdvancedSettingsController extends SimpleFormController { settingsService.setLdapManagerPassword(command.getLdapManagerPassword()); } + settingsService.setSMTPServer(command.getSMTPServer()); + settingsService.setSMTPEncryption(command.getSMTPEncryption()); + settingsService.setSMTPPort(command.getSMTPPort()); + settingsService.setSMTPUser(command.getSMTPUser()); + + if (StringUtils.isNotEmpty(command.getSMTPPassword())) { + settingsService.setSMTPPassword(command.getSMTPPassword()); + } + settingsService.save(); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java index ba446ba4..a5dac659 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java @@ -23,20 +23,21 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; +import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.mail.Message; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.params.HttpConnectionParams; import org.springframework.web.bind.ServletRequestUtils; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.multiaction.MultiActionController; @@ -137,32 +138,59 @@ public class MultiController extends MultiActionController { } private boolean emailPassword(String password, String username, String email) { - HttpClient client = new DefaultHttpClient(); + String prot = "smtp"; + + if (settingsService.getSMTPServer() == null || settingsService.getSMTPServer().isEmpty()) { + LOG.warn("Can not send email; no SMTP server configured."); + return false; + } + + Properties props = new Properties(); + if (settingsService.getSMTPEncryption().equals("SSL/TLS")) { + prot = "smtps"; + props.put("mail." + prot + ".ssl.enable", "true"); + } else if (settingsService.getSMTPEncryption().equals("STARTTLS")) { + prot = "smtp"; + props.put("mail." + prot + ".starttls.enable", "true"); + } + props.put("mail." + prot + ".host", settingsService.getSMTPServer()); + props.put("mail." + prot + ".port", settingsService.getSMTPPort()); + if (settingsService.getSMTPUser() != null && !settingsService.getSMTPUser().isEmpty()) { + props.put("mail." + prot + ".auth", "true"); + } + + Session session = Session.getInstance(props, null); + try { - HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); - HttpConnectionParams.setSoTimeout(client.getParams(), 10000); - HttpPost method = new HttpPost("http://libresonic.org/backend/sendMail.view"); - - List params = new ArrayList(); - params.add(new BasicNameValuePair("from", "noreply@libresonic.org")); - params.add(new BasicNameValuePair("to", email)); - params.add(new BasicNameValuePair("subject", "Libresonic Password")); - params.add(new BasicNameValuePair("text", - "Hi there!\n\n" + - "You have requested to reset your Libresonic password. Please find your new login details below.\n\n" + - "Username: " + username + "\n" + - "Password: " + password + "\n\n" + - "--\n" + - "The Libresonic Team\n" + - "libresonic.org")); - method.setEntity(new UrlEncodedFormEntity(params, StringUtil.ENCODING_UTF8)); - client.execute(method); + Message message = new MimeMessage(session); + message.setFrom(new InternetAddress("libresonic@libresonic.org")); + message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email)); + message.setSubject("Libresonic Password"); + message.setText("Hi there!\n\n" + + "You have requested to reset your Libresonic password. Please find your new login details below.\n\n" + + "Username: " + username + "\n" + + "Password: " + password + "\n\n" + + "--\n" + + "Your Libresonic server\n" + + "libresonic.org"); + message.setSentDate(new Date()); + + Transport trans = session.getTransport(prot); + try { + if (settingsService.getSMTPUser() != null && !settingsService.getSMTPUser().isEmpty()) { + trans.connect(); + } else { + trans.connect(settingsService.getSMTPServer(), settingsService.getSMTPUser(), settingsService.getSMTPPassword()); + } + trans.sendMessage(message, message.getAllRecipients()); + } finally { + trans.close(); + } return true; + } catch (Exception x) { LOG.warn("Failed to send email.", x); return false; - } finally { - client.getConnectionManager().shutdown(); } } diff --git a/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java b/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java index 894dadf2..53081b75 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java +++ b/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java @@ -144,6 +144,12 @@ public class SettingsService { private static final String KEY_SONOS_SERVICE_NAME = "SonosServiceName"; private static final String KEY_SONOS_SERVICE_ID = "SonosServiceId"; + private static final String KEY_SMTP_SERVER = "SMTPServer"; + private static final String KEY_SMTP_ENCRYPTION = "SMTPEncryption"; + private static final String KEY_SMTP_PORT = "SMTPPort"; + private static final String KEY_SMTP_USER = "SMTPUser"; + private static final String KEY_SMTP_PASSWORD = "SMTPPassword"; + // Default values. private static final String DEFAULT_INDEX_STRING = "A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ)"; private static final String DEFAULT_IGNORED_ARTICLES = "The El La Los Las Le Les"; @@ -212,6 +218,12 @@ public class SettingsService { private static final String DEFAULT_SONOS_SERVICE_NAME = "Libresonic"; private static final int DEFAULT_SONOS_SERVICE_ID = 242; + private static final String DEFAULT_SMTP_SERVER = null; + private static final String DEFAULT_SMTP_ENCRYPTION = "None"; + private static final String DEFAULT_SMTP_PORT = "25"; + private static final String DEFAULT_SMTP_USER = null; + private static final String DEFAULT_SMTP_PASSWORD = null; + // Array of obsolete keys. Used to clean property file. private static final List OBSOLETE_KEYS = Arrays.asList("PortForwardingPublicPort", "PortForwardingLocalPort", "DownsamplingCommand", "DownsamplingCommand2", "DownsamplingCommand3", "AutoCoverBatch", "MusicMask", @@ -1052,7 +1064,7 @@ public class SettingsService { if (cachedMusicFolders == null) { cachedMusicFolders = musicFolderDao.getAllMusicFolders(); } - + List result = new ArrayList(cachedMusicFolders.size()); for (MusicFolder folder : cachedMusicFolders) { if ((includeDisabled || folder.isEnabled()) && (includeNonExisting || FileUtil.exists(folder.getPath()))) { @@ -1446,4 +1458,54 @@ public class SettingsService { public void setVersionService(VersionService versionService) { this.versionService = versionService; } + + public String getSMTPServer() { + return properties.getProperty(KEY_SMTP_SERVER, DEFAULT_SMTP_SERVER); + } + + public void setSMTPServer(String smtpServer) { + setString(KEY_SMTP_SERVER, smtpServer); + } + + public String getSMTPPort() { + return getString(KEY_SMTP_PORT, DEFAULT_SMTP_PORT); + } + + public void setSMTPPort(String smtpPort) { + setString(KEY_SMTP_PORT, smtpPort); + } + + public String getSMTPEncryption() { + return properties.getProperty(KEY_SMTP_ENCRYPTION, DEFAULT_SMTP_ENCRYPTION); + } + + public void setSMTPEncryption(String encryptionMethod) { + setString(KEY_SMTP_ENCRYPTION, encryptionMethod); + } + + public String getSMTPUser() { + return properties.getProperty(KEY_SMTP_USER, DEFAULT_SMTP_USER); + } + + public void setSMTPUser(String smtpUser) { + setString(KEY_SMTP_USER, smtpUser); + } + + public String getSMTPPassword() { + String s = properties.getProperty(KEY_SMTP_PASSWORD, DEFAULT_SMTP_PASSWORD); + try { + return StringUtil.utf8HexDecode(s); + } catch (Exception x) { + LOG.warn("Failed to decode SMTP password.", x); + return s; + } + } + public void setSMTPPassword(String smtpPassword) { + try { + smtpPassword = StringUtil.utf8HexEncode(smtpPassword); + } catch (Exception x) { + LOG.warn("Failed to encode SMTP password.", x); + } + properties.setProperty(KEY_SMTP_PASSWORD, smtpPassword); + } }