Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use same account when logging in with Google or E-Mail, if addresses match #124

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,27 @@
import de.haumacher.phoneblock.db.DBService;
import de.haumacher.phoneblock.mail.MailService;
import de.haumacher.phoneblock.mail.MailServiceStarter;
import de.haumacher.phoneblock.util.ServletUtil;

/**
* {@link HttpServlet} that is invoked from the <code>signup.jsp</code> form.
* {@link HttpServlet} that is invoked from the <code>login.jsp</code> form when requesting to login by e-mail.
*/
@WebServlet(urlPatterns = {
EMailVerificationServlet.VERIFY_WEB,
EMailVerificationServlet.LOGIN_WEB,
})
public class EMailVerificationServlet extends HttpServlet {

public static final String VERIFY_WEB = "/verify-web";
/**
* Request attribute holding the page to re-start login/signup.
*/
public static final String RESTART_PAGE_ATTR = "restartPage";

/**
* Request attribute set, if e-mail verification failed.
*/
public static final String VERIFY_ERROR_ATTR = "message";

public static final String LOGIN_WEB = "/login-web";

private static final Logger LOG = LoggerFactory.getLogger(EMailVerificationServlet.class);

Expand Down Expand Up @@ -66,26 +77,30 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
req.getSession().setAttribute("email", email);
req.getSession().setAttribute("code", code);
req.setAttribute("email", email);
req.setAttribute(RESTART_PAGE_ATTR, failurePage(req));
req.getRequestDispatcher(successPage(req)).forward(req, resp);
}

private void sendFailure(HttpServletRequest req, HttpServletResponse resp, String message)
throws ServletException, IOException {
req.setAttribute("message", message);
req.setAttribute(VERIFY_ERROR_ATTR, message);
req.getRequestDispatcher(failurePage(req)).forward(req, resp);
}

