From de3f0553237589bbf37479b7aac928a1ff0d03dc Mon Sep 17 00:00:00 2001 From: jendib Date: Tue, 15 Mar 2016 22:44:50 +0100 Subject: [PATCH] #18: ACL check for groups --- .../com/sismics/docs/core/dao/jpa/AclDao.java | 6 +-- .../docs/core/dao/jpa/DocumentDao.java | 12 +++--- .../dao/jpa/criteria/DocumentCriteria.java | 12 +++--- .../sismics/security/AnonymousPrincipal.java | 14 ++++--- .../java/com/sismics/security/IPrincipal.java | 9 +++++ .../com/sismics/security/UserPrincipal.java | 38 ++++--------------- .../docs/rest/resource/AclResource.java | 10 +++-- .../docs/rest/resource/AuditLogResource.java | 2 +- .../docs/rest/resource/BaseResource.java | 19 ++++++++++ .../docs/rest/resource/CommentResource.java | 6 +-- .../docs/rest/resource/DocumentResource.java | 13 ++++--- .../docs/rest/resource/FileResource.java | 14 +++---- .../docs/rest/resource/ShareResource.java | 4 +- 13 files changed, 87 insertions(+), 72 deletions(-) diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/AclDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/AclDao.java index af6f726c..166b0185 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/AclDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/AclDao.java @@ -105,12 +105,12 @@ public class AclDao { * @param targetId ACL target entity ID * @return True if the document is accessible */ - public boolean checkPermission(String sourceId, PermType perm, String targetId) { + public boolean checkPermission(String sourceId, PermType perm, List targetIdList) { EntityManager em = ThreadLocalContext.get().getEntityManager(); - Query q = em.createQuery("select a from Acl a where a.sourceId = :sourceId and a.perm = :perm and a.targetId = :targetId and a.deleteDate is null"); + Query q = em.createQuery("select a from Acl a where a.sourceId = :sourceId and a.perm = :perm and a.targetId in (:targetIdList) and a.deleteDate is null"); q.setParameter("sourceId", sourceId); q.setParameter("perm", perm); - q.setParameter("targetId", targetId); + q.setParameter("targetIdList", targetIdList); // We have a matching permission if (q.getResultList().size() > 0) { diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java index 2221f532..012f5926 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/DocumentDao.java @@ -90,20 +90,20 @@ public class DocumentDao { * @param userId User ID * @return Document */ - public DocumentDto getDocument(String id, PermType perm, String userId) { + public DocumentDto getDocument(String id, PermType perm, List targetIdList) { EntityManager em = ThreadLocalContext.get().getEntityManager(); StringBuilder sb = new StringBuilder("select d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_LANGUAGE_C, "); sb.append(" (select count(s.SHA_ID_C) from T_SHARE s, T_ACL ac where ac.ACL_SOURCEID_C = d.DOC_ID_C and ac.ACL_TARGETID_C = s.SHA_ID_C and ac.ACL_DELETEDATE_D is null and s.SHA_DELETEDATE_D is null), "); sb.append(" (select count(f.FIL_ID_C) from T_FILE f where f.FIL_DELETEDATE_D is null and f.FIL_IDDOC_C = d.DOC_ID_C), "); sb.append(" u.USE_USERNAME_C "); sb.append(" from T_DOCUMENT d, T_USER u "); - sb.append(" join T_ACL a on a.ACL_SOURCEID_C = d.DOC_ID_C and a.ACL_TARGETID_C = :userId and a.ACL_PERM_C = :perm and a.ACL_DELETEDATE_D is null "); + sb.append(" join T_ACL a on a.ACL_SOURCEID_C = d.DOC_ID_C and a.ACL_TARGETID_C in (:targetIdList) and a.ACL_PERM_C = :perm and a.ACL_DELETEDATE_D is null "); sb.append(" where d.DOC_IDUSER_C = u.USE_ID_C and d.DOC_ID_C = :id and d.DOC_DELETEDATE_D is null "); Query q = em.createNativeQuery(sb.toString()); q.setParameter("id", id); q.setParameter("perm", perm.name()); - q.setParameter("userId", userId); + q.setParameter("targetIdList", targetIdList); Object[] o = null; try { @@ -212,10 +212,10 @@ public class DocumentDao { sb.append(" from T_DOCUMENT d "); // Adds search criteria - if (criteria.getUserId() != null) { + if (criteria.getTargetIdList() != null) { // Read permission is enough for searching - sb.append(" join T_ACL a on a.ACL_SOURCEID_C = d.DOC_ID_C and a.ACL_TARGETID_C = :userId and a.ACL_PERM_C = 'READ' and a.ACL_DELETEDATE_D is null "); - parameterMap.put("userId", criteria.getUserId()); + sb.append(" join T_ACL a on a.ACL_SOURCEID_C = d.DOC_ID_C and a.ACL_TARGETID_C in (:targetIdList) and a.ACL_PERM_C = 'READ' and a.ACL_DELETEDATE_D is null "); + parameterMap.put("targetIdList", criteria.getTargetIdList()); } if (!Strings.isNullOrEmpty(criteria.getSearch()) || !Strings.isNullOrEmpty(criteria.getFullSearch())) { LuceneDao luceneDao = new LuceneDao(); diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java index 181495dc..a05f73fc 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/DocumentCriteria.java @@ -11,9 +11,9 @@ import java.util.List; */ public class DocumentCriteria { /** - * User ID. + * ACL target ID list. */ - private String userId; + private List targetIdList; /** * Search query. @@ -55,12 +55,12 @@ public class DocumentCriteria { */ private String creatorId; - public String getUserId() { - return userId; + public List getTargetIdList() { + return targetIdList; } - public void setUserId(String userId) { - this.userId = userId; + public void setTargetIdList(List targetIdList) { + this.targetIdList = targetIdList; } public String getSearch() { diff --git a/docs-web-common/src/main/java/com/sismics/security/AnonymousPrincipal.java b/docs-web-common/src/main/java/com/sismics/security/AnonymousPrincipal.java index b6c6911c..530935b5 100644 --- a/docs-web-common/src/main/java/com/sismics/security/AnonymousPrincipal.java +++ b/docs-web-common/src/main/java/com/sismics/security/AnonymousPrincipal.java @@ -1,7 +1,11 @@ package com.sismics.security; +import java.util.List; + import org.joda.time.DateTimeZone; +import com.google.common.collect.Lists; + /** * Anonymous principal. * @@ -47,12 +51,12 @@ public class AnonymousPrincipal implements IPrincipal { return null; } - /** - * Setter of dateTimeZone. - * - * @param dateTimeZone dateTimeZone - */ public void setDateTimeZone(DateTimeZone dateTimeZone) { this.dateTimeZone = dateTimeZone; } + + @Override + public List getGroupIdList() { + return Lists.newArrayList(); + } } diff --git a/docs-web-common/src/main/java/com/sismics/security/IPrincipal.java b/docs-web-common/src/main/java/com/sismics/security/IPrincipal.java index 1b18eb49..0e965a0f 100644 --- a/docs-web-common/src/main/java/com/sismics/security/IPrincipal.java +++ b/docs-web-common/src/main/java/com/sismics/security/IPrincipal.java @@ -1,6 +1,7 @@ package com.sismics.security; import java.security.Principal; +import java.util.List; import org.joda.time.DateTimeZone; @@ -24,6 +25,14 @@ public interface IPrincipal extends Principal { */ public String getId(); + /** + * Returns the list of group ID of the connected user, + * or an empty list if the user is anonymous. + * + * @return List of group ID + */ + public List getGroupIdList(); + /** * Returns the timezone of the principal. * diff --git a/docs-web-common/src/main/java/com/sismics/security/UserPrincipal.java b/docs-web-common/src/main/java/com/sismics/security/UserPrincipal.java index a660189a..e12c987f 100644 --- a/docs-web-common/src/main/java/com/sismics/security/UserPrincipal.java +++ b/docs-web-common/src/main/java/com/sismics/security/UserPrincipal.java @@ -1,9 +1,12 @@ package com.sismics.security; +import java.util.List; import java.util.Set; import org.joda.time.DateTimeZone; +import jersey.repackaged.com.google.common.collect.Lists; + /** * Authenticated users principal. * @@ -56,11 +59,6 @@ public class UserPrincipal implements IPrincipal { return id; } - /** - * Setter of id. - * - * @param id id - */ public void setId(String id) { this.id = id; } @@ -70,11 +68,6 @@ public class UserPrincipal implements IPrincipal { return name; } - /** - * Setter of name. - * - * @param name name - */ public void setName(String name) { this.name = name; } @@ -84,11 +77,6 @@ public class UserPrincipal implements IPrincipal { return dateTimeZone; } - /** - * Setter of dateTimeZone. - * - * @param dateTimeZone dateTimeZone - */ public void setDateTimeZone(DateTimeZone dateTimeZone) { this.dateTimeZone = dateTimeZone; } @@ -98,31 +86,21 @@ public class UserPrincipal implements IPrincipal { return email; } - /** - * Setter of email. - * - * @param email email - */ public void setEmail(String email) { this.email = email; } - /** - * Getter of baseFunctionSet. - * - * @return baseFunctionSet - */ public Set getBaseFunctionSet() { return baseFunctionSet; } - /** - * Setter of baseFunctionSet. - * - * @param baseFunctionSet baseFunctionSet - */ public void setBaseFunctionSet(Set baseFunctionSet) { this.baseFunctionSet = baseFunctionSet; } + @Override + public List getGroupIdList() { + // TODO Real groups + return Lists.newArrayList("members"); + } } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java index 5c978d41..7d224d54 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AclResource.java @@ -14,6 +14,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; +import com.google.common.collect.Lists; import com.sismics.docs.core.constant.AclTargetType; import com.sismics.docs.core.constant.PermType; import com.sismics.docs.core.dao.jpa.AclDao; @@ -51,6 +52,7 @@ public class AclResource extends BaseResource { throw new ForbiddenClientException(); } + // TODO Allow group input // Validate input ValidationUtil.validateRequired(sourceId, "source"); PermType perm = PermType.valueOf(ValidationUtil.validateLength(permStr, "perm", 1, 30, false)); @@ -65,7 +67,7 @@ public class AclResource extends BaseResource { // Check permission on the source by the principal AclDao aclDao = new AclDao(); - if (!aclDao.checkPermission(sourceId, PermType.WRITE, principal.getId())) { + if (!aclDao.checkPermission(sourceId, PermType.WRITE, getTargetIdList(null))) { throw new ForbiddenClientException(); } @@ -76,7 +78,7 @@ public class AclResource extends BaseResource { acl.setTargetId(user.getId()); // Avoid duplicates - if (!aclDao.checkPermission(acl.getSourceId(), acl.getPerm(), acl.getTargetId())) { + if (!aclDao.checkPermission(acl.getSourceId(), acl.getPerm(), Lists.newArrayList(acl.getTargetId()))) { aclDao.create(acl, principal.getId()); // Returns the ACL @@ -114,7 +116,7 @@ public class AclResource extends BaseResource { // Check permission on the source by the principal AclDao aclDao = new AclDao(); - if (!aclDao.checkPermission(sourceId, PermType.WRITE, principal.getId())) { + if (!aclDao.checkPermission(sourceId, PermType.WRITE, getTargetIdList(null))) { throw new ForbiddenClientException(); } @@ -163,6 +165,8 @@ public class AclResource extends BaseResource { .add("username", userDto.getUsername())); } + // TODO Returns groups too + JsonObjectBuilder response = Json.createObjectBuilder() .add("users", users); return Response.ok().entity(response.build()).build(); diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java index 35bfe907..2d42e01e 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AuditLogResource.java @@ -49,7 +49,7 @@ public class AuditLogResource extends BaseResource { } else { // Check ACL on the document AclDao aclDao = new AclDao(); - if (!aclDao.checkPermission(documentId, PermType.READ, principal.getId())) { + if (!aclDao.checkPermission(documentId, PermType.READ, getTargetIdList(null))) { return Response.status(Status.NOT_FOUND).build(); } criteria.setDocumentId(documentId); diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java index f6230bb8..7a3789f2 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/BaseResource.java @@ -1,12 +1,14 @@ package com.sismics.docs.rest.resource; import java.security.Principal; +import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; +import com.google.common.collect.Lists; import com.sismics.docs.rest.constant.BaseFunction; import com.sismics.rest.exception.ForbiddenClientException; import com.sismics.security.IPrincipal; @@ -77,4 +79,21 @@ public abstract class BaseResource { Set baseFunctionSet = ((UserPrincipal) principal).getBaseFunctionSet(); return baseFunctionSet != null && baseFunctionSet.contains(baseFunction.name()); } + + /** + * Returns a list of ACL target ID. + * + * @param shareId Share ID (optional) + * @return List of ACL target ID + */ + protected List getTargetIdList(String shareId) { + List targetIdList = Lists.newArrayList(principal.getGroupIdList()); + if (principal.getId() != null) { + targetIdList.add(principal.getId()); + } + if (shareId != null) { + targetIdList.add(shareId); + } + return targetIdList; + } } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java index 28dc162d..26a1881f 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/CommentResource.java @@ -51,7 +51,7 @@ public class CommentResource extends BaseResource { // Read access on doc gives access to write comments DocumentDao documentDao = new DocumentDao(); - if (documentDao.getDocument(documentId, PermType.READ, principal.getId()) == null) { + if (documentDao.getDocument(documentId, PermType.READ, getTargetIdList(null)) == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -97,7 +97,7 @@ public class CommentResource extends BaseResource { if (!comment.getUserId().equals(principal.getId())) { // Get the associated document DocumentDao documentDao = new DocumentDao(); - if (documentDao.getDocument(comment.getDocumentId(), PermType.WRITE, principal.getId()) == null) { + if (documentDao.getDocument(comment.getDocumentId(), PermType.WRITE, getTargetIdList(null)) == null) { return Response.status(Status.NOT_FOUND).build(); } } @@ -125,7 +125,7 @@ public class CommentResource extends BaseResource { // Read access on doc gives access to read comments DocumentDao documentDao = new DocumentDao(); - if (documentDao.getDocument(documentId, PermType.READ, shareId == null ? principal.getId() : shareId) == null) { + if (documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)) == null) { return Response.status(Status.NOT_FOUND).build(); } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java index 9e2cd043..092eb3d7 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java @@ -94,7 +94,7 @@ public class DocumentResource extends BaseResource { DocumentDao documentDao = new DocumentDao(); AclDao aclDao = new AclDao(); - DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, shareId == null ? principal.getId() : shareId); + DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)); if (documentDto == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -148,7 +148,8 @@ public class DocumentResource extends BaseResource { .add("type", aclDto.getTargetType())); if (!principal.isAnonymous() - && aclDto.getTargetId().equals(principal.getId()) + && (aclDto.getTargetId().equals(principal.getId()) + || principal.getGroupIdList().contains(aclDto.getTargetId())) && aclDto.getPerm() == PermType.WRITE) { // The document is writable for the current user writable = true; @@ -205,7 +206,7 @@ public class DocumentResource extends BaseResource { // Get document and check read permission DocumentDao documentDao = new DocumentDao(); - final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, shareId == null ? principal.getId() : shareId); + final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)); if (documentDto == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -268,7 +269,7 @@ public class DocumentResource extends BaseResource { PaginatedList paginatedList = PaginatedLists.create(limit, offset); SortCriteria sortCriteria = new SortCriteria(sortColumn, asc); DocumentCriteria documentCriteria = parseSearchQuery(search); - documentCriteria.setUserId(principal.getId()); + documentCriteria.setTargetIdList(getTargetIdList(null)); try { documentDao.findByCriteria(paginatedList, documentCriteria, sortCriteria); } catch (Exception e) { @@ -564,7 +565,7 @@ public class DocumentResource extends BaseResource { // Check write permission AclDao aclDao = new AclDao(); - if (!aclDao.checkPermission(id, PermType.WRITE, principal.getId())) { + if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) { throw new ForbiddenClientException(); } @@ -676,7 +677,7 @@ public class DocumentResource extends BaseResource { // Get the document DocumentDao documentDao = new DocumentDao(); FileDao fileDao = new FileDao(); - DocumentDto documentDto = documentDao.getDocument(id, PermType.WRITE, principal.getId()); + DocumentDto documentDto = documentDao.getDocument(id, PermType.WRITE, getTargetIdList(null)); if (documentDto == null) { return Response.status(Status.NOT_FOUND).build(); } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java index b8c4386a..084eb13b 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java @@ -98,7 +98,7 @@ public class FileResource extends BaseResource { documentId = null; } else { DocumentDao documentDao = new DocumentDao(); - documentDto = documentDao.getDocument(documentId, PermType.WRITE, principal.getId()); + documentDto = documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)); if (documentDto == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -213,7 +213,7 @@ public class FileResource extends BaseResource { DocumentDao documentDao = new DocumentDao(); FileDao fileDao = new FileDao(); File file = fileDao.getFile(id, principal.getId()); - DocumentDto documentDto = documentDao.getDocument(documentId, PermType.WRITE, principal.getId()); + DocumentDto documentDto = documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)); if (file == null || documentDto == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -276,7 +276,7 @@ public class FileResource extends BaseResource { // Get the document DocumentDao documentDao = new DocumentDao(); - if (documentDao.getDocument(documentId, PermType.WRITE, principal.getId()) == null) { + if (documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)) == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -312,7 +312,7 @@ public class FileResource extends BaseResource { // Check document visibility if (documentId != null) { AclDao aclDao = new AclDao(); - if (!aclDao.checkPermission(documentId, PermType.READ, shareId == null ? principal.getId() : shareId)) { + if (!aclDao.checkPermission(documentId, PermType.READ, getTargetIdList(shareId))) { return Response.status(Status.NOT_FOUND).build(); } } else if (!authenticated) { @@ -370,7 +370,7 @@ public class FileResource extends BaseResource { // But not ours throw new ForbiddenClientException(); } - } else if ((documentDto = documentDao.getDocument(file.getDocumentId(), PermType.WRITE, principal.getId())) == null) { + } else if ((documentDto = documentDao.getDocument(file.getDocumentId(), PermType.WRITE, getTargetIdList(null))) == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -445,7 +445,7 @@ public class FileResource extends BaseResource { } else { // Check document accessibility AclDao aclDao = new AclDao(); - if (!aclDao.checkPermission(file.getDocumentId(), PermType.READ, shareId == null ? principal.getId() : shareId)) { + if (!aclDao.checkPermission(file.getDocumentId(), PermType.READ, getTargetIdList(shareId))) { throw new ForbiddenClientException(); } } @@ -519,7 +519,7 @@ public class FileResource extends BaseResource { // Get the document DocumentDao documentDao = new DocumentDao(); - DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, shareId == null ? principal.getId() : shareId); + DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId)); if (documentDto == null) { return Response.status(Status.NOT_FOUND).build(); } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java index 869af2cb..c406aa57 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/ShareResource.java @@ -53,7 +53,7 @@ public class ShareResource extends BaseResource { // Get the document DocumentDao documentDao = new DocumentDao(); - if (documentDao.getDocument(documentId, PermType.WRITE, principal.getId()) == null) { + if (documentDao.getDocument(documentId, PermType.WRITE, getTargetIdList(null)) == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -102,7 +102,7 @@ public class ShareResource extends BaseResource { } Acl acl = aclList.get(0); - if (!aclDao.checkPermission(acl.getSourceId(), PermType.WRITE, principal.getId())) { + if (!aclDao.checkPermission(acl.getSourceId(), PermType.WRITE, getTargetIdList(null))) { throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", acl.getSourceId())); }