Commit a3dc9eda authored by Administrator's avatar Administrator

Merge tag 'v0.1.11' into angular

This merge adds the test improvements done in v0.1.11 to the angular
branch. This consist in adding security check to the people resource
tests to verify that normal users can't access people information.
parents 1376aaa7 408c4203
......@@ -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]);
requestContext.setSecurityContext(new UserSecurityContext(user));
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,27 +85,49 @@ 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>>(){});
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);
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,24 +139,37 @@ public class PeopleResourceTest extends JerseyTest {
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_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());
final Person person = response.readEntity(Person.class);
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)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_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,9 +179,9 @@ public class PeopleResourceTest extends JerseyTest {
final Form form = new Form();
form.param("name", newName());
final Response response = target("people")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_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,9 +193,9 @@ public class PeopleResourceTest extends JerseyTest {
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people/" + existentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_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());
final Person modifiedPerson = response.readEntity(Person.class);
......@@ -168,14 +207,27 @@ 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)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_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,9 +237,9 @@ 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)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_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,9 +250,9 @@ public class PeopleResourceTest extends JerseyTest {
form.param("name", newName());
form.param("surname", newSurname());
final Response response = target("people/" + nonExistentId())
.request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_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());
......@@ -216,10 +270,21 @@ 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