Commit 408c4203 authored by Administrator's avatar Administrator

Adds security check to PeopleResourceTest

The PeopleResourceTests now include security tests to verify that normal
users can't access people data.
parent 6fd8f7ef
......@@ -5,7 +5,7 @@
<groupId>es.uvigo.esei.daa</groupId>
<artifactId>example</artifactId>
<packaging>war</packaging>
<version>0.1.10</version>
<version>0.1.11</version>
<name>DAA Example</name>
<licenses>
......
......@@ -3,12 +3,14 @@ package es.uvigo.esei.daa.filters;
import java.io.IOException;
import java.security.Principal;
import java.util.Base64;
import java.util.List;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.SecurityContext;
......@@ -18,6 +20,12 @@ import es.uvigo.esei.daa.dao.DAOException;
import es.uvigo.esei.daa.dao.UsersDAO;
import es.uvigo.esei.daa.entities.User;
/**
* This performs the Basic HTTP authentication following (almost) the same
* rules as the defined in the web.xml file.
*
* @author Miguel Reboiro Jato
*/
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthorizationFilter implements ContainerRequestFilter {
......@@ -46,7 +54,11 @@ public class AuthorizationFilter implements ContainerRequestFilter {
if (this.dao.checkLogin(userPass[0], userPass[1])) {
final User user = this.dao.get(userPass[0]);
if (isPeoplePath(requestContext) && !user.getRole().equals("ADMIN")) {
requestContext.abortWith(createResponse());
} else {
requestContext.setSecurityContext(new UserSecurityContext(user));
}
} else {
requestContext.abortWith(createResponse());
}
......@@ -59,6 +71,11 @@ public class AuthorizationFilter implements ContainerRequestFilter {
}
}
private static boolean isPeoplePath(ContainerRequestContext context) {
final List<PathSegment> pathSegments = context.getUriInfo().getPathSegments();
return !pathSegments.isEmpty() && pathSegments.get(0).getPath().equals("people");
}
private static Response createResponse() {
return Response.status(Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"DAAExample\"")
......
......@@ -7,8 +7,12 @@ import static es.uvigo.esei.daa.dataset.PeopleDataset.newPerson;
import static es.uvigo.esei.daa.dataset.PeopleDataset.newSurname;
import static es.uvigo.esei.daa.dataset.PeopleDataset.nonExistentId;
import static es.uvigo.esei.daa.dataset.PeopleDataset.people;
import static es.uvigo.esei.daa.dataset.UsersDataset.adminLogin;
import static es.uvigo.esei.daa.dataset.UsersDataset.normalLogin;
import static es.uvigo.esei.daa.dataset.UsersDataset.userToken;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasBadRequestStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasOkStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasUnauthorized;
import static es.uvigo.esei.daa.matchers.IsEqualToPerson.containsPeopleInAnyOrder;
import static es.uvigo.esei.daa.matchers.IsEqualToPerson.equalsToPerson;
import static javax.ws.rs.client.Entity.entity;
......@@ -40,7 +44,7 @@ import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import es.uvigo.esei.daa.DAAExampleApplication;
import es.uvigo.esei.daa.DAAExampleTestApplication;
import es.uvigo.esei.daa.entities.Person;
import es.uvigo.esei.daa.listeners.ApplicationContextBinding;
import es.uvigo.esei.daa.listeners.ApplicationContextJndiBindingTestExecutionListener;
......@@ -67,7 +71,7 @@ import es.uvigo.esei.daa.listeners.DbManagementTestExecutionListener;
public class PeopleResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new DAAExampleApplication();
return new DAAExampleTestApplication();
}
@Override
......@@ -81,7 +85,9 @@ public class PeopleResourceTest extends JerseyTest {
@Test
public void testList() throws IOException {
final Response response = target("people").request().get();
final Response response = target("people").request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasOkStatus());
final List<Person> people = response.readEntity(new GenericType<List<Person>>(){});
......@@ -89,9 +95,19 @@ public class PeopleResourceTest extends JerseyTest {
assertThat(people, containsPeopleInAnyOrder(people()));
}
@Test
public void testListUnauthorized() throws IOException {
final Response response = target("people").request()
.header("Authorization", "Basic " + userToken(normalLogin()))
.get();
assertThat(response, hasUnauthorized());
}
@Test
public void testGet() throws IOException {
final Response response = target("people/" + existentId()).request().get();
final Response response = target("people/" + existentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasOkStatus());
final Person person = response.readEntity(Person.class);
......@@ -99,9 +115,19 @@ public class PeopleResourceTest extends JerseyTest {
assertThat(person, is(equalsToPerson(existentPerson())));
}
@Test
public void testGetUnauthorized() throws IOException {
final Response response = target("people/" + existentId()).request()
.header("Authorization", "Basic " + userToken(normalLogin()))
.get();
assertThat(response, hasUnauthorized());
}
@Test
public void testGetInvalidId() throws IOException {
final Response response = target("people/" + nonExistentId()).request().get();
final Response response = target("people/" + nonExistentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasBadRequestStatus());
}
......@@ -113,8 +139,8 @@ public class PeopleResourceTest extends JerseyTest {
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people")
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasOkStatus());
......@@ -123,13 +149,26 @@ public class PeopleResourceTest extends JerseyTest {
assertThat(person, is(equalsToPerson(newPerson())));
}
@Test
public void testAddUnauthorized() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(normalLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasUnauthorized());
}
@Test
public void testAddMissingName() throws IOException {
final Form form = new Form();
form.param("surname", newSurname());
final Response response = target("people")
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
......@@ -140,8 +179,8 @@ public class PeopleResourceTest extends JerseyTest {
final Form form = new Form();
form.param("name", newName());
final Response response = target("people")
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
......@@ -154,8 +193,8 @@ public class PeopleResourceTest extends JerseyTest {
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasOkStatus());
......@@ -168,13 +207,26 @@ public class PeopleResourceTest extends JerseyTest {
assertThat(modifiedPerson, is(equalsToPerson(person)));
}
@Test
public void testModifyUnauthorized() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(normalLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasUnauthorized());
}
@Test
public void testModifyName() throws IOException {
final Form form = new Form();
form.param("name", newName());
final Response response = target("people/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
......@@ -185,8 +237,8 @@ public class PeopleResourceTest extends JerseyTest {
final Form form = new Form();
form.param("surname", newSurname());
final Response response = target("people/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
......@@ -198,8 +250,8 @@ public class PeopleResourceTest extends JerseyTest {
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people/" + nonExistentId())
.request(MediaType.APPLICATION_JSON_TYPE)
final Response response = target("people/" + nonExistentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
......@@ -208,7 +260,9 @@ public class PeopleResourceTest extends JerseyTest {
@Test
@ExpectedDatabase("/datasets/dataset-delete.xml")
public void testDelete() throws IOException {
final Response response = target("people/" + existentId()).request().delete();
final Response response = target("people/" + existentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.delete();
assertThat(response, hasOkStatus());
......@@ -217,9 +271,20 @@ public class PeopleResourceTest extends JerseyTest {
assertThat(deletedId, is(equalTo(existentId())));
}
@Test
public void testDeleteUnauthorized() throws IOException {
final Response response = target("people/" + existentId()).request()
.header("Authorization", "Basic " + userToken(normalLogin()))
.delete();
assertThat(response, hasUnauthorized());
}
@Test
public void testDeleteInvalidId() throws IOException {
final Response response = target("people/" + nonExistentId()).request().delete();
final Response response = target("people/" + nonExistentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.delete();
assertThat(response, hasBadRequestStatus());
}
......
......@@ -17,13 +17,7 @@ import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.test.DeploymentContext;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.ServletDeploymentContext;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
......@@ -74,20 +68,6 @@ public class UsersResourceTest extends JerseyTest {
config.property("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE);
}
@Override
protected TestContainerFactory getTestContainerFactory() {
return new GrizzlyWebTestContainerFactory();
}
@Override
protected DeploymentContext configureDeployment() {
return ServletDeploymentContext.forServlet(
new ServletContainer(ResourceConfig.forApplication(configure()))
)
.servletPath("/rest")
.build();
}
@Test
public void testGetAdminOwnUser() throws IOException {
final String admin = adminLogin();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment