#83: Access documents by a shared tag

This commit is contained in:
jendib 2016-05-06 00:36:54 +02:00
parent 5226df53a2
commit f12e3ec663
11 changed files with 267 additions and 188 deletions

View File

@ -213,7 +213,7 @@ public class TagDao {
Map<String, Object> parameterMap = new HashMap<>(); Map<String, Object> parameterMap = new HashMap<>();
List<String> criteriaList = new ArrayList<>(); List<String> criteriaList = new ArrayList<>();
StringBuilder sb = new StringBuilder("select t.TAG_ID_C as c0, t.TAG_NAME_C as c1, t.TAG_COLOR_C as c2, t.TAG_IDPARENT_C as c3 "); StringBuilder sb = new StringBuilder("select distinct t.TAG_ID_C as c0, t.TAG_NAME_C as c1, t.TAG_COLOR_C as c2, t.TAG_IDPARENT_C as c3 ");
sb.append(" from T_TAG t "); sb.append(" from T_TAG t ");
// Add search criterias // Add search criterias
@ -223,6 +223,7 @@ public class TagDao {
} }
if (criteria.getTargetIdList() != null) { if (criteria.getTargetIdList() != null) {
sb.append(" left join T_ACL a on a.ACL_TARGETID_C in (:targetIdList) and a.ACL_SOURCEID_C = t.TAG_ID_C and a.ACL_PERM_C = 'READ' and a.ACL_DELETEDATE_D is null "); sb.append(" left join T_ACL a on a.ACL_TARGETID_C in (:targetIdList) and a.ACL_SOURCEID_C = t.TAG_ID_C and a.ACL_PERM_C = 'READ' and a.ACL_DELETEDATE_D is null ");
criteriaList.add("a.ACL_ID_C is not null");
parameterMap.put("targetIdList", criteria.getTargetIdList()); parameterMap.put("targetIdList", criteria.getTargetIdList());
} }
if (criteria.getDocumentId() != null) { if (criteria.getDocumentId() != null) {

View File

@ -30,7 +30,7 @@ public abstract class BaseJerseyTest extends JerseyTest {
/** /**
* Test HTTP server. * Test HTTP server.
*/ */
protected HttpServer httpServer; private HttpServer httpServer;
/** /**
* Utility class for the REST client. * Utility class for the REST client.
@ -45,7 +45,11 @@ public abstract class BaseJerseyTest extends JerseyTest {
@Override @Override
protected Application configure() { protected Application configure() {
enable(TestProperties.LOG_TRAFFIC); enable(TestProperties.LOG_TRAFFIC);
// enable(TestProperties.DUMP_ENTITY); String travisEnv = System.getenv("TRAVIS");
if (travisEnv == null || !travisEnv.equals("true")) {
// Travis don't like entity dumped in the logs
enable(TestProperties.DUMP_ENTITY);
}
return new Application(); return new Application();
} }

View File

@ -1,14 +1,5 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.sismics.docs.core.constant.PermType; import com.sismics.docs.core.constant.PermType;
import com.sismics.docs.core.dao.jpa.AclDao; import com.sismics.docs.core.dao.jpa.AclDao;
@ -21,6 +12,15 @@ import com.sismics.docs.core.util.jpa.SortCriteria;
import com.sismics.rest.exception.ForbiddenClientException; import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.JsonUtil;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
/** /**
* Audit log REST resources. * Audit log REST resources.
* *
@ -50,7 +50,7 @@ public class AuditLogResource extends BaseResource {
// Check ACL on the document // Check ACL on the document
AclDao aclDao = new AclDao(); AclDao aclDao = new AclDao();
if (!aclDao.checkPermission(documentId, PermType.READ, getTargetIdList(null))) { if (!aclDao.checkPermission(documentId, PermType.READ, getTargetIdList(null))) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
criteria.setDocumentId(documentId); criteria.setDocumentId(documentId);
} }

View File

@ -1,20 +1,5 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import java.util.List;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.sismics.docs.core.constant.PermType; import com.sismics.docs.core.constant.PermType;
import com.sismics.docs.core.dao.jpa.CommentDao; import com.sismics.docs.core.dao.jpa.CommentDao;
import com.sismics.docs.core.dao.jpa.DocumentDao; import com.sismics.docs.core.dao.jpa.DocumentDao;
@ -24,6 +9,13 @@ import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.ValidationUtil; import com.sismics.rest.util.ValidationUtil;
import com.sismics.util.ImageUtil; import com.sismics.util.ImageUtil;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.util.List;
/** /**
* Comment REST resource. * Comment REST resource.
* *
@ -52,7 +44,7 @@ public class CommentResource extends BaseResource {
// Read access on doc gives access to write comments // Read access on doc gives access to write comments
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
if (documentDao.getDocument(documentId, PermType.READ, getTargetIdList(null)) == null) { if (documentDao.getDocument(documentId, PermType.READ, getTargetIdList(null)) == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Create the comment // Create the comment
@ -90,7 +82,7 @@ public class CommentResource extends BaseResource {
CommentDao commentDao = new CommentDao(); CommentDao commentDao = new CommentDao();
Comment comment = commentDao.getActiveById(id); Comment comment = commentDao.getActiveById(id);
if (comment == null) { if (comment == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// If the current user owns the comment, skip ACL check // If the current user owns the comment, skip ACL check
@ -98,7 +90,7 @@ public class CommentResource extends BaseResource {
// Get the associated document // Get the associated document
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
if (documentDao.getDocument(comment.getDocumentId(), PermType.WRITE, getTargetIdList(null)) == null) { if (documentDao.getDocument(comment.getDocumentId(), PermType.WRITE, getTargetIdList(null)) == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
} }
@ -126,7 +118,7 @@ public class CommentResource extends BaseResource {
// Read access on doc gives access to read comments // Read access on doc gives access to read comments
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
if (documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)) == null) { if (documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)) == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Assemble results // Assemble results

View File

@ -1,57 +1,14 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
import com.sismics.docs.core.dao.jpa.criteria.TagCriteria;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.sismics.docs.core.constant.Constants; import com.sismics.docs.core.constant.Constants;
import com.sismics.docs.core.constant.PermType; import com.sismics.docs.core.constant.PermType;
import com.sismics.docs.core.dao.jpa.AclDao; import com.sismics.docs.core.dao.jpa.*;
import com.sismics.docs.core.dao.jpa.ContributorDao;
import com.sismics.docs.core.dao.jpa.DocumentDao;
import com.sismics.docs.core.dao.jpa.FileDao;
import com.sismics.docs.core.dao.jpa.RelationDao;
import com.sismics.docs.core.dao.jpa.TagDao;
import com.sismics.docs.core.dao.jpa.UserDao;
import com.sismics.docs.core.dao.jpa.criteria.DocumentCriteria; import com.sismics.docs.core.dao.jpa.criteria.DocumentCriteria;
import com.sismics.docs.core.dao.jpa.dto.AclDto; import com.sismics.docs.core.dao.jpa.criteria.TagCriteria;
import com.sismics.docs.core.dao.jpa.dto.ContributorDto; import com.sismics.docs.core.dao.jpa.dto.*;
import com.sismics.docs.core.dao.jpa.dto.DocumentDto;
import com.sismics.docs.core.dao.jpa.dto.RelationDto;
import com.sismics.docs.core.dao.jpa.dto.TagDto;
import com.sismics.docs.core.event.DocumentCreatedAsyncEvent; import com.sismics.docs.core.event.DocumentCreatedAsyncEvent;
import com.sismics.docs.core.event.DocumentDeletedAsyncEvent; import com.sismics.docs.core.event.DocumentDeletedAsyncEvent;
import com.sismics.docs.core.event.DocumentUpdatedAsyncEvent; import com.sismics.docs.core.event.DocumentUpdatedAsyncEvent;
@ -60,7 +17,6 @@ import com.sismics.docs.core.model.context.AppContext;
import com.sismics.docs.core.model.jpa.Acl; import com.sismics.docs.core.model.jpa.Acl;
import com.sismics.docs.core.model.jpa.Document; import com.sismics.docs.core.model.jpa.Document;
import com.sismics.docs.core.model.jpa.File; import com.sismics.docs.core.model.jpa.File;
import com.sismics.docs.core.model.jpa.Tag;
import com.sismics.docs.core.model.jpa.User; import com.sismics.docs.core.model.jpa.User;
import com.sismics.docs.core.util.PdfUtil; import com.sismics.docs.core.util.PdfUtil;
import com.sismics.docs.core.util.jpa.PaginatedList; import com.sismics.docs.core.util.jpa.PaginatedList;
@ -72,6 +28,23 @@ import com.sismics.rest.exception.ServerException;
import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.JsonUtil;
import com.sismics.rest.util.ValidationUtil; import com.sismics.rest.util.ValidationUtil;
import com.sismics.util.mime.MimeType; import com.sismics.util.mime.MimeType;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.*;
/** /**
* Document REST resources. * Document REST resources.
@ -98,7 +71,7 @@ public class DocumentResource extends BaseResource {
AclDao aclDao = new AclDao(); AclDao aclDao = new AclDao();
DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)); DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
if (documentDto == null) { if (documentDto == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
JsonObjectBuilder document = Json.createObjectBuilder() JsonObjectBuilder document = Json.createObjectBuilder()
@ -215,7 +188,7 @@ public class DocumentResource extends BaseResource {
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)); final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
if (documentDto == null) { if (documentDto == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Get files // Get files
@ -606,7 +579,7 @@ public class DocumentResource extends BaseResource {
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
Document document = documentDao.getById(id); Document document = documentDao.getById(id);
if (document == null) { if (document == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Update the document // Update the document
@ -712,7 +685,7 @@ public class DocumentResource extends BaseResource {
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
DocumentDto documentDto = documentDao.getDocument(id, PermType.WRITE, getTargetIdList(null)); DocumentDto documentDto = documentDao.getDocument(id, PermType.WRITE, getTargetIdList(null));
if (documentDto == null) { if (documentDto == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
List<File> fileList = fileDao.getByDocumentId(principal.getId(), id); List<File> fileList = fileDao.getByDocumentId(principal.getId(), id);

View File

@ -16,17 +16,7 @@ import java.util.zip.ZipOutputStream;
import javax.json.Json; import javax.json.Json;
import javax.json.JsonArrayBuilder; import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder; import javax.json.JsonObjectBuilder;
import javax.ws.rs.Consumes; import javax.ws.rs.*;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status;
@ -100,7 +90,7 @@ public class FileResource extends BaseResource {
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
documentDto = documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)); documentDto = documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null));
if (documentDto == null) { if (documentDto == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
} }
@ -215,7 +205,7 @@ public class FileResource extends BaseResource {
File file = fileDao.getFile(id, principal.getId()); File file = fileDao.getFile(id, principal.getId());
DocumentDto documentDto = documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)); DocumentDto documentDto = documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null));
if (file == null || documentDto == null) { if (file == null || documentDto == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Check that the file is orphan // Check that the file is orphan
@ -277,7 +267,7 @@ public class FileResource extends BaseResource {
// Get the document // Get the document
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
if (documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)) == null) { if (documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)) == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Reorder files // Reorder files
@ -313,7 +303,7 @@ public class FileResource extends BaseResource {
if (documentId != null) { if (documentId != null) {
AclDao aclDao = new AclDao(); AclDao aclDao = new AclDao();
if (!aclDao.checkPermission(documentId, PermType.READ, getTargetIdList(shareId))) { if (!aclDao.checkPermission(documentId, PermType.READ, getTargetIdList(shareId))) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
} else if (!authenticated) { } else if (!authenticated) {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
@ -360,7 +350,7 @@ public class FileResource extends BaseResource {
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
File file = fileDao.getFile(id); File file = fileDao.getFile(id);
if (file == null) { if (file == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
DocumentDto documentDto = null; DocumentDto documentDto = null;
@ -371,7 +361,7 @@ public class FileResource extends BaseResource {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
} }
} else if ((documentDto = documentDao.getDocument(file.getDocumentId(), PermType.WRITE, getTargetIdList(null))) == null) { } else if ((documentDto = documentDao.getDocument(file.getDocumentId(), PermType.WRITE, getTargetIdList(null))) == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Delete the file // Delete the file
@ -433,7 +423,7 @@ public class FileResource extends BaseResource {
UserDao userDao = new UserDao(); UserDao userDao = new UserDao();
File file = fileDao.getFile(fileId); File file = fileDao.getFile(fileId);
if (file == null) { if (file == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
if (file.getDocumentId() == null) { if (file.getDocumentId() == null) {
@ -454,7 +444,7 @@ public class FileResource extends BaseResource {
// Get the stored file // Get the stored file
java.nio.file.Path storedFile; java.nio.file.Path storedFile;
String mimeType; String mimeType;
boolean decrypt = false; boolean decrypt;
if (size != null) { if (size != null) {
storedFile = DirectoryUtil.getStorageDirectory().resolve(fileId + "_" + size); storedFile = DirectoryUtil.getStorageDirectory().resolve(fileId + "_" + size);
mimeType = MimeType.IMAGE_JPEG; // Thumbnails are JPEG mimeType = MimeType.IMAGE_JPEG; // Thumbnails are JPEG
@ -488,8 +478,12 @@ public class FileResource extends BaseResource {
try { try {
ByteStreams.copy(responseInputStream, outputStream); ByteStreams.copy(responseInputStream, outputStream);
} finally { } finally {
responseInputStream.close(); try {
outputStream.close(); responseInputStream.close();
outputStream.close();
} catch (IOException e) {
// Ignore
}
} }
} }
}; };
@ -521,7 +515,7 @@ public class FileResource extends BaseResource {
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)); DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
if (documentDto == null) { if (documentDto == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Get files and user associated with this document // Get files and user associated with this document

View File

@ -1,22 +1,5 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import java.text.MessageFormat;
import java.util.List;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.sismics.docs.core.dao.jpa.GroupDao; import com.sismics.docs.core.dao.jpa.GroupDao;
import com.sismics.docs.core.dao.jpa.UserDao; import com.sismics.docs.core.dao.jpa.UserDao;
@ -34,6 +17,14 @@ import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.JsonUtil;
import com.sismics.rest.util.ValidationUtil; import com.sismics.rest.util.ValidationUtil;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.text.MessageFormat;
import java.util.List;
/** /**
* Group REST resources. * Group REST resources.
* *
@ -109,12 +100,12 @@ public class GroupResource extends BaseResource {
GroupDao groupDao = new GroupDao(); GroupDao groupDao = new GroupDao();
Group group = groupDao.getActiveByName(groupName); Group group = groupDao.getActiveByName(groupName);
if (group == null) { if (group == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Avoid duplicates // Avoid duplicates
Group existingGroup = groupDao.getActiveByName(name); Group existingGroup = groupDao.getActiveByName(name);
if (existingGroup != null && existingGroup.getId() != group.getId()) { if (existingGroup != null && !existingGroup.getId().equals(group.getId())) {
throw new ClientException("GroupAlreadyExists", MessageFormat.format("This group already exists: {0}", name)); throw new ClientException("GroupAlreadyExists", MessageFormat.format("This group already exists: {0}", name));
} }
@ -155,7 +146,7 @@ public class GroupResource extends BaseResource {
GroupDao groupDao = new GroupDao(); GroupDao groupDao = new GroupDao();
Group group = groupDao.getActiveByName(groupName); Group group = groupDao.getActiveByName(groupName);
if (group == null) { if (group == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Delete the group // Delete the group
@ -191,14 +182,14 @@ public class GroupResource extends BaseResource {
GroupDao groupDao = new GroupDao(); GroupDao groupDao = new GroupDao();
Group group = groupDao.getActiveByName(groupName); Group group = groupDao.getActiveByName(groupName);
if (group == null) { if (group == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Get the user // Get the user
UserDao userDao = new UserDao(); UserDao userDao = new UserDao();
User user = userDao.getActiveByUsername(username); User user = userDao.getActiveByUsername(username);
if (user == null) { if (user == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Avoid duplicates // Avoid duplicates
@ -248,14 +239,14 @@ public class GroupResource extends BaseResource {
GroupDao groupDao = new GroupDao(); GroupDao groupDao = new GroupDao();
Group group = groupDao.getActiveByName(groupName); Group group = groupDao.getActiveByName(groupName);
if (group == null) { if (group == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Get the user // Get the user
UserDao userDao = new UserDao(); UserDao userDao = new UserDao();
User user = userDao.getActiveByUsername(username); User user = userDao.getActiveByUsername(username);
if (user == null) { if (user == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Remove the membership // Remove the membership
@ -315,7 +306,7 @@ public class GroupResource extends BaseResource {
GroupDao groupDao = new GroupDao(); GroupDao groupDao = new GroupDao();
Group group = groupDao.getActiveByName(groupName); Group group = groupDao.getActiveByName(groupName);
if (group == null) { if (group == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Build the response // Build the response

View File

@ -1,19 +1,6 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import java.text.MessageFormat;
import java.util.List;
import javax.json.Json;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.sismics.docs.core.constant.AclTargetType; import com.sismics.docs.core.constant.AclTargetType;
import com.sismics.docs.core.constant.PermType; import com.sismics.docs.core.constant.PermType;
import com.sismics.docs.core.dao.jpa.AclDao; import com.sismics.docs.core.dao.jpa.AclDao;
@ -26,6 +13,13 @@ import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.JsonUtil;
import com.sismics.rest.util.ValidationUtil; import com.sismics.rest.util.ValidationUtil;
import javax.json.Json;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.text.MessageFormat;
import java.util.List;
/** /**
* Share REST resources. * Share REST resources.
* *
@ -55,7 +49,7 @@ public class ShareResource extends BaseResource {
// Get the document // Get the document
DocumentDao documentDao = new DocumentDao(); DocumentDao documentDao = new DocumentDao();
if (documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)) == null) { if (documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)) == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Create the share // Create the share

View File

@ -6,13 +6,7 @@ import java.util.List;
import javax.json.Json; import javax.json.Json;
import javax.json.JsonArrayBuilder; import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder; import javax.json.JsonObjectBuilder;
import javax.ws.rs.DELETE; import javax.ws.rs.*;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import com.sismics.docs.core.constant.PermType; import com.sismics.docs.core.constant.PermType;
@ -20,6 +14,7 @@ import com.sismics.docs.core.dao.jpa.AclDao;
import com.sismics.docs.core.dao.jpa.criteria.TagCriteria; import com.sismics.docs.core.dao.jpa.criteria.TagCriteria;
import com.sismics.docs.core.dao.jpa.dto.TagDto; import com.sismics.docs.core.dao.jpa.dto.TagDto;
import com.sismics.docs.core.model.jpa.Acl; import com.sismics.docs.core.model.jpa.Acl;
import com.sismics.docs.core.util.jpa.SortCriteria;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import com.sismics.docs.core.dao.jpa.TagDao; import com.sismics.docs.core.dao.jpa.TagDao;
@ -50,7 +45,7 @@ public class TagResource extends BaseResource {
} }
TagDao tagDao = new TagDao(); TagDao tagDao = new TagDao();
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)), null); List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)), new SortCriteria(1, true));
JsonArrayBuilder items = Json.createArrayBuilder(); JsonArrayBuilder items = Json.createArrayBuilder();
for (TagDto tagDto : tagDtoList) { for (TagDto tagDto : tagDtoList) {
items.add(Json.createObjectBuilder() items.add(Json.createObjectBuilder()
@ -121,18 +116,17 @@ public class TagResource extends BaseResource {
} }
// Check the parent // Check the parent
TagDao tagDao = new TagDao();
if (StringUtils.isEmpty(parentId)) { if (StringUtils.isEmpty(parentId)) {
parentId = null; parentId = null;
} else { } else {
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)).setId(parentId), null); AclDao aclDao = new AclDao();
if (tagDtoList.size() == 0) { if (!aclDao.checkPermission(parentId, PermType.READ, getTargetIdList(null))) {
throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId)); throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId));
} }
parentId = tagDtoList.get(0).getId();
} }
// Create the tag // Create the tag
TagDao tagDao = new TagDao();
Tag tag = new Tag(); Tag tag = new Tag();
tag.setName(name); tag.setName(name);
tag.setColor(color); tag.setColor(color);
@ -188,25 +182,23 @@ public class TagResource extends BaseResource {
throw new ClientException("SpacesNotAllowed", "Spaces are not allowed in tag name"); throw new ClientException("SpacesNotAllowed", "Spaces are not allowed in tag name");
} }
// Get the tag // Check permission
TagDao tagDao = new TagDao(); AclDao aclDao = new AclDao();
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)).setId(id), null); if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
if (tagDtoList.size() == 0) { throw new NotFoundException();
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", id));
} }
// Check the parent // Check the parent
if (StringUtils.isEmpty(parentId)) { if (StringUtils.isEmpty(parentId)) {
parentId = null; parentId = null;
} else { } else {
tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)).setId(parentId), null); if (!aclDao.checkPermission(parentId, PermType.READ, getTargetIdList(null))) {
if (tagDtoList.size() == 0) {
throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId)); throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId));
} }
parentId = tagDtoList.get(0).getId();
} }
// Update the tag // Update the tag
TagDao tagDao = new TagDao();
Tag tag = tagDao.getById(id); Tag tag = tagDao.getById(id);
if (!StringUtils.isEmpty(name)) { if (!StringUtils.isEmpty(name)) {
tag.setName(name); tag.setName(name);
@ -239,13 +231,13 @@ public class TagResource extends BaseResource {
} }
// Get the tag // Get the tag
TagDao tagDao = new TagDao(); AclDao aclDao = new AclDao();
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)).setId(id), null); if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
if (tagDtoList.size() == 0) { throw new NotFoundException();
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", id));
} }
// Delete the tag // Delete the tag
TagDao tagDao = new TagDao();
tagDao.delete(id, principal.getId()); tagDao.delete(id, principal.getId());
// Always return OK // Always return OK

View File

@ -1,26 +1,18 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import java.util.List;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.sismics.docs.core.dao.jpa.VocabularyDao; import com.sismics.docs.core.dao.jpa.VocabularyDao;
import com.sismics.docs.core.model.jpa.Vocabulary; import com.sismics.docs.core.model.jpa.Vocabulary;
import com.sismics.docs.rest.constant.BaseFunction; import com.sismics.docs.rest.constant.BaseFunction;
import com.sismics.rest.exception.ForbiddenClientException; import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.util.ValidationUtil; import com.sismics.rest.util.ValidationUtil;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.util.List;
/** /**
* Vocabulary REST resources. * Vocabulary REST resources.
* *
@ -58,7 +50,7 @@ public class VocabularyResource extends BaseResource {
* *
* @param name Name * @param name Name
* @param value Value * @param value Value
* @param order Order * @param orderStr Order
* @return Response * @return Response
*/ */
@PUT @PUT
@ -95,10 +87,11 @@ public class VocabularyResource extends BaseResource {
/** /**
* Update a vocabulary. * Update a vocabulary.
* *
* @param id ID
* @param name Name * @param name Name
* @param value Value * @param value Value
* @param order Order * @param orderStr Order
* @return Response * @return Response
*/ */
@POST @POST
@ -127,7 +120,7 @@ public class VocabularyResource extends BaseResource {
VocabularyDao vocabularyDao = new VocabularyDao(); VocabularyDao vocabularyDao = new VocabularyDao();
Vocabulary vocabulary = vocabularyDao.getById(id); Vocabulary vocabulary = vocabularyDao.getById(id);
if (vocabulary == null) { if (vocabulary == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Update the vocabulary // Update the vocabulary
@ -169,7 +162,7 @@ public class VocabularyResource extends BaseResource {
VocabularyDao vocabularyDao = new VocabularyDao(); VocabularyDao vocabularyDao = new VocabularyDao();
Vocabulary vocabulary = vocabularyDao.getById(id); Vocabulary vocabulary = vocabularyDao.getById(id);
if (vocabulary == null) { if (vocabulary == null) {
return Response.status(Status.NOT_FOUND).build(); throw new NotFoundException();
} }
// Delete the vocabulary // Delete the vocabulary

View File

@ -249,4 +249,149 @@ public class TestAclResource extends BaseJerseyTest {
groups = json.getJsonArray("groups"); groups = json.getJsonArray("groups");
Assert.assertEquals(1, groups.size()); Assert.assertEquals(1, groups.size());
} }
@Test
public void testAclTags() {
// Login acltag1
clientUtil.createUser("acltag1");
String acltag1Token = clientUtil.login("acltag1");
// Login acltag2
clientUtil.createUser("acltag2");
String acltag2Token = clientUtil.login("acltag2");
// Create tag1 with acltag1
JsonObject json = target().path("/tag").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
.put(Entity.form(new Form()
.param("name", "AclTag1")
.param("color", "#ff0000")), JsonObject.class);
String tag1Id = json.getString("id");
Assert.assertNotNull(tag1Id);
// Create document1 with acltag1 tagged with tag1
json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
.put(Entity.form(new Form()
.param("title", "My super document 1")
.param("tags", tag1Id)
.param("language", "eng")), JsonObject.class);
String document1Id = json.getString("id");
// acltag2 cannot see document1
Response response = target().path("/document/" + document1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.get();
Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
// acltag2 cannot see any tag
json = target().path("/tag/list").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.get(JsonObject.class);
JsonArray tags = json.getJsonArray("tags");
Assert.assertEquals(0, tags.size());
// acltag2 cannot see any document
json = target().path("/document/list")
.queryParam("sort_column", 3)
.queryParam("asc", true)
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.get(JsonObject.class);
JsonArray documents = json.getJsonArray("documents");
Assert.assertEquals(0, documents.size());
// acltag2 cannot edit tag1
response = target().path("/tag/" + tag1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.post(Entity.form(new Form()
.param("name", "AclTag1")
.param("color", "#ff0000")));
Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
// acltag2 cannot edit document1
response = target().path("/document/" + document1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.post(Entity.form(new Form()
.param("title", "My super document 1")
.param("tags", tag1Id)
.param("language", "eng")));
Assert.assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
// Add an ACL READ for acltag2 with acltag1 on tag1
target().path("/acl").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
.put(Entity.form(new Form()
.param("source", tag1Id)
.param("perm", "READ")
.param("target", "acltag2")
.param("type", "USER")), JsonObject.class);
// acltag2 still cannot edit tag1
response = target().path("/tag/" + tag1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.post(Entity.form(new Form()
.param("name", "AclTag1")
.param("color", "#ff0000")));
Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
// acltag2 still cannot edit document1
response = target().path("/document/" + document1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.post(Entity.form(new Form()
.param("title", "My super document 1")
.param("tags", tag1Id)
.param("language", "eng")));
Assert.assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
// acltag2 can see document1 with tag1
json = target().path("/document/" + document1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.get(JsonObject.class);
tags = json.getJsonArray("tags");
Assert.assertEquals(1, tags.size());
Assert.assertEquals(tag1Id, tags.getJsonObject(0).getString("id"));
// acltag2 can see tag1
json = target().path("/tag/list").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.get(JsonObject.class);
tags = json.getJsonArray("tags");
Assert.assertEquals(1, tags.size());
Assert.assertEquals(tag1Id, tags.getJsonObject(0).getString("id"));
// acltag2 can see exactly one document
json = target().path("/document/list")
.queryParam("sort_column", 3)
.queryParam("asc", true)
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.get(JsonObject.class);
documents = json.getJsonArray("documents");
Assert.assertEquals(1, documents.size());
// Add an ACL WRITE for acltag2 with acltag1 on tag1
target().path("/acl").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag1Token)
.put(Entity.form(new Form()
.param("source", tag1Id)
.param("perm", "WRITE")
.param("target", "acltag2")
.param("type", "USER")), JsonObject.class);
// acltag2 can edit tag1
target().path("/tag/" + tag1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.post(Entity.form(new Form()
.param("name", "AclTag1")
.param("color", "#ff0000")), JsonObject.class);
// acltag2 can edit document1
target().path("/document/" + document1Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, acltag2Token)
.post(Entity.form(new Form()
.param("title", "My super document 1")
.param("tags", tag1Id)
.param("language", "eng")), JsonObject.class);
}
} }