use of javax.jcr.security.AccessControlEntry in project jackrabbit-oak by apache.
the class VersionManagementTest method testRemoveVersion3.
/**
* @since oak (DIFF: jr required jcr:versionManagement privilege on the version store)
*/
@Test
public void testRemoveVersion3() throws Exception {
Node n = createVersionableNode(superuser.getNode(path));
Version v = n.checkin();
n.checkout();
n.checkin();
testSession.refresh(false);
assertFalse(testAcMgr.hasPrivileges(n.getPath(), versionPrivileges));
AccessControlList acl = allow(SYSTEM, versionPrivileges);
try {
Node testNode = testSession.getNode(n.getPath());
testNode.getVersionHistory().removeVersion(v.getName());
fail("Missing jcr:versionManagement privilege -> remove a version must fail.");
} catch (AccessDeniedException e) {
// success
} finally {
// revert privilege modification (manually remove the ACE added)
for (AccessControlEntry entry : acl.getAccessControlEntries()) {
if (entry.getPrincipal().equals(testUser.getPrincipal())) {
acl.removeAccessControlEntry(entry);
}
}
acMgr.setPolicy(SYSTEM, acl);
superuser.save();
}
}
use of javax.jcr.security.AccessControlEntry in project sling by apache.
the class AccessControlUtil method reorderAccessControlEntries.
/**
* Move the ACE(s) for the specified principal to the position specified by the 'order'
* parameter.
*
* @param acl the acl of the node containing the ACE to position
* @param principal the user or group of the ACE to position
* @param order where the access control entry should go in the list.
* Value should be one of these:
* <table>
* <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
* <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
* <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
* <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
* <tr><td>numeric</td><td>Place the target ACE at the specified index</td></tr>
* </table>
* @throws RepositoryException
* @throws UnsupportedRepositoryOperationException
* @throws AccessControlException
*/
private static void reorderAccessControlEntries(AccessControlList acl, Principal principal, String order) throws RepositoryException {
if (order == null || order.length() == 0) {
//nothing to do
return;
}
if (acl instanceof JackrabbitAccessControlList) {
JackrabbitAccessControlList jacl = (JackrabbitAccessControlList) acl;
AccessControlEntry[] accessControlEntries = jacl.getAccessControlEntries();
if (accessControlEntries.length <= 1) {
//only one ACE, so nothing to reorder.
return;
}
AccessControlEntry beforeEntry = null;
if ("first".equals(order)) {
beforeEntry = accessControlEntries[0];
} else if ("last".equals(order)) {
beforeEntry = null;
} else if (order.startsWith("before ")) {
String beforePrincipalName = order.substring(7);
//find the index of the ACE of the 'before' principal
for (int i = 0; i < accessControlEntries.length; i++) {
if (beforePrincipalName.equals(accessControlEntries[i].getPrincipal().getName())) {
//found it!
beforeEntry = accessControlEntries[i];
break;
}
}
if (beforeEntry == null) {
//didn't find an ACE that matched the 'before' principal
throw new IllegalArgumentException("No ACE was found for the specified principal: " + beforePrincipalName);
}
} else if (order.startsWith("after ")) {
String afterPrincipalName = order.substring(6);
//find the index of the ACE of the 'after' principal
for (int i = accessControlEntries.length - 1; i >= 0; i--) {
if (afterPrincipalName.equals(accessControlEntries[i].getPrincipal().getName())) {
// the 'before' ACE is the next one after the 'after' ACE
if (i >= accessControlEntries.length - 1) {
//the after is the last one in the list
beforeEntry = null;
} else {
beforeEntry = accessControlEntries[i + 1];
}
break;
}
}
if (beforeEntry == null) {
//didn't find an ACE that matched the 'after' principal
throw new IllegalArgumentException("No ACE was found for the specified principal: " + afterPrincipalName);
}
} else {
try {
int index = Integer.parseInt(order);
if (index > accessControlEntries.length) {
//invalid index
throw new IndexOutOfBoundsException("Index value is too large: " + index);
}
if (index == 0) {
beforeEntry = accessControlEntries[0];
} else {
//the index value is the index of the principal. A principal may have more
// than one ACEs (deny + grant), so we need to compensate.
Set<Principal> processedPrincipals = new HashSet<Principal>();
for (int i = 0; i < accessControlEntries.length; i++) {
Principal principal2 = accessControlEntries[i].getPrincipal();
if (processedPrincipals.size() == index && !processedPrincipals.contains(principal2)) {
//we are now at the correct position in the list
beforeEntry = accessControlEntries[i];
break;
}
processedPrincipals.add(principal2);
}
}
} catch (NumberFormatException nfe) {
//not a number.
throw new IllegalArgumentException("Illegal value for the order parameter: " + order);
}
}
// position.
for (int i = accessControlEntries.length - 1; i >= 0; i--) {
AccessControlEntry ace = accessControlEntries[i];
if (principal.equals(ace.getPrincipal())) {
//this ACE is for the specified principal.
jacl.orderBefore(ace, beforeEntry);
}
}
} else {
throw new IllegalArgumentException("The acl must be an instance of JackrabbitAccessControlList");
}
}
use of javax.jcr.security.AccessControlEntry in project sling by apache.
the class AccessControlUtil method replaceAccessControlEntry.
/**
* Replaces existing access control entries in the ACL for the specified
* <code>principal</code> and <code>resourcePath</code>. Any existing granted
* or denied privileges which do not conflict with the specified privileges
* are maintained. Where conflicts exist, existing privileges are dropped.
* The end result will be at most two ACEs for the principal: one for grants
* and one for denies. Aggregate privileges are disaggregated before checking
* for conflicts.
* @param session
* @param resourcePath
* @param principal
* @param grantedPrivilegeNames
* @param deniedPrivilegeNames
* @param removedPrivilegeNames privileges which, if they exist, should be
* removed for this principal and resource
* @param order where the access control entry should go in the list.
* Value should be one of these:
* <table>
* <tr><td>null</td><td>If the ACE for the principal doesn't exist add at the end, otherwise leave the ACE at it's current position.</td></tr>
* <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
* <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
* <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
* <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
* <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
* </table>
* @throws RepositoryException
*/
public static void replaceAccessControlEntry(Session session, String resourcePath, Principal principal, String[] grantedPrivilegeNames, String[] deniedPrivilegeNames, String[] removedPrivilegeNames, String order) throws RepositoryException {
AccessControlManager accessControlManager = getAccessControlManager(session);
Set<String> specifiedPrivilegeNames = new HashSet<String>();
Set<String> newGrantedPrivilegeNames = disaggregateToPrivilegeNames(accessControlManager, grantedPrivilegeNames, specifiedPrivilegeNames);
Set<String> newDeniedPrivilegeNames = disaggregateToPrivilegeNames(accessControlManager, deniedPrivilegeNames, specifiedPrivilegeNames);
disaggregateToPrivilegeNames(accessControlManager, removedPrivilegeNames, specifiedPrivilegeNames);
// Get or create the ACL for the node.
AccessControlList acl = null;
AccessControlPolicy[] policies = accessControlManager.getPolicies(resourcePath);
for (AccessControlPolicy policy : policies) {
if (policy instanceof AccessControlList) {
acl = (AccessControlList) policy;
break;
}
}
if (acl == null) {
AccessControlPolicyIterator applicablePolicies = accessControlManager.getApplicablePolicies(resourcePath);
while (applicablePolicies.hasNext()) {
AccessControlPolicy policy = applicablePolicies.nextAccessControlPolicy();
if (policy instanceof AccessControlList) {
acl = (AccessControlList) policy;
break;
}
}
}
if (acl == null) {
throw new RepositoryException("Could not obtain ACL for resource " + resourcePath);
}
// Used only for logging.
Set<Privilege> oldGrants = null;
Set<Privilege> oldDenies = null;
if (log.isDebugEnabled()) {
oldGrants = new HashSet<Privilege>();
oldDenies = new HashSet<Privilege>();
}
// Combine all existing ACEs for the target principal.
AccessControlEntry[] accessControlEntries = acl.getAccessControlEntries();
for (int i = 0; i < accessControlEntries.length; i++) {
AccessControlEntry ace = accessControlEntries[i];
if (principal.equals(ace.getPrincipal())) {
if (log.isDebugEnabled()) {
log.debug("Found Existing ACE for principal {} on resource {}", new Object[] { principal.getName(), resourcePath });
}
if (order == null || order.length() == 0) {
//order not specified, so keep track of the original ACE position.
order = String.valueOf(i);
}
boolean isAllow = isAllow(ace);
Privilege[] privileges = ace.getPrivileges();
if (log.isDebugEnabled()) {
if (isAllow) {
oldGrants.addAll(Arrays.asList(privileges));
} else {
oldDenies.addAll(Arrays.asList(privileges));
}
}
for (Privilege privilege : privileges) {
Set<String> maintainedPrivileges = disaggregateToPrivilegeNames(privilege);
// break the existing privilege down; otherwise, maintain as is.
if (!maintainedPrivileges.removeAll(specifiedPrivilegeNames)) {
// No conflicts, so preserve the original.
maintainedPrivileges.clear();
maintainedPrivileges.add(privilege.getName());
}
if (!maintainedPrivileges.isEmpty()) {
if (isAllow) {
newGrantedPrivilegeNames.addAll(maintainedPrivileges);
} else {
newDeniedPrivilegeNames.addAll(maintainedPrivileges);
}
}
}
// Remove the old ACE.
acl.removeAccessControlEntry(ace);
}
}
//add a fresh ACE with the granted privileges
List<Privilege> grantedPrivilegeList = new ArrayList<Privilege>();
for (String name : newGrantedPrivilegeNames) {
Privilege privilege = accessControlManager.privilegeFromName(name);
grantedPrivilegeList.add(privilege);
}
if (grantedPrivilegeList.size() > 0) {
acl.addAccessControlEntry(principal, grantedPrivilegeList.toArray(new Privilege[grantedPrivilegeList.size()]));
}
//add a fresh ACE with the denied privileges
List<Privilege> deniedPrivilegeList = new ArrayList<Privilege>();
for (String name : newDeniedPrivilegeNames) {
Privilege privilege = accessControlManager.privilegeFromName(name);
deniedPrivilegeList.add(privilege);
}
if (deniedPrivilegeList.size() > 0) {
addEntry(acl, principal, deniedPrivilegeList.toArray(new Privilege[deniedPrivilegeList.size()]), false);
}
//order the ACL
reorderAccessControlEntries(acl, principal, order);
accessControlManager.setPolicy(resourcePath, acl);
if (log.isDebugEnabled()) {
List<String> oldGrantedNames = new ArrayList<String>(oldGrants.size());
for (Privilege privilege : oldGrants) {
oldGrantedNames.add(privilege.getName());
}
List<String> oldDeniedNames = new ArrayList<String>(oldDenies.size());
for (Privilege privilege : oldDenies) {
oldDeniedNames.add(privilege.getName());
}
log.debug("Updated ACE for principalName {} for resource {} from grants {}, denies {} to grants {}, denies {}", new Object[] { principal.getName(), resourcePath, oldGrantedNames, oldDeniedNames, newGrantedPrivilegeNames, newDeniedPrivilegeNames });
}
}
use of javax.jcr.security.AccessControlEntry in project sling by apache.
the class DeleteAcesServlet method deleteAces.
/* (non-Javadoc)
* @see org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces#deleteAces(javax.jcr.Session, java.lang.String, java.lang.String[])
*/
public void deleteAces(Session jcrSession, String resourcePath, String[] principalNamesToDelete) throws RepositoryException {
if (principalNamesToDelete == null) {
throw new RepositoryException("principalIds were not sumitted.");
} else {
if (jcrSession == null) {
throw new RepositoryException("JCR Session not found");
}
if (resourcePath == null) {
throw new ResourceNotFoundException("Resource path was not supplied.");
}
Item item = jcrSession.getItem(resourcePath);
if (item != null) {
resourcePath = item.getPath();
} else {
throw new ResourceNotFoundException("Resource is not a JCR Node");
}
//load the principalIds array into a set for quick lookup below
Set<String> pidSet = new HashSet<String>();
pidSet.addAll(Arrays.asList(principalNamesToDelete));
try {
AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(jcrSession);
AccessControlList updatedAcl = getAccessControlList(accessControlManager, resourcePath, false);
//keep track of the existing Aces for the target principal
AccessControlEntry[] accessControlEntries = updatedAcl.getAccessControlEntries();
List<AccessControlEntry> oldAces = new ArrayList<AccessControlEntry>();
for (AccessControlEntry ace : accessControlEntries) {
if (pidSet.contains(ace.getPrincipal().getName())) {
oldAces.add(ace);
}
}
//remove the old aces
if (!oldAces.isEmpty()) {
for (AccessControlEntry ace : oldAces) {
updatedAcl.removeAccessControlEntry(ace);
}
}
//apply the changed policy
accessControlManager.setPolicy(resourcePath, updatedAcl);
} catch (RepositoryException re) {
throw new RepositoryException("Failed to delete access control.", re);
}
}
}
use of javax.jcr.security.AccessControlEntry in project sling by apache.
the class GetAclServlet method getAccessControlEntries.
@Override
protected AccessControlEntry[] getAccessControlEntries(Session session, String absPath) throws RepositoryException {
AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
List<AccessControlEntry> allEntries = new ArrayList<AccessControlEntry>();
for (AccessControlPolicy accessControlPolicy : policies) {
if (accessControlPolicy instanceof AccessControlList) {
AccessControlEntry[] accessControlEntries = ((AccessControlList) accessControlPolicy).getAccessControlEntries();
for (AccessControlEntry accessControlEntry : accessControlEntries) {
allEntries.add(accessControlEntry);
}
}
}
return allEntries.toArray(new AccessControlEntry[allEntries.size()]);
}
Aggregations