Search in sources :

Example 66 with AccessControlEntry

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();
    }
}
Also used : AccessControlList(javax.jcr.security.AccessControlList) AccessDeniedException(javax.jcr.AccessDeniedException) Version(javax.jcr.version.Version) Node(javax.jcr.Node) AccessControlEntry(javax.jcr.security.AccessControlEntry) Test(org.junit.Test)

Example 67 with AccessControlEntry

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");
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) AccessControlEntry(javax.jcr.security.AccessControlEntry) JackrabbitAccessControlList(org.apache.jackrabbit.api.security.JackrabbitAccessControlList) Principal(java.security.Principal)

Example 68 with AccessControlEntry

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 });
    }
}
Also used : AccessControlManager(javax.jcr.security.AccessControlManager) JackrabbitAccessControlList(org.apache.jackrabbit.api.security.JackrabbitAccessControlList) AccessControlList(javax.jcr.security.AccessControlList) AccessControlPolicy(javax.jcr.security.AccessControlPolicy) ArrayList(java.util.ArrayList) AccessControlEntry(javax.jcr.security.AccessControlEntry) AccessControlPolicyIterator(javax.jcr.security.AccessControlPolicyIterator) RepositoryException(javax.jcr.RepositoryException) Privilege(javax.jcr.security.Privilege) HashSet(java.util.HashSet)

Example 69 with AccessControlEntry

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);
        }
    }
}
Also used : AccessControlManager(javax.jcr.security.AccessControlManager) AccessControlList(javax.jcr.security.AccessControlList) Item(javax.jcr.Item) ArrayList(java.util.ArrayList) AccessControlEntry(javax.jcr.security.AccessControlEntry) RepositoryException(javax.jcr.RepositoryException) ResourceNotFoundException(org.apache.sling.api.resource.ResourceNotFoundException) HashSet(java.util.HashSet)

Example 70 with AccessControlEntry

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()]);
}
Also used : AccessControlManager(javax.jcr.security.AccessControlManager) AccessControlList(javax.jcr.security.AccessControlList) AccessControlPolicy(javax.jcr.security.AccessControlPolicy) ArrayList(java.util.ArrayList) AccessControlEntry(javax.jcr.security.AccessControlEntry)

Aggregations

AccessControlEntry (javax.jcr.security.AccessControlEntry)126 JackrabbitAccessControlEntry (org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry)50 JackrabbitAccessControlList (org.apache.jackrabbit.api.security.JackrabbitAccessControlList)50 Privilege (javax.jcr.security.Privilege)47 AccessControlManager (javax.jcr.security.AccessControlManager)39 AccessControlPolicy (javax.jcr.security.AccessControlPolicy)39 AccessControlList (javax.jcr.security.AccessControlList)38 Test (org.junit.Test)29 Principal (java.security.Principal)28 NodeImpl (org.apache.jackrabbit.core.NodeImpl)13 ArrayList (java.util.ArrayList)12 Node (javax.jcr.Node)12 Value (javax.jcr.Value)10 JackrabbitAccessControlManager (org.apache.jackrabbit.api.security.JackrabbitAccessControlManager)9 NotExecutableException (org.apache.jackrabbit.test.NotExecutableException)9 ByteArrayInputStream (java.io.ByteArrayInputStream)8 InputStream (java.io.InputStream)8 RepositoryException (javax.jcr.RepositoryException)8 Authorizable (org.apache.jackrabbit.api.security.user.Authorizable)8 ParsingContentHandler (org.apache.jackrabbit.commons.xml.ParsingContentHandler)8