#1396 Fix templates path for views

This commit is contained in:
Nanne Baars 2023-02-15 11:44:56 +00:00
parent c9d1653d4f
commit bd398e4c09
4 changed files with 125 additions and 24 deletions

View File

@ -10,7 +10,7 @@
</parent> </parent>
<groupId>org.owasp.webgoat</groupId> <groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat</artifactId> <artifactId>webgoat</artifactId>
<version>2023.3</version> <version>2023.4-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>WebGoat</name> <name>WebGoat</name>
@ -675,7 +675,7 @@
<argument>${project.build.directory}/webgoat-${project.version}.jar</argument> <argument>${project.build.directory}/webgoat-${project.version}.jar</argument>
</arguments> </arguments>
<waitForInterrupt>false</waitForInterrupt> <waitForInterrupt>false</waitForInterrupt>
<healthcheckUrl>http://localhost:${webgoat.port}/WebGoat/</healthcheckUrl> <healthcheckUrl>http://localhost:${webgoat.port}/WebGoat/actuator/health</healthcheckUrl>
</configuration> </configuration>
</execution> </execution>
<execution> <execution>

View File

@ -57,6 +57,7 @@ import org.springframework.web.servlet.ModelAndView;
}) })
public class ResetLinkAssignment extends AssignmentEndpoint { public class ResetLinkAssignment extends AssignmentEndpoint {
private static final String VIEW_FORMATTER = "lessons/passwordreset/templates/%s.html";
static final String PASSWORD_TOM_9 = static final String PASSWORD_TOM_9 =
"somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom"; "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom";
static final String TOM_EMAIL = "tom@webgoat-cloud.org"; static final String TOM_EMAIL = "tom@webgoat-cloud.org";
@ -65,15 +66,18 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
static List<String> resetLinks = new ArrayList<>(); static List<String> resetLinks = new ArrayList<>();
static final String TEMPLATE = static final String TEMPLATE =
"Hi, you requested a password reset link, please use this <a target='_blank'" """
+ " href='http://%s/WebGoat/PasswordReset/reset/reset-password/%s'>link</a> to reset your" Hi, you requested a password reset link, please use this <a target='_blank'
+ " password.\n" href='http://%s/WebGoat/PasswordReset/reset/reset-password/%s'>link</a> to reset your
+ " \n\n" password.
+ "If you did not request this password change you can ignore this message.\n"
+ "If you have any comments or questions, please do not hesitate to reach us at" If you did not request this password change you can ignore this message.
+ " support@webgoat-cloud.org\n\n" If you have any comments or questions, please do not hesitate to reach us at
+ "Kind regards, \n" support@webgoat-cloud.org
+ "Team WebGoat";
Kind regards,
Team WebGoat
""";
@PostMapping("/PasswordReset/reset/login") @PostMapping("/PasswordReset/reset/login")
@ResponseBody @ResponseBody
@ -98,20 +102,14 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
form.setResetLink(link); form.setResetLink(link);
model.addAttribute("form", form); model.addAttribute("form", form);
modelAndView.addObject("form", form); modelAndView.addObject("form", form);
modelAndView.setViewName("password_reset"); // Display html page for changing password modelAndView.setViewName(
VIEW_FORMATTER.formatted("password_reset")); // Display html page for changing password
} else { } else {
modelAndView.setViewName("password_link_not_found"); modelAndView.setViewName(VIEW_FORMATTER.formatted("password_link_not_found"));
} }
return modelAndView; return modelAndView;
} }
@GetMapping("/PasswordReset/reset/change-password")
public ModelAndView illegalCall() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("password_link_not_found");
return modelAndView;
}
@PostMapping("/PasswordReset/reset/change-password") @PostMapping("/PasswordReset/reset/change-password")
public ModelAndView changePassword( public ModelAndView changePassword(
@ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) { @ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) {
@ -120,17 +118,17 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
bindingResult.rejectValue("password", "not.empty"); bindingResult.rejectValue("password", "not.empty");
} }
if (bindingResult.hasErrors()) { if (bindingResult.hasErrors()) {
modelAndView.setViewName("password_reset"); modelAndView.setViewName(VIEW_FORMATTER.formatted("password_reset"));
return modelAndView; return modelAndView;
} }
if (!resetLinks.contains(form.getResetLink())) { if (!resetLinks.contains(form.getResetLink())) {
modelAndView.setViewName("password_link_not_found"); modelAndView.setViewName(VIEW_FORMATTER.formatted("password_link_not_found"));
return modelAndView; return modelAndView;
} }
if (checkIfLinkIsFromTom(form.getResetLink())) { if (checkIfLinkIsFromTom(form.getResetLink())) {
usersToTomPassword.put(getWebSession().getUserName(), form.getPassword()); usersToTomPassword.put(getWebSession().getUserName(), form.getPassword());
} }
modelAndView.setViewName("lessons/passwordreset/templates/success.html"); modelAndView.setViewName(VIEW_FORMATTER.formatted("success"));
return modelAndView; return modelAndView;
} }

