/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jackrabbit.core.security.authorization.acl; import java.security.Principal; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.jcr.AccessDeniedException; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.security.AccessControlManager; import javax.jcr.security.Privilege; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.apache.jackrabbit.core.security.authorization.AbstractEvaluationTest; import org.apache.jackrabbit.test.NotExecutableException; import org.apache.jackrabbit.value.StringValue; /** * <code>ReadTest</code>... */ public class RestrictionTest extends AbstractEvaluationTest { private String path_root; private String path_a; private String path_b; private String path_c; private String path_d; @Override protected void setUp() throws Exception { super.setUp(); // create some nodes below the test root in order to apply ac-stuff Node a = testRootNode.addNode("a", testNodeType); Node b = a.addNode("b", testNodeType); Node c = b.addNode("c", testNodeType); Node d = c.addNode("d", testNodeType); superuser.save(); path_root = testRootNode.getPath(); path_a = a.getPath(); path_b = b.getPath(); path_c = c.getPath(); path_d = d.getPath(); } @Override protected boolean isExecutable() { return EvaluationUtil.isExecutable(acMgr); } @Override protected JackrabbitAccessControlList getPolicy(AccessControlManager acM, String path, Principal principal) throws RepositoryException, AccessDeniedException, NotExecutableException { return EvaluationUtil.getPolicy(acM, path, principal); } @Override protected Map<String, Value> getRestrictions(Session s, String path) { return Collections.emptyMap(); } private void addEntry(String path, boolean grant, String restriction, String... privilegeNames) throws Exception { if (restriction.length() > 0) { Map<String, Value> rs = new HashMap<String, Value>(); rs.put("rep:glob", new StringValue(restriction)); modifyPrivileges(path, testUser.getPrincipal(), AccessControlUtils.privilegesFromNames(acMgr, privilegeNames), grant, rs); } else { modifyPrivileges(path, testUser.getPrincipal(), AccessControlUtils.privilegesFromNames(acMgr, privilegeNames), grant, Collections.<String, Value>emptyMap()); } } /** * Tests if the restriction are active at the proper place */ public void testHasPermissionWithRestrictions() throws Exception { // create permissions // allow rep:write /testroot // deny jcr:removeNode /testroot/a glob=*/c // allow jcr:removeNode /testroot/a glob=*/b // allow jcr:removeNode /testroot/a glob=*/c/* addEntry(path_root, true, "", Privilege.JCR_READ, Privilege.JCR_WRITE); addEntry(path_a, false, "*/c", Privilege.JCR_REMOVE_NODE); addEntry(path_a, true, "*/b", Privilege.JCR_REMOVE_NODE); addEntry(path_a, true, "*/c/*", Privilege.JCR_REMOVE_NODE); Session testSession = getTestSession(); try { AccessControlManager acMgr = getAccessControlManager(testSession); assertFalse("user should not have remove node on /a/b/c", acMgr.hasPrivileges(path_c, AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_REMOVE_NODE))); assertTrue("user should have remove node on /a/b", acMgr.hasPrivileges(path_b, AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_REMOVE_NODE))); assertTrue("user should have remove node on /a/b/c/d", acMgr.hasPrivileges(path_d, AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_REMOVE_NODE))); // should be able to remove /a/b/c/d testSession.getNode(path_d).remove(); testSession.save(); try { testSession.getNode(path_c).remove(); testSession.save(); fail("removing node on /a/b/c should fail"); } catch (RepositoryException e) { // all ok } } finally { testSession.logout(); } } }