package org.swellrt.server.box.servlet; import com.google.inject.Inject; import org.waveprotocol.box.server.account.AccountData; import org.waveprotocol.box.server.account.HumanAccountData; import org.waveprotocol.box.server.account.SecretToken; import org.waveprotocol.box.server.authentication.PasswordDigest; import org.waveprotocol.box.server.authentication.SessionManager; import org.waveprotocol.box.server.persistence.AccountStore; import org.waveprotocol.box.server.persistence.PersistenceException; import org.waveprotocol.wave.model.wave.InvalidParticipantAddress; import org.waveprotocol.wave.model.wave.ParticipantId; import java.io.IOException; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PasswordService extends BaseService { public static final String ID = "id"; public static final String TOKEN_OR_PASSWORD = "token-or-password"; public static final String NEW_PASSWORD = "new-password"; private final AccountStore accountStore; @Inject public PasswordService(SessionManager sessionManager, AccountStore accountStore) { super(sessionManager); this.accountStore = accountStore; } @Override public void execute(HttpServletRequest req, HttpServletResponse response) throws IOException { ParticipantId participantId = sessionManager.getLoggedInUser(req); if (participantId == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } Enumeration<String> paramNames = req.getParameterNames(); if (!paramNames.hasMoreElements()) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No parameters found!"); return; } String id = req.getParameter(ID); String tokenOrPassword = req.getParameter(TOKEN_OR_PASSWORD); String newPassword = req.getParameter(NEW_PASSWORD); if (id == null || tokenOrPassword == null || newPassword == null) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing required parameters"); } try { ParticipantId pId = ParticipantId.of(id); if (pId.isAnonymous()) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "User is anonymous"); return; } AccountData a = accountStore.getAccount(pId); if (a != null) { HumanAccountData account = a.asHuman(); SecretToken storedToken = account.getRecoveryToken(); if ((storedToken != null && storedToken.isActive() && storedToken.getToken().equals( tokenOrPassword)) || account.getPasswordDigest().verify(tokenOrPassword.toCharArray())) { // Change the original account object to preserve all acount data // during DB update. account.setPasswordDigest(new PasswordDigest(newPassword.toCharArray())); // Reset the token anyway account.setRecoveryToken((String) null); accountStore.putAccount(account); response.setStatus(HttpServletResponse.SC_OK); } else { response.sendError(HttpServletResponse.SC_FORBIDDEN); } } } catch (PersistenceException e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } catch (InvalidParticipantAddress e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "User id is not valid"); } } }