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

View File

@ -57,6 +57,7 @@ import org.springframework.web.servlet.ModelAndView;
})
public class ResetLinkAssignment extends AssignmentEndpoint {
private static final String VIEW_FORMATTER = "lessons/passwordreset/templates/%s.html";
static final String PASSWORD_TOM_9 =
"somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom";
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 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"
+ " password.\n"
+ " \n\n"
+ "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"
+ " support@webgoat-cloud.org\n\n"
+ "Kind regards, \n"
+ "Team WebGoat";
"""
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
password.
If you did not request this password change you can ignore this message.
If you have any comments or questions, please do not hesitate to reach us at
support@webgoat-cloud.org
Kind regards,
Team WebGoat
""";
@PostMapping("/PasswordReset/reset/login")
@ResponseBody
@ -98,20 +102,14 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
form.setResetLink(link);
model.addAttribute("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 {
modelAndView.setViewName("password_link_not_found");
modelAndView.setViewName(VIEW_FORMATTER.formatted("password_link_not_found"));
}
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")
public ModelAndView changePassword(
@ModelAttribute("form") PasswordChangeForm form, BindingResult bindingResult) {
@ -120,17 +118,17 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
bindingResult.rejectValue("password", "not.empty");
}
if (bindingResult.hasErrors()) {
modelAndView.setViewName("password_reset");
modelAndView.setViewName(VIEW_FORMATTER.formatted("password_reset"));
return modelAndView;
}
if (!resetLinks.contains(form.getResetLink())) {
modelAndView.setViewName("password_link_not_found");
modelAndView.setViewName(VIEW_FORMATTER.formatted("password_link_not_found"));
return modelAndView;
}
if (checkIfLinkIsFromTom(form.getResetLink())) {
usersToTomPassword.put(getWebSession().getUserName(), form.getPassword());
}
modelAndView.setViewName("lessons/passwordreset/templates/success.html");
modelAndView.setViewName(VIEW_FORMATTER.formatted("success"));
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.boot.test.context.SpringBootTest;
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.web.servlet.MockMvc;
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();
}
}