Fix url in password reset email (#12078)

This commit is contained in:
Suresh Kumar Anaparti 2026-01-28 17:17:50 +05:30 committed by GitHub
parent 8c2ba2b341
commit 4d35d68e4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 17 deletions

View File

@ -71,11 +71,6 @@ public class ServerDaemon implements Daemon {
private static final String BIND_INTERFACE = "bind.interface";
private static final String CONTEXT_PATH = "context.path";
private static final String SESSION_TIMEOUT = "session.timeout";
private static final String HTTP_ENABLE = "http.enable";
private static final String HTTP_PORT = "http.port";
private static final String HTTPS_ENABLE = "https.enable";
private static final String HTTPS_PORT = "https.port";
private static final String KEYSTORE_FILE = "https.keystore";
private static final String KEYSTORE_PASSWORD = "https.keystore.password";
private static final String WEBAPP_DIR = "webapp.dir";
private static final String ACCESS_LOG = "access.log";
@ -137,11 +132,11 @@ public class ServerDaemon implements Daemon {
}
setBindInterface(properties.getProperty(BIND_INTERFACE, null));
setContextPath(properties.getProperty(CONTEXT_PATH, "/client"));
setHttpEnable(Boolean.valueOf(properties.getProperty(HTTP_ENABLE, "true")));
setHttpPort(Integer.valueOf(properties.getProperty(HTTP_PORT, "8080")));
setHttpsEnable(Boolean.valueOf(properties.getProperty(HTTPS_ENABLE, "false")));
setHttpsPort(Integer.valueOf(properties.getProperty(HTTPS_PORT, "8443")));
setKeystoreFile(properties.getProperty(KEYSTORE_FILE));
setHttpEnable(Boolean.valueOf(properties.getProperty(ServerProperties.HTTP_ENABLE, "true")));
setHttpPort(Integer.valueOf(properties.getProperty(ServerProperties.HTTP_PORT, "8080")));
setHttpsEnable(Boolean.valueOf(properties.getProperty(ServerProperties.HTTPS_ENABLE, "false")));
setHttpsPort(Integer.valueOf(properties.getProperty(ServerProperties.HTTPS_PORT, "8443")));
setKeystoreFile(properties.getProperty(ServerProperties.KEYSTORE_FILE));
setKeystorePassword(properties.getProperty(KEYSTORE_PASSWORD));
setWebAppLocation(properties.getProperty(WEBAPP_DIR));
setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));

View File

@ -78,7 +78,9 @@ public interface UserPasswordResetManager {
ConfigKey<String> UserPasswordResetDomainURL = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED,
String.class, "user.password.reset.mail.domain.url", null,
"Domain URL for reset password links sent to the user via email", true,
"Domain URL (along with scheme - http:// or https:// and port as applicable) for reset password links sent to the user via email. " +
"If this is not set, CloudStack would determine the domain url based on the first management server from 'host' setting " +
"and http scheme based on the https.enabled flag from server.properties file in the management server.", true,
ConfigKey.Scope.Global);
void setResetTokenAndSend(UserAccount userAccount);

View File

@ -23,6 +23,7 @@ import com.cloud.user.UserVO;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.server.ServerProperties;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;
@ -48,6 +49,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import static org.apache.cloudstack.config.ApiServiceConfiguration.ManagementServerAddresses;
import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordResetToken;
import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordResetTokenExpiryDate;
@ -68,7 +70,7 @@ public class UserPasswordResetManagerImpl extends ManagerBase implements UserPas
new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, String.class,
"user.password.reset.mail.template", "Hello {{username}}!\n" +
"You have requested to reset your password. Please click the following link to reset your password:\n" +
"{{{domainUrl}}}{{{resetLink}}}\n" +
"{{{resetLink}}}\n" +
"If you did not request a password reset, please ignore this email.\n" +
"\n" +
"Regards,\n" +
@ -179,10 +181,26 @@ public class UserPasswordResetManagerImpl extends ManagerBase implements UserPas
final String email = userAccount.getEmail();
final String username = userAccount.getUsername();
final String subject = "Password Reset Request";
final String domainUrl = UserPasswordResetDomainURL.value();
String domainUrl = UserPasswordResetDomainURL.value();
if (StringUtils.isBlank(domainUrl)) {
String mgmtServerAddr = ManagementServerAddresses.value().split(",")[0];
if (ServerProperties.isHttpsEnabled()) {
domainUrl = "https://" + mgmtServerAddr + ":" + ServerProperties.getHttpsPort();
} else {
domainUrl = "http://" + mgmtServerAddr + ":" + ServerProperties.getHttpPort();
}
} else if (!domainUrl.startsWith("http://") && !domainUrl.startsWith("https://")) {
if (ServerProperties.isHttpsEnabled()) {
domainUrl = "https://" + domainUrl;
} else {
domainUrl = "http://" + domainUrl;
}
}
String resetLink = String.format("/client/#/user/resetPassword?username=%s&token=%s",
username, resetToken);
domainUrl = domainUrl.replaceAll("/+$", "");
String resetLink = String.format("%s/client/#/user/resetPassword?username=%s&token=%s",
domainUrl, username, resetToken);
String content = getMessageBody(userAccount, resetToken, resetLink);
SMTPMailProperties mailProperties = new SMTPMailProperties();

View File

@ -17,10 +17,12 @@
package com.cloud.utils.server;
import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
import com.cloud.utils.StringUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
@ -28,9 +30,20 @@ import java.util.Properties;
public class ServerProperties {
protected Logger logger = LogManager.getLogger(getClass());
public static final String HTTP_ENABLE = "http.enable";
public static final String HTTP_PORT = "http.port";
public static final String HTTPS_ENABLE = "https.enable";
public static final String HTTPS_PORT = "https.port";
public static final String KEYSTORE_FILE = "https.keystore";
public static final String PASSWORD_ENCRYPTION_TYPE = "password.encryption.type";
private static Properties properties = new Properties();
private static boolean loaded = false;
public static final String passwordEncryptionType = "password.encryption.type";
private static int httpPort = 8080;
private static boolean httpsEnable = false;
private static int httpsPort = 8443;
public synchronized static Properties getServerProperties(InputStream inputStream) {
if (!loaded) {
@ -39,7 +52,7 @@ public class ServerProperties {
serverProps.load(inputStream);
EncryptionSecretKeyChecker checker = new EncryptionSecretKeyChecker();
checker.check(serverProps, passwordEncryptionType);
checker.check(serverProps, PASSWORD_ENCRYPTION_TYPE);
if (EncryptionSecretKeyChecker.useEncryption()) {
EncryptionSecretKeyChecker.decryptAnyProperties(serverProps);
@ -50,10 +63,29 @@ public class ServerProperties {
IOUtils.closeQuietly(inputStream);
}
httpPort = Integer.parseInt(serverProps.getProperty(ServerProperties.HTTP_PORT, "8080"));
boolean httpsEnabled = Boolean.parseBoolean(serverProps.getProperty(ServerProperties.HTTPS_ENABLE, "false"));
String keystoreFile = serverProps.getProperty(KEYSTORE_FILE);
httpsEnable = httpsEnabled && StringUtils.isNotEmpty(keystoreFile) && new File(keystoreFile).exists();
httpsPort = Integer.parseInt(serverProps.getProperty(ServerProperties.HTTPS_PORT, "8443"));
properties = serverProps;
loaded = true;
}
return properties;
}
public static int getHttpPort() {
return httpPort;
}
public static boolean isHttpsEnabled() {
return httpsEnable;
}
public static int getHttpsPort() {
return httpsPort;
}
}