protected void checkNegativeAcl(ACP acp) { if (negativeAclAllowed) { return; } if (acp == null) { return; } for (ACL acl : acp.getACLs()) { if (acl.getName().equals(ACL.INHERITED_ACL)) { continue; } for (ACE ace : acl.getACEs()) { if (ace.isGranted()) { continue; } String permission = ace.getPermission(); if (permission.equals(SecurityConstants.EVERYTHING) && ace.getUsername().equals(SecurityConstants.EVERYONE)) { continue; } // allow Write, as we're sure it doesn't include Read/Browse if (permission.equals(SecurityConstants.WRITE)) { continue; } throw new IllegalArgumentException("Negative ACL not allowed: " + ace); } } }
// unit tested protected static ACLRow[] updateAclRows(ACLRow[] aclrows, ACP acp) { List<ACLRow> newaclrows = new LinkedList<ACLRow>(); Map<String, ACL> aclmap = new HashMap<String, ACL>(); for (ACL acl : acp.getACLs()) { String name = acl.getName(); if (ACL.INHERITED_ACL.equals(name)) { continue; } aclmap.put(name, acl); } List<ACE> aces = Collections.emptyList(); Set<String> aceKeys = null; String name = null; for (ACLRow aclrow : aclrows) { // new acl? if (!aclrow.name.equals(name)) { // finish remaining aces for (ACE ace : aces) { addACLRow(newaclrows, name, ace); } // start next round name = aclrow.name; ACL acl = aclmap.remove(name); aces = acl == null ? Collections.<ACE>emptyList() : new LinkedList<ACE>(Arrays.asList(acl.getACEs())); aceKeys = new HashSet<String>(); for (ACE ace : aces) { aceKeys.add(getACEkey(ace)); } } if (!aceKeys.contains(getACLrowKey(aclrow))) { // no match, keep the aclrow info instead of the ace newaclrows.add( new ACLRow( newaclrows.size(), name, aclrow.grant, aclrow.permission, aclrow.user, aclrow.group)); } } // finish remaining aces for last acl done for (ACE ace : aces) { addACLRow(newaclrows, name, ace); } // do non-done acls for (ACL acl : aclmap.values()) { name = acl.getName(); for (ACE ace : acl.getACEs()) { addACLRow(newaclrows, name, ace); } } ACLRow[] array = new ACLRow[newaclrows.size()]; return newaclrows.toArray(array); }
// unit tested protected static ACLRow[] acpToAclRows(ACP acp) { List<ACLRow> aclrows = new LinkedList<ACLRow>(); for (ACL acl : acp.getACLs()) { String name = acl.getName(); if (name.equals(ACL.INHERITED_ACL)) { continue; } for (ACE ace : acl.getACEs()) { addACLRow(aclrows, name, ace); } } ACLRow[] array = new ACLRow[aclrows.size()]; return aclrows.toArray(array); }
// security on versions, see TestLocalAPIWithCustomVersioning @Test public void testVersionSecurity() throws Exception { DocumentModel folder = new DocumentModelImpl("/", "folder", "Folder"); folder = session.createDocument(folder); ACP acp = new ACPImpl(); ACE ace = new ACE("princ1", "perm1", true); ACL acl = new ACLImpl("acl1", false); acl.add(ace); acp.addACL(acl); session.setACP(folder.getRef(), acp, true); DocumentModel file = new DocumentModelImpl("/folder", "file", "File"); file = session.createDocument(file); // set security acp = new ACPImpl(); ace = new ACE("princ2", "perm2", true); acl = new ACLImpl("acl2", false); acl.add(ace); acp.addACL(acl); session.setACP(file.getRef(), acp, true); session.save(); DocumentModel proxy = session.publishDocument(file, folder); DocumentModel version = session.getLastDocumentVersion(file.getRef()); session.save(); // check security on version acp = session.getACP(version.getRef()); ACL[] acls = acp.getACLs(); assertEquals(2, acls.length); acl = acls[0]; assertEquals(1, acl.size()); assertEquals("princ2", acl.get(0).getUsername()); acl = acls[1]; assertEquals(1 + 3, acl.size()); // 1 + 3 root defaults assertEquals("princ1", acl.get(0).getUsername()); // remove live document (there's a proxy so the version stays) session.removeDocument(file.getRef()); session.save(); // recheck security on version (works because we're administrator) acp = session.getACP(version.getRef()); assertNull(acp); // check proxy still accessible (in another session) try (CoreSession session2 = openSessionAs(SecurityConstants.ADMINISTRATOR)) { session2.getDocument(proxy.getRef()); } }