File sharing (in progress)

This commit is contained in:
jendib 2013-08-13 23:15:58 +02:00
parent 99978a12b7
commit 5cfc487193
6 changed files with 242 additions and 34 deletions

View File

@ -56,12 +56,12 @@ public class FileDao {
public void delete(String id) { public void delete(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
// Get the document // Get the file
Query q = em.createQuery("select f from File f where f.id = :id and f.deleteDate is null"); Query q = em.createQuery("select f from File f where f.id = :id and f.deleteDate is null");
q.setParameter("id", id); q.setParameter("id", id);
File fileDb = (File) q.getSingleResult(); File fileDb = (File) q.getSingleResult();
// Delete the document // Delete the file
Date dateNow = new Date(); Date dateNow = new Date();
fileDb.setDeleteDate(dateNow); fileDb.setDeleteDate(dateNow);
} }
@ -69,8 +69,8 @@ public class FileDao {
/** /**
* Gets a file by its ID. * Gets a file by its ID.
* *
* @param id Document ID * @param id File ID
* @return Document * @return File
*/ */
public File getById(String id) { public File getById(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();

View File

@ -0,0 +1,98 @@
package com.sismics.docs.core.dao.jpa;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import com.sismics.docs.core.model.jpa.FileShare;
import com.sismics.util.context.ThreadLocalContext;
/**
* File share DAO.
*
* @author bgamard
*/
public class FileShareDao {
/**
* Creates a new file share.
*
* @param fileShare File share
* @return New ID
* @throws Exception
*/
public String create(FileShare fileShare) {
// Create the UUID
fileShare.setId(UUID.randomUUID().toString());
// Create the file
EntityManager em = ThreadLocalContext.get().getEntityManager();
fileShare.setCreateDate(new Date());
em.persist(fileShare);
return fileShare.getId();
}
/**
* Returns an active file share.
*
* @param id File ID
* @return Document
*/
public FileShare getFileShare(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select fs from FileShare fs where fs.id = :id and fs.deleteDate is null");
q.setParameter("id", id);
return (FileShare) q.getSingleResult();
}
/**
* Deletes a file share.
*
* @param id File ID
*/
public void delete(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
// Get the document
Query q = em.createQuery("select fs from FileShare fs where fs.id = :id and fs.deleteDate is null");
q.setParameter("id", id);
FileShare fileShareDb = (FileShare) q.getSingleResult();
// Delete the document
Date dateNow = new Date();
fileShareDb.setDeleteDate(dateNow);
}
/**
* Gets a file share by its ID.
*
* @param id Document ID
* @return Document
*/
public FileShare getById(String id) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
try {
return em.find(FileShare.class, id);
} catch (NoResultException e) {
return null;
}
}
/**
* Get file shares by file ID.
*
* @param fileId File ID
* @return List of file shares
*/
@SuppressWarnings("unchecked")
public List<FileShare> getByFileId(String fileId) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select fs from FileShare fs where fs.fileId = :fileId and fs.deleteDate is null");
q.setParameter("fileId", fileId);
return q.getResultList();
}
}

View File

@ -54,10 +54,11 @@ public class FileResource extends BaseResource {
} }
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
DocumentDao documentDao = new DocumentDao();
File fileDb; File fileDb;
try { try {
fileDb = fileDao.getFile(id); fileDb = fileDao.getFile(id);
// TODO Check that the current user owns the document linked to this file documentDao.getDocument(fileDb.getDocumentId(), principal.getId());
} catch (NoResultException e) { } catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id)); throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
} }
@ -241,15 +242,17 @@ public class FileResource extends BaseResource {
// Get the file // Get the file
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
DocumentDao documentDao = new DocumentDao();
File file; File file;
try { try {
file = fileDao.getFile(id); file = fileDao.getFile(id);
// TODO Check that the current user owns the document linked to this file documentDao.getDocument(file.getDocumentId(), principal.getId());
} catch (NoResultException e) { } catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id)); throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
} }
// Delete the document // Delete the file
// TODO Delete the file from storage too
fileDao.delete(file.getId()); fileDao.delete(file.getId());
// Always return ok // Always return ok
@ -277,10 +280,11 @@ public class FileResource extends BaseResource {
// Get the file // Get the file
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
DocumentDao documentDao = new DocumentDao();
File file; File file;
try { try {
file = fileDao.getFile(id); file = fileDao.getFile(id);
// TODO Check that the current user owns the document linked to this file documentDao.getDocument(file.getDocumentId(), principal.getId());
} catch (NoResultException e) { } catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id)); throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
} }

