Download zip of files not in same document (#591)

This commit is contained in:
Julien Kirch 2022-04-15 10:18:39 +02:00 committed by GitHub
parent d5832c48e1
commit 46f6b9e537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 312 additions and 291 deletions

View File

@ -10,6 +10,7 @@ import com.sismics.util.context.ThreadLocalContext;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
import javax.persistence.Query; import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -50,10 +51,9 @@ public class DocumentDao {
* @param limit Limit * @param limit Limit
* @return List of documents * @return List of documents
*/ */
@SuppressWarnings("unchecked")
public List<Document> findAll(int offset, int limit) { public List<Document> findAll(int offset, int limit) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select d from Document d where d.deleteDate is null"); TypedQuery<Document> q = em.createQuery("select d from Document d where d.deleteDate is null", Document.class);
q.setFirstResult(offset); q.setFirstResult(offset);
q.setMaxResults(limit); q.setMaxResults(limit);
return q.getResultList(); return q.getResultList();
@ -65,10 +65,9 @@ public class DocumentDao {
* @param userId User ID * @param userId User ID
* @return List of documents * @return List of documents
*/ */
@SuppressWarnings("unchecked")
public List<Document> findByUserId(String userId) { public List<Document> findByUserId(String userId) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select d from Document d where d.userId = :userId and d.deleteDate is null"); TypedQuery<Document> q = em.createQuery("select d from Document d where d.userId = :userId and d.deleteDate is null", Document.class);
q.setParameter("userId", userId); q.setParameter("userId", userId);
return q.getResultList(); return q.getResultList();
} }
@ -138,16 +137,16 @@ public class DocumentDao {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
// Get the document // Get the document
Query q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null"); TypedQuery<Document> dq = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null", Document.class);
q.setParameter("id", id); dq.setParameter("id", id);
Document documentDb = (Document) q.getSingleResult(); Document documentDb = dq.getSingleResult();
// Delete the document // Delete the document
Date dateNow = new Date(); Date dateNow = new Date();
documentDb.setDeleteDate(dateNow); documentDb.setDeleteDate(dateNow);
// Delete linked data // Delete linked data
q = em.createQuery("update File f set f.deleteDate = :dateNow where f.documentId = :documentId and f.deleteDate is null"); Query q = em.createQuery("update File f set f.deleteDate = :dateNow where f.documentId = :documentId and f.deleteDate is null");
q.setParameter("documentId", id); q.setParameter("documentId", id);
q.setParameter("dateNow", dateNow); q.setParameter("dateNow", dateNow);
q.executeUpdate(); q.executeUpdate();
@ -179,10 +178,10 @@ public class DocumentDao {
*/ */
public Document getById(String id) { public Document getById(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null"); TypedQuery<Document> q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null", Document.class);
q.setParameter("id", id); q.setParameter("id", id);
try { try {
return (Document) q.getSingleResult(); return q.getSingleResult();
} catch (NoResultException e) { } catch (NoResultException e) {
return null; return null;
} }
@ -199,9 +198,9 @@ public class DocumentDao {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
// Get the document // Get the document
Query q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null"); TypedQuery<Document> q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null", Document.class);
q.setParameter("id", document.getId()); q.setParameter("id", document.getId());
Document documentDb = (Document) q.getSingleResult(); Document documentDb = q.getSingleResult();
// Update the document // Update the document
documentDb.setTitle(document.getTitle()); documentDb.setTitle(document.getTitle());
@ -237,7 +236,6 @@ public class DocumentDao {
query.setParameter("fileId", document.getFileId()); query.setParameter("fileId", document.getFileId());
query.setParameter("id", document.getId()); query.setParameter("id", document.getId());
query.executeUpdate(); query.executeUpdate();
} }
/** /**

View File

@ -70,19 +70,30 @@ public class FileDao {
} }
/** /**
* Returns an active file. * Returns a list of active files.
*
* @param ids Files IDs
* @return List of files
*/
public List<File> getFiles(List<String> ids) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
TypedQuery<File> q = em.createQuery("select f from File f where f.id in :ids and f.deleteDate is null", File.class);
q.setParameter("ids", ids);
return q.getResultList();
}
/**
* Returns an active file or null.
* *
* @param id File ID * @param id File ID
* @return File * @return File
*/ */
public File getFile(String id) { public File getFile(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); List<File> files = getFiles(List.of(id));
TypedQuery<File> q = em.createQuery("select f from File f where f.id = :id and f.deleteDate is null", File.class); if (files.isEmpty()) {
q.setParameter("id", id);
try {
return q.getSingleResult();
} catch (NoResultException e) {
return null; return null;
} else {
return files.get(0);
} }
} }

View File

@ -34,6 +34,16 @@ import java.util.Objects;
* @author jtremeaux * @author jtremeaux
*/ */
public abstract class BaseJerseyTest extends JerseyTest { public abstract class BaseJerseyTest extends JerseyTest {
protected static final String FILE_APACHE_PPTX = "file/apache.pptx";
protected static final String FILE_DOCUMENT_DOCX = "file/document.docx";
protected static final String FILE_DOCUMENT_ODT = "file/document.odt";
protected static final String FILE_DOCUMENT_TXT = "file/document.txt";
protected static final String FILE_EINSTEIN_ROOSEVELT_LETTER_PNG = "file/Einstein-Roosevelt-letter.png";
protected static final String FILE_PIA_00452_JPG = "file/PIA00452.jpg";
protected static final String FILE_VIDEO_WEBM = "file/video.webm";
protected static final String FILE_WIKIPEDIA_PDF = "file/wikipedia.pdf";
protected static final String FILE_WIKIPEDIA_ZIP = "file/wikipedia.zip";
/** /**
* Test HTTP server. * Test HTTP server.
*/ */

View File

@ -3,6 +3,7 @@ package com.sismics.docs.rest.util;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import com.sismics.util.filter.TokenBasedSecurityFilter; import com.sismics.util.filter.TokenBasedSecurityFilter;
import org.glassfish.jersey.media.multipart.FormDataMultiPart; import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.media.multipart.file.StreamDataBodyPart; import org.glassfish.jersey.media.multipart.file.StreamDataBodyPart;
import org.junit.Assert; import org.junit.Assert;
@ -16,6 +17,12 @@ import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
/** /**
* REST client utilities. * REST client utilities.
@ -156,27 +163,58 @@ public class ClientUtil {
return authToken; return authToken;
} }
/**
* Create a document
*
* @param token Authentication token
* @return Document ID
*/
public String createDocument(String token) {
JsonObject json = this.resource.path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, token)
.put(Entity.form(new Form()
.param("title", "Document Title")
.param("description", "Document description")
.param("language", "eng")
.param("create_date", Long.toString(new Date().getTime()))), JsonObject.class);
String documentId = json.getString("id");
Assert.assertNotNull(documentId);
return documentId;
}
/** /**
* Add a file to a document. * Add a file to a document.
* *
* @param file File path * @param file File path
* @param filename Filename
* @param token Authentication token * @param token Authentication token
* @param documentId Document ID * @param documentId Document ID
* @return File ID * @return File ID
* @throws IOException e * @throws IOException e
* @throws URISyntaxException e
*/ */
public String addFileToDocument(String file, String filename, String token, String documentId) throws IOException { public String addFileToDocument(String file, String token, String documentId) throws IOException, URISyntaxException {
try (InputStream is = Resources.getResource(file).openStream()) { URL fileResource = Resources.getResource(file);
Path filePath = Paths.get(fileResource.toURI());
String filename = filePath.getFileName().toString();
try (InputStream is = fileResource.openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, filename); StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, filename);
try (FormDataMultiPart multiPart = new FormDataMultiPart()) { try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
JsonObject json = resource MultiPart formContent;
if (documentId != null) {
formContent = multiPart.field("id", documentId).bodyPart(streamDataBodyPart);
} else {
formContent = multiPart.bodyPart(streamDataBodyPart);
}
JsonObject json = this.resource
.register(MultiPartFeature.class) .register(MultiPartFeature.class)
.path("/file").request() .path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, token)
.put(Entity.entity(multiPart.field("id", documentId).bodyPart(streamDataBodyPart), .put(Entity.entity(formContent,
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class); MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
return json.getString("id"); String fileId = json.getString("id");
Assert.assertNotNull(fileId);
Assert.assertEquals(Files.size(filePath), json.getJsonNumber("size").longValue());
return fileId;
} }
} }
} }

View File

@ -9,6 +9,7 @@ import com.sismics.util.filter.SecurityFilter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
@ -22,6 +23,7 @@ import java.util.Set;
* @author jtremeaux * @author jtremeaux
*/ */
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
public abstract class BaseResource { public abstract class BaseResource {
/** /**
* @apiDefine admin Admin * @apiDefine admin Admin

View File

@ -0,0 +1,34 @@
package com.sismics.docs.rest.resource;
import org.glassfish.jersey.message.internal.ReaderWriter;
import javax.json.JsonObject;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
/**
* When a JSON-based exception is thrown but a JSON response is not expected,
* set the media type of the response as plain text.
*/
@Provider
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public class DocsMessageBodyWriter implements MessageBodyWriter<JsonObject> {
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public void writeTo(JsonObject o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
ReaderWriter.writeToAsString(o.toString(), entityStream, MediaType.TEXT_PLAIN_TYPE);
}
}

View File

@ -575,6 +575,7 @@ public class FileResource extends BaseResource {
*/ */
@GET @GET
@Path("{id: [a-z0-9\\-]+}/data") @Path("{id: [a-z0-9\\-]+}/data")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response data( public Response data(
@PathParam("id") final String fileId, @PathParam("id") final String fileId,
@QueryParam("share") String shareId, @QueryParam("share") String shareId,
@ -664,23 +665,24 @@ public class FileResource extends BaseResource {
/** /**
* Returns all files from a document, zipped. * Returns all files from a document, zipped.
* *
* @api {get} /file/zip Get zipped files * @api {get} /file/zip Returns all files from a document, zipped.
* @apiName GetFileZip * @apiName GetFileZip
* @apiGroup File * @apiGroup File
* @apiParam {String} id Document ID * @apiParam {String} id Document ID
* @apiParam {String} share Share ID * @apiParam {String} share Share ID
* @apiSuccess {Object} file The ZIP file is the whole response * @apiSuccess {Object} file The ZIP file is the whole response
* @apiError (client) NotFound Document not found * @apiError (client) NotFoundException Document not found
* @apiError (server) InternalServerError Error creating the ZIP file * @apiError (server) InternalServerError Error creating the ZIP file
* @apiPermission none * @apiPermission none
* @apiVersion 1.5.0 * @apiVersion 1.5.0
* *
* @param documentId Document ID * @param documentId Document ID
* @param shareId Share ID
* @return Response * @return Response
*/ */
@GET @GET
@Path("zip") @Path("zip")
@Produces(MediaType.APPLICATION_OCTET_STREAM) @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
public Response zip( public Response zip(
@QueryParam("id") String documentId, @QueryParam("id") String documentId,
@QueryParam("share") String shareId) { @QueryParam("share") String shareId) {
@ -693,10 +695,44 @@ public class FileResource extends BaseResource {
throw new NotFoundException(); throw new NotFoundException();
} }
// Get files and user associated with this document // Get files associated with this document
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
final UserDao userDao = new UserDao();
final List<File> fileList = fileDao.getByDocumentId(principal.getId(), documentId); final List<File> fileList = fileDao.getByDocumentId(principal.getId(), documentId);
String zipFileName = documentDto.getTitle().replaceAll("\\W+", "_");
return sendZippedFiles(zipFileName, fileList);
}
/**
* Returns a list of files, zipped
*
* @api {post} /file/zip Returns a list of files, zipped
* @apiName GetFilesZip
* @apiGroup File
* @apiParam {String[]} files IDs
* @apiSuccess {Object} file The ZIP file is the whole response
* @apiError (client) NotFoundException Files not found
* @apiError (server) InternalServerError Error creating the ZIP file
* @apiPermission none
* @apiVersion 1.11.0
*
* @param filesIdsList Files IDs
* @return Response
*/
@POST
@Path("zip")
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
public Response zip(
@FormParam("files") List<String> filesIdsList) {
authenticate();
List<File> fileList = findFiles(filesIdsList);
return sendZippedFiles("files", fileList);
}
/**
* Sent the content of a list of files.
*/
private Response sendZippedFiles(String zipFileName, List<File> fileList) {
final UserDao userDao = new UserDao();
// Create the ZIP stream // Create the ZIP stream
StreamingOutput stream = outputStream -> { StreamingOutput stream = outputStream -> {
@ -727,7 +763,7 @@ public class FileResource extends BaseResource {
// Write to the output // Write to the output
return Response.ok(stream) return Response.ok(stream)
.header("Content-Type", "application/zip") .header("Content-Type", "application/zip")
.header("Content-Disposition", "attachment; filename=\"" + documentDto.getTitle().replaceAll("\\W+", "_") + ".zip\"") .header("Content-Disposition", "attachment; filename=\"" + zipFileName + ".zip\"")
.build(); .build();
} }
@ -744,7 +780,32 @@ public class FileResource extends BaseResource {
if (file == null) { if (file == null) {
throw new NotFoundException(); throw new NotFoundException();
} }
checkFileAccessible(shareId, file);
return file;
}
/**
* Find a list of files with access rights checking.
*
* @param filesIds Files IDs
* @return List<File>
*/
private List<File> findFiles(List<String> filesIds) {
FileDao fileDao = new FileDao();
List<File> files = fileDao.getFiles(filesIds);
for (File file : files) {
checkFileAccessible(null, file);
}
return files;
}
/**
* Check if a file is accessible to the current user
* @param shareId Share ID
* @param file
*/
private void checkFileAccessible(String shareId, File file) {
if (file.getDocumentId() == null) { if (file.getDocumentId() == null) {
// It's an orphan file // It's an orphan file
if (!file.getUserId().equals(principal.getId())) { if (!file.getUserId().equals(principal.getId())) {
@ -758,6 +819,5 @@ public class FileResource extends BaseResource {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
} }
} }
return file;
} }
} }

View File

@ -99,7 +99,7 @@ public class TestAuditLogResource extends BaseJerseyTest {
long update1Date = json.getJsonNumber("update_date").longValue(); long update1Date = json.getJsonNumber("update_date").longValue();
// Add a file to the document // Add a file to the document
clientUtil.addFileToDocument("file/wikipedia.pdf", "wikipedia.pdf", auditlog1Token, document1Id); clientUtil.addFileToDocument(FILE_WIKIPEDIA_PDF, auditlog1Token, document1Id);
// Get document 1 // Get document 1
json = target().path("/document/" + document1Id).request() json = target().path("/document/" + document1Id).request()

View File

@ -96,8 +96,8 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document2Id); Assert.assertNotNull(document2Id);
// Add a file // Add a file
String file1Id = clientUtil.addFileToDocument("file/Einstein-Roosevelt-letter.png", String file1Id = clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG,
"Einstein-Roosevelt-letter.png", document1Token, document1Id); document1Token, document1Id);
// Share this document // Share this document
target().path("/share").request() target().path("/share").request()
@ -151,8 +151,8 @@ public class TestDocumentResource extends BaseJerseyTest {
Assert.assertNotNull(document3Id); Assert.assertNotNull(document3Id);
// Add a file // Add a file
clientUtil.addFileToDocument("file/Einstein-Roosevelt-letter.png", clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG,
"Einstein-Roosevelt-letter.png", document3Token, document3Id); document3Token, document3Id);
// List all documents from document3 // List all documents from document3
json = target().path("/document/list") json = target().path("/document/list")
@ -444,22 +444,13 @@ public class TestDocumentResource extends BaseJerseyTest {
String documentOdtToken = clientUtil.login("document_odt"); String documentOdtToken = clientUtil.login("document_odt");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(documentOdtToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentOdtToken)
.put(Entity.form(new Form()
.param("title", "My super title document 1")
.param("description", "My super description for document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a PDF file // Add a PDF file
String file1Id = clientUtil.addFileToDocument("file/document.odt", "document.odt", documentOdtToken, document1Id); String file1Id = clientUtil.addFileToDocument(FILE_DOCUMENT_ODT, documentOdtToken, document1Id);
// Search documents by query in full content // Search documents by query in full content
json = target().path("/document/list") JsonObject json = target().path("/document/list")
.queryParam("search", "full:ipsum") .queryParam("search", "full:ipsum")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentOdtToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentOdtToken)
@ -504,22 +495,13 @@ public class TestDocumentResource extends BaseJerseyTest {
String documentDocxToken = clientUtil.login("document_docx"); String documentDocxToken = clientUtil.login("document_docx");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(documentDocxToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentDocxToken)
.put(Entity.form(new Form()
.param("title", "My super title document 1")
.param("description", "My super description for document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a PDF file // Add a PDF file
String file1Id = clientUtil.addFileToDocument("file/document.docx", "document.docx", documentDocxToken, document1Id); String file1Id = clientUtil.addFileToDocument(FILE_DOCUMENT_DOCX, documentDocxToken, document1Id);
// Search documents by query in full content // Search documents by query in full content
json = target().path("/document/list") JsonObject json = target().path("/document/list")
.queryParam("search", "full:dolor") .queryParam("search", "full:dolor")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentDocxToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentDocxToken)
@ -564,22 +546,13 @@ public class TestDocumentResource extends BaseJerseyTest {
String documentPdfToken = clientUtil.login("document_pdf"); String documentPdfToken = clientUtil.login("document_pdf");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(documentPdfToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPdfToken)
.put(Entity.form(new Form()
.param("title", "My super title document 1")
.param("description", "My super description for document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a PDF file // Add a PDF file
String file1Id = clientUtil.addFileToDocument("file/wikipedia.pdf", "wikipedia.pdf", documentPdfToken, document1Id); String file1Id = clientUtil.addFileToDocument(FILE_WIKIPEDIA_PDF, documentPdfToken, document1Id);
// Search documents by query in full content // Search documents by query in full content
json = target().path("/document/list") JsonObject json = target().path("/document/list")
.queryParam("search", "full:vrandecic") .queryParam("search", "full:vrandecic")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPdfToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPdfToken)
@ -624,22 +597,13 @@ public class TestDocumentResource extends BaseJerseyTest {
String documentPlainToken = clientUtil.login("document_plain"); String documentPlainToken = clientUtil.login("document_plain");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(documentPlainToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPlainToken)
.put(Entity.form(new Form()
.param("title", "My super title document 1")
.param("description", "My super description for document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a plain text file // Add a plain text file
String file1Id = clientUtil.addFileToDocument("file/document.txt", "document.txt", documentPlainToken, document1Id); String file1Id = clientUtil.addFileToDocument(FILE_DOCUMENT_TXT, documentPlainToken, document1Id);
// Search documents by query in full content // Search documents by query in full content
json = target().path("/document/list") JsonObject json = target().path("/document/list")
.queryParam("search", "full:love") .queryParam("search", "full:love")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPlainToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPlainToken)
@ -694,22 +658,13 @@ public class TestDocumentResource extends BaseJerseyTest {
String documentVideoToken = clientUtil.login("document_video"); String documentVideoToken = clientUtil.login("document_video");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(documentVideoToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentVideoToken)
.put(Entity.form(new Form()
.param("title", "My super title document 1")
.param("description", "My super description for document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a video file // Add a video file
String file1Id = clientUtil.addFileToDocument("file/video.webm", "video.webm", documentVideoToken, document1Id); String file1Id = clientUtil.addFileToDocument(FILE_VIDEO_WEBM, documentVideoToken, document1Id);
// Search documents by query in full content // Search documents by query in full content
json = target().path("/document/list") JsonObject json = target().path("/document/list")
.queryParam("search", "full:vp9") .queryParam("search", "full:vp9")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentVideoToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentVideoToken)
@ -754,22 +709,13 @@ public class TestDocumentResource extends BaseJerseyTest {
String documentPptxToken = clientUtil.login("document_pptx"); String documentPptxToken = clientUtil.login("document_pptx");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(documentPptxToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPptxToken)
.put(Entity.form(new Form()
.param("title", "My super title document 1")
.param("description", "My super description for document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a PPTX file // Add a PPTX file
String file1Id = clientUtil.addFileToDocument("file/apache.pptx", "apache.pptx", documentPptxToken, document1Id); String file1Id = clientUtil.addFileToDocument(FILE_APACHE_PPTX, documentPptxToken, document1Id);
// Search documents by query in full content // Search documents by query in full content
json = target().path("/document/list") JsonObject json = target().path("/document/list")
.queryParam("search", "full:scaling") .queryParam("search", "full:scaling")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPptxToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, documentPptxToken)

View File

@ -23,6 +23,7 @@ import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Date; import java.util.Date;
import java.util.zip.ZipInputStream;
/** /**
* Exhaustive test of the file resource. * Exhaustive test of the file resource.
@ -37,53 +38,18 @@ public class TestFileResource extends BaseJerseyTest {
*/ */
@Test @Test
public void testFileResource() throws Exception { public void testFileResource() throws Exception {
// Login file1 // Login file_resources
clientUtil.createUser("file1"); clientUtil.createUser("file_resources");
String file1Token = clientUtil.login("file1"); String file1Token = clientUtil.login("file_resources");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(file1Token);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.put(Entity.form(new Form()
.param("title", "File test document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a file // Add a file
String file1Id; String file1Id = clientUtil.addFileToDocument(FILE_PIA_00452_JPG, file1Token, document1Id);
try (InputStream is = Resources.getResource("file/PIA00452.jpg").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "PIA00452.jpg");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.put(Entity.entity(multiPart.field("id", document1Id).bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file1Id = json.getString("id");
Assert.assertNotNull(file1Id);
Assert.assertEquals(163510L, json.getJsonNumber("size").longValue());
}
}
// Add a file // Add a file
String file2Id; String file2Id = clientUtil.addFileToDocument(FILE_PIA_00452_JPG, file1Token, document1Id);
try (InputStream is = Resources.getResource("file/PIA00452.jpg").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "PIA00452.jpg");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.put(Entity.entity(multiPart.field("id", document1Id).bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file2Id = json.getString("id");
Assert.assertNotNull(file2Id);
}
}
// Get the file data // Get the file data
Response response = target().path("/file/" + file1Id + "/data").request() Response response = target().path("/file/" + file1Id + "/data").request()
@ -131,7 +97,7 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(MimeType.DEFAULT, MimeTypeUtil.guessMimeType(storedFile, null)); Assert.assertEquals(MimeType.DEFAULT, MimeTypeUtil.guessMimeType(storedFile, null));
// Get all files from a document // Get all files from a document
json = target().path("/file/list") JsonObject json = target().path("/file/list")
.queryParam("id", document1Id) .queryParam("id", document1Id)
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
@ -294,44 +260,82 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(1, files.getJsonObject(0).getInt("version")); Assert.assertEquals(1, files.getJsonObject(0).getInt("version"));
} }
@Test
public void testFileResourceZip() throws Exception {
// Login file_resources
clientUtil.createUser("file_resources_zip");
String file1Token = clientUtil.login("file_resources_zip");
// Create a document
String document1Id = clientUtil.createDocument(file1Token);
// Add a file
String file1Id = clientUtil.addFileToDocument(FILE_PIA_00452_JPG, file1Token, document1Id);
// Get a ZIP from all files of the document
Response response = target().path("/file/zip")
.queryParam("id", document1Id)
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.get();
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
InputStream is = (InputStream) response.getEntity();
ZipInputStream zipInputStream = new ZipInputStream(is);
Assert.assertEquals(zipInputStream.getNextEntry().getName(), "0-PIA00452.jpg");
Assert.assertNull(zipInputStream.getNextEntry());
// Fail if we don't have access to the document
response = target().path("/file/zip")
.queryParam("id", document1Id)
.request()
.get();
Assert.assertEquals(Status.NOT_FOUND, Status.fromStatusCode(response.getStatus()));
// Create a document
String document2Id = clientUtil.createDocument(file1Token);
// Add a file
String file2Id = clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, file1Token, document2Id);
// Get a ZIP from both files
response = target().path("/file/zip")
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.post(Entity.form(new Form()
.param("files", file1Id)
.param("files", file2Id)));
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
is = (InputStream) response.getEntity();
zipInputStream = new ZipInputStream(is);
Assert.assertNotNull(zipInputStream.getNextEntry().getName());
Assert.assertNotNull(zipInputStream.getNextEntry().getName());
Assert.assertNull(zipInputStream.getNextEntry());
// Fail if we don't have access to the files
response = target().path("/file/zip")
.request()
.post(Entity.form(new Form()
.param("files", file1Id)
.param("files", file2Id)));
Assert.assertEquals(Status.FORBIDDEN, Status.fromStatusCode(response.getStatus()));
}
/** /**
* Test using a ZIP file. * Test using a ZIP file.
* *
* @throws Exception e * @throws Exception e
*/ */
@Test @Test
public void testZipFile() throws Exception { public void testZipFileUpload() throws Exception {
// Login file1 // Login file_zip
clientUtil.createUser("file2"); clientUtil.createUser("file_zip");
String file2Token = clientUtil.login("file2"); String fileZipToken = clientUtil.login("file_zip");
// Create a document // Create a document
long create1Date = new Date().getTime(); String document1Id = clientUtil.createDocument(fileZipToken);
JsonObject json = target().path("/document").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file2Token)
.put(Entity.form(new Form()
.param("title", "File test document 1")
.param("language", "eng")
.param("create_date", Long.toString(create1Date))), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Add a file // Add a file
String file1Id; clientUtil.addFileToDocument(FILE_WIKIPEDIA_ZIP, fileZipToken, document1Id);
try (InputStream is = Resources.getResource("file/wikipedia.zip").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "wikipedia.zip");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file2Token)
.put(Entity.entity(multiPart.field("id", document1Id).bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file1Id = json.getString("id");
Assert.assertNotNull(file1Id);
Assert.assertEquals(525069L, json.getJsonNumber("size").longValue());
}
}
} }
/** /**
@ -341,29 +345,16 @@ public class TestFileResource extends BaseJerseyTest {
*/ */
@Test @Test
public void testOrphanFile() throws Exception { public void testOrphanFile() throws Exception {
// Login file3 // Login file_orphan
clientUtil.createUser("file3"); clientUtil.createUser("file_orphan");
String file3Token = clientUtil.login("file3"); String fileOrphanToken = clientUtil.login("file_orphan");
// Add a file // Add a file
String file1Id; String file1Id = clientUtil.addFileToDocument(FILE_PIA_00452_JPG, fileOrphanToken, null);
try (InputStream is = Resources.getResource("file/PIA00452.jpg").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "PIA00452.jpg");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
JsonObject json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file1Id = json.getString("id");
Assert.assertNotNull(file1Id);
}
}
// Get all orphan files // Get all orphan files
JsonObject json = target().path("/file/list").request() JsonObject json = target().path("/file/list").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileOrphanToken)
.get(JsonObject.class); .get(JsonObject.class);
JsonArray files = json.getJsonArray("files"); JsonArray files = json.getJsonArray("files");
Assert.assertEquals(1, files.size()); Assert.assertEquals(1, files.size());
@ -372,7 +363,7 @@ public class TestFileResource extends BaseJerseyTest {
Response response = target().path("/file/" + file1Id + "/data") Response response = target().path("/file/" + file1Id + "/data")
.queryParam("size", "thumb") .queryParam("size", "thumb")
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileOrphanToken)
.get(); .get();
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
InputStream is = (InputStream) response.getEntity(); InputStream is = (InputStream) response.getEntity();
@ -382,56 +373,37 @@ public class TestFileResource extends BaseJerseyTest {
// Get the file data // Get the file data
response = target().path("/file/" + file1Id + "/data").request() response = target().path("/file/" + file1Id + "/data").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileOrphanToken)
.get(); .get();
is = (InputStream) response.getEntity(); is = (InputStream) response.getEntity();
fileBytes = ByteStreams.toByteArray(is); fileBytes = ByteStreams.toByteArray(is);
Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes, null)); Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes, null));
Assert.assertEquals(163510, fileBytes.length); Assert.assertEquals(163510, fileBytes.length);
// Create a document // Create another document
json = target().path("/document").request() String document2Id = clientUtil.createDocument(fileOrphanToken);
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token)
.put(Entity.form(new Form()
.param("title", "File test document 1")
.param("language", "eng")), JsonObject.class);
String document1Id = json.getString("id");
Assert.assertNotNull(document1Id);
// Attach a file to a document // Attach a file to a document
target().path("/file/" + file1Id + "/attach").request() target().path("/file/" + file1Id + "/attach").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileOrphanToken)
.post(Entity.form(new Form() .post(Entity.form(new Form()
.param("id", document1Id)), JsonObject.class); .param("id", document2Id)), JsonObject.class);
// Get all files from a document // Get all files from a document
json = target().path("/file/list") json = target().path("/file/list")
.queryParam("id", document1Id) .queryParam("id", document2Id)
.request() .request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileOrphanToken)
.get(JsonObject.class); .get(JsonObject.class);
files = json.getJsonArray("files"); files = json.getJsonArray("files");
Assert.assertEquals(1, files.size()); Assert.assertEquals(1, files.size());
// Add a file // Add a file
String file2Id; String file2Id = clientUtil.addFileToDocument(FILE_PIA_00452_JPG, fileOrphanToken, null);
try (InputStream is0 = Resources.getResource("file/PIA00452.jpg").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is0, "PIA00452.jpg");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file2Id = json.getString("id");
Assert.assertNotNull(file2Id);
}
}
// Deletes a file // Deletes a file
json = target().path("/file/" + file2Id).request() json = target().path("/file/" + file2Id).request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file3Token) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileOrphanToken)
.delete(JsonObject.class); .delete(JsonObject.class);
Assert.assertEquals("ok", json.getString("status")); Assert.assertEquals("ok", json.getString("status"));
} }
@ -448,20 +420,7 @@ public class TestFileResource extends BaseJerseyTest {
String fileQuotaToken = clientUtil.login("file_quota"); String fileQuotaToken = clientUtil.login("file_quota");
// Add a file (292641 bytes large) // Add a file (292641 bytes large)
String file1Id; String file1Id = clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, fileQuotaToken, null);
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "Einstein-Roosevelt-letter.png");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
JsonObject json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileQuotaToken)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file1Id = json.getString("id");
Assert.assertNotNull(file1Id);
}
}
// Check current quota // Check current quota
JsonObject json = target().path("/user").request() JsonObject json = target().path("/user").request()
@ -470,17 +429,7 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(292641L, json.getJsonNumber("storage_current").longValue()); Assert.assertEquals(292641L, json.getJsonNumber("storage_current").longValue());
// Add a file (292641 bytes large) // Add a file (292641 bytes large)
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) { clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, fileQuotaToken, null);
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "Einstein-Roosevelt-letter.png");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileQuotaToken)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
}
}
// Check current quota // Check current quota
json = target().path("/user").request() json = target().path("/user").request()
@ -489,17 +438,7 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(585282L, json.getJsonNumber("storage_current").longValue()); Assert.assertEquals(585282L, json.getJsonNumber("storage_current").longValue());
// Add a file (292641 bytes large) // Add a file (292641 bytes large)
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) { clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, fileQuotaToken, null);
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "Einstein-Roosevelt-letter.png");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileQuotaToken)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
}
}
// Check current quota // Check current quota
json = target().path("/user").request() json = target().path("/user").request()
@ -508,17 +447,10 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(877923L, json.getJsonNumber("storage_current").longValue()); Assert.assertEquals(877923L, json.getJsonNumber("storage_current").longValue());
// Add a file (292641 bytes large) // Add a file (292641 bytes large)
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) { try {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "Einstein-Roosevelt-letter.png"); clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, fileQuotaToken, null);
try (FormDataMultiPart multiPart = new FormDataMultiPart()) { Assert.fail();
Response response = target() } catch (javax.ws.rs.BadRequestException ignored) {
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileQuotaToken)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE));
Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
}
} }
// Deletes a file // Deletes a file
@ -545,17 +477,7 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertNotNull(document1Id); Assert.assertNotNull(document1Id);
// Add a file to this document (163510 bytes large) // Add a file to this document (163510 bytes large)
try (InputStream is = Resources.getResource("file/PIA00452.jpg").openStream()) { clientUtil.addFileToDocument(FILE_PIA_00452_JPG, fileQuotaToken, document1Id);
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, "PIA00452.jpg");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, fileQuotaToken)
.put(Entity.entity(multiPart.field("id", document1Id).bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
}
}
// Check current quota // Check current quota
json = target().path("/user").request() json = target().path("/user").request()