diff --git a/db/mysql-with-inserts.sql b/db/mysql-with-inserts.sql index 088d807e70c310f7458312360b2e5a84eddd2199..9f4e77368cd6a01245555594579d66e9f28c16ff 100644 --- a/db/mysql-with-inserts.sql +++ b/db/mysql-with-inserts.sql @@ -24,4 +24,6 @@ INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'María','Nu INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Alba','Fernández'); INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Asunción','Jiménez'); -INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('admin', '0b893644f3b2097d004c58d585e784ac92dd1356d25158a298573ad54ab2d15d'); +-- The password for each user is its login suffixed with "pass". For example, user "admin" has the password "adminpass". +INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('admin', '43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70'); +INSERT INTO `daaexample`.`users` (`login`,`password`) VALUES ('normal', '688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336'); diff --git a/src/main/java/es/uvigo/esei/daa/DAAExampleApplication.java b/src/main/java/es/uvigo/esei/daa/DAAExampleApplication.java index 9ee0e9e29bbc161ebae5beb1a5c25140425207c8..1857d92dd3ddb15e297aece55655563c576b36d4 100644 --- a/src/main/java/es/uvigo/esei/daa/DAAExampleApplication.java +++ b/src/main/java/es/uvigo/esei/daa/DAAExampleApplication.java @@ -1,15 +1,17 @@ package es.uvigo.esei.daa; +import static java.util.stream.Collectors.toSet; + import java.util.Collections; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import es.uvigo.esei.daa.rest.PeopleResource; +import es.uvigo.esei.daa.rest.UsersResource; /** * Configuration of the REST application. This class includes the resources and @@ -22,8 +24,8 @@ import es.uvigo.esei.daa.rest.PeopleResource; public class DAAExampleApplication extends Application { @Override public Set> getClasses() { - return Stream.of(PeopleResource.class) - .collect(Collectors.toSet()); + return Stream.of(PeopleResource.class, UsersResource.class) + .collect(toSet()); } @Override diff --git a/src/main/java/es/uvigo/esei/daa/LoginFilter.java b/src/main/java/es/uvigo/esei/daa/LoginFilter.java index b62919bcd467a8de06e602206686c5f3425cef3a..6dd8ad265521e5322bce8bfcdda4f00118fad349 100644 --- a/src/main/java/es/uvigo/esei/daa/LoginFilter.java +++ b/src/main/java/es/uvigo/esei/daa/LoginFilter.java @@ -30,11 +30,13 @@ import es.uvigo.esei.daa.dao.UsersDAO; * @author Miguel Reboiro Jato * */ -@WebFilter(urlPatterns = { "/*", "/logout" }) +@WebFilter(urlPatterns = "/*") public class LoginFilter implements Filter { - private static final String REST_PATH = "/rest"; - private static final String INDEX_PATH = "/index.html"; private static final String LOGOUT_PATH = "/logout"; + private static final String REST_PATH = "/rest"; + private static final String[] PUBLIC_PATHS = new String[] { + "/index.html" // Add the paths that can be publicly accessed (e.g. /js, /css...) + }; @Override public void doFilter( @@ -48,15 +50,15 @@ public class LoginFilter implements Filter { try { if (isLogoutPath(httpRequest)) { destroySession(httpRequest); - removeTokenCookie(httpResponse); + removeTokenCookie(httpRequest, httpResponse); redirectToIndex(httpRequest, httpResponse); - } else if (isIndexPath(httpRequest) || checkToken(httpRequest)) { + } else if (isPublicPath(httpRequest) || checkToken(httpRequest)) { chain.doFilter(request, response); } else if (checkLogin(httpRequest, httpResponse)) { continueWithRedirect(httpRequest, httpResponse); } else if (isRestPath(httpRequest)) { destroySession(httpRequest); - httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); + httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); } else { destroySession(httpRequest); redirectToIndex(httpRequest, httpResponse); @@ -80,8 +82,13 @@ public class LoginFilter implements Filter { return request.getServletPath().equals(LOGOUT_PATH); } - private boolean isIndexPath(HttpServletRequest request) { - return request.getServletPath().equals(INDEX_PATH); + private boolean isPublicPath(HttpServletRequest request) { + for (String path : PUBLIC_PATHS) { + if (request.getServletPath().startsWith(path)) + return true; + } + + return false; } private boolean isRestPath(HttpServletRequest request) { @@ -106,10 +113,15 @@ public class LoginFilter implements Filter { response.sendRedirect(redirectPath); } - private void removeTokenCookie(HttpServletResponse response) { - final Cookie cookie = new Cookie("token", ""); - cookie.setMaxAge(0); - response.addCookie(cookie); + private void removeTokenCookie( + HttpServletRequest request, + HttpServletResponse response + ) { + final Cookie cookie = getTokenCookie(request); + if (cookie != null) { + cookie.setMaxAge(0); + response.addCookie(cookie); + } } private void destroySession(HttpServletRequest request) { @@ -125,6 +137,7 @@ public class LoginFilter implements Filter { if (login != null && password != null) { final UsersDAO dao = new UsersDAO(); + if (dao.checkLogin(login, password)) { final Credentials credentials = new Credentials(login, password); @@ -140,18 +153,33 @@ public class LoginFilter implements Filter { } } - private boolean checkToken(HttpServletRequest request) - throws DAOException, IllegalArgumentException { + private Cookie getTokenCookie(HttpServletRequest request) { final Cookie[] cookies = Optional.ofNullable(request.getCookies()) .orElse(new Cookie[0]); for (Cookie cookie : cookies) { if ("token".equals(cookie.getName())) { - final Credentials credentials = new Credentials(cookie.getValue()); - - final UsersDAO dao = new UsersDAO(); - - return dao.checkLogin(credentials.getLogin(), credentials.getPassword()); + return cookie; + } + } + + return null; + } + + private boolean checkToken(HttpServletRequest request) + throws DAOException, IllegalArgumentException { + final Cookie cookie = getTokenCookie(request); + + if (cookie != null) { + final Credentials credentials = new Credentials(cookie.getValue()); + + final UsersDAO dao = new UsersDAO(); + + if (dao.checkLogin(credentials.getLogin(), credentials.getPassword())) { + request.getSession().setAttribute("login", credentials.getLogin()); + return true; + } else { + return false; } } diff --git a/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java b/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java index 61ea8464f0c0c1b31aebd36c9bb9143fa0b16642..8c17b7ef2fe7a942ebad022c5e95bece5735ab58 100644 --- a/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java +++ b/src/main/java/es/uvigo/esei/daa/dao/UsersDAO.java @@ -9,6 +9,8 @@ import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; +import es.uvigo.esei.daa.entities.User; + /** * DAO class for managing the users of the system. * @@ -18,35 +20,28 @@ public class UsersDAO extends DAO { private final static Logger LOG = Logger.getLogger(UsersDAO.class.getName()); private final static String SALT = "daaexample-"; - + /** - * Checks if the provided credentials (login and password) correspond with a - * valid user registered in the system. + * Returns a user stored persisted in the system. * - *

