package com.jdriven.stateless.security;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.JsonProcessingException;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = StatelessAuthentication.class)
@WebAppConfiguration
@IntegrationTest("server.port:8181")
public class StatelessAuthenticationIntegrationTest {
// GET RESOURCES
@Test
public void testRoot_Get_Anonymous() {
doAnonymousExchange(HttpMethod.GET, "/");
}
@Test
public void testResource_Get_Anonymous() {
doAnonymousExchange(HttpMethod.GET, "/resources/js/controllers.js");
}
// CHANGE OWN USER PASSWORD
@Test(expected = HttpClientErrorException.class)
public void testUserApi_Change_Password_AsAnonymous() {
doAnonymousExchange(HttpMethod.POST, "/api/users/current?_method=PATCH",
"{\"password\":\"user\", \"newPassword\":\"test\"}");
}
@Test
public void testUserApi_Change_Password_AsUser() throws JsonProcessingException {
doAuthenticatedExchange("user", HttpMethod.POST, "/api/users/current?_method=PATCH",
"{\"password\":\"user\", \"newPassword\":\"test\"}", "user");
doAuthenticatedExchange("user", HttpMethod.POST, "/api/users/current?_method=PATCH",
"{\"password\":\"test\", \"newPassword\":\"user\"}", "test");
}
// GET OWN USER DETAILS
@Test
public void testUserApi_Get_Anonymous() {
final String result = doAnonymousExchange(HttpMethod.GET, "/api/users/current");
assertTrue(result.contains("\"username\":\"anonymousUser\""));
assertTrue(result.contains("\"roles\":[]"));
}
@Test
public void testUserApi_Get_User() {
final String result = doAuthenticatedExchange("user", HttpMethod.GET, "/api/users/current");
assertTrue(result.contains("\"username\":\"user\""));
assertTrue(result.contains("\"roles\":[\"USER\"]"));
}
@Test
public void testUserApi_Get_Admin() {
final String result = doAuthenticatedExchange("admin", HttpMethod.GET, "/api/users/current");
assertTrue(result.contains("\"username\":\"admin\""));
assertTrue(result.contains("\"roles\":[\"ADMIN\"]"));
}
// GET ALL USER DETAILS (ADMIN FUNCTIONALITY)
@Test(expected = HttpClientErrorException.class)
public void testAdminApi_Get_Users_AsAnonymous() {
doAnonymousExchange(HttpMethod.GET, "/admin/api/users");
}
@Test(expected = HttpClientErrorException.class)
public void testAdminApi_Get_Users_AsUser() {
doAuthenticatedExchange("user", HttpMethod.GET, "/admin/api/users");
}
@Test
public void testAdminApi_Get_Users_AsAdmin() {
final String result = doAuthenticatedExchange("admin", HttpMethod.GET, "/admin/api/users");
assertEquals("[{\"id\":10,\"username\":\"admin\",\"expires\":0,\"roles\":[\"ADMIN\"]}"
+ ",{\"id\":11,\"username\":\"user\",\"expires\":0,\"roles\":[\"USER\"]}]", result);
}
// GRANT A ROLE TO A USER (ADMIN FUNCTIONALITY)
@Test(expected = HttpClientErrorException.class)
public void testAdminApi_GrantRole_AsAnonymous() {
doAnonymousExchange(HttpMethod.POST, "/admin/api/users/11/grant/role/ADMIN");
}
@Test(expected = HttpClientErrorException.class)
public void testAdminApi_GrantRole_AsUser() {
doAuthenticatedExchange("user", HttpMethod.POST, "/admin/api/users/11/grant/role/ADMIN");
}
@Test
public void testAdminApi_GrantRole_AsAdmin() {
doAuthenticatedExchange("admin", HttpMethod.POST, "/admin/api/users/11/grant/role/ADMIN");
doAuthenticatedExchange("admin", HttpMethod.POST, "/admin/api/users/11/revoke/role/ADMIN");
}
private String doAnonymousExchange(final HttpMethod method, final String path) {
return doAnonymousExchange(method, path, null);
}
private String doAnonymousExchange(final HttpMethod method, final String path, String request) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> testRequest = new HttpEntity<>(request, httpHeaders);
HttpEntity<String> testResponse = restTemplate.exchange("http://localhost:8181/" + path, method, testRequest,
String.class);
return testResponse.getBody();
}
private String doAuthenticatedExchange(final String user, final HttpMethod method, final String path) {
return doAuthenticatedExchange(user, method, path, null, user);
}
private String doAuthenticatedExchange(final String user, final HttpMethod method, final String path,
String request, String password) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> login = new HttpEntity<>(
"{\"username\":\"" + user + "\",\"password\":\"" + password + "\"}", httpHeaders);
ResponseEntity<Void> results = restTemplate.postForEntity("http://localhost:8181/api/login", login, Void.class);
httpHeaders.add("X-AUTH-TOKEN", results.getHeaders().getFirst("X-AUTH-TOKEN"));
HttpEntity<String> testRequest = new HttpEntity<>(request, httpHeaders);
HttpEntity<String> testResponse = restTemplate.exchange("http://localhost:8181/" + path, method, testRequest,
String.class);
return testResponse.getBody();
}
}