private String failurePage(HttpServletRequest req) {
/**
* The page to redirect, if something went wrong.
*/
private static String failurePage(HttpServletRequest req) {
switch (req.getServletPath()) {
case VERIFY_WEB:
case LOGIN_WEB:
default:
return "/signup.jsp";
return "/login.jsp";
}
}

private String successPage(HttpServletRequest req) {
switch (req.getServletPath()) {
case VERIFY_WEB:
case LOGIN_WEB:
default:
return "/signup-code.jsp";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
@WebServlet(urlPatterns = LoginServlet.PATH)
public class LoginServlet extends HttpServlet {

/**
* Request attribute set, if a login was not successful.
*/
public static final String LOGIN_ERROR_ATTR = "loginError";

public static final String USER_NAME_PARAM = "userName";

public static final String PASSWORD_PARAM = "password";
Expand Down Expand Up @@ -96,6 +101,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S

LoginFilter.setAuthenticatedUser(req, authenticatedUser);

redirectToLocationAfterLogin(req, resp);
}

/**
* Redirects the current request to its final destination.
*/
public static void redirectToLocationAfterLogin(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String location = location(req);
if (location == null) {
resp.sendRedirect(req.getContextPath() + SettingsServlet.PATH);
Expand All @@ -120,7 +132,7 @@ public static void processRememberMe(HttpServletRequest req, HttpServletResponse
* Redirects the client to the login page.
*/
public static void sendFailure(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("error", "Anmeldung fehlgeschlagen.");
req.setAttribute(LOGIN_ERROR_ATTR, "Anmeldung fehlgeschlagen.");
req.getRequestDispatcher("/login.jsp").forward(req, resp);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
})
public class RegistrationServlet extends HttpServlet {

/**
* Request attribute set, if registration fails.
*/
public static final String REGISTER_ERROR_ATTR = "message";

public static final String REGISTER_WEB = "/register-web";

private static final String PASSWORD_ATTR = "passwd";

/**
* The authorization scope "email".
*/
public static final String IDENTIFIED_BY_EMAIL = "email";

private static final Logger LOG = LoggerFactory.getLogger(RegistrationServlet.class);

@Override
Expand All @@ -57,26 +57,33 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
String email = (String) req.getSession().getAttribute("email");

String login;
String passwd;
try {
String passwd;

DB db = DBService.getInstance();
String extId = email.trim().toLowerCase();
login = db.getLogin(RegistrationServlet.IDENTIFIED_BY_EMAIL, extId);
login = db.getEmailLogin(email);
if (login == null) {
login = UUID.randomUUID().toString();
passwd = db.createUser(IDENTIFIED_BY_EMAIL, extId, login, email);

String displayName = DB.toDisplayName(email);

passwd = db.createUser(login, displayName);
db.setEmail(login, email);
} else {
passwd = db.resetPassword(login);
// No longer known.
passwd = null;
}

String rememberValue = req.getParameter(LoginServlet.REMEMBER_PARAM);
LoginServlet.processRememberMe(req, resp, db, rememberValue, login);

startSetup(req, resp, login, passwd);
} catch (Exception ex) {
LOG.error("Failed to create user: " + email, ex);

sendError(req, resp, "Bei der Erstellung des Accounts ist ein Fehler aufgetreten: " + ex.getMessage());
return;
}

startSetup(req, resp, login, passwd);
}

/**
Expand All @@ -85,13 +92,20 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
public static void startSetup(HttpServletRequest req, HttpServletResponse resp,
String login, String passwd) throws ServletException, IOException {
LoginFilter.setAuthenticatedUser(req, login);
req.getSession().setAttribute(PASSWORD_ATTR, passwd);
if (passwd != null) {
req.getSession().setAttribute(PASSWORD_ATTR, passwd);
}

String location = LoginServlet.location(req);
if (location != null) {
resp.sendRedirect(req.getContextPath() + location);
} else {
resp.sendRedirect(req.getContextPath() + successPage(req));
if (passwd == null) {
// Was already registered, no automatic password-reset.
resp.sendRedirect(req.getContextPath() + SettingsServlet.PATH);
} else {
resp.sendRedirect(req.getContextPath() + successPage(req));
}
}
}

Expand All @@ -104,7 +118,7 @@ private static String successPage(HttpServletRequest req) {
}

private void sendError(HttpServletRequest req, HttpServletResponse resp, String message) throws ServletException, IOException {
req.setAttribute("message", message);
req.setAttribute(REGISTER_ERROR_ATTR, message);
req.getRequestDispatcher(errorPage(req)).forward(req, resp);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
String password = DBService.getInstance().resetPassword(login);
if (password == null) {
req.setAttribute("message", "Nutzername nicht gefunden, bitte versuch Dich neu zu registrieren.");
req.getRequestDispatcher("/signup.jsp").forward(req, resp);
req.getRequestDispatcher("/login.jsp").forward(req, resp);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.IOException;
import java.util.UUID;

import jakarta.mail.internet.AddressException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
Expand Down Expand Up @@ -45,17 +46,22 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
DB db = DBService.getInstance();
String email = sessionInfo.getEmail();

String extId = email.trim().toLowerCase();
String login = db.getLogin(RegistrationServlet.IDENTIFIED_BY_EMAIL, extId);
String login;
String password;
if (login == null) {
login = UUID.randomUUID().toString();
password = db.createUser(RegistrationServlet.IDENTIFIED_BY_EMAIL, extId, login, email);
} else {
password = db.resetPassword(login);
try {
login = db.getEmailLogin(email);
if (login == null) {
login = UUID.randomUUID().toString();
password = db.createUser(login, email);
db.setEmail(login, email);
} else {
password = db.resetPassword(login);
}
} catch (AddressException e) {
ServletUtil.sendError(resp, "Invalid e-mail address.");
return;
}

db.setEmail(login, email);

ServletUtil.sendResult(req, resp, RegistrationResult.create().setSession(sessionInfo.getSession()).setLogin(login).setPassword(password));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Optional;
import java.util.UUID;

import jakarta.mail.internet.AddressException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
Expand Down Expand Up @@ -76,13 +77,31 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
displayName = null;
}

String extId = userProfile.getId();
String googleId = userProfile.getId();

Optional<Object> location = sessionStore.get(context, LoginServlet.LOCATION_ATTRIBUTE);

DB db = DBService.getInstance();
String login = db.getLogin(clientName, extId);
String login = db.getGoogleLogin(googleId);
if (login == null) {
if (email != null && !email.isBlank()) {
try {
login = db.getEmailLogin(email);
if (login != null) {
// Link accounts.
db.setGoogleId(login, googleId, displayName);
}
} catch (AddressException e) {
LOG.warn("Reveived invalid e-mail address during Google login of {} login: {}", googleId, email);

// Do not try again, see below.
email = null;
}
}
}

if (login == null) {
// Create new account.
login = UUID.randomUUID().toString();

if (displayName == null) {
Expand All @@ -93,10 +112,14 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
}
}

String passwd = db.createUser(clientName, extId, login, displayName);
db.setExtId(login, extId);
String passwd = db.createUser(login, displayName);
db.setGoogleId(login, googleId, null);
if (email != null) {
db.setEmail(login, email);
try {
db.setEmail(login, email);
} catch (AddressException e) {
LOG.warn("Reveived invalid e-mail address during Google login of {} login: {}", googleId, email);
}
}

if (location.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public AddressBookResource lookupAddressBook(String rootUrl, String serverRoot,

try (SqlSession session = DBService.getInstance().openSession()) {
Users users = session.getMapper(Users.class);
UserSettings settings = users.getSettings(principal);
UserSettings settings = users.getSettingsRaw(principal);

int minVotes = settings.getMinVotes();
int maxLength = settings.getMaxLength();
Expand Down
Loading