View File

@ -1,7 +1,11 @@
package com.sismics.docs.rest.resource; package com.sismics.docs.rest.resource;
import javax.ws.rs.Consumes;
import java.text.MessageFormat;
import javax.persistence.NoResultException;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
@ -12,16 +16,21 @@ import javax.ws.rs.core.Response;
import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
import com.sismics.docs.core.dao.jpa.DocumentDao;
import com.sismics.docs.core.dao.jpa.FileDao;
import com.sismics.docs.core.dao.jpa.FileShareDao;
import com.sismics.docs.core.model.jpa.File;
import com.sismics.docs.core.model.jpa.FileShare;
import com.sismics.rest.exception.ClientException;
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 com.sun.jersey.multipart.FormDataParam;
/** /**
* File share REST resources. * File share REST resources.
* *
* @author bgamard * @author bgamard
*/ */
@Path("/share") @Path("/fileshare")
public class FileShareResource extends BaseResource { public class FileShareResource extends BaseResource {
/** /**
* Add a file share to a file. * Add a file share to a file.
@ -32,10 +41,9 @@ public class FileShareResource extends BaseResource {
* @throws JSONException * @throws JSONException
*/ */
@PUT @PUT
@Consumes("multipart/form-data")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response add( public Response add(
@FormDataParam("id") String fileId) throws JSONException { @FormParam("id") String fileId) throws JSONException {
if (!authenticate()) { if (!authenticate()) {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
} }
@ -44,19 +52,32 @@ public class FileShareResource extends BaseResource {
ValidationUtil.validateRequired(fileId, "id"); ValidationUtil.validateRequired(fileId, "id");
// Get the file // Get the file
// TODO Not implemented FileDao fileDao = new FileDao();
DocumentDao documentDao = new DocumentDao();
try {
File file = fileDao.getFile(fileId);
documentDao.getDocument(file.getDocumentId(), principal.getId());
} catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", fileId));
}
// Create the file share
FileShareDao fileShareDao = new FileShareDao();
FileShare fileShare = new FileShare();
fileShare.setFileId(fileId);
fileShareDao.create(fileShare);
// Always return ok // Always return ok
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put("status", "ok"); response.put("status", "ok");
response.put("id", fileId); response.put("id", fileShare.getId());
return Response.ok().entity(response).build(); return Response.ok().entity(response).build();
} }
/** /**
* Deletes a file share. * Deletes a file share.
* *
* @param id File shqre ID * @param id File share ID
* @return Response * @return Response
* @throws JSONException * @throws JSONException
*/ */
@ -69,19 +90,21 @@ public class FileShareResource extends BaseResource {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
} }
// Get the file shqre // Get the file share
// FileShareDao fileShareDao = new FileShareDao(); FileShareDao fileShareDao = new FileShareDao();
// FileShare fileShare; FileDao fileDao = new FileDao();
// try { DocumentDao documentDao = new DocumentDao();
// fileShare = fileShareDao.getFileShare(id); FileShare fileShare;
// } catch (NoResultException e) { try {
// throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id)); fileShare = fileShareDao.getFileShare(id);
// } File file = fileDao.getFile(fileShare.getFileId());
// documentDao.getDocument(file.getDocumentId(), principal.getId());
// // Delete the file share } catch (NoResultException e) {
// fileShareDao.delete(fileShare.getId()); throw new ClientException("FileShareNotFound", MessageFormat.format("File share not found: {0}", id));
}
// TODO Not implemented // Delete the file share
fileShareDao.delete(fileShare.getId());
// Always return ok // Always return ok
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();

