Added testcases for challenge 2 and 5

This commit is contained in:
Nanne Baars 2017-05-03 02:47:04 +02:00
parent efe5ca4b4d
commit 4f561fc377
3 changed files with 179 additions and 18 deletions

View File

@ -1,10 +1,7 @@
package org.owasp.webgoat.plugin.challenge5; package org.owasp.webgoat.plugin.challenge5;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.*;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -39,7 +36,7 @@ public class VotesEndpoint {
private Map<String, Vote> votes = Maps.newHashMap(); private Map<String, Vote> votes = Maps.newHashMap();
@PostConstruct @PostConstruct
private void initVotes() { public void initVotes() {
votes.put("Admin lost password", new Vote("Admin lost password", votes.put("Admin lost password", new Vote("Admin lost password",
"In this challenge you will need to help the admin and find the password in order to login", "In this challenge you will need to help the admin and find the password in order to login",
"challenge1-small.png", "challenge1.png", 36000, totalVotes)); "challenge1-small.png", "challenge1.png", 36000, totalVotes));
@ -89,13 +86,13 @@ public class VotesEndpoint {
Claims claims = (Claims) jwt.getBody(); Claims claims = (Claims) jwt.getBody();
String user = (String) claims.get("user"); String user = (String) claims.get("user");
boolean isAdmin = Boolean.valueOf((String) claims.get("admin")); boolean isAdmin = Boolean.valueOf((String) claims.get("admin"));
if ("Guest".equals(user)) { if ("Guest".equals(user) || !validUsers.contains(user)) {
value.setSerializationView(Views.GuestView.class); value.setSerializationView(Views.GuestView.class);
} else { } else {
((Collection<Vote>)value.getValue()).forEach(v -> v.setFlag(FLAGS.get(5))); ((Collection<Vote>) value.getValue()).forEach(v -> v.setFlag(FLAGS.get(5)));
value.setSerializationView(isAdmin ? Views.AdminView.class : Views.UserView.class); value.setSerializationView(isAdmin ? Views.AdminView.class : Views.UserView.class);
} }
} catch (IllegalArgumentException e) { } catch (JwtException e) {
value.setSerializationView(Views.GuestView.class); value.setSerializationView(Views.GuestView.class);
} }
} }
@ -109,13 +106,17 @@ public class VotesEndpoint {
if (StringUtils.isEmpty(accessToken)) { if (StringUtils.isEmpty(accessToken)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
} else { } else {
Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken); try {
Claims claims = (Claims) jwt.getBody(); Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);
String user = (String) claims.get("user"); Claims claims = (Claims) jwt.getBody();
if (validUsers.contains(user)) { String user = (String) claims.get("user");
ofNullable(votes.get(title)).ifPresent(v -> v.incrementNumberOfVotes(totalVotes)); if (validUsers.contains(user)) {
return ResponseEntity.accepted().build(); ofNullable(votes.get(title)).ifPresent(v -> v.incrementNumberOfVotes(totalVotes));
} else { return ResponseEntity.accepted().build();
} else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
} catch (JwtException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
} }
} }

View File

@ -32,7 +32,6 @@ public class ShopEndpointTest {
@Test @Test
public void getSuperCoupon() throws Exception { public void getSuperCoupon() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/" + SUPER_COUPON_CODE)) mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/" + SUPER_COUPON_CODE))
.andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$.code", CoreMatchers.is(SUPER_COUPON_CODE))) .andExpect(jsonPath("$.code", CoreMatchers.is(SUPER_COUPON_CODE)))
.andExpect(jsonPath("$.discount", CoreMatchers.is(100))); .andExpect(jsonPath("$.discount", CoreMatchers.is(100)));
} }
@ -48,7 +47,6 @@ public class ShopEndpointTest {
@Test @Test
public void askForUnknownCouponCode() throws Exception { public void askForUnknownCouponCode() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/does-not-exists")) mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/does-not-exists"))
.andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$.code", CoreMatchers.is("no"))) .andExpect(jsonPath("$.code", CoreMatchers.is("no")))
.andExpect(jsonPath("$.discount", CoreMatchers.is(0))); .andExpect(jsonPath("$.discount", CoreMatchers.is(0)));
} }
@ -56,7 +54,6 @@ public class ShopEndpointTest {
@Test @Test
public void fetchAllTheCouponsShouldContainGetItForFree() throws Exception { public void fetchAllTheCouponsShouldContainGetItForFree() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/")) mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/"))
.andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$.codes[3].code", is("get_it_for_free"))); .andExpect(jsonPath("$.codes[3].code", is("get_it_for_free")));
} }

