You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2017/03/30 16:30:08 UTC
svn commit: r1789537 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImpl.java
test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java
Author: angela
Date: Thu Mar 30 16:30:07 2017
New Revision: 1789537
URL: http://svn.apache.org/viewvc?rev=1789537&view=rev
Log:
OAK-6013 : Add annotations to AuthorizablePropertiesImpl
OAK-6014 : AuthorizablePropertiesImpl.removeProperty if non-existing property outside of scope
OAK-5882 : Improve coverage for oak.security code in oak-core (wip)
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImpl.java?rev=1789537&r1=1789536&r2=1789537&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImpl.java Thu Mar 30 16:30:07 2017
@@ -29,6 +29,7 @@ import javax.jcr.Value;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.PropertyDefinition;
+import com.google.common.collect.Iterators;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
@@ -80,7 +81,7 @@ class AuthorizablePropertiesImpl impleme
}
return l.iterator();
} else {
- throw new RepositoryException("Relative path " + relPath + " refers to items outside of scope of authorizable.");
+ throw new RepositoryException("Relative path " + relPath + " refers to non-existing tree or tree outside of scope of authorizable.");
}
}
@@ -137,7 +138,7 @@ class AuthorizablePropertiesImpl impleme
* @see org.apache.jackrabbit.api.security.user.Authorizable#setProperty(String, javax.jcr.Value[])
*/
@Override
- public void setProperty(@Nonnull String relPath, Value[] values) throws RepositoryException {
+ public void setProperty(@Nonnull String relPath, @Nullable Value[] values) throws RepositoryException {
if (values == null) {
removeProperty(relPath);
} else {
@@ -168,6 +169,8 @@ class AuthorizablePropertiesImpl impleme
} else {
throw new ConstraintViolationException("Property " + relPath + " isn't a modifiable authorizable property");
}
+ } else {
+ checkScope(node.getPath(), propertyLocation.getPath(), relPath);
}
// no such property or wasn't a property of this authorizable.
return false;
@@ -194,7 +197,7 @@ class AuthorizablePropertiesImpl impleme
* {@code false} otherwise.
* @throws RepositoryException If an error occurs.
*/
- private boolean isAuthorizableProperty(Tree authorizableTree, TreeLocation propertyLocation, boolean verifyAncestor) throws RepositoryException {
+ private boolean isAuthorizableProperty(@Nonnull Tree authorizableTree, @Nonnull TreeLocation propertyLocation, boolean verifyAncestor) throws RepositoryException {
return getAuthorizableProperty(authorizableTree, propertyLocation, verifyAncestor) != null;
}
@@ -215,10 +218,7 @@ class AuthorizablePropertiesImpl impleme
* @throws RepositoryException If an error occurs.
*/
@CheckForNull
- private PropertyState getAuthorizableProperty(Tree authorizableTree, TreeLocation propertyLocation, boolean verifyAncestor) throws RepositoryException {
- if (propertyLocation == null) {
- return null;
- }
+ private PropertyState getAuthorizableProperty(@Nonnull Tree authorizableTree, @Nonnull TreeLocation propertyLocation, boolean verifyAncestor) throws RepositoryException {
PropertyState property = propertyLocation.getProperty();
if (property == null) {
return null;
@@ -245,7 +245,7 @@ class AuthorizablePropertiesImpl impleme
return property;
}
- private void checkProtectedProperty(Tree parent, PropertyState property) throws RepositoryException {
+ private void checkProtectedProperty(@Nonnull Tree parent, @Nonnull PropertyState property) throws RepositoryException {
ReadOnlyNodeTypeManager nodeTypeManager = authorizable.getUserManager().getNodeTypeManager();
PropertyDefinition def = nodeTypeManager.getDefinition(parent, property, false);
if (def.isProtected()) {
@@ -272,14 +272,10 @@ class AuthorizablePropertiesImpl impleme
String userPath = userTree.getPath();
targetTree = getLocation(userTree, relPath).getTree();
if (targetTree != null) {
- if (!Text.isDescendantOrEqual(userPath, targetTree.getPath())) {
- throw new RepositoryException("Relative path " + relPath + " outside of scope of " + this);
- }
+ checkScope(userPath, targetTree.getPath(), relPath);
} else {
targetTree = new NodeUtil(userTree).getOrAddTree(relPath, JcrConstants.NT_UNSTRUCTURED).getTree();
- if (!Text.isDescendantOrEqual(userPath, targetTree.getPath())) {
- throw new RepositoryException("Relative path " + relPath + " outside of scope of " + this);
- }
+ checkScope(userPath, targetTree.getPath(), relPath);
}
} else {
targetTree = userTree;
@@ -311,4 +307,10 @@ class AuthorizablePropertiesImpl impleme
}
return oakPath;
}
+
+ private static void checkScope(@Nonnull String userPath, @Nonnull String targetPath, @Nonnull String relPath) throws RepositoryException {
+ if (!Text.isDescendantOrEqual(userPath, targetPath)) {
+ throw new RepositoryException("Relative path " + relPath + " outside of scope of " + userPath);
+ }
+ }
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java?rev=1789537&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java Thu Mar 30 16:30:07 2017
@@ -0,0 +1,310 @@
+/*
+ * 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.oak.security.user;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
+import javax.annotation.Nonnull;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.nodetype.ConstraintViolationException;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class AuthorizablePropertiesImplTest extends AbstractSecurityTest {
+
+ private AuthorizablePropertiesImpl emptyProperties;
+
+ private Authorizable user2;
+ private AuthorizablePropertiesImpl properties;
+
+ private ValueFactory vf;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ User user = getTestUser();
+ emptyProperties = new AuthorizablePropertiesImpl((AuthorizableImpl) user, getNamePathMapper());
+
+ String id2 = "user2" + UUID.randomUUID().toString();
+ user2 = getUserManager(root).createUser(id2, null, new PrincipalImpl(id2), PathUtils.getAncestorPath(user.getPath(), 1));
+
+ vf = getValueFactory(root);
+ Value v = vf.createValue("value");
+ Value[] vArr = new Value[] {vf.createValue(2), vf.createValue(30)};
+
+ user2.setProperty("prop", v);
+ user2.setProperty("mvProp", vArr);
+
+ user2.setProperty("relPath/prop", v);
+ user2.setProperty("relPath/mvProp", vArr);
+ root.commit();
+
+ properties = new AuthorizablePropertiesImpl((AuthorizableImpl) user2, getNamePathMapper());
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ root.refresh();
+ user2.remove();
+ root.commit();
+ } finally {
+ super.after();
+ }
+ }
+
+ //-----------------------------------------------------------< getNames >---
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesNullPath() throws Exception {
+ emptyProperties.getNames("");
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesEmptyPath() throws Exception {
+ emptyProperties.getNames("");
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesAbsPath() throws Exception {
+ emptyProperties.getNames("/");
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesOutSideScope() throws Exception {
+ emptyProperties.getNames("../..");
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesOtherUser() throws Exception {
+ emptyProperties.getNames("../" + PathUtils.getName(user2.getPath()));
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesMissingResolutionToOakPath() throws Exception {
+ AuthorizableProperties props = new AuthorizablePropertiesImpl((AuthorizableImpl) user2, new NamePathMapper.Default() {
+ @Override
+ public String getOakNameOrNull(@Nonnull String jcrName) {
+ return null;
+ }
+
+ @Override
+ public String getOakPath(String jcrPath) {
+ return null;
+ }
+ });
+ props.getNames("relPath");
+ }
+
+ @Test
+ public void testGetNamesCurrent() throws Exception {
+ assertFalse(emptyProperties.getNames(".").hasNext());
+ }
+
+ @Test
+ public void testGetNamesCurrent2() throws Exception {
+ Iterator<String> names = properties.getNames(".");
+
+ Set<String> expected = ImmutableSet.of("prop", "mvProp");
+ assertEquals(expected, ImmutableSet.copyOf(names));
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testGetNamesNonExistingRelPath() throws Exception {
+ properties.getNames("nonExisting");
+ }
+
+ @Test
+ public void testGetNamesRelPath() throws Exception {
+ Iterator<String> names = properties.getNames("relPath");
+
+ Set<String> expected = ImmutableSet.of("prop", "mvProp");
+ assertEquals(expected, ImmutableSet.copyOf(names));
+ }
+
+
+ //--------------------------------------------------------< setProperty >---
+
+ @Test(expected = ConstraintViolationException.class)
+ public void testSetAuthorizableId() throws Exception {
+ properties.setProperty(UserConstants.REP_AUTHORIZABLE_ID, vf.createValue("otherId"));
+ }
+
+ @Test(expected = ConstraintViolationException.class)
+ public void testSetPrimaryType() throws Exception {
+ properties.setProperty("relPath/" + JcrConstants.JCR_PRIMARYTYPE, vf.createValue(NodeTypeConstants.NT_OAK_UNSTRUCTURED, PropertyType.NAME));
+ }
+
+ @Test
+ public void testSetNewProperty() throws Exception {
+ properties.setProperty("prop2", vf.createValue(true));
+ assertTrue(properties.hasProperty("prop2"));
+ }
+
+ @Test
+ public void testSetNewPropertyWithRelPath() throws Exception {
+ properties.setProperty("relPath/prop2", vf.createValue("val"));
+ assertTrue(properties.hasProperty("relPath/prop2"));
+ }
+
+ @Test
+ public void testSetNewPropertyNewRelPath() throws Exception {
+ properties.setProperty("newPath/prop2", vf.createValue("val"));
+ assertTrue(properties.hasProperty("newPath/prop2"));
+ }
+
+ @Test
+ public void testSetModifyProperty() throws Exception {
+ Value v = vf.createValue("newValue");
+ properties.setProperty("prop", v);
+ assertArrayEquals(new Value[] {v}, properties.getProperty("prop"));
+ }
+
+ @Test
+ public void testSetPropertyChangeMvStatus() throws Exception {
+ Value v = vf.createValue("newValue");
+ properties.setProperty("mvProp", v);
+ assertArrayEquals(new Value[]{v}, properties.getProperty("mvProp"));
+ }
+
+ @Test
+ public void testSetPropertyChangeMvStatus2() throws Exception {
+ Value v = vf.createValue("newValue");
+ properties.setProperty("relPath/prop", new Value[] {v, v});
+ assertArrayEquals(new Value[]{v, v}, properties.getProperty("relPath/prop"));
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testSetMissingResolutionToOakPath() throws Exception {
+ AuthorizableProperties props = new AuthorizablePropertiesImpl((AuthorizableImpl) user2, new NamePathMapper.Default() {
+ @Override
+ public String getOakNameOrNull(@Nonnull String jcrName) {
+ return null;
+ }
+
+ @Override
+ public String getOakPath(String jcrPath) {
+ return null;
+ }
+ });
+ props.setProperty("relPath/prop", vf.createValue("value"));
+ }
+
+ @Test
+ public void testSetPropertyNullArray() throws Exception {
+ properties.setProperty("mvProp", (Value[]) null);
+ assertFalse(properties.hasProperty("mvProp"));
+
+ properties.setProperty("relPath/prop", (Value[]) null);
+ assertFalse(properties.hasProperty("relPath/prop"));
+ }
+
+ @Test
+ public void testSetPropertyNull() throws Exception {
+ properties.setProperty("mvProp", (Value) null);
+ assertFalse(properties.hasProperty("mvProp"));
+
+ properties.setProperty("relPath/prop", (Value) null);
+ assertFalse(properties.hasProperty("relPath/prop"));
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testSetOutSideScope() throws Exception {
+ properties.setProperty("../../prop", vf.createValue("newValue"));
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testSetPropertyOtherUser() throws Exception {
+ emptyProperties.setProperty("../" + PathUtils.getName(user2.getPath()) + "/prop", vf.createValue("newValue"));
+ }
+
+ //-----------------------------------------------------< removeProperty >---
+
+ @Test(expected = ConstraintViolationException.class)
+ public void testRemoveAuthorizableId() throws Exception {
+ properties.removeProperty(UserConstants.REP_AUTHORIZABLE_ID);
+ }
+
+ @Test(expected = ConstraintViolationException.class)
+ public void testRemovePrimaryType() throws Exception {
+ properties.removeProperty("relPath/" + JcrConstants.JCR_PRIMARYTYPE);
+ }
+
+ @Test
+ public void testRemoveNonExisting() throws Exception {
+ assertFalse(properties.removeProperty("nonExisting"));
+ assertFalse(properties.removeProperty("relPath/nonExisting"));
+ assertFalse(emptyProperties.removeProperty("prop"));
+ }
+
+ @Test
+ public void testRemove() throws Exception {
+ assertTrue(properties.removeProperty("mvProp"));
+ assertTrue(properties.removeProperty("relPath/prop"));
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testRemoveMissingResolutionToOakPath() throws Exception {
+ AuthorizableProperties props = new AuthorizablePropertiesImpl((AuthorizableImpl) user2, new NamePathMapper.Default() {
+ @Override
+ public String getOakNameOrNull(@Nonnull String jcrName) {
+ return null;
+ }
+
+ @Override
+ public String getOakPath(String jcrPath) {
+ return null;
+ }
+ });
+ props.removeProperty("relPath/prop");
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testRemovePropertyOutSideScope() throws Exception {
+ properties.removeProperty("../../" + JcrConstants.JCR_PRIMARYTYPE);
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testRemoveNonExistingPropertyOutSideScope() throws Exception {
+ properties.removeProperty("../../nonExistingTree/nonExistingProp");
+ }
+
+ @Test(expected = RepositoryException.class)
+ public void testRemovePropertyOtherUser() throws Exception {
+ emptyProperties.removeProperty("../" + PathUtils.getName(user2.getPath()) + "/prop");
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/AuthorizablePropertiesImplTest.java
------------------------------------------------------------------------------
svn:eol-style = native