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 2012/08/22 14:47:14 UTC
svn commit: r1376023 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/spi/security/user/
test/java/org/apache/jackrabbit/oak/security/
test/java/org/apache/jackrabbit/oak/security/user/
Author: angela
Date: Wed Aug 22 12:47:14 2012
New Revision: 1376023
URL: http://svn.apache.org/viewvc?rev=1376023&view=rev
Log:
OAK-50 : Implement User Management (WIP)
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java?rev=1376023&r1=1376022&r2=1376023&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java Wed Aug 22 12:47:14 2012
@@ -33,7 +33,8 @@ public interface UserConstants {
String REP_MEMBERS = "rep:members";
String REP_IMPERSONATORS = "rep:impersonators";
- String DEFAULT_USER_PATH = "rep:security/rep:authorizables/rep:users";
- String DEFAULT_GROUP_PATH = "rep:security/rep:authorizables/rep:groups";
+ String DEFAULT_USER_PATH = "/rep:security/rep:authorizables/rep:users";
+ String DEFAULT_GROUP_PATH = "/rep:security/rep:authorizables/rep:groups";
+ int DEFAULT_DEPTH = 2;
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java?rev=1376023&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java Wed Aug 22 12:47:14 2012
@@ -0,0 +1,371 @@
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.AbstractOakTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.core.DefaultConflictHandler;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfig;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
+import org.apache.jackrabbit.util.Text;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * UserProviderImplTest...
+ *
+ * TODO: create tests with custom config that persists changes (currently fails since config used in UserValidator is different)
+ * TODO: add tests for setProtectedProperty (might still be refactored...)
+ */
+public class UserProviderImplTest extends AbstractOakTest {
+
+ private ContentSession contentSession;
+ private Root root;
+
+ private UserConfig defaultConfig;
+ private String defaultUserPath;
+ private String defaultGroupPath;
+
+ private Map<String, Object> customOptions;
+ private String customUserPath = "/home/users";
+ private String customGroupPath = "/home/groups";
+
+ private List<String> cleanupPaths = new ArrayList<String>();
+
+ @Before
+ public void setUp() throws Exception {
+ contentSession = createAdminSession();
+ root = contentSession.getCurrentRoot();
+
+ defaultConfig = new UserConfig("admin");
+ defaultUserPath = defaultConfig.getConfigValue(UserConfig.PARAM_USER_PATH, UserConstants.DEFAULT_USER_PATH);
+ defaultGroupPath = defaultConfig.getConfigValue(UserConfig.PARAM_GROUP_PATH, UserConstants.DEFAULT_GROUP_PATH);
+
+ customOptions = new HashMap<String, Object>();
+ customOptions.put(UserConfig.PARAM_GROUP_PATH, customGroupPath);
+ customOptions.put(UserConfig.PARAM_USER_PATH, customUserPath);
+
+ cleanupPaths.add(defaultUserPath);
+ cleanupPaths.add(defaultGroupPath);
+ cleanupPaths.add(customUserPath);
+ cleanupPaths.add(customGroupPath);
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ for (String path : cleanupPaths) {
+ Tree t = root.getTree(path);
+ if (t != null) {
+ t.remove();
+ }
+ }
+ }
+
+ @Override
+ protected ContentRepository createRepository() {
+ return createEmptyRepository();
+ }
+
+ private UserProvider createUserProvider() {
+ return new UserProviderImpl(contentSession, root, defaultConfig);
+ }
+
+ private UserProvider createUserProvider(int defaultDepth) {
+ Map<String, Object> options = new HashMap<String, Object>(customOptions);
+ options.put(UserConfig.PARAM_DEFAULT_DEPTH, defaultDepth);
+ return new UserProviderImpl(contentSession, root, new UserConfig("admin", options, Collections.<AuthorizableAction>emptySet()));
+ }
+
+ @Test
+ public void testCreateUser() throws Exception {
+ UserProvider up = createUserProvider();
+
+ // create test user
+ Tree userTree = up.createUser("user1", null);
+
+ assertNotNull(userTree);
+ assertTrue(Text.isDescendant(defaultUserPath, userTree.getPath()));
+ int level = defaultConfig.getConfigValue(UserConfig.PARAM_DEFAULT_DEPTH, UserConstants.DEFAULT_DEPTH) + 1;
+ assertEquals(defaultUserPath, Text.getRelativeParent(userTree.getPath(), level));
+
+ // make sure all users are created in a structure with default depth
+ userTree = up.createUser("b", null);
+ assertEquals(defaultUserPath + "/b/bb/b", userTree.getPath());
+
+ Map<String, String> m = new HashMap<String,String>();
+ m.put("bb", "/b/bb/bb");
+ m.put("bbb", "/b/bb/bbb");
+ m.put("bbbb", "/b/bb/bbbb");
+ m.put("bh", "/b/bh/bh");
+ m.put("bHbh", "/b/bH/bHbh");
+ m.put("b_Hb", "/b/b_/b_Hb");
+ m.put("basim", "/b/ba/basim");
+
+ for (String uid : m.keySet()) {
+ userTree = up.createUser(uid, null);
+ assertEquals(defaultUserPath + m.get(uid), userTree.getPath());
+ }
+ }
+
+ @Test
+ public void testCreateUserWithPath() throws Exception {
+ UserProvider up = createUserProvider(1);
+
+ // create test user
+ Tree userTree = up.createUser("nadine", "a/b/c");
+ assertNotNull(userTree);
+ assertTrue(Text.isDescendant(customUserPath, userTree.getPath()));
+ String userPath = customUserPath + "/a/b/c/nadine";
+ assertEquals(userPath, userTree.getPath());
+ }
+
+ @Test
+ public void testCreateGroup() throws RepositoryException {
+ UserProvider up = createUserProvider();
+
+ Tree groupTree = up.createGroup("group1", null);
+
+ assertNotNull(groupTree);
+ assertTrue(Text.isDescendant(defaultGroupPath, groupTree.getPath()));
+
+ int level = defaultConfig.getConfigValue(UserConfig.PARAM_DEFAULT_DEPTH, UserConstants.DEFAULT_DEPTH) + 1;
+ assertEquals(defaultGroupPath, Text.getRelativeParent(groupTree.getPath(), level));
+ }
+
+ @Test
+ public void testCreateGroupWithPath() throws Exception {
+ UserProvider up = createUserProvider(4);
+
+ // create test user
+ Tree group = up.createGroup("authors", "a/b/c");
+ assertNotNull(group);
+ assertTrue(Text.isDescendant(customGroupPath, group.getPath()));
+ String groupPath = customGroupPath + "/a/b/c/authors";
+ assertEquals(groupPath, group.getPath());
+ }
+
+ @Test
+ public void testCreateWithCustomDepth() throws Exception {
+ UserProvider userProvider = createUserProvider(3);
+
+ Tree userTree = userProvider.createUser("b", null);
+ assertEquals(customUserPath + "/b/bb/bbb/b", userTree.getPath());
+
+ Map<String, String> m = new HashMap<String,String>();
+ m.put("bb", "/b/bb/bbb/bb");
+ m.put("bbb", "/b/bb/bbb/bbb");
+ m.put("bbbb", "/b/bb/bbb/bbbb");
+ m.put("bL", "/b/bL/bLL/bL");
+ m.put("bLbh", "/b/bL/bLb/bLbh");
+ m.put("b_Lb", "/b/b_/b_L/b_Lb");
+ m.put("basiL", "/b/ba/bas/basiL");
+
+ for (String uid : m.keySet()) {
+ userTree = userProvider.createUser(uid, null);
+ assertEquals(customUserPath + m.get(uid), userTree.getPath());
+ }
+ }
+
+ @Ignore("OAK-270: UUID collisions are not yet detected upon commit.")
+ @Test
+ public void testCreateWithCollision() throws Exception {
+ UserProvider userProvider = createUserProvider();
+
+ Tree userTree = userProvider.createUser("AmaLia", null);
+
+ Map<String, String> colliding = new HashMap<String, String>();
+ colliding.put("AmaLia", null);
+ colliding.put("AmaLia", "s/ome/path");
+ colliding.put("amalia", null);
+ colliding.put("Amalia", "a/b/c");
+
+ for (String uid : colliding.keySet()) {
+ try {
+ Tree c = userProvider.createUser(uid, colliding.get(uid));
+ root.commit(DefaultConflictHandler.OURS);
+ fail("userID collision must be detected");
+ } catch (CommitFailedException e) {
+ // success
+ }
+ }
+
+ for (String uid : colliding.keySet()) {
+ try {
+ Tree c = userProvider.createGroup(uid, colliding.get(uid));
+ root.commit(DefaultConflictHandler.OURS);
+ fail("userID collision must be detected");
+ } catch (CommitFailedException e) {
+ // success
+ }
+ }
+ }
+
+ @Test
+ public void testIllegalChars() throws Exception {
+ UserProvider userProvider = createUserProvider();
+
+ Map<String, String> m = new HashMap<String, String>();
+ m.put("z[x]", "/z/" + Text.escapeIllegalJcrChars("z[") + '/' + Text.escapeIllegalJcrChars("z[x]"));
+ m.put("z*x", "/z/" + Text.escapeIllegalJcrChars("z*") + '/' + Text.escapeIllegalJcrChars("z*x"));
+ m.put("z/x", "/z/" + Text.escapeIllegalJcrChars("z/") + '/' + Text.escapeIllegalJcrChars("z/x"));
+ m.put("%\r|", '/' +Text.escapeIllegalJcrChars("%")+ '/' + Text.escapeIllegalJcrChars("%\r") + '/' + Text.escapeIllegalJcrChars("%\r|"));
+
+ for (String uid : m.keySet()) {
+ Tree user = userProvider.createUser(uid, null);
+ root.commit(DefaultConflictHandler.OURS);
+
+ assertEquals(defaultUserPath + m.get(uid), user.getPath());
+ assertEquals(uid, userProvider.getAuthorizableId(user));
+
+ Tree ath = userProvider.getAuthorizable(uid);
+ assertNotNull("Tree with id " + uid + " must exist.", ath);
+ }
+ }
+
+ @Test
+ public void testGetAuthorizable() throws Exception {
+ UserProvider up = createUserProvider();
+
+ String userID = "hannah";
+ String groupID = "cLevel";
+
+ Tree user = up.createUser(userID, null);
+ Tree group = up.createGroup(groupID, null);
+ root.commit(DefaultConflictHandler.OURS);
+
+ Tree a = up.getAuthorizable(userID);
+ assertNotNull(a);
+ assertEquals(user.getPath(), a.getPath());
+
+ a = up.getAuthorizable(groupID);
+ assertNotNull(a);
+ assertEquals(group.getPath(), a.getPath());
+ }
+
+ @Test
+ public void testGetAuthorizableWithType() throws Exception {
+ UserProvider up = createUserProvider();
+
+ String userID = "thabit";
+ Tree user = up.createUser(userID, null);
+ root.commit(DefaultConflictHandler.OURS);
+
+ Tree a = up.getAuthorizable(userID, UserManager.SEARCH_TYPE_USER);
+ assertNotNull(a);
+ assertEquals(user.getPath(), a.getPath());
+
+ assertNotNull(up.getAuthorizable(userID, UserManager.SEARCH_TYPE_AUTHORIZABLE));
+ assertNull(up.getAuthorizable(userID, UserManager.SEARCH_TYPE_GROUP));
+
+ String groupID = "hr";
+ Tree group = up.createGroup(groupID, null);
+ root.commit(DefaultConflictHandler.OURS);
+
+ Tree g = up.getAuthorizable(groupID, UserManager.SEARCH_TYPE_GROUP);
+ assertNotNull(a);
+ assertEquals(user.getPath(), a.getPath());
+
+ assertNotNull(up.getAuthorizable(groupID, UserManager.SEARCH_TYPE_AUTHORIZABLE));
+ assertNull(up.getAuthorizable(groupID, UserManager.SEARCH_TYPE_USER));
+ }
+
+ @Test
+ public void testGetAuthorizableByPath() throws Exception {
+ UserProvider up = createUserProvider();
+
+ Tree user = up.createUser("shams", null);
+ Tree a = up.getAuthorizableByPath(user.getPath());
+ assertNotNull(a);
+ assertEquals(user, a);
+
+ Tree group = up.createGroup("devs", null);
+ a = up.getAuthorizableByPath(group.getPath());
+ assertNotNull(a);
+ assertEquals(group, a);
+ }
+
+ @Test
+ public void testIsAdminUser() throws Exception {
+ UserProvider userProvider = createUserProvider();
+
+ Tree adminTree = userProvider.createUser(defaultConfig.getAdminId(), null);
+ userProvider.isAdminUser(adminTree);
+
+ List<Tree> others = new ArrayList<Tree>();
+ others.add(userProvider.createUser("laura", null));
+ others.add(userProvider.createGroup("administrators", null));
+
+ for (Tree other : others) {
+ assertFalse(userProvider.isAdminUser(other));
+ }
+ }
+
+ @Test
+ public void testGetAuthorizableId() throws Exception {
+ UserProvider up = createUserProvider();
+
+ String userID = "Amanda";
+ Tree user = up.createUser(userID, null);
+ assertEquals(userID, up.getAuthorizableId(user));
+
+ String groupID = "visitors";
+ Tree group = up.createGroup(groupID, null);
+ assertEquals(groupID, up.getAuthorizableId(group));
+ }
+
+ @Test
+ public void testRemoveParentTree() throws Exception {
+ UserProvider up = createUserProvider();
+ Tree u1 = up.createUser("b", "b");
+ Tree u2 = up.createUser("bb", "bb");
+
+ Tree folder = root.getTree(Text.getRelativeParent(u1.getPath(), 2));
+ folder.remove();
+ if (up.getAuthorizable("b") != null) {
+ fail("Removing the top authorizable folder must remove all users contained.");
+ u1.remove();
+ }
+ if (up.getAuthorizable("bb") != null) {
+ fail("Removing the top authorizable folder must remove all users contained.");
+ u2.remove();
+ }
+ }
+}