diff --git a/pom.xml b/pom.xml
index 5a27e31724fee2ce1ac0d9d11f3b1151b2c722e7..8120da27f1742ae487925c87e3697bd3a276a700 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
es.uvigo.esei.daa
example
war
- 0.1.10
+ 0.1.11
DAA Example
diff --git a/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java b/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java
index 6c058a1b0ecb05adb6bb2f2d6ade5a832d273888..b2144df2ce1c5c1aaebd61932c0334430991cddc 100644
--- a/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java
+++ b/src/test/java/es/uvigo/esei/daa/filters/AuthorizationFilter.java
@@ -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 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\"")
diff --git a/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java
index 3fe2f7401b5f0fe84822a35f2d5bb1d32333c12a..4cbc8be87daee45673830bfebfed6171a9135df9 100644
--- a/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java
+++ b/src/test/java/es/uvigo/esei/daa/rest/PeopleResourceTest.java
@@ -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 people = response.readEntity(new GenericType>(){});
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());
}
diff --git a/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java
index ed9a674b5d7e31dfa146d95222182a7fc9195010..0c74ad1d3e3531d283512c301ec3d54ac72cb28a 100644
--- a/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java
+++ b/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java
@@ -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();