From 4eb8263687c5386b7d5f6dbe77c8dfe69878cdaa Mon Sep 17 00:00:00 2001 From: Sofia Baltzi <> Date: Wed, 16 May 2018 10:53:57 +0000 Subject: [PATCH] Add RequestActivationCode.java and .jsp, Fix titles of .jps pages, Fix email messages --- .../usermanagement/ForgotPasswordServlet.java | 4 +- .../usermanagement/RegisterServlet.java | 6 +- .../usermanagement/RemindUsernameServlet.java | 3 +- .../RequestActivationCodeServlet.java | 159 ++++++++++++++++++ ...ndLinkURIAuthenticationSuccessHandler.java | 8 + .../usermanagement/security/JWTGenerator.java | 84 +++++++-- src/main/webapp/WEB-INF/web.xml | 12 ++ src/main/webapp/activate.jsp | 2 +- src/main/webapp/emailSuccess.jsp | 2 +- src/main/webapp/error.jsp | 2 +- src/main/webapp/error404.jsp | 2 +- src/main/webapp/expiredVerificationCode.jsp | 2 +- src/main/webapp/registerSuccess.jsp | 2 +- src/main/webapp/requestActivationCode.jsp | 122 ++++++++++++++ src/main/webapp/resetPassword.jsp | 2 +- src/main/webapp/success.jsp | 2 +- src/main/webapp/successAddPassword.jsp | 2 +- src/main/webapp/verify.jsp | 2 +- src/main/webapp/verifyEmail.jsp | 2 +- 19 files changed, 392 insertions(+), 28 deletions(-) create mode 100644 src/main/java/eu/dnetlib/openaire/usermanagement/RequestActivationCodeServlet.java create mode 100644 src/main/webapp/requestActivationCode.jsp diff --git a/src/main/java/eu/dnetlib/openaire/usermanagement/ForgotPasswordServlet.java b/src/main/java/eu/dnetlib/openaire/usermanagement/ForgotPasswordServlet.java index e634d2e..77f1194 100644 --- a/src/main/java/eu/dnetlib/openaire/usermanagement/ForgotPasswordServlet.java +++ b/src/main/java/eu/dnetlib/openaire/usermanagement/ForgotPasswordServlet.java @@ -98,7 +98,9 @@ public class ForgotPasswordServlet extends HttpServlet { "

The verification code is " + vCode + "

" + "Click the URL below and proceed with verification." + "

" + resultPathWithVCode + "

" + - "

Thank you

"; + "

The verification code is valid for 24 hours.

" + + "

Thank you,

" + + "

OpenAIRE technical team

"; String verificationCodeSubject = "Your OpenAIRE password reset request"; diff --git a/src/main/java/eu/dnetlib/openaire/usermanagement/RegisterServlet.java b/src/main/java/eu/dnetlib/openaire/usermanagement/RegisterServlet.java index 2b75458..fc8879d 100644 --- a/src/main/java/eu/dnetlib/openaire/usermanagement/RegisterServlet.java +++ b/src/main/java/eu/dnetlib/openaire/usermanagement/RegisterServlet.java @@ -109,14 +109,16 @@ public class RegisterServlet extends HttpServlet { String verificationCodeMsg = "

Hello " + username + ",

" + "

A request has been made to verify your email and activate your OpenAIRE account. To activate your " + - "account, you will need to submit your username and this activation code in order to verify that the" + + "account, you will need to submit your username and this activation code in order to verify that the " + "request was legitimate.

" + "

" + "The activation code is " + vCode + "

" + "Click the URL below and proceed with activating your password." + "

" + resultPathWithVCode + "

" + - "

Thank you

"; + "

The activation code is valid for 24 hours.

" + + "

Thank you,

" + + "

OpenAIRE technical team

"; String verificationCodeSubject = "Activate your OpenAIRE account"; diff --git a/src/main/java/eu/dnetlib/openaire/usermanagement/RemindUsernameServlet.java b/src/main/java/eu/dnetlib/openaire/usermanagement/RemindUsernameServlet.java index e434f03..eb86008 100644 --- a/src/main/java/eu/dnetlib/openaire/usermanagement/RemindUsernameServlet.java +++ b/src/main/java/eu/dnetlib/openaire/usermanagement/RemindUsernameServlet.java @@ -86,7 +86,8 @@ public class RemindUsernameServlet extends HttpServlet { String verificationCodeMsg = "

Hello,

" + "

A username reminder has been requested for your OpenAIRE account.

" + "

Your username is " + username + ".

" + - "

Thank you

"; + "

Thank you,

" + + "

OpenAIRE technical team

"; String verificationCodeSubject = "Your OpenAIRE username"; diff --git a/src/main/java/eu/dnetlib/openaire/usermanagement/RequestActivationCodeServlet.java b/src/main/java/eu/dnetlib/openaire/usermanagement/RequestActivationCodeServlet.java new file mode 100644 index 0000000..92d5c11 --- /dev/null +++ b/src/main/java/eu/dnetlib/openaire/usermanagement/RequestActivationCodeServlet.java @@ -0,0 +1,159 @@ +package eu.dnetlib.openaire.usermanagement; + +import eu.dnetlib.openaire.user.utils.EmailSender; +import eu.dnetlib.openaire.user.utils.LDAPActions; +import eu.dnetlib.openaire.user.utils.VerificationActions; +import eu.dnetlib.openaire.user.utils.VerifyRecaptcha; +import eu.dnetlib.openaire.usermanagement.utils.UrlConstructor; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.context.support.SpringBeanAutowiringSupport; + +import javax.mail.MessagingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.UUID; + +/** + * Created by sofia on 14/5/2018. + */ +public class RequestActivationCodeServlet extends HttpServlet { + + @Autowired + private VerificationActions verificationActions; + + @Autowired + private LDAPActions ldapActions; + + @Autowired + private EmailSender emailSender; + + @Value("${oidc.home}") + private String oidcHomeUrl; + + @Value("${google.recaptcha.secret}") + private String secret; + + @Value("${google.recaptcha.key}") + private String sitekey; + + private static final Logger logger = Logger.getLogger(RequestActivationCodeServlet.class); + + public void init(ServletConfig config) throws ServletException { + super.init(config); + SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, + config.getServletContext()); + config.getServletContext().setAttribute("sitekey", sitekey); + + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + String formUsername = request.getParameter("username").trim(); + + String gRecaptchaResponse = request.getParameter("g-recaptcha-response"); + + HttpSession session = request.getSession(); + session.setAttribute("homeUrl", oidcHomeUrl); + + if (formUsername == null) { + request.getSession().setAttribute("message", "Error reading username."); + response.sendRedirect("./requestActivationCode.jsp"); + + } else if (formUsername.isEmpty()) { + request.getSession().setAttribute("message", "Please enter your username."); + response.sendRedirect("./requestActivationCode.jsp"); + + } else if (!VerifyRecaptcha.verify(gRecaptchaResponse, secret)) { + request.getSession().setAttribute("reCAPTCHA_message", "You missed the reCAPTCHA validation!"); + response.sendRedirect("./requestActivationCode.jsp"); + + } else { + + try { + if (ldapActions.isZombieUsersUsername(formUsername)) { + logger.info("User " + formUsername + " is zombie user!"); + + UUID verificationCode = UUID.randomUUID(); + Date creationDate = new Date(); + String vCode = verificationCode.toString(); + + Timestamp timestamp = new Timestamp(creationDate.getTime()); + + if (!verificationActions.verificationEntryExists(formUsername)) { + verificationActions.addVerificationEntry(formUsername, vCode, timestamp); + + } else { + verificationActions.updateVerificationEntry(formUsername, vCode, timestamp); + } + + String resultPath = UrlConstructor.getRedirectUrl(request, "activate.jsp"); + String resultPathWithVCode = UrlConstructor.getVerificationLink(resultPath, vCode); + + String verificationCodeMsg = "

Hello " + formUsername + ",

" + + "

A request has been made to get a new activation code to verify your email and activate your OpenAIRE account. To activate your " + + "account, you will need to submit your username and this activation code in order to verify that the " + + "request was legitimate.

" + + "

" + + "The activation code is " + vCode + + "

" + + "Click the URL below and proceed with activating your password." + + "

" + resultPathWithVCode + "

" + + "

The activation code is valid for 24 hours.

" + + "

Thank you,

" + + "

OpenAIRE technical team

"; + + String verificationCodeSubject = "Request a new activation code for your OpenAIRE account"; + + String email = ldapActions.getZombieUsersEmail(formUsername); + + if (email != null && !email.isEmpty()) { + emailSender.sendEmail(email, verificationCodeSubject, verificationCodeMsg); + logger.info("Sending activation code to user: " + formUsername); + } + + response.sendRedirect("./activate.jsp"); + + } else if (ldapActions.usernameExists(formUsername)) { + logger.info("User " + formUsername + " has already activated his account."); + request.getSession().setAttribute("message", "Your account is already activated."); + response.sendRedirect("./requestActivationCode.jsp"); + + } else { + logger.info("No user with username: " + formUsername); + request.getSession().setAttribute("message", "There is no user registered with that username."); + response.sendRedirect("./requestActivationCode.jsp"); + } + + } catch (MessagingException e) { + logger.error("Error in sending email", e); + request.getSession().setAttribute("message", "Error sending email"); + response.sendRedirect("./requestActivationCode.jsp"); + } catch (Exception ldape) { + logger.error("Could not find zombie user with username " + formUsername, ldape); + response.sendRedirect(UrlConstructor.getRedirectUrl(request, "error.jsp")); + } + } + } + + public String getOidcHomeUrl() { + return oidcHomeUrl; + } + + public void setOidcHomeUrl(String oidcHomeUrl) { + this.oidcHomeUrl = oidcHomeUrl; + } + + + + + +} diff --git a/src/main/java/eu/dnetlib/openaire/usermanagement/security/FrontEndLinkURIAuthenticationSuccessHandler.java b/src/main/java/eu/dnetlib/openaire/usermanagement/security/FrontEndLinkURIAuthenticationSuccessHandler.java index d666a11..e299f3f 100644 --- a/src/main/java/eu/dnetlib/openaire/usermanagement/security/FrontEndLinkURIAuthenticationSuccessHandler.java +++ b/src/main/java/eu/dnetlib/openaire/usermanagement/security/FrontEndLinkURIAuthenticationSuccessHandler.java @@ -1,5 +1,6 @@ package eu.dnetlib.openaire.usermanagement.security; +import com.google.gson.Gson; import org.apache.log4j.Logger; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.security.core.Authentication; @@ -29,15 +30,19 @@ public class FrontEndLinkURIAuthenticationSuccessHandler implements Authenticati try { Cookie jwt = new Cookie("XCsrfToken", JWTGenerator.generateToken(authOIDC, "my-very-secret")); + // Cookie openAIREUser = new Cookie("openAIREUser", new Gson().toJson(JWTGenerator.generateJsonToken(authOIDC))); Cookie accessToken = new Cookie("AccessToken", authOIDC.getAccessTokenValue()); // Expire the cookies in four hours (4 * 3600) jwt.setMaxAge(14400); + // openAIREUser.setMaxAge(14400); accessToken.setMaxAge(14400); //TODO DELETE LOG logger.info("\n////////////////////////////////////////////////////////////////////////////////////////////////\n"); + logger.info("jwt: " + JWTGenerator.generateToken(authOIDC, "my-very-secret")); logger.info("access token: " + authOIDC.getAccessTokenValue()); + // logger.info("openAIREUser: " + JWTGenerator.generateJsonToken(authOIDC)); logger.info("\n////////////////////////////////////////////////////////////////////////////////////////////////\n"); //TODO DELETE LOG @@ -48,10 +53,13 @@ public class FrontEndLinkURIAuthenticationSuccessHandler implements Authenticati jwt.setPath(frontPath); if (frontDomain!=null) jwt.setDomain(frontDomain); + // openAIREUser.setPath(frontPath); + // if (frontDomain!=null) openAIREUser.setDomain(frontDomain); accessToken.setPath(frontPath); if (frontDomain!=null) accessToken.setDomain(frontDomain); response.addCookie(jwt); + // response.addCookie(openAIREUser); response.addCookie(accessToken); response.sendRedirect(frontEndURI); diff --git a/src/main/java/eu/dnetlib/openaire/usermanagement/security/JWTGenerator.java b/src/main/java/eu/dnetlib/openaire/usermanagement/security/JWTGenerator.java index 7f18ccc..2155979 100644 --- a/src/main/java/eu/dnetlib/openaire/usermanagement/security/JWTGenerator.java +++ b/src/main/java/eu/dnetlib/openaire/usermanagement/security/JWTGenerator.java @@ -50,16 +50,16 @@ public class JWTGenerator { if (authOIDC.getUserInfo().getGivenName() == null){ logger.info("User: " + authOIDC.getUserInfo().getName() + "doesn't have first name"); claims.put("firstname", URLEncoder.encode(" ", "UTF-8") + ""); +// claims.put("firstname", ""); } else { claims.put("firstname", URLEncoder.encode(authOIDC.getUserInfo().getGivenName(), "UTF-8") + ""); - } if (authOIDC.getUserInfo().getFamilyName() == null){ logger.info("User: " + authOIDC.getUserInfo().getName() + "doesn't have first name"); claims.put("lastname", URLEncoder.encode(" ", "UTF-8") + ""); +// claims.put("lastname", ""); } else { claims.put("lastname", URLEncoder.encode(authOIDC.getUserInfo().getFamilyName(), "UTF-8") + ""); - } claims.put("email", authOIDC.getUserInfo().getEmail() + ""); // claims.put("role", URLEncoder.encode(userInfo.getAsJsonArray("edu_person_entitlements").toString(), "UTF-8") + ""); @@ -72,6 +72,7 @@ public class JWTGenerator { if (userInfo.getAsJsonArray("edu_person_entitlements") == null){ logger.info("User: " + authOIDC.getUserInfo().getName() + "doesn't have role"); claims.put("role", URLEncoder.encode(" ", "UTF-8") + ""); +//s claims.put("role", ""); } else { claims.put("role", URLEncoder.encode(userInfo.getAsJsonArray("edu_person_entitlements").toString(), "UTF-8") + ""); } @@ -103,11 +104,11 @@ public class JWTGenerator { // logger.info("expirationTime: " + exp); // logger.info("\n////////////////////////////////////////////////////////////////////////////////////////////////\n"); - return Jwts.builder() - .setClaims(claims) - .setExpiration(exp) - .signWith(SignatureAlgorithm.HS512, secret) - .compact(); + return Jwts.builder() + .setClaims(claims) + .setExpiration(exp) + .signWith(SignatureAlgorithm.HS512, secret) + .compact(); } catch (ParseException e) { e.printStackTrace(); @@ -120,6 +121,62 @@ public class JWTGenerator { } } + + public static JsonObject generateJsonToken(OIDCAuthenticationToken authOIDC) { + try { + + JsonObject userInfo = authOIDC.getUserInfo().getSource(); + JsonObject userInfo2 = new JsonObject(); + + if (authOIDC.getUserInfo().getSub() == null) { + logger.info("User doesn't have sub"); + userInfo2.addProperty("sub", ""); + } else { + userInfo2.addProperty("sub", URLEncoder.encode(authOIDC.getUserInfo().getSub(), "UTF-8")); + } + if (authOIDC.getUserInfo().getName() == null) { + logger.info("User doesn't have fullname"); + userInfo2.addProperty("fullname", ""); + } else { + userInfo2.addProperty("fullname", URLEncoder.encode(authOIDC.getUserInfo().getName(), "UTF-8")); + } + if (authOIDC.getUserInfo().getGivenName() == null){ + logger.info("User: " + authOIDC.getUserInfo().getName() + "doesn't have first name"); +// userInfo2.addProperty("firstname", URLEncoder.encode(" ", "UTF-8") + ""); + userInfo2.addProperty("firstname", ""); + } else { + userInfo2.addProperty("firstname", URLEncoder.encode(authOIDC.getUserInfo().getGivenName(), "UTF-8") + ""); + } + if (authOIDC.getUserInfo().getFamilyName() == null){ + logger.info("User: " + authOIDC.getUserInfo().getName() + "doesn't have first name"); +// userInfo2.addProperty("lastname", URLEncoder.encode(" ", "UTF-8") + ""); + userInfo2.addProperty("lastname", ""); + } else { + userInfo2.addProperty("lastname", URLEncoder.encode(authOIDC.getUserInfo().getFamilyName(), "UTF-8") + ""); + } + userInfo2.addProperty("email", authOIDC.getUserInfo().getEmail() + ""); + + if (userInfo.getAsJsonArray("edu_person_entitlements") == null){ + logger.info("User: " + authOIDC.getUserInfo().getName() + "doesn't have role"); +// userInfo2.addProperty("role", URLEncoder.encode(" ", "UTF-8") + ""); + userInfo2.addProperty("role", ""); + } else { + userInfo2.addProperty("role", URLEncoder.encode(userInfo.getAsJsonArray("edu_person_entitlements").toString(), "UTF-8") + ""); + } + + logger.info("UserINFO: " + userInfo2.toString()); + return userInfo2; + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + logger.error("UnsupportedEncodingException UTF-8 ", e); + JsonObject error = new JsonObject(); + error.addProperty("error", "UnsupportedEncodingException UTF-8 " + e); + return error; + } + + } + //TODO DELETE IF IT IS NOT NECESSARY public static String generateAccessToken(OIDCAuthenticationToken authOIDC, String secret) { Claims claims = Jwts.claims().setId(authOIDC.getAccessTokenValue()); @@ -141,14 +198,14 @@ public class JWTGenerator { JsonObject userInfo = user.getSource(); - Claims claims = Jwts.claims().setSubject(user.getSub()); - claims.put("email", user.getEmail() + ""); + Claims claims = Jwts.claims().setSubject(user.getSub()); + claims.put("email", user.getEmail() + ""); claims.put("role", URLEncoder.encode(userInfo.getAsJsonArray("edu_person_entitlements").toString(), "UTF-8") + ""); - return Jwts.builder() - .setClaims(claims) - .signWith(SignatureAlgorithm.HS512, secret) - .compact(); + return Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret) + .compact(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); logger.error("UnsupportedEncodingException UTF-8 ", e); @@ -160,6 +217,7 @@ public class JWTGenerator { + // How to add it manually // long nowMillis = System.currentTimeMillis(); // //This is my token diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index b7e9c40..7f8d519 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -106,6 +106,18 @@ /remindUsername + + RequestActivationCodeServlet + Request an activation code + eu.dnetlib.openaire.usermanagement.RequestActivationCodeServlet + 1 + + + + RequestActivationCodeServlet + /requestActivationCode + + CorsFilter diff --git a/src/main/webapp/activate.jsp b/src/main/webapp/activate.jsp index 4a109f1..9089a3e 100644 --- a/src/main/webapp/activate.jsp +++ b/src/main/webapp/activate.jsp @@ -14,7 +14,7 @@ - OpenAIRE - Forgot password, verification code + OpenAIRE - Activation diff --git a/src/main/webapp/emailSuccess.jsp b/src/main/webapp/emailSuccess.jsp index 79b2ffd..e56f175 100644 --- a/src/main/webapp/emailSuccess.jsp +++ b/src/main/webapp/emailSuccess.jsp @@ -21,7 +21,7 @@ - OpenAIRE - Forgot password + OpenAIRE - Email Sent diff --git a/src/main/webapp/error.jsp b/src/main/webapp/error.jsp index 54695ba..7b02e00 100644 --- a/src/main/webapp/error.jsp +++ b/src/main/webapp/error.jsp @@ -20,7 +20,7 @@ - OpenAIRE Single Sign-On Service + OpenAIRE - Error diff --git a/src/main/webapp/error404.jsp b/src/main/webapp/error404.jsp index 6028931..6fd57dd 100644 --- a/src/main/webapp/error404.jsp +++ b/src/main/webapp/error404.jsp @@ -6,7 +6,7 @@ - OpenAIRE Single Sign-On Service + OpenAIRE - Error 404 diff --git a/src/main/webapp/expiredVerificationCode.jsp b/src/main/webapp/expiredVerificationCode.jsp index cdbea7b..1300f3a 100644 --- a/src/main/webapp/expiredVerificationCode.jsp +++ b/src/main/webapp/expiredVerificationCode.jsp @@ -20,7 +20,7 @@ - OpenAIRE Single Sign-On Service + OpenAIRE - Expired Verification Code diff --git a/src/main/webapp/registerSuccess.jsp b/src/main/webapp/registerSuccess.jsp index b3bad51..25c788f 100644 --- a/src/main/webapp/registerSuccess.jsp +++ b/src/main/webapp/registerSuccess.jsp @@ -21,7 +21,7 @@ - OpenAIRE - Forgot password + OpenAIRE - Successful registration diff --git a/src/main/webapp/requestActivationCode.jsp b/src/main/webapp/requestActivationCode.jsp new file mode 100644 index 0000000..57bc524 --- /dev/null +++ b/src/main/webapp/requestActivationCode.jsp @@ -0,0 +1,122 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%-- + Created by IntelliJ IDEA. + User: sofia + Date: 14/5/2018 + Time: 5:37 μμ + To change this template use File | Settings | File Templates. +--%> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + + + + + + + + + + + OpenAIRE - Request an Activation Code + + +
+ + +
+
+ +
+
+ + +
+
+
+
+
+
+

Request an Activation Code

+
+
+
+ +
+
+

Please enter your username. We will send you an email with a new activation code to activate your account.

+
+ +
+
+ + + +
+ ${message} + + +
+
+ ${reCAPTCHA_message} + +
+
+
+
+ +
+
+
+
+ + +
+ +
+
+ +
+
+
+
+
+ + + +
+ + diff --git a/src/main/webapp/resetPassword.jsp b/src/main/webapp/resetPassword.jsp index 82793ba..2d9f0c4 100644 --- a/src/main/webapp/resetPassword.jsp +++ b/src/main/webapp/resetPassword.jsp @@ -13,7 +13,7 @@ - OpenAIRE - Enter new password + OpenAIRE - Reset Password diff --git a/src/main/webapp/success.jsp b/src/main/webapp/success.jsp index df50eea..bc75288 100644 --- a/src/main/webapp/success.jsp +++ b/src/main/webapp/success.jsp @@ -24,7 +24,7 @@ - OpenAIRE - Forgot password + OpenAIRE - Success diff --git a/src/main/webapp/successAddPassword.jsp b/src/main/webapp/successAddPassword.jsp index 04d602d..ec5f515 100644 --- a/src/main/webapp/successAddPassword.jsp +++ b/src/main/webapp/successAddPassword.jsp @@ -23,7 +23,7 @@ - OpenAIRE - Forgot password + OpenAIRE - Success diff --git a/src/main/webapp/verify.jsp b/src/main/webapp/verify.jsp index ea5960d..56386d1 100644 --- a/src/main/webapp/verify.jsp +++ b/src/main/webapp/verify.jsp @@ -6,7 +6,7 @@ - OpenAIRE - Forgot password, verification code + OpenAIRE - Account verification diff --git a/src/main/webapp/verifyEmail.jsp b/src/main/webapp/verifyEmail.jsp index 9425e86..80062ae 100644 --- a/src/main/webapp/verifyEmail.jsp +++ b/src/main/webapp/verifyEmail.jsp @@ -14,7 +14,7 @@ - OpenAIRE - Forgot password, verification code + OpenAIRE - Email Verification