diff --git a/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationModule.java b/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationModule.java index fcfd883b0172febf6edb1870e31e807695899f16..3283283dd8d8e2b9fc2484f06931001d748857da 100644 --- a/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationModule.java +++ b/jams-common/src/main/java/net/jami/jams/common/authmodule/AuthenticationModule.java @@ -5,10 +5,12 @@ import net.jami.jams.common.authentication.AuthenticationSourceType; import net.jami.jams.common.jami.NameServer; import net.jami.jams.common.objects.user.User; +import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; public interface AuthenticationModule { @@ -19,4 +21,9 @@ public interface AuthenticationModule { boolean testModuleConfiguration(AuthenticationSourceType type, String configuration); boolean createUser(AuthenticationSourceType type, String realm, NameServer nameServer, User user); RSAPublicKey getAuthModulePubKey(); + boolean updateReset(User user, int needsReset); + boolean userExists(User user); + boolean userNeedsReset(User user); + boolean setNewOneTimePassword(String username, String otp); + char[] getOTP(String username); } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/user/LocalUserNeedsResetServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/user/LocalUserNeedsResetServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..70c49f6e488f0d88763467dd78bfb7fc215f19f5 --- /dev/null +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/user/LocalUserNeedsResetServlet.java @@ -0,0 +1,93 @@ +package net.jami.jams.server.servlets.api.user; + + +import com.jsoniter.output.JsonStream; +import lombok.extern.slf4j.Slf4j; +import net.jami.jams.ca.JamsCA; +import net.jami.jams.common.authentication.local.LocalAuthSettings; +import net.jami.jams.common.authmodule.AuthModuleKey; +import net.jami.jams.common.dao.StatementElement; +import net.jami.jams.common.dao.StatementList; +import net.jami.jams.common.objects.user.User; +import net.jami.jams.server.Server; +import net.jami.jams.server.servlets.api.install.CachedObjects; +import org.apache.catalina.webresources.CachedResource; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.security.SecureRandom; +import java.util.HashMap; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +@WebServlet("/api/user/needsreset") +@Slf4j +public class LocalUserNeedsResetServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + resp.setHeader("Access-Control-Allow-Origin", JamsCA.serverDomain); + resp.setContentType("application/json"); + StringBuilder stringBuilder = new StringBuilder(); + + try { + int x = 0; + while (true) { + x = req.getInputStream().read(); + if(x == -1) break; + stringBuilder.append((char) x); + } + } + catch (Exception e){ + log.error("error decoding request body"); + } + + + if(stringBuilder.toString() != null) { + + try { + if (CachedObjects.localAuthSettings != null && req.getParameterMap().containsKey("username")) { + + HashMap<String,String> statusInfo = new HashMap<>(); + LocalAuthSettings settings = CachedObjects.localAuthSettings; + String username = req.getParameter("username"); + + if(Server.dataStore.userExists(username)){ + StatementList statementList = new StatementList(); + StatementElement statementElement = new StatementElement("username","=",username,""); + statementList.addStatement(statementElement); + User user = Server.dataStore.getUserDao().getObjects(statementList).get(0); + + if (Server.userAuthenticationModule.userNeedsReset(user)) { + // show the OTP modal + char[] otp = Server.userAuthenticationModule.getOTP(req.getParameter("username")); + statusInfo.put("needsReset", "true"); + statusInfo.put("otp", new String(otp)); + } else { + // change status for user, generate new password and update info + Server.userAuthenticationModule.updateReset(user, 1); + String newPW = generateRandomPassword(); + Server.userAuthenticationModule.setNewOneTimePassword(req.getParameter("username"), newPW); + statusInfo.put("needsReset", "false"); + statusInfo.put("newPW", newPW); + } + } + + resp.getOutputStream().write(JsonStream.serialize(statusInfo).getBytes()); + resp.setStatus(200); + } + + } catch (Exception e) { + log.info(e.toString()); + resp.setStatus(500); + } + } + } + + // TODO : change to char array + public String generateRandomPassword() { + return new SecureRandom().ints(12, 48, 58).mapToObj(i -> String.valueOf((char)i)).collect(Collectors.joining()); + } +}