Orphan files are linked to a specific user

This commit is contained in:
jendib 2015-03-06 22:40:33 +01:00
parent d0c259ead2
commit 18cedaef2c
6 changed files with 117 additions and 19 deletions

View File

@ -61,6 +61,21 @@ public class FileDao {
return (File) q.getSingleResult(); return (File) q.getSingleResult();
} }
/**
* Returns an active file.
*
* @param id File ID
* @param userId User ID
* @return Document
*/
public File getFile(String id, String userId) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select f from File f where f.id = :id and f.userId = :userId and f.deleteDate is null");
q.setParameter("id", id);
q.setParameter("userId", userId);
return (File) q.getSingleResult();
}
/** /**
* Deletes a file. * Deletes a file.
* *
@ -117,16 +132,18 @@ public class FileDao {
} }
/** /**
* Get files by document ID. * Get files by document ID or all orphan files of an user.
* *
* @parma userId User ID
* @param documentId Document ID * @param documentId Document ID
* @return List of files * @return List of files
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<File> getByDocumentId(String documentId) { public List<File> getByDocumentId(String userId, String documentId) {
EntityManager em = ThreadLocalContext.get().getEntityManager(); EntityManager em = ThreadLocalContext.get().getEntityManager();
if (documentId == null) { if (documentId == null) {
Query q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null order by f.createDate asc"); Query q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null and f.userId = :userId order by f.createDate asc");
q.setParameter("userId", userId);
return q.getResultList(); return q.getResultList();
} }
Query q = em.createQuery("select f from File f where f.documentId = :documentId and f.deleteDate is null order by f.order asc"); Query q = em.createQuery("select f from File f where f.documentId = :documentId and f.deleteDate is null order by f.order asc");

View File

@ -27,9 +27,15 @@ public class File {
/** /**
* Document ID. * Document ID.
*/ */
@Column(name = "FIL_IDDOC_C", nullable = false, length = 36) @Column(name = "FIL_IDDOC_C", length = 36)
private String documentId; private String documentId;
/**
* User ID.
*/
@Column(name = "FIL_IDUSER_C", length = 36)
private String userId;
/** /**
* MIME type. * MIME type.
*/ */
@ -187,6 +193,24 @@ public class File {
this.order = order; this.order = order;
} }
/**
* Getter of userId.
*
* @return the userId
*/
public String getUserId() {
return userId;
}
/**
* Setter of userId.
*
* @param userId userId
*/
public void setUserId(String userId) {
this.userId = userId;
}
@Override @Override
public String toString() { public String toString() {
return Objects.toStringHelper(this) return Objects.toStringHelper(this)

View File

@ -1,2 +1,3 @@
alter table T_FILE alter column FIL_IDDOC_C set null; alter table T_FILE alter column FIL_IDDOC_C set null;
alter table T_FILE add column FIL_IDUSER_C varchar(36);
update T_CONFIG set CFG_VALUE_C='7' where CFG_ID_C='DB_VERSION'; update T_CONFIG set CFG_VALUE_C='7' where CFG_ID_C='DB_VERSION';

View File

@ -471,7 +471,7 @@ public class DocumentResource extends BaseResource {
List<File> fileList; List<File> fileList;
try { try {
document = documentDao.getDocument(id, principal.getId()); document = documentDao.getDocument(id, principal.getId());
fileList = fileDao.getByDocumentId(id); fileList = fileDao.getByDocumentId(principal.getId(), id);
} catch (NoResultException e) { } catch (NoResultException e) {
throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", id)); throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", id));
} }

View File

@ -128,7 +128,7 @@ public class FileResource extends BaseResource {
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
int order = 0; int order = 0;
if (documentId != null) { if (documentId != null) {
for (File file : fileDao.getByDocumentId(documentId)) { for (File file : fileDao.getByDocumentId(principal.getId(), documentId)) {
file.setOrder(order++); file.setOrder(order++);
} }
} }
@ -138,6 +138,7 @@ public class FileResource extends BaseResource {
file.setOrder(order); file.setOrder(order);
file.setDocumentId(documentId); file.setDocumentId(documentId);
file.setMimeType(mimeType); file.setMimeType(mimeType);
file.setUserId(principal.getId());
String fileId = fileDao.create(file); String fileId = fileDao.create(file);
// Save the file // Save the file
@ -192,7 +193,7 @@ public class FileResource extends BaseResource {
Document document; Document document;
File file; File file;
try { try {
file = fileDao.getFile(id); file = fileDao.getFile(id, principal.getId());
document = documentDao.getDocument(documentId, principal.getId()); document = documentDao.getDocument(documentId, principal.getId());
} catch (NoResultException e) { } catch (NoResultException e) {
throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", documentId)); throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", documentId));
@ -205,7 +206,7 @@ public class FileResource extends BaseResource {
// Update the file // Update the file
file.setDocumentId(documentId); file.setDocumentId(documentId);
file.setOrder(fileDao.getByDocumentId(documentId).size()); file.setOrder(fileDao.getByDocumentId(principal.getId(), documentId).size());
fileDao.update(file); fileDao.update(file);
// Raise a new file created event (it wasn't sent during file creation) // Raise a new file created event (it wasn't sent during file creation)
@ -260,7 +261,7 @@ public class FileResource extends BaseResource {
// Reorder files // Reorder files
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
for (File file : fileDao.getByDocumentId(documentId)) { for (File file : fileDao.getByDocumentId(principal.getId(), documentId)) {
int order = idList.lastIndexOf(file.getId()); int order = idList.lastIndexOf(file.getId());
if (order != -1) { if (order != -1) {
file.setOrder(order); file.setOrder(order);
@ -274,9 +275,10 @@ public class FileResource extends BaseResource {
} }
/** /**
* Returns files linked to a document. * Returns files linked to a document or not linked to any document.
* *
* @param documentId Document ID * @param documentId Document ID
* @param shareId Sharing ID
* @return Response * @return Response
* @throws JSONException * @throws JSONException
*/ */
@ -305,7 +307,7 @@ public class FileResource extends BaseResource {
} }
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
List<File> fileList = fileDao.getByDocumentId(documentId); List<File> fileList = fileDao.getByDocumentId(principal.getId(), documentId);
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
List<JSONObject> files = new ArrayList<>(); List<JSONObject> files = new ArrayList<>();
@ -345,7 +347,15 @@ public class FileResource extends BaseResource {
File file; File file;
try { try {
file = fileDao.getFile(id); file = fileDao.getFile(id);
documentDao.getDocument(file.getDocumentId(), principal.getId()); if (file.getDocumentId() == null) {
// It's an orphan file
if (!file.getUserId().equals(principal.getId())) {
// But not ours
throw new ForbiddenClientException();
}
} else {
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));
} }
@ -392,14 +402,28 @@ public class FileResource extends BaseResource {
UserDao userDao = new UserDao(); UserDao userDao = new UserDao();
File file; File file;
Document document; Document document;
String userId;
try { try {
file = fileDao.getFile(fileId); file = fileDao.getFile(fileId);
document = documentDao.getDocument(file.getDocumentId());
// Check document visibility if (file.getDocumentId() == null) {
ShareDao shareDao = new ShareDao(); // It's an orphan file
if (!shareDao.checkVisibility(document, principal.getId(), shareId)) { if (!file.getUserId().equals(principal.getId())) {
throw new ForbiddenClientException(); // But not ours
throw new ForbiddenClientException();
}
userId = file.getUserId();
} else {
// It's a file linked to a document
document = documentDao.getDocument(file.getDocumentId());
userId = document.getUserId();
// Check document visibility
ShareDao shareDao = new ShareDao();
if (!shareDao.checkVisibility(document, principal.getId(), shareId)) {
throw new ForbiddenClientException();
}
} }
} catch (NoResultException e) { } catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", fileId)); throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", fileId));
@ -427,7 +451,7 @@ public class FileResource extends BaseResource {
// Stream the output and decrypt it if necessary // Stream the output and decrypt it if necessary
StreamingOutput stream; StreamingOutput stream;
User user = userDao.getById(document.getUserId()); User user = userDao.getById(userId);
try { try {
InputStream fileInputStream = new FileInputStream(storedfile); InputStream fileInputStream = new FileInputStream(storedfile);
final InputStream responseInputStream = decrypt ? final InputStream responseInputStream = decrypt ?
@ -487,7 +511,7 @@ public class FileResource extends BaseResource {
// Get files and user associated with this document // Get files and user associated with this document
FileDao fileDao = new FileDao(); FileDao fileDao = new FileDao();
UserDao userDao = new UserDao(); UserDao userDao = new UserDao();
final List<File> fileList = fileDao.getByDocumentId(documentId); final List<File> fileList = fileDao.getByDocumentId(principal.getId(), documentId);
final User user = userDao.getById(document.getUserId()); final User user = userDao.getById(document.getUserId());
// Create the ZIP stream // Create the ZIP stream

View File

@ -228,6 +228,16 @@ public class TestFileResource extends BaseJerseyTest {
JSONArray files = json.getJSONArray("files"); JSONArray files = json.getJSONArray("files");
Assert.assertEquals(1, files.length()); Assert.assertEquals(1, files.length());
// Get the file data
fileResource = resource().path("/file/" + file1Id + "/data");
fileResource.addFilter(new CookieAuthenticationFilter(file2AuthenticationToken));
response = fileResource.get(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
InputStream is = response.getEntityInputStream();
byte[] fileBytes = ByteStreams.toByteArray(is);
Assert.assertEquals(MimeType.IMAGE_JPEG, MimeTypeUtil.guessMimeType(fileBytes));
Assert.assertEquals(163510, fileBytes.length);
// Create a document // Create a document
WebResource documentResource = resource().path("/document"); WebResource documentResource = resource().path("/document");
documentResource.addFilter(new CookieAuthenticationFilter(file2AuthenticationToken)); documentResource.addFilter(new CookieAuthenticationFilter(file2AuthenticationToken));
@ -259,5 +269,27 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
files = json.getJSONArray("files"); files = json.getJSONArray("files");
Assert.assertEquals(1, files.length()); Assert.assertEquals(1, files.length());
// Add a file
fileResource = resource().path("/file");
fileResource.addFilter(new CookieAuthenticationFilter(file2AuthenticationToken));
form = new FormDataMultiPart();
file = this.getClass().getResourceAsStream("/file/PIA00452.jpg");
fdp = new FormDataBodyPart("file",
new BufferedInputStream(file),
MediaType.APPLICATION_OCTET_STREAM_TYPE);
form.bodyPart(fdp);
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 file2Id = json.getString("id");
// Deletes a file
fileResource = resource().path("/file/" + file2Id);
fileResource.addFilter(new CookieAuthenticationFilter(file2AuthenticationToken));
response = fileResource.delete(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
Assert.assertEquals("ok", json.getString("status"));
} }
} }