View File

@ -18,7 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;

View File

@ -0,0 +1,103 @@
package org.owasp.webgoat.lessons.passwordreset;
import static org.mockito.Mockito.when;
import static org.owasp.webgoat.lessons.passwordreset.ResetLinkAssignment.TOM_EMAIL;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.owasp.webgoat.container.plugins.LessonTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@ExtendWith(SpringExtension.class)
class ResetLinkAssignmentTest extends LessonTest {
@Value("${webwolf.host}")
private String webWolfHost;
@Value("${webwolf.port}")
private String webWolfPort;
@Autowired private ResourceLoader resourceLoader;
@BeforeEach
public void setup() {
when(webSession.getCurrentLesson()).thenReturn(new PasswordReset());
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
void wrongResetLink() throws Exception {
MvcResult mvcResult =
mockMvc
.perform(
MockMvcRequestBuilders.get("/PasswordReset/reset/reset-password/{link}", "test"))
.andExpect(status().isOk())
.andExpect(view().name("lessons/passwordreset/templates/password_link_not_found.html"))
.andReturn();
Assertions.assertThat(resourceLoader.getResource(mvcResult.getModelAndView().getViewName()))
.isNotNull();
}
@Test
void changePasswordWithoutPasswordShouldReturnPasswordForm() throws Exception {
MvcResult mvcResult =
mockMvc
.perform(MockMvcRequestBuilders.post("/PasswordReset/reset/change-password"))
.andExpect(status().isOk())
.andExpect(view().name("lessons/passwordreset/templates/password_reset.html"))
.andReturn();
Assertions.assertThat(resourceLoader.getResource(mvcResult.getModelAndView().getViewName()))
.isNotNull();
}
@Test
void changePasswordWithoutLinkShouldReturnPasswordLinkNotFound() throws Exception {
MvcResult mvcResult =
mockMvc
.perform(
MockMvcRequestBuilders.post("/PasswordReset/reset/change-password")
.param("password", "new_password"))
.andExpect(status().isOk())
.andExpect(view().name("lessons/passwordreset/templates/password_link_not_found.html"))
.andReturn();
Assertions.assertThat(resourceLoader.getResource(mvcResult.getModelAndView().getViewName()))
.isNotNull();
}
@Test
void knownLinkShouldReturnPasswordResetPage() throws Exception {
// Create a reset link
mockMvc
.perform(
MockMvcRequestBuilders.post("/PasswordReset/ForgotPassword/create-password-reset-link")
.param("email", TOM_EMAIL)
.header(HttpHeaders.HOST, webWolfHost + ":" + webWolfPort))
.andExpect(status().isOk());
Assertions.assertThat(ResetLinkAssignment.resetLinks).isNotEmpty();
// With a known link you should be
MvcResult mvcResult =
mockMvc
.perform(
MockMvcRequestBuilders.get(
"/PasswordReset/reset/reset-password/{link}",
ResetLinkAssignment.resetLinks.get(0)))
.andExpect(status().isOk())
.andExpect(view().name("lessons/passwordreset/templates/password_reset.html"))
.andReturn();
Assertions.assertThat(resourceLoader.getResource(mvcResult.getModelAndView().getViewName()))
.isNotNull();
}
}