Added testcases for all JWT endpoints
This commit is contained in:
parent
e0cf5b4a84
commit
8d7ecb19d7
@ -1,14 +1,19 @@
|
|||||||
package org.owasp.webgoat.plugin;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||||
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwt;
|
import io.jsonwebtoken.Jwt;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nbaars
|
* @author nbaars
|
||||||
@ -18,23 +23,29 @@ import io.jsonwebtoken.Jwts;
|
|||||||
@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"})
|
@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"})
|
||||||
public class JWTSecretKeyEndpoint extends AssignmentEndpoint {
|
public class JWTSecretKeyEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
private static final String JWT_SECRET = "victory";
|
public static final String JWT_SECRET = "victory";
|
||||||
private static final String WEBGOAT_USER = "WebGoat";
|
private static final String WEBGOAT_USER = "WebGoat";
|
||||||
|
private static final List<String> expectedClaims = Lists.newArrayList("iss", "iat", "exp", "aud", "sub", "username", "Email", "Role");
|
||||||
|
|
||||||
@PostMapping()
|
@PostMapping
|
||||||
public void login(@RequestParam String token) {
|
@ResponseBody
|
||||||
|
public AttackResult login(@RequestParam String token) {
|
||||||
try {
|
try {
|
||||||
Jwt jwt = Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJwt(token);
|
Jwt jwt = Jwts.parser().setSigningKey(JWT_SECRET).parse(token);
|
||||||
Claims claims = (Claims) jwt.getBody();
|
Claims claims = (Claims) jwt.getBody();
|
||||||
|
if (!claims.keySet().containsAll(expectedClaims)) {
|
||||||
|
return trackProgress(failed().feedback("jwt-secret-claims-missing").build());
|
||||||
|
} else {
|
||||||
String user = (String) claims.get("username");
|
String user = (String) claims.get("username");
|
||||||
|
|
||||||
if (WEBGOAT_USER.equalsIgnoreCase(user)) {
|
if (WEBGOAT_USER.equalsIgnoreCase(user)) {
|
||||||
trackProgress(success().build());
|
return trackProgress(success().build());
|
||||||
} else {
|
} else {
|
||||||
trackProgress(failed().feedback("jwt-secret.not-correct").feedbackArgs(user).build());
|
return trackProgress(failed().feedback("jwt-secret-incorrect-user").feedbackArgs(user).build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
trackProgress(failed().feedback("jwt-invalid-token").output(e.getMessage()).build());
|
return trackProgress(failed().feedback("jwt-invalid-token").output(e.getMessage()).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -37,7 +39,7 @@ import static java.util.stream.Collectors.toList;
|
|||||||
@AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"})
|
@AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"})
|
||||||
public class JWTVotesEndpoint extends AssignmentEndpoint {
|
public class JWTVotesEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
private static final String JWT_PASSWORD = "victory";
|
public static final String JWT_PASSWORD = "victory";
|
||||||
private static String validUsers = "TomJerrySylvester";
|
private static String validUsers = "TomJerrySylvester";
|
||||||
|
|
||||||
private static int totalVotes = 38929;
|
private static int totalVotes = 38929;
|
||||||
@ -65,11 +67,10 @@ public class JWTVotesEndpoint extends AssignmentEndpoint {
|
|||||||
@GetMapping("/login")
|
@GetMapping("/login")
|
||||||
public void login(@RequestParam("user") String user, HttpServletResponse response) {
|
public void login(@RequestParam("user") String user, HttpServletResponse response) {
|
||||||
if (validUsers.contains(user)) {
|
if (validUsers.contains(user)) {
|
||||||
Map<String, Object> claims = Maps.newHashMap();
|
Claims claims = Jwts.claims().setIssuedAt(Date.from(Instant.now().plus(Duration.ofDays(10))));
|
||||||
claims.put("admin", "false");
|
claims.put("admin", "false");
|
||||||
claims.put("user", user);
|
claims.put("user", user);
|
||||||
String token = Jwts.builder()
|
String token = Jwts.builder()
|
||||||
.setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10)))
|
|
||||||
.setClaims(claims)
|
.setClaims(claims)
|
||||||
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD)
|
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD)
|
||||||
.compact();
|
.compact();
|
||||||
@ -96,11 +97,11 @@ public class JWTVotesEndpoint extends AssignmentEndpoint {
|
|||||||
Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);
|
Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);
|
||||||
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"));
|
|
||||||
if ("Guest".equals(user) || !validUsers.contains(user)) {
|
if ("Guest".equals(user) || !validUsers.contains(user)) {
|
||||||
value.setSerializationView(Views.GuestView.class);
|
value.setSerializationView(Views.GuestView.class);
|
||||||
|
} else {
|
||||||
|
value.setSerializationView(Views.UserView.class);
|
||||||
}
|
}
|
||||||
value.setSerializationView(isAdmin ? Views.AdminView.class : Views.UserView.class);
|
|
||||||
} catch (JwtException e) {
|
} catch (JwtException e) {
|
||||||
value.setSerializationView(Views.GuestView.class);
|
value.setSerializationView(Views.GuestView.class);
|
||||||
}
|
}
|
||||||
@ -132,7 +133,8 @@ public class JWTVotesEndpoint extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("reset")
|
@PostMapping("reset")
|
||||||
public @ResponseBody AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) {
|
public @ResponseBody
|
||||||
|
AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) {
|
||||||
if (StringUtils.isEmpty(accessToken)) {
|
if (StringUtils.isEmpty(accessToken)) {
|
||||||
return trackProgress(failed().feedback("jwt-invalid-token").build());
|
return trackProgress(failed().feedback("jwt-invalid-token").build());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.refresh;
|
|
||||||
|
|
||||||
public class RefreshEndpoint {
|
|
||||||
|
|
||||||
private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0OTUyODU3NDUsImV4cCI6MTQ5NTI4NTc0NSwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJuYW1lIjoiVG9tIiwiZW1haWwiOiJ0b21Ad2ViZ29hdC5jb20iLCJyb2xlIjoiQ2F0In0.NTd3E17JZlVKZk52Wq_AWZ0RDafV5KDRMuJner_zUn4";
|
|
||||||
private static final String JWT_KEY = "qwertyuiopasdfghjklzxcvbnm123456";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -10,7 +10,4 @@ public class Views {
|
|||||||
|
|
||||||
public interface UserView extends GuestView {
|
public interface UserView extends GuestView {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface AdminView extends UserView {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,6 @@ public class Vote {
|
|||||||
private final String imageBig;
|
private final String imageBig;
|
||||||
@JsonView(Views.UserView.class)
|
@JsonView(Views.UserView.class)
|
||||||
private int numberOfVotes;
|
private int numberOfVotes;
|
||||||
@JsonView(Views.AdminView.class)
|
|
||||||
@Setter
|
|
||||||
private String flag;
|
|
||||||
@JsonView(Views.UserView.class)
|
@JsonView(Views.UserView.class)
|
||||||
private boolean votingAllowed = true;
|
private boolean votingAllowed = true;
|
||||||
@JsonView(Views.UserView.class)
|
@JsonView(Views.UserView.class)
|
||||||
|
@ -13,11 +13,13 @@ jwt-change-token-hint5=Submit the token by changing the algorithm to None and re
|
|||||||
jwt-secret-hint1=Save the token and try to verify the token locally
|
jwt-secret-hint1=Save the token and try to verify the token locally
|
||||||
jwt-secret-hint2=Download a word list dictionary (https://github.com/first20hours/google-10000-english)
|
jwt-secret-hint2=Download a word list dictionary (https://github.com/first20hours/google-10000-english)
|
||||||
jwt-secret-hint3=Write a small program or use HashCat for brute forcing the token according the word list
|
jwt-secret-hint3=Write a small program or use HashCat for brute forcing the token according the word list
|
||||||
|
jwt-secret-claims-missing=You are missing some claims, you should keep all the claims in the token
|
||||||
|
jwt-secret-incorrect-user=The user is {0}, you need to change it to WebGoat
|
||||||
|
|
||||||
jwt-refresh-hint1=Look at the access log you will find a token there
|
jwt-refresh-hint1=Look at the access log you will find a token there
|
||||||
jwt-refresh-hint2=The token from the access log is no longer valid, can you find a way to refresh it?
|
jwt-refresh-hint2=The token from the access log is no longer valid, can you find a way to refresh it?
|
||||||
jwt-refresh-hint3=The endpoint for refreshing a token is 'jwt/refresh/newToken'
|
jwt-refresh-hint3=The endpoint for refreshing a token is 'jwt/refresh/newToken'
|
||||||
jwt-refresh-hint4=Use the found access token in the Authorization: Bearer header and use your refresh token
|
jwt-refresh-hint4=Use the found access token in the Authorization: Bearer header and use your own refresh token
|
||||||
jwt-refresh-not-tom=User is not Tom but {0}, please try again
|
jwt-refresh-not-tom=User is not Tom but {0}, please try again
|
||||||
|
|
||||||
jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom
|
jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.joda.time.Days;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static io.jsonwebtoken.SignatureAlgorithm.*;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.owasp.webgoat.plugin.JWTSecretKeyEndpoint.JWT_SECRET;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class JWTSecretKeyEndpointTest extends LessonTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
JWT jwt = new JWT();
|
||||||
|
when(webSession.getCurrentLesson()).thenReturn(jwt);
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||||
|
when(webSession.getUserName()).thenReturn("unit-test");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Claims createClaims(String username) {
|
||||||
|
Claims claims = Jwts.claims();
|
||||||
|
claims.put("admin", "true");
|
||||||
|
claims.put("user", "Tom");
|
||||||
|
claims.setExpiration(Date.from(Instant.now().plus(Duration.ofDays(1))));
|
||||||
|
claims.setIssuedAt(Date.from(Instant.now().plus(Duration.ofDays(1))));
|
||||||
|
claims.setIssuer("iss");
|
||||||
|
claims.setAudience("aud");
|
||||||
|
claims.setSubject("sub");
|
||||||
|
claims.put("username", username);
|
||||||
|
claims.put("Email", "webgoat@webgoat.io");
|
||||||
|
claims.put("Role", new String[]{"user"});
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void solveAssignment() throws Exception {
|
||||||
|
Claims claims = createClaims("WebGoat");
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||||
|
.param("token", token))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void solveAssignmentWithLowercase() throws Exception {
|
||||||
|
Claims claims = createClaims("webgoat");
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||||
|
.param("token", token))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void oneOfClaimIsMissingShouldNotSolveAssignment() throws Exception {
|
||||||
|
Claims claims = createClaims("WebGoat");
|
||||||
|
claims.remove("aud");
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||||
|
.param("token", token))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-secret-claims-missing"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void incorrectUser() throws Exception {
|
||||||
|
Claims claims = createClaims("Tom");
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||||
|
.param("token", token))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-secret-incorrect-user", "default", "Tom"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void incorrectToken() throws Exception {
|
||||||
|
Claims claims = createClaims("Tom");
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(HS512, "wrong_password").compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||||
|
.param("token", token))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,187 @@
|
|||||||
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.owasp.webgoat.plugin.JWTVotesEndpoint.JWT_PASSWORD;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class JWTVotesEndpointTest extends LessonTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
JWT jwt = new JWT();
|
||||||
|
when(webSession.getCurrentLesson()).thenReturn(jwt);
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||||
|
when(webSession.getUserName()).thenReturn("unit-test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void solveAssignment() throws Exception {
|
||||||
|
//Create new token and set alg to none and do not sign it
|
||||||
|
Claims claims = Jwts.claims();
|
||||||
|
claims.put("admin", "true");
|
||||||
|
claims.put("user", "Tom");
|
||||||
|
String token = Jwts.builder().setClaims(claims).setHeaderParam("alg", "none").compact();
|
||||||
|
|
||||||
|
//Call the reset endpoint
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/reset")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.cookie(new Cookie("access_token", token)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resetWithoutTokenShouldNotWork() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/reset")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void guestShouldNotGetAToken() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.param("user", "Guest"))
|
||||||
|
.andExpect(status().isUnauthorized()).andExpect(cookie().value("access_token", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tomShouldGetAToken() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.param("user", "Tom"))
|
||||||
|
.andExpect(status().isOk()).andExpect(cookie().value("access_token", containsString("eyJhbGciOiJIUzUxMiJ9.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void guestShouldNotSeeNumberOfVotes() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||||
|
.cookie(new Cookie("access_token", "")))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$[0].numberOfVotes").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$[0].votingAllowed").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$[0].average").doesNotExist());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tomShouldSeeNumberOfVotes() throws Exception {
|
||||||
|
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.param("user", "Tom"))
|
||||||
|
.andExpect(status().isOk()).andReturn();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||||
|
.cookie(result.getResponse().getCookies()[0]))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$[0].numberOfVotes").exists())
|
||||||
|
.andExpect(jsonPath("$[0].votingAllowed").exists())
|
||||||
|
.andExpect(jsonPath("$[0].average").exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invalidTokenShouldSeeGuestView() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||||
|
.cookie(new Cookie("access_token", "abcd.efgh.ijkl")))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$[0].numberOfVotes").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$[0].votingAllowed").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$[0].average").doesNotExist());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tomShouldBeAbleToVote() throws Exception {
|
||||||
|
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.param("user", "Tom"))
|
||||||
|
.andExpect(status().isOk()).andReturn();
|
||||||
|
Cookie cookie = result.getResponse().getCookie("access_token");
|
||||||
|
|
||||||
|
result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||||
|
.cookie(cookie))
|
||||||
|
.andExpect(status().isOk()).andDo(print()).andReturn();
|
||||||
|
Object[] nodes = new ObjectMapper().readValue(result.getResponse().getContentAsString(), Object[].class);
|
||||||
|
int currentNumberOfVotes = (int) findNodeByTitle(nodes, "Admin lost password").get("numberOfVotes");
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password")
|
||||||
|
.cookie(cookie))
|
||||||
|
.andExpect(status().isAccepted());
|
||||||
|
result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||||
|
.cookie(cookie))
|
||||||
|
.andExpect(status().isOk()).andReturn();
|
||||||
|
nodes = new ObjectMapper().readValue(result.getResponse().getContentAsString(), Object[].class);
|
||||||
|
int numberOfVotes = (int) findNodeByTitle(nodes, "Admin lost password").get("numberOfVotes");
|
||||||
|
assertThat(numberOfVotes).isEqualTo(currentNumberOfVotes + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> findNodeByTitle(Object[] nodes, String title) {
|
||||||
|
for (Object n : nodes) {
|
||||||
|
Map<String, Object> node = (Map<String, Object>) n;
|
||||||
|
if (node.get("title").equals(title)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void guestShouldNotBeAbleToVote() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password")
|
||||||
|
.cookie(new Cookie("access_token", "")))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unknownUserWithValidTokenShouldNotBeAbleToVote() throws Exception {
|
||||||
|
Claims claims = Jwts.claims();
|
||||||
|
claims.put("admin", "true");
|
||||||
|
claims.put("user", "Intruder");
|
||||||
|
String token = Jwts.builder().signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).setClaims(claims).compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password")
|
||||||
|
.cookie(new Cookie("access_token", token)))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unknownUserShouldSeeGuestView() throws Exception {
|
||||||
|
Claims claims = Jwts.claims();
|
||||||
|
claims.put("admin", "true");
|
||||||
|
claims.put("user", "Intruder");
|
||||||
|
String token = Jwts.builder().signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).setClaims(claims).compact();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/")
|
||||||
|
.cookie(new Cookie("access_token", token)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$[0].numberOfVotes").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$[0].votingAllowed").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$[0].average").doesNotExist());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user