();
String usernameOrEmail = StringUtils.trimToNull(request.getParameter("usernameOrEmail"));
- ReCaptcha captcha = ReCaptchaFactory.newSecureReCaptcha("6LcZ3OMSAAAAANkKMdFdaNopWu9iS03V-nLOuoiH",
- "6LcZ3OMSAAAAAPaFg89mEzs-Ft0fIu7wxfKtkwmQ", false);
- boolean showCaptcha = true;
if (usernameOrEmail != null) {
map.put("usernameOrEmail", usernameOrEmail);
User user = getUserByUsernameOrEmail(usernameOrEmail);
- String challenge = request.getParameter("recaptcha_challenge_field");
- String uresponse = request.getParameter("recaptcha_response_field");
- ReCaptchaResponse captchaResponse = captcha.checkAnswer(request.getRemoteAddr(), challenge, uresponse);
- if (!captchaResponse.isValid()) {
+ boolean captchaOk;
+ if (settingsService.isCaptchaEnabled()) {
+ String recaptchaResponse = request.getParameter("g-recaptcha-response");
+ ReCaptcha captcha = new ReCaptcha(settingsService.getRecaptchaSecretKey());
+ captchaOk = recaptchaResponse != null && captcha.isValid(recaptchaResponse);
+ } else {
+ captchaOk = true;
+ }
+
+ if (!captchaOk) {
map.put("error", "recover.error.invalidcaptcha");
} else if (user == null) {
map.put("error", "recover.error.usernotfound");
@@ -74,15 +75,14 @@ public class RecoverController {
user.setLdapAuthenticated(false);
user.setPassword(password);
securityService.updateUser(user);
- showCaptcha = false;
} else {
map.put("error", "recover.error.sendfailed");
}
}
}
- if (showCaptcha) {
- map.put("captcha", captcha.createRecaptchaHtml(null, null));
+ if (settingsService.isCaptchaEnabled()) {
+ map.put("recaptchaSiteKey", settingsService.getRecaptchaSiteKey());
}
return new ModelAndView("recover", "model", map);
diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java b/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java
index c9463280..1ba3702f 100644
--- a/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java
+++ b/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java
@@ -117,6 +117,10 @@ public class SettingsService {
private static final String KEY_IGNORE_SYMLINKS = "IgnoreSymLinks";
private static final String KEY_EXCLUDE_PATTERN_STRING = "ExcludePattern";
+ private static final String KEY_CAPTCHA_ENABLED = "CaptchaEnabled";
+ private static final String KEY_RECAPTCHA_SITE_KEY = "ReCaptchaSiteKey";
+ private static final String KEY_RECAPTCHA_SECRET_KEY = "ReCaptchaSecretKey";
+
// Database Settings
private static final String KEY_DATABASE_CONFIG_TYPE = "DatabaseConfigType";
private static final String KEY_DATABASE_CONFIG_EMBED_DRIVER = "DatabaseConfigEmbedDriver";
@@ -193,6 +197,10 @@ public class SettingsService {
private static final String DEFAULT_SMTP_PASSWORD = null;
private static final String DEFAULT_SMTP_FROM = "airsonic@airsonic.org";
+ private static final boolean DEFAULT_CAPTCHA_ENABLED = false;
+ private static final String DEFAULT_RECAPTCHA_SITE_KEY = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI";
+ private static final String DEFAULT_RECAPTCHA_SECRET_KEY = "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe";
+
private static final DataSourceConfigType DEFAULT_DATABASE_CONFIG_TYPE = DataSourceConfigType.LEGACY;
private static final String DEFAULT_DATABASE_CONFIG_EMBED_DRIVER = null;
private static final String DEFAULT_DATABASE_CONFIG_EMBED_URL = null;
@@ -1311,6 +1319,30 @@ public class SettingsService {
setString(KEY_SMTP_FROM, smtpFrom);
}
+ public boolean isCaptchaEnabled() {
+ return getBoolean(KEY_CAPTCHA_ENABLED, DEFAULT_CAPTCHA_ENABLED);
+ }
+
+ public void setCaptchaEnabled(boolean captchaEnabled) {
+ setBoolean(KEY_CAPTCHA_ENABLED, captchaEnabled);
+ }
+
+ public String getRecaptchaSiteKey() {
+ return getProperty(KEY_RECAPTCHA_SITE_KEY, DEFAULT_RECAPTCHA_SITE_KEY);
+ }
+
+ public void setRecaptchaSiteKey(String recaptchaSiteKey) {
+ setString(KEY_RECAPTCHA_SITE_KEY, recaptchaSiteKey);
+ }
+
+ public String getRecaptchaSecretKey() {
+ return getProperty(KEY_RECAPTCHA_SECRET_KEY, DEFAULT_RECAPTCHA_SECRET_KEY);
+ }
+
+ public void setRecaptchaSecretKey(String recaptchaSecretKey) {
+ setString(KEY_RECAPTCHA_SECRET_KEY, recaptchaSecretKey);
+ }
+
public DataSourceConfigType getDatabaseConfigType() {
String raw = getString(KEY_DATABASE_CONFIG_TYPE, DEFAULT_DATABASE_CONFIG_TYPE.name());
return DataSourceConfigType.valueOf(StringUtils.upperCase(raw));
diff --git a/airsonic-main/src/main/resources/org/airsonic/player/i18n/ResourceBundle_en.properties b/airsonic-main/src/main/resources/org/airsonic/player/i18n/ResourceBundle_en.properties
index b14e9356..09831897 100644
--- a/airsonic-main/src/main/resources/org/airsonic/player/i18n/ResourceBundle_en.properties
+++ b/airsonic-main/src/main/resources/org/airsonic/player/i18n/ResourceBundle_en.properties
@@ -338,6 +338,9 @@ advancedsettings.smtpEncryption.none=None
advancedsettings.smtpEncryption.starttls=STARTTLS
advancedsettings.smtpEncryption.ssl=SSL/TLS
advancedsettings.smtpFrom=E-mail sender
+advancedsettings.enableCaptcha=Require CAPTCHA for account recovery
+advancedsettings.recaptchaSiteKey=reCAPTCHA site key
+advancedsettings.recaptchaSecretKey=reCAPTCHA secret key
# personalSettings.jsp
personalsettings.title=Personal settings for {0}
personalsettings.language=Language
@@ -730,6 +733,12 @@ helppopup.smtpEncryption.title=SMTP Encryption
helppopup.smtpEncryption.text=Encryption method used for connections to the SMTP server. Choose "None" for no encryption.
helppopup.smtpFrom.title=From address
helppopup.smtpFrom.text=The sender address for e-mails originating from the Airsonic server. Must be a valid e-mail address.
+helppopup.captcha.title=CAPTCHA
+helppopup.captcha.text=When enabled, users must solve a CAPTCHA to prove they are human when requesting a password reset.
Requires registration with an external service; see the documentation.
+helppopup.recaptchaSiteKey.title=reCAPTCHA site key
+helppopup.recaptchaSiteKey.text=A site key obtained from the reCAPTCHA admin console.
+helppopup.recaptchaSecretKey.title=reCAPTCHA secret key
+helppopup.recaptchaSecretKey.text=A secret key obtained from the reCAPTCHA admin console. Left unchanged if blank.
helppopup.scanMediaFolders.title=Media folders scanning rules
helppopup.scanMediaFolders.text=Note that subfolder names starting with a dot (.) or @eaDir, as well as Thumbs.db files, are ignored.
# wap/index.jsp
diff --git a/airsonic-main/src/main/webapp/WEB-INF/jsp/advancedSettings.jsp b/airsonic-main/src/main/webapp/WEB-INF/jsp/advancedSettings.jsp
index 66937f7a..42fb932e 100644
--- a/airsonic-main/src/main/webapp/WEB-INF/jsp/advancedSettings.jsp
+++ b/airsonic-main/src/main/webapp/WEB-INF/jsp/advancedSettings.jsp
@@ -91,7 +91,34 @@
+
+
+
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+ |
+