From a45e397169ee464f3cfe5497d1cd24f728c22205 Mon Sep 17 00:00:00 2001 From: JBI <22871153+jbilandzija@users.noreply.github.com> Date: Tue, 11 Jul 2023 09:24:07 +0200 Subject: [PATCH] Skip reset password requests with HEAD method (#2389) Co-authored-by: Josip Bilandzija --- .../uaa/account/ResetPasswordController.java | 5 +++++ .../uaa/login/ResetPasswordControllerTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java b/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java index 61884331f92..42108794573 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java @@ -161,6 +161,11 @@ public String emailSentPage(@ModelAttribute("code") String code, return "email_sent"; } + @RequestMapping(value = "/reset_password", method = RequestMethod.HEAD) + public void resetPassword() { + // Some mail providers initially send a HEAD request to check the validity of the link before redirecting users. + } + @RequestMapping(value = "/reset_password", method = RequestMethod.GET, params = {"code"}) public String resetPasswordPage(Model model, HttpServletResponse response, diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerTest.java index d27c3233e47..6f4c45e4024 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerTest.java @@ -45,6 +45,7 @@ import static org.mockito.Mockito.*; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.head; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -282,6 +283,21 @@ void testResetPasswordPage() throws Exception { .andExpect(content().string(containsString(""))); } + @Test + void testResetPasswordPageWithPriorHeadRequest() throws Exception { + ExpiringCode code = codeStore.generateCode("{\"user_id\" : \"some-user-id\"}", new Timestamp(System.currentTimeMillis() + 1000000), null, IdentityZoneHolder.get().getId()); + mockMvc.perform(head("/reset_password").param("email", "user@example.com").param("code", code.getCode())) + .andExpect(status().isOk()); + mockMvc.perform(get("/reset_password").param("email", "user@example.com").param("code", code.getCode())) + .andExpect(status().isOk()) + .andDo(print()) + .andExpect(view().name("reset_password")) + .andExpect(model().attribute("email", "email")) + .andExpect(model().attribute("username", "username")) + .andExpect(content().string(containsString("
Username: username
"))) + .andExpect(content().string(containsString(""))); + } + @Test void testResetPasswordPageDuplicate() throws Exception { ExpiringCode code = codeStore.generateCode("{\"user_id\" : \"some-user-id\"}", new Timestamp(System.currentTimeMillis() + 1000000), null, IdentityZoneHolder.get().getId());