View File

@ -19,13 +19,13 @@ import java.io.BufferedInputStream;
import java.io.InputStream; import java.io.InputStream;
/** /**
* Exhaustive test of the document resource. * Exhaustive test of the file resource.
* *
* @author bgamard * @author bgamard
*/ */
public class TestFileResource extends BaseJerseyTest { public class TestFileResource extends BaseJerseyTest {
/** /**
* Test the document resource. * Test the file resource.
* *
* @throws Exception * @throws Exception
*/ */
@ -144,9 +144,9 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(file1Id, files.getJSONObject(1).getString("id")); Assert.assertEquals(file1Id, files.getJSONObject(1).getString("id"));
// Deletes a file // Deletes a file
documentResource = resource().path("/file/" + file1Id); fileResource = resource().path("/file/" + file1Id);
documentResource.addFilter(new CookieAuthenticationFilter(file1AuthenticationToken)); fileResource.addFilter(new CookieAuthenticationFilter(file1AuthenticationToken));
response = documentResource.delete(ClientResponse.class); response = fileResource.delete(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class); json = response.getEntity(JSONObject.class);
Assert.assertEquals("ok", json.getString("status")); Assert.assertEquals("ok", json.getString("status"));

View File

@ -0,0 +1,83 @@
package com.sismics.docs.rest;
import java.io.BufferedInputStream;
import java.io.InputStream;
import javax.ws.rs.core.MediaType;
import junit.framework.Assert;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Test;
import com.sismics.docs.rest.filter.CookieAuthenticationFilter;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataMultiPart;
/**
* Exhaustive test of the file share resource.
*
* @author bgamard
*/
public class TestFileShareResource extends BaseJerseyTest {
/**
* Test the file share resource.
*
* @throws Exception
*/
@Test
public void testFileShareResource() throws Exception {
// Login fileshare1
clientUtil.createUser("fileshare1");
String fileShare1AuthenticationToken = clientUtil.login("fileshare1");
// Create a document
WebResource documentResource = resource().path("/document");
documentResource.addFilter(new CookieAuthenticationFilter(fileShare1AuthenticationToken));
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
postParams.add("title", "File test document 1");
ClientResponse response = documentResource.put(ClientResponse.class, postParams);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
JSONObject json = response.getEntity(JSONObject.class);
String document1Id = json.optString("id");
Assert.assertNotNull(document1Id);
// Add a file
WebResource fileResource = resource().path("/file");
fileResource.addFilter(new CookieAuthenticationFilter(fileShare1AuthenticationToken));
FormDataMultiPart form = new FormDataMultiPart();
InputStream file = this.getClass().getResourceAsStream("/file/PIA00452.jpg");
FormDataBodyPart fdp = new FormDataBodyPart("file",
new BufferedInputStream(file),
MediaType.APPLICATION_OCTET_STREAM_TYPE);
form.bodyPart(fdp);
form.field("id", document1Id);
response = fileResource.type(MediaType.MULTIPART_FORM_DATA).put(ClientResponse.class, form);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
String file1Id = json.getString("id");
// Share this file
WebResource fileShareResource = resource().path("/fileshare");
fileShareResource.addFilter(new CookieAuthenticationFilter(fileShare1AuthenticationToken));
postParams = new MultivaluedMapImpl();
postParams.add("id", file1Id);
response = fileShareResource.put(ClientResponse.class, postParams);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
String fileShare1Id = json.getString("id");
// Deletes the share
fileShareResource = resource().path("/fileshare/" + fileShare1Id);
fileShareResource.addFilter(new CookieAuthenticationFilter(fileShare1AuthenticationToken));
response = fileShareResource.delete(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
Assert.assertEquals("ok", json.getString("status"));
}
}