The password is stored in the system "salted" and encoded with the - * SHA-256 algorithm.

- * - * @param login the login of the user. - * @param password the password of the user. - * @return {@code true} if the credentials are valid. {@code false} - * otherwise. - * @throws DAOException if an error happens while checking the credentials. + * @param login the login of the user to be retrieved. + * @return a user with the provided login. + * @throws DAOException if an error happens while retrieving the user. + * @throws IllegalArgumentException if the provided login does not + * corresponds with any persisted user. */ - public boolean checkLogin(String login, String password) throws DAOException { + public User get(String login) throws DAOException { try (final Connection conn = this.getConnection()) { - final String query = "SELECT password FROM users WHERE login=?"; + final String query = "SELECT * FROM users WHERE login=?"; try (final PreparedStatement statement = conn.prepareStatement(query)) { statement.setString(1, login); try (final ResultSet result = statement.executeQuery()) { if (result.next()) { - final String dbPassword = result.getString("password"); - final String shaPassword = encodeSha256(SALT + password); - - return shaPassword.equals(dbPassword); + return rowToEntity(result); } else { - return false; + throw new IllegalArgumentException("Invalid id"); } } } @@ -55,6 +50,28 @@ public class UsersDAO extends DAO { throw new DAOException(e); } } + + /** + * Checks if the provided credentials (login and password) correspond with a + * valid user registered in the system. + * + *

The password is stored in the system "salted" and encoded with the + * SHA-256 algorithm.

+ * + * @param login the login of the user. + * @param password the password of the user. + * @return {@code true} if the credentials are valid. {@code false} + * otherwise. + * @throws DAOException if an error happens while checking the credentials. + */ + public boolean checkLogin(String login, String password) throws DAOException { + final User user = this.get(login); + + final String dbPassword = user.getPassword(); + final String shaPassword = encodeSha256(SALT + password); + + return shaPassword.equals(dbPassword); + } private final static String encodeSha256(String text) { try { @@ -77,4 +94,11 @@ public class UsersDAO extends DAO { return sb.toString(); } + + private User rowToEntity(ResultSet result) throws SQLException { + return new User( + result.getString("login"), + result.getString("password") + ); + } } diff --git a/src/main/java/es/uvigo/esei/daa/entities/User.java b/src/main/java/es/uvigo/esei/daa/entities/User.java new file mode 100644 index 0000000000000000000000000000000000000000..ade776c45175de8414d887c1bbb0e6a85fa49ac1 --- /dev/null +++ b/src/main/java/es/uvigo/esei/daa/entities/User.java @@ -0,0 +1,68 @@ +package es.uvigo.esei.daa.entities; + +import static java.util.Objects.requireNonNull; + +/** + * An entity that represents a user. + * + * @author Miguel Reboiro Jato + */ +public class User { + private String login; + private String password; + + // Constructor needed for the JSON conversion + User() {} + + /** + * Constructs a new instance of {@link User}. + * + * @param login login that identifies the user in the system. + * @param password password of the user encoded using SHA-256 and with the + * "salt" prefix added. + */ + public User(String login, String password) { + this.setLogin(login); + this.setPassword(password); + } + + /** + * Returns the login of the user. + * + * @return the login of the user. + */ + public String getLogin() { + return login; + } + + /** + * Sets the login of the user. + * + * @param login the login that identifies the user in the system. + */ + public void setLogin(String login) { + this.login = requireNonNull(login, "Login can't be null"); + } + + /** + * Returns the password of the user. + * + * @return the password of the user. + */ + public String getPassword() { + return password; + } + + /** + * Sets the users password. + * @param password the password of the user encoded using SHA-256 and with + * the "salt" prefix added. + */ + public void setPassword(String password) { + requireNonNull(password, "Password can't be null"); + if (!password.matches("[a-zA-Z0-9]{64}")) + throw new IllegalArgumentException("Password must be a valid SHA-256"); + + this.password = password; + } +} diff --git a/src/main/java/es/uvigo/esei/daa/rest/UsersResource.java b/src/main/java/es/uvigo/esei/daa/rest/UsersResource.java new file mode 100644 index 0000000000000000000000000000000000000000..7693f5bad2399f58cd587013bb3339fc89eca691 --- /dev/null +++ b/src/main/java/es/uvigo/esei/daa/rest/UsersResource.java @@ -0,0 +1,98 @@ +package es.uvigo.esei.daa.rest; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import es.uvigo.esei.daa.dao.DAOException; +import es.uvigo.esei.daa.dao.UsersDAO; +/** + * REST resource for managing users. + * + * @author Miguel Reboiro Jato. + */ +@Path("/users") +@Produces(MediaType.APPLICATION_JSON) +public class UsersResource { + private final static Logger LOG = Logger.getLogger(UsersResource.class.getName()); + + private final UsersDAO dao; + + // The HttpServletRequest can be also injected as a parameter in the REST + // methods. + private @Context HttpServletRequest request; + + /** + * Constructs a new instance of {@link UsersResource}. + */ + public UsersResource() { + this(new UsersDAO()); + } + + // Needed for testing purposes + UsersResource(UsersDAO dao) { + this(dao, null); + } + + // Needed for testing purposes + UsersResource(UsersDAO dao, HttpServletRequest request) { + this.dao = dao; + this.request = request; + } + + /** + * Returns a user with the provided login. + * + * @param login the identifier of the user to retrieve. + * @return a 200 OK response with an user that has the provided login. + * If the request is done without providing the login credentials or using + * invalid credentials a 401 Unauthorized response will be returned. If the + * credentials are provided and a regular user (i.e. non admin user) tries + * to access the data of other user, a 403 Forbidden response will be + * returned. If the credentials are OK, but the login does not corresponds + * with any user, a 400 Bad Request response with an error message will be + * returned. If an error happens while retrieving the list, a 500 Internal + * Server Error response with an error message will be returned. + */ + @GET + @Path("/{login}") + public Response get( + @PathParam("login") String login + ) { + final String loggedUser = getLogin(); + + // Each user can only access his or her own data. Only the admin user + // can access the data of any user. + if (loggedUser.equals(login) || loggedUser.equals("admin")) { + try { + return Response.ok(dao.get(login)).build(); + } catch (IllegalArgumentException iae) { + LOG.log(Level.FINE, "Invalid user login in get method", iae); + + return Response.status(Response.Status.BAD_REQUEST) + .entity(iae.getMessage()) + .build(); + } catch (DAOException e) { + LOG.log(Level.SEVERE, "Error getting an user", e); + + return Response.serverError() + .entity(e.getMessage()) + .build(); + } + } else { + return Response.status(Response.Status.UNAUTHORIZED).build(); + } + } + + private String getLogin() { + return (String) request.getSession().getAttribute("login"); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/dataset/UsersDataset.java b/src/test/java/es/uvigo/esei/daa/dataset/UsersDataset.java new file mode 100644 index 0000000000000000000000000000000000000000..44082c7045b3e14a3ee882bb45f7349be93b3ec8 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/dataset/UsersDataset.java @@ -0,0 +1,38 @@ +package es.uvigo.esei.daa.dataset; + +import java.util.Arrays; +import java.util.Base64; + +import es.uvigo.esei.daa.entities.User; + +public final class UsersDataset { + private UsersDataset() {} + + public static User[] users() { + return new User[] { + new User(adminLogin(), "43f413b773f7d0cfad0e8e6529ec1249ce71e8697919eab30d82d800a3986b70"), + new User(normalLogin(), "688f21dd2d65970f174e2c9d35159250a8a23e27585452683db8c5d10b586336") + }; + } + + public static User user(String login) { + return Arrays.stream(users()) + .filter(user -> user.getLogin().equals(login)) + .findAny() + .orElseThrow(IllegalArgumentException::new); + } + + public static String adminLogin() { + return "admin"; + } + + public static String normalLogin() { + return "normal"; + } + + public static String userToken(String login) { + final String chain = login + ":" + login + "pass"; + + return Base64.getEncoder().encodeToString(chain.getBytes()); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/matchers/HasHttpStatus.java b/src/test/java/es/uvigo/esei/daa/matchers/HasHttpStatus.java index 03bc3e30b9b2877616cbc8e64dfa5ebceeacc122..e5e7111741c59ff73893ff6c01cb5ba323ad3bdb 100644 --- a/src/test/java/es/uvigo/esei/daa/matchers/HasHttpStatus.java +++ b/src/test/java/es/uvigo/esei/daa/matchers/HasHttpStatus.java @@ -77,4 +77,14 @@ public class HasHttpStatus extends TypeSafeMatcher { public static Matcher hasInternalServerErrorStatus() { return new HasHttpStatus(Response.Status.INTERNAL_SERVER_ERROR); } + + @Factory + public static Matcher hasUnauthorized() { + return new HasHttpStatus(Response.Status.UNAUTHORIZED); + } + + @Factory + public static Matcher hasForbidden() { + return new HasHttpStatus(Response.Status.FORBIDDEN); + } } diff --git a/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToUser.java b/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToUser.java new file mode 100644 index 0000000000000000000000000000000000000000..689674ea1e7e97580ce16377bc3109a668e4768c --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/matchers/IsEqualToUser.java @@ -0,0 +1,56 @@ +package es.uvigo.esei.daa.matchers; + +import org.hamcrest.Factory; +import org.hamcrest.Matcher; + +import es.uvigo.esei.daa.entities.Person; +import es.uvigo.esei.daa.entities.User; + +public class IsEqualToUser extends IsEqualToEntity { + public IsEqualToUser(User entity) { + super(entity); + } + + @Override + protected boolean matchesSafely(User actual) { + this.clearDescribeTo(); + + if (actual == null) { + this.addTemplatedDescription("actual", expected.toString()); + return false; + } else { + return checkAttribute("login", User::getLogin, actual) + && checkAttribute("password", User::getPassword, actual); + } + } + + /** + * Factory method that creates a new {@link IsEqualToEntity} matcher with + * the provided {@link Person} as the expected value. + * + * @param user the expected person. + * @return a new {@link IsEqualToEntity} matcher with the provided + * {@link Person} as the expected value. + */ + @Factory + public static IsEqualToUser equalsToUser(User user) { + return new IsEqualToUser(user); + } + + /** + * Factory method that returns a new {@link Matcher} that includes several + * {@link IsEqualToUser} matchers, each one using an {@link Person} of the + * provided ones as the expected value. + * + * @param users the persons to be used as the expected values. + * @return a new {@link Matcher} that includes several + * {@link IsEqualToUser} matchers, each one using an {@link Person} of the + * provided ones as the expected value. + * @see IsEqualToEntity#containsEntityInAnyOrder(java.util.function.Function, Object...) + */ + @Factory + public static Matcher> containsPeopleInAnyOrder(User ... users) { + return containsEntityInAnyOrder(IsEqualToUser::equalsToUser, users); + } + +} diff --git a/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..042faec332b2448c2d0bc42560b431da9a6de926 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/rest/UsersResourceTest.java @@ -0,0 +1,161 @@ +package es.uvigo.esei.daa.rest; + +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.user; +import static es.uvigo.esei.daa.dataset.UsersDataset.userToken; +import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasForbidden; +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.IsEqualToUser.equalsToUser; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; + +import javax.sql.DataSource; +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; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +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.LoginFilter; +import es.uvigo.esei.daa.entities.User; +import es.uvigo.esei.daa.listeners.ApplicationContextBinding; +import es.uvigo.esei.daa.listeners.ApplicationContextJndiBindingTestExecutionListener; +import es.uvigo.esei.daa.listeners.DbManagement; +import es.uvigo.esei.daa.listeners.DbManagementTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:contexts/mem-context.xml") +@TestExecutionListeners({ + DbUnitTestExecutionListener.class, + DbManagementTestExecutionListener.class, + ApplicationContextJndiBindingTestExecutionListener.class +}) +@ApplicationContextBinding( + jndiUrl = "java:/comp/env/jdbc/daaexample", + type = DataSource.class +) +@DbManagement( + create = "classpath:db/hsqldb.sql", + drop = "classpath:db/hsqldb-drop.sql" +) +@DatabaseSetup("/datasets/dataset.xml") +@ExpectedDatabase("/datasets/dataset.xml") +public class UsersResourceTest extends JerseyTest { + @Override + protected Application configure() { + return new DAAExampleApplication(); + } + + @Override + protected void configureClient(ClientConfig config) { + super.configureClient(config); + + // Enables JSON transformation in client + config.register(JacksonJsonProvider.class); + 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") + .addFilter(LoginFilter.class, "login-filter") + .build(); + } + + @Test + public void testGetAdminOwnUser() throws IOException { + final String admin = adminLogin(); + + final Response response = target("users/" + admin).request() + .cookie("token", userToken(admin)) + .get(); + assertThat(response, hasOkStatus()); + + final User user = response.readEntity(User.class); + + assertThat(user, is(equalsToUser(user(admin)))); + } + + @Test + public void testGetAdminOtherUser() throws IOException { + final String admin = adminLogin(); + final String otherUser = normalLogin(); + + final Response response = target("users/" + otherUser).request() + .cookie("token", userToken(admin)) + .get(); + assertThat(response, hasOkStatus()); + + final User user = response.readEntity(User.class); + + assertThat(user, is(equalsToUser(user(otherUser)))); + } + + @Test + public void testGetNormalOwnUser() throws IOException { + final String login = normalLogin(); + + final Response response = target("users/" + login).request() + .cookie("token", userToken(login)) + .get(); + assertThat(response, hasOkStatus()); + + final User user = response.readEntity(User.class); + + assertThat(user, is(equalsToUser(user(login)))); + } + + @Test + public void testGetNoCredentials() throws IOException { + final Response response = target("users/" + normalLogin()).request().get(); + + assertThat(response, hasForbidden()); + } + + @Test + public void testGetBadCredentials() throws IOException { + final Response response = target("users/" + adminLogin()).request() + .cookie("token", "YmFkOmNyZWRlbnRpYWxz") + .get(); + + assertThat(response, hasForbidden()); + } + + @Test + public void testGetIllegalAccess() throws IOException { + final Response response = target("users/" + adminLogin()).request() + .cookie("token", userToken(normalLogin())) + .get(); + + assertThat(response, hasUnauthorized()); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java b/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java index 35ad0bfb18d7db92fb905687effbc807ce76e09e..822c83f44b63c0c998e6b17c1ab25bddbd750a63 100644 --- a/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java +++ b/src/test/java/es/uvigo/esei/daa/suites/IntegrationTestSuite.java @@ -6,10 +6,12 @@ import org.junit.runners.Suite.SuiteClasses; import es.uvigo.esei.daa.dao.PeopleDAOTest; import es.uvigo.esei.daa.rest.PeopleResourceTest; +import es.uvigo.esei.daa.rest.UsersResourceTest; @SuiteClasses({ PeopleDAOTest.class, - PeopleResourceTest.class + PeopleResourceTest.class, + UsersResourceTest.class }) @RunWith(Suite.class) public class IntegrationTestSuite { diff --git a/src/test/resources/datasets/dataset-add.xml b/src/test/resources/datasets/dataset-add.xml index 7ec50ae633d2308f6a42cca7e254c8156d3bc9df..832a4a12b2244988bb86eb12ea33aa531677d9da 100644 --- a/src/test/resources/datasets/dataset-add.xml +++ b/src/test/resources/datasets/dataset-add.xml @@ -14,5 +14,6 @@ - + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-delete.xml b/src/test/resources/datasets/dataset-delete.xml index 51b0b21175dba6d713466042cf4c73ebc3f9d556..7480a415572f1a39d6616d56359f522445b1febd 100644 --- a/src/test/resources/datasets/dataset-delete.xml +++ b/src/test/resources/datasets/dataset-delete.xml @@ -12,5 +12,6 @@ - + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset-modify.xml b/src/test/resources/datasets/dataset-modify.xml index 8b0811fda62ce744d21fb1ab47bc9db2e342a444..f840fb5a8cb65c2ef9fa22d155a1ee4cfcb7433e 100644 --- a/src/test/resources/datasets/dataset-modify.xml +++ b/src/test/resources/datasets/dataset-modify.xml @@ -13,5 +13,6 @@ - + + \ No newline at end of file diff --git a/src/test/resources/datasets/dataset.xml b/src/test/resources/datasets/dataset.xml index 9aed5897b14ed8ff13085ee289ef2fabdc259b0e..2a7eff17e942477b6dd2bd4a5da60844964f22d7 100644 --- a/src/test/resources/datasets/dataset.xml +++ b/src/test/resources/datasets/dataset.xml @@ -13,5 +13,6 @@ - + + \ No newline at end of file