View File

@ -0,0 +1,163 @@
package org.owasp.webgoat.plugin.challenge5;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.owasp.webgoat.plugin.Flag;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import javax.servlet.http.Cookie;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
/**
* @author nbaars
* @since 5/2/17.
*/
@RunWith(MockitoJUnitRunner.class)
public class VotesEndpointTest {
private MockMvc mockMvc;
@Before
public void setup() {
VotesEndpoint votesEndpoint = new VotesEndpoint();
votesEndpoint.initVotes();
new Flag().initFlags();
this.mockMvc = standaloneSetup(votesEndpoint).build();
}
@Test
public void loginWithUnknownUser() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "uknown"))
.andExpect(unauthenticated());
}
@Test
public void loginWithTomShouldGiveJwtToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "Tom"))
.andExpect(status().isOk()).andExpect(cookie().exists("access_token"));
}
@Test
public void loginWithGuestShouldNotGiveJwtToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "Guest"))
.andExpect(unauthenticated()).andExpect(cookie().value("access_token", ""));
}
@Test
public void userShouldSeeMore() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "Tom"))
.andExpect(status().isOk()).andExpect(cookie().exists("access_token")).andReturn();
mockMvc.perform(MockMvcRequestBuilders.get("/votings")
.cookie(mvcResult.getResponse().getCookie("access_token")))
.andExpect(jsonPath("$.[*].numberOfVotes").exists());
}
@Test
public void guestShouldNotSeeNumberOfVotes() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "Guest"))
.andExpect(unauthenticated()).andExpect(cookie().exists("access_token")).andReturn();
mockMvc.perform(MockMvcRequestBuilders.get("/votings")
.cookie(mvcResult.getResponse().getCookie("access_token")))
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
}
@Test
public void adminShouldSeeFlags() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings")
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJhZG1pbiI6InRydWUiLCJ1c2VyIjoiSmVycnkifQ.")))
.andExpect(jsonPath("$.[*].flag").isNotEmpty());
}
@Test
public void votingIsNotAllowedAsGuest() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/votings/Get it for free"))
.andExpect(unauthenticated());
}
@Test
public void normalUserShouldBeAbleToVote() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "Tom"))
.andExpect(status().isOk()).andExpect(cookie().exists("access_token")).andReturn();
mockMvc.perform(MockMvcRequestBuilders.post("/votings/Get it for free")
.cookie(mvcResult.getResponse().getCookie("access_token")));
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
.cookie(mvcResult.getResponse().getCookie("access_token")))
.andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$..[?(@.title == 'Get it for free')].numberOfVotes", CoreMatchers.hasItem(20001)));
}
@Test
public void votingForUnknownLessonShouldNotCrash() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
.param("user", "Tom"))
.andExpect(status().isOk()).andExpect(cookie().exists("access_token")).andReturn();
mockMvc.perform(MockMvcRequestBuilders.post("/votings/UKNOWN_VOTE")
.cookie(mvcResult.getResponse().getCookie("access_token"))).andExpect(status().isAccepted());
}
@Test
public void votingWithInvalidToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/votings/UKNOWN_VOTE")
.cookie(new Cookie("access_token", "abc"))).andExpect(unauthenticated());
}
@Test
public void gettingVotesWithInvalidToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
.cookie(new Cookie("access_token", "abc"))).andExpect(unauthenticated());
}
@Test
public void gettingVotesWithUnknownUserInToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJhZG1pbiI6InRydWUiLCJ1c2VyIjoiVW5rbm93biJ9.")))
.andExpect(unauthenticated())
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
}
@Test
public void gettingVotesForUnknownShouldWork() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiVW5rbm93biJ9.")))
.andExpect(unauthenticated())
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
}
@Test
public void gettingVotesForKnownWithoutAdminFieldShouldWork() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiVG9tIn0.")))
.andExpect(status().isOk())
.andExpect(jsonPath("$.[*].numberOfVotes").exists());
}
@Test
public void gettingVotesWithEmptyToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
.cookie(new Cookie("access_token", "")))
.andExpect(status().isOk())
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
}
@Test
public void votingAsUnknownUserShouldNotBeAllowed() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/votings/Get it for free")
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiVW5rbm93biJ9.")))
.andExpect(unauthenticated());
}
}