diff --git a/teamengine-core/src/main/java/com/occamlab/te/util/XMLUtils.java b/teamengine-core/src/main/java/com/occamlab/te/util/XMLUtils.java
index ce333e51..5a1c1337 100644
--- a/teamengine-core/src/main/java/com/occamlab/te/util/XMLUtils.java
+++ b/teamengine-core/src/main/java/com/occamlab/te/util/XMLUtils.java
@@ -9,15 +9,26 @@
*/
package com.occamlab.te.util;
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
+import org.apache.xerces.impl.Constants;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
/**
* @author lbermudez
@@ -72,4 +83,66 @@ public static NodeList getAllNodes(Document doc, String xPathExpression) {
return null;
}
+ /**
+ * This method is used to parse xml document and will return document object.
+ * @param xmlFile Input should XML file with File object.
+ * @return doc Return document object.
+ */
+ public static Document parseDocument(File xmlFile) {
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setExpandEntityReferences(false);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document doc = db.parse(xmlFile);
+ return doc;
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Failed to parse xml file: " + xmlFile + " Error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * This method is used to write the DOM object to XML file.
+ * @param xmlFile
+ * @return
+ */
+ public static void transformDocument(Document doc, File xmlFile) {
+ try {
+ DOMImplementationRegistry domRegistry = DOMImplementationRegistry.newInstance();
+ DOMImplementationLS lsFactory = (DOMImplementationLS) domRegistry.getDOMImplementation("LS 3.0");
+
+ LSSerializer serializer = lsFactory.createLSSerializer();
+ serializer.getDomConfig().setParameter(Constants.DOM_XMLDECL, Boolean.FALSE);
+ serializer.getDomConfig().setParameter(Constants.DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
+ LSOutput output = lsFactory.createLSOutput();
+ output.setEncoding("UTF-8");
+
+ FileOutputStream os = new FileOutputStream(xmlFile, false);
+ output.setByteStream(os);
+ serializer.write(doc, output);
+ os.close();
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Failed to update user details. " + e.getMessage());
+ }
+ }
+
+ /**
+ * This method removes the element from the document.
+ * @param doc
+ * @param element Object of root element
+ * @param elementName The name of element to remove.
+ * @return
+ */
+ public static Document removeElement(Document doc, Element element, String elementName) {
+ NodeList elementList = element.getElementsByTagName(elementName);
+ if (elementList.getLength() != 0) {
+ Element elementToRemove = (Element) doc.getElementsByTagName(elementName).item(0);
+ Node parent = elementToRemove.getParentNode();
+ parent.removeChild(elementToRemove);
+ }
+ return doc;
+ }
+
}
diff --git a/teamengine-realm/src/main/java/com/occamlab/te/realm/PBKDF2Realm.java b/teamengine-realm/src/main/java/com/occamlab/te/realm/PBKDF2Realm.java
index f224781d..f63e3332 100644
--- a/teamengine-realm/src/main/java/com/occamlab/te/realm/PBKDF2Realm.java
+++ b/teamengine-realm/src/main/java/com/occamlab/te/realm/PBKDF2Realm.java
@@ -75,7 +75,7 @@ public class PBKDF2Realm extends RealmBase {
private DocumentBuilder DB = null;
- private final HashMap principals = new HashMap<>();
+ private HashMap principals = UserGenericPrincipal.getInstance().getPrincipals();
private String password;
diff --git a/teamengine-realm/src/main/java/com/occamlab/te/realm/UserGenericPrincipal.java b/teamengine-realm/src/main/java/com/occamlab/te/realm/UserGenericPrincipal.java
new file mode 100644
index 00000000..4c9eaf29
--- /dev/null
+++ b/teamengine-realm/src/main/java/com/occamlab/te/realm/UserGenericPrincipal.java
@@ -0,0 +1,42 @@
+package com.occamlab.te.realm;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+public class UserGenericPrincipal {
+
+ private static final Logger logger = Logger.getLogger(UserGenericPrincipal.class.getPackage().getName());
+
+ private HashMap principals = new HashMap();
+
+ private static volatile UserGenericPrincipal userPrincipal = null;
+
+ public static UserGenericPrincipal getInstance() {
+
+ if (null == userPrincipal) {
+ synchronized (UserGenericPrincipal.class) {
+ // check again, because the thread might have been preempted
+ // just after the outer if was processed but before the
+ // synchronized statement was executed
+ if (userPrincipal == null) {
+ userPrincipal = new UserGenericPrincipal();
+ }
+ }
+ }
+ return userPrincipal;
+ }
+
+ public Principal removePrincipal(String username) {
+
+ synchronized (principals) {
+ return (Principal) principals.remove(username);
+ }
+
+ }
+
+ public HashMap getPrincipals() {
+ return principals;
+ }
+
+}
diff --git a/teamengine-web/RegistrationHandlerServlet.java b/teamengine-web/RegistrationHandlerServlet.java
new file mode 100644
index 00000000..c0fcad63
--- /dev/null
+++ b/teamengine-web/RegistrationHandlerServlet.java
@@ -0,0 +1,78 @@
+/****************************************************************************
+
+ The Original Code is TEAM Engine.
+
+ The Initial Developer of the Original Code is Northrop Grumman Corporation
+ jointly with The National Technology Alliance. Portions created by
+ Northrop Grumman Corporation are Copyright (C) 2005-2006, Northrop
+ Grumman Corporation. All Rights Reserved.
+
+ Contributor(s): No additional contributors to date
+
+ ****************************************************************************/
+package com.occamlab.te.web;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.occamlab.te.realm.PasswordStorage;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+
+/**
+ * Handles requests to register new users.
+ *
+ */
+public class RegistrationHandlerServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 7428127065308163495L;
+
+ Config conf;
+
+ public void init() throws ServletException {
+ conf = new Config();
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+ try {
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+ String hashedPassword = PasswordStorage.createHash(password);
+ String email = request.getParameter("email");
+ String firstName = request.getParameter("firstName");
+ String lastName = request.getParameter("lastName");
+ String organization = request.getParameter("organization");
+ File userDir = new File(conf.getUsersDir(), username);
+ if (userDir.exists()) {
+ String url = "register.jsp?error=duplicate&username=" + username;
+ if (email != null) {
+ url += "&email=" + email;
+ }
+ response.sendRedirect(url);
+ } else {
+ userDir.mkdirs();
+ File xmlfile = new File(userDir, "user.xml");
+ PrintStream out = new PrintStream(new FileOutputStream(xmlfile));
+ out.println("");
+ out.println(" " + username + "");
+ out.println(" ");
+ out.println(" user");
+ out.println(" ");
+ out.println(" " + hashedPassword + "");
+ out.println(" " + email + "");
+ out.println(" " + firstName + "");
+ out.println(" " + lastName + "");
+ out.println(" " + organization + "");
+ out.println("");
+ out.close();
+ response.sendRedirect("registered.jsp");
+ }
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+}
diff --git a/teamengine-web/src/main/java/com/occamlab/te/web/ChangePasswordHandler.java b/teamengine-web/src/main/java/com/occamlab/te/web/ChangePasswordHandler.java
new file mode 100644
index 00000000..3966d0f6
--- /dev/null
+++ b/teamengine-web/src/main/java/com/occamlab/te/web/ChangePasswordHandler.java
@@ -0,0 +1,81 @@
+package com.occamlab.te.web;
+
+import java.io.File;
+import java.security.Principal;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import com.occamlab.te.config.Config;
+import com.occamlab.te.realm.PasswordStorage;
+import com.occamlab.te.realm.UserGenericPrincipal;
+import com.occamlab.te.util.XMLUtils;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+/**
+ * Handles requests to change password.
+ *
+ */
+public class ChangePasswordHandler extends HttpServlet {
+
+ Config conf;
+
+ public void init() throws ServletException {
+ conf = new Config();
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+
+ try {
+ String oldPass = request.getParameter("oldPass");
+ String username = request.getParameter("username");
+ String newPassword = request.getParameter("newPassword");
+
+ File userDir = new File(conf.getUsersDir(), username);
+ if (!userDir.exists()) {
+ String url = "changePassword.jsp?error=userNotExists&username=" + username;
+ response.sendRedirect(url);
+ }
+ else {
+ File xmlfile = new File(userDir, "user.xml");
+ Document doc = XMLUtils.parseDocument(xmlfile);
+ Element userDetails = (Element) (doc.getElementsByTagName("user").item(0));
+
+ NodeList oldPwdList = userDetails.getElementsByTagName("password");
+ String storedOldPassword = null;
+ if (oldPwdList.getLength() > 0) {
+ Element oldePwdElement = (Element) oldPwdList.item(0);
+ storedOldPassword = oldePwdElement.getTextContent();
+ }
+
+ Boolean isValid = PasswordStorage.verifyPassword(oldPass, storedOldPassword);
+ if (isValid) {
+ doc = XMLUtils.removeElement(doc, userDetails, "password");
+ Element pwdElement = doc.createElement("password");
+ pwdElement.setTextContent(PasswordStorage.createHash(newPassword));
+ userDetails.appendChild(pwdElement);
+ XMLUtils.transformDocument(doc, new File(userDir, "user.xml"));
+ Principal userPrincipal = UserGenericPrincipal.getInstance().removePrincipal(username);
+ if (userPrincipal == null) {
+ throw new RuntimeException("Failed update old credentials");
+ }
+ request.getSession().invalidate();
+ response.sendRedirect(request.getContextPath());
+ }
+ else {
+ String url = "changePassword.jsp?error=invalidOldPwd";
+ response.sendRedirect(url);
+ }
+ }
+ }
+ catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+}
diff --git a/teamengine-web/src/main/java/com/occamlab/te/web/EmailUtility.java b/teamengine-web/src/main/java/com/occamlab/te/web/EmailUtility.java
new file mode 100644
index 00000000..2852973e
--- /dev/null
+++ b/teamengine-web/src/main/java/com/occamlab/te/web/EmailUtility.java
@@ -0,0 +1,59 @@
+package com.occamlab.te.web;
+
+import java.util.Date;
+import java.util.Properties;
+import java.util.Random;
+
+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;
+
+public class EmailUtility {
+
+ public static void sendEmail(String host, String portNo, final String userName, final String pwd, String toAddress,
+ String subject, String message) throws AddressException, MessagingException {
+
+ Properties properties = new Properties();
+ properties.put("mail.smtp.host", host);
+ properties.put("mail.smtp.port", portNo);
+ properties.put("mail.smtp.auth", "true");
+ properties.put("mail.smtp.starttls.enable", "true");
+ // see https://bugs.openjdk.org/browse/JDK-8202343
+ properties.put("mail.smtp.ssl.protocols", "TLSv1.2");
+
+ Authenticator auth = new Authenticator() {
+ public PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(userName, pwd);
+ }
+ };
+
+ Session session = Session.getInstance(properties, auth);
+ Message msg = new MimeMessage(session);
+ try {
+ msg.setFrom(new InternetAddress(userName));
+ InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
+ msg.setRecipients(Message.RecipientType.TO, toAddresses);
+ msg.setSubject(subject);
+ msg.setSentDate(new Date());
+ msg.setContent(message, "text/html; charset=utf-8");
+
+ Transport.send(msg);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Failed send mail : " + e.getMessage());
+ }
+ }
+
+ public static String getRandomNumberString() {
+ Random randomNo = new Random();
+ int number = randomNo.nextInt(999999);
+ return String.format("%06d", number);
+ }
+
+}
diff --git a/teamengine-web/src/main/java/com/occamlab/te/web/ResetPasswordHandler.java b/teamengine-web/src/main/java/com/occamlab/te/web/ResetPasswordHandler.java
new file mode 100644
index 00000000..e338a798
--- /dev/null
+++ b/teamengine-web/src/main/java/com/occamlab/te/web/ResetPasswordHandler.java
@@ -0,0 +1,268 @@
+package com.occamlab.te.web;
+
+import static java.util.logging.Level.SEVERE;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.occamlab.te.config.Config;
+import com.occamlab.te.realm.PasswordStorage;
+import com.occamlab.te.util.XMLUtils;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+/**
+ * Handles requests to register new users.
+ *
+ */
+public class ResetPasswordHandler extends HttpServlet {
+
+ private static final Logger LOGR = Logger.getLogger(ResetPasswordHandler.class.getName());
+
+ Config conf;
+
+ private String host;
+
+ private String port;
+
+ private String user;
+
+ private String pass;
+
+ private String subject = "Reset your TEAM Engine password";
+
+ private String message;
+
+ File userDir;
+
+ public void init() throws ServletException {
+ conf = new Config();
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+ String servletPath = request.getServletPath();
+ if ("/resetPasswordHandler".equalsIgnoreCase(servletPath)) {
+ resetPassowrdHandler(request, response);
+ }
+ else if ("/updatePasswordHandler".equalsIgnoreCase(servletPath)) {
+ updatePassword(request, response);
+ }
+ }
+
+ /**
+ * This method will send email to registered user along with the verification code and
+ * verification code will stored into user.xml file.
+ */
+ public void resetPassowrdHandler(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+ try {
+ String username = request.getParameter("username");
+ userDir = new File(conf.getUsersDir(), username);
+ if (!userDir.exists()) {
+ String url = "resetPassword.jsp?error=userNotExists&username=" + username;
+ response.sendRedirect(url);
+ }
+ else {
+ Properties properties = new Properties();
+ properties = getEmailProps();
+ host = properties.getProperty("host");
+ port = properties.getProperty("port");
+ user = properties.getProperty("user");
+ pass = properties.getProperty("pass");
+ File xmlfile = new File(userDir, "user.xml");
+ Document doc = XMLUtils.parseDocument(xmlfile);
+ Element userDetails = (Element) (doc.getElementsByTagName("user").item(0));
+ NodeList emailList = userDetails.getElementsByTagName("email");
+ String vCode = EmailUtility.getRandomNumberString();
+ message = "" + "" + ""
+ + ""
+ + "" + ""
+ + "" + "" + " "
+ + ""
+ + "" + " "
+ + " "
+ + " " + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " | Dear "
+ + username + ", | " + " "
+ + " "
+ + " | You recently requested to reset your password for your TEAM Engine account. Use below verfication code to reset your password. | "
+ + " "
+ + " "
+ + " | Verification Code : "
+ + vCode + " | " + " "
+ + " "
+ + " | If you did not request a password reset, please ignore this email or contact the CITE team. | "
+ + " "
+ + " "
+ + " | Follow this link to reset your password. | "
+ + " "
+ + " "
+ + " Regards, CITE team | "
+ + " "
+ + " " + " | "
+ + " " + " "
+ + " | " + " " + " "
+ + " | " + "
" + "
" + "" + "";
+
+ if (emailList.getLength() > 0) {
+ saveVerificationCode(doc, userDetails, vCode);
+ EmailUtility.sendEmail(host, port, user, pass, emailList.item(0).getTextContent(), subject,
+ message);
+ response.sendRedirect("updatePassword.jsp?emailStatus=true");
+ }
+ else {
+ String url = "resetPassword.jsp?error=emailNotExists&username=" + username;
+ response.sendRedirect(url);
+ }
+ }
+ }
+ catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+ /**
+ * This method will validate the verification code and update the new password if the
+ * code is valid. Otherwise it will throw error.
+ * @throws ServletException
+ */
+ public void updatePassword(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+ try {
+ String vCode = request.getParameter("vCode");
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+ String hashedPassword = PasswordStorage.createHash(password);
+
+ userDir = new File(conf.getUsersDir(), username);
+ if (!userDir.exists()) {
+ String url = "updatePassword.jsp?error=userNotExists&username=" + username;
+ response.sendRedirect(url);
+ }
+ else {
+ File xmlfile = new File(userDir, "user.xml");
+ Document doc = XMLUtils.parseDocument(xmlfile);
+ Element userDetails = (Element) (doc.getElementsByTagName("user").item(0));
+
+ NodeList vCodeList = userDetails.getElementsByTagName("verificationCode");
+ String storedVerificationCode = null;
+ if (vCodeList.getLength() > 0) {
+ Element vCodeElement = (Element) doc.getElementsByTagName("verificationCode").item(0);
+ storedVerificationCode = vCodeElement.getTextContent();
+ }
+
+ if (storedVerificationCode.equalsIgnoreCase(vCode)) {
+ NodeList pwdList = userDetails.getElementsByTagName("password");
+ if (pwdList.getLength() != 0) {
+ Element pwdElement = (Element) doc.getElementsByTagName("password").item(0);
+ Node parent = pwdElement.getParentNode();
+ parent.removeChild(pwdElement);
+ }
+ Element pwdElement = doc.createElement("password");
+ pwdElement.setTextContent(hashedPassword);
+ userDetails.appendChild(pwdElement);
+ XMLUtils.transformDocument(doc, new File(userDir, "user.xml"));
+ String url = "viewSessions.jsp?success=pwd";
+ response.sendRedirect(url);
+ }
+ else {
+ String url = "updatePassword.jsp?error=invalidVcode&username=" + username + "&vCode=" + vCode;
+ response.sendRedirect(url);
+ }
+ }
+ }
+ catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+ /**
+ * Store verification code into the user.xml file to validate the code.
+ * @param doc
+ * @param userDetails
+ * @param verifyCode
+ */
+ public void saveVerificationCode(Document doc, Element userDetails, String verifyCode) {
+
+ // Remove element if exist.
+ doc = XMLUtils.removeElement(doc, userDetails, "verificationCode");
+
+ // Update new details to existing document
+ Element verificationCode = doc.createElement("verificationCode");
+ verificationCode.setTextContent(verifyCode);
+ userDetails.appendChild(verificationCode);
+ XMLUtils.transformDocument(doc, new File(userDir, "user.xml"));
+ }
+
+ /**
+ * Returns the base URL from the current request context.
+ * @param request
+ * @return baseUrl
+ */
+ public static String getBaseUrl(HttpServletRequest request) {
+ String scheme = request.getScheme();
+ String host = request.getServerName();
+ int port = request.getServerPort();
+ String contextPath = request.getContextPath();
+
+ String baseUrl = scheme + "://" + host
+ + ((("http".equals(scheme) && port == 80) || ("https".equals(scheme) && port == 443)) ? "" : ":" + port)
+ + contextPath;
+ return baseUrl;
+ }
+
+ public Properties getEmailProps() {
+
+ Properties prop = new Properties();
+ InputStream input = null;
+
+ try {
+
+ input = getClass().getResourceAsStream("/email.properties");
+ if (input == null) {
+ LOGR.log(SEVERE, "Sorry, unable to find 'email.properties'");
+ return prop;
+ }
+ prop.load(input);
+
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ finally {
+ if (input != null) {
+ try {
+ input.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return prop;
+ }
+
+}
diff --git a/teamengine-web/src/main/java/com/occamlab/te/web/listeners/ClearVerificationCode.java b/teamengine-web/src/main/java/com/occamlab/te/web/listeners/ClearVerificationCode.java
new file mode 100644
index 00000000..a92fbb8d
--- /dev/null
+++ b/teamengine-web/src/main/java/com/occamlab/te/web/listeners/ClearVerificationCode.java
@@ -0,0 +1,55 @@
+package com.occamlab.te.web.listeners;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.occamlab.te.config.Config;
+import com.occamlab.te.util.XMLUtils;
+
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterConfig;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+public class ClearVerificationCode implements Filter {
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse res = (HttpServletResponse) response;
+ String username = req.getRemoteUser();
+
+ if (username != null) {
+
+ Config conf = new Config();
+ File userDir = new File(conf.getUsersDir(), username);
+ if (userDir.exists()) {
+ String fileName = "user.xml";
+ File xmlfile = new File(userDir, fileName);
+ Document doc = XMLUtils.parseDocument(xmlfile);
+ Element userDetails = (Element) (doc.getElementsByTagName("user").item(0));
+ doc = XMLUtils.removeElement(doc, userDetails, "verificationCode");
+ XMLUtils.transformDocument(doc, new File(userDir, fileName));
+ }
+ }
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+}
diff --git a/teamengine-web/src/main/java/com/occamlab/te/web/listeners/CleartextPasswordContextListener.java b/teamengine-web/src/main/java/com/occamlab/te/web/listeners/CleartextPasswordContextListener.java
index b575fcbf..9929d63b 100644
--- a/teamengine-web/src/main/java/com/occamlab/te/web/listeners/CleartextPasswordContextListener.java
+++ b/teamengine-web/src/main/java/com/occamlab/te/web/listeners/CleartextPasswordContextListener.java
@@ -12,9 +12,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import jakarta.servlet.ServletContextEvent;
-import jakarta.servlet.ServletContextListener;
-import jakarta.servlet.annotation.WebListener;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -30,6 +27,10 @@
import com.occamlab.te.SetupOptions;
import com.occamlab.te.realm.PasswordStorage;
+import jakarta.servlet.ServletContextEvent;
+import jakarta.servlet.ServletContextListener;
+import jakarta.servlet.annotation.WebListener;
+
/**
* A context listener that checks for the presence of clear text passwords in user info
* files ({TE_BASE}/users/{userid}/user.xml). If one is found that does not
diff --git a/teamengine-web/src/main/resources/email.properties b/teamengine-web/src/main/resources/email.properties
new file mode 100644
index 00000000..cb2b23ac
--- /dev/null
+++ b/teamengine-web/src/main/resources/email.properties
@@ -0,0 +1,4 @@
+host=smtp.gmail.com
+port=587
+user=demo@demo.com
+pass=demo123
\ No newline at end of file
diff --git a/teamengine-web/src/main/webapp/WEB-INF/web.xml b/teamengine-web/src/main/webapp/WEB-INF/web.xml
index 08a657d1..32bad2b0 100644
--- a/teamengine-web/src/main/webapp/WEB-INF/web.xml
+++ b/teamengine-web/src/main/webapp/WEB-INF/web.xml
@@ -11,6 +11,14 @@
appVersion
${project.version}
+
+ clearVerificationCode
+ com.occamlab.te.web.listeners.ClearVerificationCode
+
+
+ clearVerificationCode
+ /viewSessions.jsp
+
test
com.occamlab.te.web.TestServlet
@@ -41,6 +49,18 @@
prettyPrintLogs
com.occamlab.te.web.PrettyPrintLogsServlet
+
+ resetPasswordHandler
+ com.occamlab.te.web.ResetPasswordHandler
+
+
+ updatePasswordHandler
+ com.occamlab.te.web.ResetPasswordHandler
+
+
+ changePasswordHandler
+ com.occamlab.te.web.ChangePasswordHandler
+
emailLog
com.occamlab.te.web.EmailLogServlet
@@ -94,6 +114,18 @@
registrationHandler
/registrationHandler
+
+ resetPasswordHandler
+ /resetPasswordHandler
+
+
+ updatePasswordHandler
+ /updatePasswordHandler
+
+
+ changePasswordHandler
+ /changePasswordHandler
+
logout
/logout
@@ -144,6 +176,7 @@
/viewSessionLog.jsp
/viewOldSessionLog.jsp
/viewSessions.jsp
+ /changePassword.jsp
/viewTest.jsp
/viewTestLog.jsp
/emailLog.jsp
diff --git a/teamengine-web/src/main/webapp/changePassword.jsp b/teamengine-web/src/main/webapp/changePassword.jsp
new file mode 100644
index 00000000..233b24f9
--- /dev/null
+++ b/teamengine-web/src/main/webapp/changePassword.jsp
@@ -0,0 +1,99 @@
+<%@ page language="java" session="false"%>
+
+<%
+String username = request.getRemoteUser();
+%>
+
+
+
+
+Reset Password
+
+
+
+ <%@ include file="header.jsp"%>
+ Change Password
+
+ <%
+ if ("userNotExists".equals(request.getParameter("error"))) {
+ out.println("The \"" + username + "\" is not registered username. Please try with registered User.");
+ } else if ("invalidOldPwd".equals(request.getParameter("error"))) {
+ out.println("The Old password is not valid.");
+ }
+ %>
+
+
+
+ <%@ include file="footer.jsp"%>
+
+
diff --git a/teamengine-web/src/main/webapp/header.jsp b/teamengine-web/src/main/webapp/header.jsp
index 9cff2033..353590b7 100644
--- a/teamengine-web/src/main/webapp/header.jsp
+++ b/teamengine-web/src/main/webapp/header.jsp
@@ -16,7 +16,7 @@
if (user != null && user.length() > 0) {
out.println("\t\t");
out.println("\t\t\tUser: " + user + "
");
- out.println("\t\t\t
Logout");
+ out.println("\t\t\t
Logout\t\t\t" + "
| Change Password");
out.println("\t\t
");
} else {
out.println("");
diff --git a/teamengine-web/src/main/webapp/login.jsp b/teamengine-web/src/main/webapp/login.jsp
index 755bea93..82a69608 100644
--- a/teamengine-web/src/main/webapp/login.jsp
+++ b/teamengine-web/src/main/webapp/login.jsp
@@ -25,14 +25,29 @@ if (request.getParameter("error") != null) {
out.println("
The username and/or password did not match. Please try again.");
}
%>
+
+ <%
+ if ("pwd".equals(request.getParameter("success"))) {
+ out.println("Thank you! Your password is succesfully changed.");
+ }
+ %>
+
If you don't have a username and password, please
register.
<%@ include file="footer.jsp" %>
diff --git a/teamengine-web/src/main/webapp/resetPassword.jsp b/teamengine-web/src/main/webapp/resetPassword.jsp
new file mode 100644
index 00000000..453d42cd
--- /dev/null
+++ b/teamengine-web/src/main/webapp/resetPassword.jsp
@@ -0,0 +1,67 @@
+<%@ page language="java" session="false"%>
+
+<%
+String email = request.getParameter("email");
+String username = request.getParameter("username");
+%>
+
+
+
+
+
Reset Password
+
+
+
+ <%@ include file="header.jsp" %>
+
Reset Password
+
+<%
+if ("userNotExists".equals(request.getParameter("error"))) {
+ out.println("The \"" + username + "\" is not registered username. Please try with registered User.");
+} else if ("emailNotExists".equals(request.getParameter("error"))) {
+ out.println("Sorry, email \"" + email + "\" is not registered. Please try with registered email.");
+ }
+%>
+
+
+ <%@ include file="footer.jsp" %>
+
+
diff --git a/teamengine-web/src/main/webapp/updatePassword.jsp b/teamengine-web/src/main/webapp/updatePassword.jsp
new file mode 100644
index 00000000..919705c2
--- /dev/null
+++ b/teamengine-web/src/main/webapp/updatePassword.jsp
@@ -0,0 +1,106 @@
+<%@ page language="java" session="false"%>
+
+<%
+String vCode = request.getParameter("vCode");
+String username = request.getParameter("username");
+%>
+
+
+
+
+
Reset Password
+
+
+
+ <%@ include file="header.jsp"%>
+
Reset Password
+
+ <%
+ if ("invalidVcode".equals(request.getParameter("error"))) {
+ out.println("The Verification code is invalid.");
+ }
+ %>
+
+
+ <%
+ if ("true".equals(request.getParameter("emailStatus"))) {
+ out.println("Thank you! The verification code has been sent successfully to registered email.");
+ }
+ %>
+
+
+ <%@ include file="footer.jsp"%>
+
+