Skip to content

Commit

Permalink
ROResource Access Control Filter implemented adn tested.
Browse files Browse the repository at this point in the history
  • Loading branch information
filip franek committed Dec 31, 2013
1 parent 9353073 commit e28399a
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 22 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
/rosrs.log
/.checkstyle
*~
/tokens
/tokens
/build
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
package pl.psnc.dl.wf4ever.accesscontrol.filters;

import java.net.URI;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;

import org.apache.log4j.Logger;

import pl.psnc.dl.wf4ever.accesscontrol.dicts.Mode;
import pl.psnc.dl.wf4ever.accesscontrol.dicts.Role;
import pl.psnc.dl.wf4ever.accesscontrol.model.AccessMode;
import pl.psnc.dl.wf4ever.accesscontrol.model.Permission;
import pl.psnc.dl.wf4ever.accesscontrol.model.dao.ModeDAO;
import pl.psnc.dl.wf4ever.accesscontrol.model.dao.PermissionDAO;
import pl.psnc.dl.wf4ever.db.UserProfile;
import pl.psnc.dl.wf4ever.db.dao.UserProfileDAO;
import pl.psnc.dl.wf4ever.dl.UserMetadata;
import pl.psnc.dl.wf4ever.exceptions.ForbiddenException;
import pl.psnc.dl.wf4ever.model.Builder;

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;

Expand All @@ -17,31 +33,144 @@
*/
public class ROsResourceFilter implements ContainerRequestFilter {

/** logger. */
private static final Logger LOGGER = Logger.getLogger(ROsResourceFilter.class);
/** logger. */
private static final Logger LOGGER = Logger
.getLogger(ROsResourceFilter.class);

/** URI info. */
@Context
private UriInfo uriInfo;

/** HTTP request. */
@Context
private HttpServletRequest httpRequest;

/** Profile DAO. */
private UserProfileDAO profileDao = new UserProfileDAO();

/** User Metadata. */
private UserMetadata user;

/** User Profile. */
private UserProfile userProfile;

/** Access Mode DAO. */
private ModeDAO modeDao = new ModeDAO();

/** Permission DAO. */
private PermissionDAO permissionDAO = new PermissionDAO();

@Override
public ContainerRequest filter(ContainerRequest request) {
Builder builder = (Builder) httpRequest.getAttribute("Builder");
user = builder.getUser();
if (user.equals(UserProfile.ADMIN)) {
return request;
}
userProfile = profileDao.findByLogin(user.getLogin());
ROType resourceType = discoverResource(request.getPath());
AccessMode mode = null;
URI roUri = null;
if (resourceType != ROType.RO_COLLECTION) {
roUri = getRootROUri(request.getPath());
List<Permission> permissions = permissionDAO
.findByResearchObject(roUri.toString());
mode = modeDao.findByResearchObject(roUri.toString());
if (permissions == null || permissions.size() == 0 || mode == null) {
LOGGER.warn("Permissions for ro: " + roUri.toString()
+ " couldn't be calculated.");
return request;
}
}

// handle create operation
if (request.getMethod().equals("POST")
&& resourceType == ROType.RO_COLLECTION) {
// just check if user isn't anonymous to make let him create new ro
if (user.equals(userProfile.PUBLIC)) {
throw new ForbiddenException(
"User must be logged in to create a new RO");
} else {
return request;
}
}
// if user is an author
List<Permission> owners = permissionDAO.findByUserROAndPermission(
userProfile, roUri.toString(), Role.OWNER);
if (owners != null) {
if (owners.size() > 1) {
LOGGER.error("Ro " + roUri + " has more them one owner");
throw new WebApplicationException(500);
} else if (owners.size() == 1) {
// it's an owner, full permissions
return request;
}
}

/** URI info. */
@Context
private UriInfo uriInfo;
// if it's an access to the public resource
if (request.getMethod().equals("GET")) {
if (mode.getMode().equals(Mode.PUBLIC)) {
return request;
}
// first iterations doesn't include permission links
// just cut out all requests to private resource
if (mode.getMode().equals(Mode.PUBLIC)) {
return request;
}
}
// if there is edit request (POST,PUT,DELETE) chec if user has a writer
// permission
if (request.getMethod().equals("POST")
|| request.getMethod().equals("DELETE")
|| request.getMethod().equals("PUT")) {
List<Permission> editors = permissionDAO.findByUserROAndPermission(
userProfile, roUri.toString(), Role.EDITOR);
if (editors != null && editors.size() > 1) {
LOGGER.warn("There in a duplicated permission for the user "
+ userProfile.getLogin() + " and ro "
+ roUri.toString());
return request;
}
if (editors != null && editors.size() == 1) {
return request;
} else {
throw new ForbiddenException("User " + userProfile.getLogin()
+ " deosn't have permission to modify "
+ roUri.toString());
}

/** HTTP request. */
@Context
private HttpServletRequest httpRequest;
}
return request;
}

private ROType discoverResource(String path) {
String[] requestPathArray = path.split("ROs");
if (requestPathArray.length == 1) {
return ROType.RO_COLLECTION;
}
String resourcePath = requestPathArray[1];
if (resourcePath.replace("/", "").equals("")
&& resourcePath.split("/").length == 2) {
return ROType.RO_COLLECTION;
}
requestPathArray = path.split("ROs/");
resourcePath = requestPathArray[1];
return ROType.RESOURCE;
}

@Override
public ContainerRequest filter(ContainerRequest request) {
//we can take care only
enum ROType {
RESOURCE, RO_COLLECTION
}

//there are several rules which tells which user read or edit RO
//first if user is an author they can do everything
//if RO is public ...
//... then everybody can read
//... and users with special permissions can edit
//if RO is private
//... nobody apart from author can read
//if RO is accessed via permission link then RO can be read by everybody with link and can be edited is someone has a special permission.
return request;
}
private URI getRootROUri(String path) {
String base = path.split("ROs/")[0] + "ROs/";
String resource = path.split(uriInfo.getBaseUriBuilder().path("ROs/")
.toString())[1];
if (resource.split("/").length == 1) {
return URI.create(base + resource);
} else {
return URI.create(base + resource.split("/")[0] + "/");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package pl.psnc.dl.wf4ever.accesscontrol.filters;

import java.net.URI;

import javax.ws.rs.core.MediaType;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import pl.psnc.dl.wf4ever.accesscontrol.AccessControlTest;
import pl.psnc.dl.wf4ever.accesscontrol.dicts.Role;
import pl.psnc.dl.wf4ever.accesscontrol.model.Permission;
import pl.psnc.dl.wf4ever.integration.IntegrationTest;

import com.sun.jersey.api.client.ClientResponse;

@Category(IntegrationTest.class)
public class AccessControlROsResourceTest extends AccessControlTest {

@Override
@Before
public void setUp()
throws Exception {
super.setUp();
}


@Override
@After
public void tearDown()
throws Exception {
super.tearDown();
}


@Test
public void testIfOnlyOnwerCanReadAndWriteModes() {
URI createdRO = createRO(accessToken);
}

}

0 comments on commit e28399a

Please sign in to comment.