You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2008/03/19 14:57:11 UTC

svn commit: r638834 [14/14] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/principal/ jack...

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,347 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.api.security.user.AbstractUserTest;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.Impersonation;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Iterator;
+
+/**
+ * <code>GroupAdministratorTest</code>...
+ */
+public class GroupAdministratorTest extends AbstractUserTest {
+
+    private static Logger log = LoggerFactory.getLogger(GroupAdministratorTest.class);
+
+    // group-admin
+    private String uID;
+    private String uPath;
+    private Session uSession;
+
+    private String parentUID;
+    private String childUID;
+
+    private String groupID;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // create a first user
+        Principal p = getTestPrincipal();
+        UserImpl pUser = (UserImpl) userMgr.createUser(p.getName(), buildCredentials(p), p);
+        parentUID = pUser.getID();
+
+        // create a second user 'below' the first user and make it group-admin
+        p = getTestPrincipal();
+        Credentials creds = buildCredentials(p);
+        User u = userMgr.createUser(p.getName(), creds, p, pUser.getNode().getPath());
+        uID = u.getID();
+        uPath = ((UserImpl) u).getNode().getPath();
+
+        // create a third child user below
+        p = getTestPrincipal();
+        childUID = userMgr.createUser(p.getName(), buildCredentials(p), p, uPath).getID();
+
+        // make other user a user-administrator:
+        Authorizable ua = userMgr.getAuthorizable(UserConstants.GROUP_ADMIN_GROUP_NAME);
+        if (ua == null || !ua.isGroup()) {
+            throw new NotExecutableException("Cannot execute test. Group-Admin name has been changed by config.");
+        }
+        Group grAdministrators = (Group) ua;
+        grAdministrators.addMember(u);
+        groupID = grAdministrators.getID();
+
+        // create a session for the other user.
+        uSession = helper.getRepository().login(creds);
+    }
+
+    protected void tearDown() throws Exception {
+        try {
+            if (uSession != null) {
+                uSession.logout();
+            }
+        } finally {
+            // remove group member ship
+            Group grAdministrators = (Group) userMgr.getAuthorizable(UserConstants.GROUP_ADMIN_GROUP_NAME);
+            grAdministrators.removeMember(userMgr.getAuthorizable(uID));
+
+            // remove all users that have been created
+            Authorizable a = userMgr.getAuthorizable(parentUID);
+            if (a != null) {
+                a.remove();
+            }
+
+        }
+        super.tearDown();
+    }
+
+    public void testIsGroupAdmin() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+        Group gr = (Group) umgr.getAuthorizable(groupID);
+
+        assertTrue(gr.isMember(umgr.getAuthorizable(uID)));
+    }
+
+    public void testCreateUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+        UserImpl u = null;
+        // create a new user -> must succeed and user must be create below 'other'
+        try {
+            Principal p = getTestPrincipal();
+            u = (UserImpl) umgr.createUser(p.getName(), buildCredentials(p), p);
+            fail("Group administrator should not be allowed to create a new user.");
+            u.remove();
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    public void testRemoveSelf() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+
+        Authorizable himself = umgr.getAuthorizable(uID);
+        try {
+            himself.remove();
+            fail("A GroupAdministrator should not be allowed to remove the own authorizable.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    public void testCreateGroup() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+        Group testGroup = null;
+        try {
+            testGroup = umgr.createGroup(getTestPrincipal());
+            assertTrue(Text.isDescendant(UserConstants.GROUPS_PATH, ((GroupImpl)testGroup).getNode().getPath()));
+        } finally {
+            if (testGroup != null) {
+                testGroup.remove();
+            }
+        }
+    }
+
+    public void testCreateGroupWithIntermediatePath() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+        Group testGroup = null;
+        try {
+            testGroup = umgr.createGroup(getTestPrincipal(), "/any/intermediate/path");
+            assertTrue(Text.isDescendant(UserConstants.GROUPS_PATH + "/any/intermediate/path", ((GroupImpl)testGroup).getNode().getPath()));
+        } finally {
+            if (testGroup != null) {
+                testGroup.remove();
+            }
+        }
+    }
+
+    public void testAddChildToGroup() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+        Authorizable cU = umgr.getAuthorizable(childUID);
+        Group gr = (Group) umgr.getAuthorizable(groupID);
+
+        // adding and removing a child user from a group the group-admin
+        // is member of must succeed.
+        assertTrue(gr.addMember(cU));
+        assertTrue(gr.removeMember(cU));
+    }
+
+    public void testAddMemberToForeignGroup() throws RepositoryException, NotExecutableException {
+        try {
+            // let superuser create child user below the user with uID.
+            UserManager umgr = getUserManager(uSession);
+            Authorizable cU = umgr.getAuthorizable(childUID);
+            Group uadminGr = (Group) umgr.getAuthorizable(UserConstants.USER_ADMIN_GROUP_NAME);
+            if (uadminGr.isMember(cU)) {
+                throw new RepositoryException("Test user is already member -> cannot execute.");
+            }
+
+            // adding to and removing a child user from a group the group-admin
+            // is NOT member of must fail.
+            uadminGr.addMember(cU);
+            fail("A GroupAdmin should not be allowed to add a user to a group she/he is not member of.");
+
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+    }
+
+    public void testAddParentToGroup() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+
+        Authorizable pU = umgr.getAuthorizable(parentUID);
+        Group gr = (Group) umgr.getAuthorizable(groupID);
+
+        // adding and removing the 'parent' user to/from a group the group-admin
+        // is member of must succeed.
+        assertTrue(gr.addMember(pU));
+        assertTrue(gr.removeMember(pU));
+    }
+
+    public void testAddOwnAuthorizableAsGroupAdmin() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+
+        Authorizable user = umgr.getAuthorizable(uID);
+        Group gr = (Group) umgr.getAuthorizable(groupID);
+
+        // user is already group-admin -> adding must return false.
+        // but should not throw exception.
+        assertFalse(gr.addMember(user));
+    }
+
+    public void testRemoveMembershipForOwnAuthorizable() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+
+        Authorizable user = umgr.getAuthorizable(uID);
+        Group gr = (Group) umgr.getAuthorizable(groupID);
+
+        // removing himself from group. should succeed.
+        assertTrue(gr.removeMember(user));
+    }
+
+    public void testAddOwnAuthorizableToForeignGroup() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+
+        Authorizable user = umgr.getAuthorizable(uID);
+        Group uadminGr = (Group) umgr.getAuthorizable(UserConstants.USER_ADMIN_GROUP_NAME);
+        if (uadminGr.isMember(user)) {
+            throw new RepositoryException("Test user is already member -> cannot execute.");
+        }
+
+        try {
+            String msg = "GroupAdmin cannot add its own authorizable to a group she/he is not yet member of.";
+            assertFalse(msg, uadminGr.addMember(user));
+
+            // didn't throw -> clean up.
+            uadminGr.removeMember(user);
+        } catch (AccessDeniedException e) {
+            // fine as well
+        }
+    }
+
+    public void testRemoveMembersOfForeignGroup() throws RepositoryException, NotExecutableException {
+        Group nGr = null;
+        User nUs = null;
+        User nUs2 = null;
+
+        try {
+            // let superuser create a group and a user a make user member of group
+            nGr = userMgr.createGroup(getTestPrincipal());
+            Principal p = getTestPrincipal();
+            nUs = userMgr.createUser(p.getName(), buildCredentials(p), p);
+            p = getTestPrincipal();
+            nUs2 = userMgr.createUser(p.getName(), buildCredentials(p), p);
+            nGr.addMember(nUs);
+            nGr.addMember(nUs2);
+
+            Group gr = (Group) getUserManager(uSession).getAuthorizable(nGr.getID());
+
+            // removing any member must fail since uSession is not member of that group.
+            Iterator it = gr.getMembers();
+            if (it.hasNext()) {
+                Authorizable auth = (Authorizable) it.next();
+
+                String msg = "GroupAdmin cannot remove members of a group itself is not member of.";
+                assertFalse(msg, gr.removeMember(auth));
+            } else {
+                throw new RepositoryException("Must contain members....");
+            }
+
+        } catch (AccessDeniedException e) {
+            // fine as well.
+        } finally {
+            // let superuser remove authorizables again
+            if (nGr != null) {
+                nGr.removeMember(nUs);
+                nGr.removeMember(nUs2);
+                nGr.remove();
+            }
+            if (nUs != null) nUs.remove();
+            if (nUs2 != null) nUs2.remove();
+        }
+    }
+
+    public void testRemoveAllMembersOfForeignGroup() throws RepositoryException, NotExecutableException {
+        Group nGr = null;
+        User nUs = null;
+
+        try {
+            // let superuser create a group and a user a make user member of group
+            nGr = userMgr.createGroup(getTestPrincipal());
+            Principal p = getTestPrincipal();
+            nUs = userMgr.createUser(p.getName(), buildCredentials(p), p);
+            nGr.addMember(nUs);
+
+            Group gr = (Group) getUserManager(uSession).getAuthorizable(nGr.getID());
+
+            // since only 1 single member -> removal rather than modification.
+            // since uSession is not member this must fail.
+            for (Iterator it = gr.getMembers(); it.hasNext();) {
+                Authorizable auth = (Authorizable) it.next();
+
+                String msg = "GroupAdmin cannot remove members of a group itself is not member of.";
+                assertFalse(gr.removeMember(auth));
+            }
+        } catch (AccessDeniedException e) {
+            // fine as well.
+        } finally {
+            // let superuser remove authorizables again
+            if (nGr != null && nUs != null) nGr.removeMember(nUs);
+            if (nGr != null) nGr.remove();
+            if (nUs != null) nUs.remove();
+        }
+    }
+
+    public void testImpersonationOfOtherUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(uSession);
+        Principal selfPrinc = umgr.getAuthorizable(uID).getPrincipal();
+
+        User child = (User) umgr.getAuthorizable(childUID);
+        Impersonation impers = child.getImpersonation();
+        assertFalse(impers.allows(buildSubject(selfPrinc)));
+        try {
+            assertFalse(impers.grantImpersonation(selfPrinc));
+        } catch (AccessDeniedException e) {
+            // ok.
+        }
+        assertFalse(impers.allows(buildSubject(selfPrinc)));
+
+        User parent = (User) umgr.getAuthorizable(parentUID);
+        impers = parent.getImpersonation();
+        assertFalse(impers.allows(buildSubject(selfPrinc)));
+        try {
+            assertFalse(impers.grantImpersonation(selfPrinc));
+        } catch (AccessDeniedException e) {
+            // ok.
+        }
+        assertFalse(impers.allows(buildSubject(selfPrinc)));
+
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,102 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.api.security.user.AbstractUserTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+
+/**
+ * <code>ImpersonationImplTest</code>...
+ */
+public class ImpersonationImplTest extends AbstractUserTest {
+
+    private static Logger log = LoggerFactory.getLogger(ImpersonationImplTest.class);
+
+    private Credentials creds;
+    private String uID;
+    private Session uSession;
+    private UserManager uMgr;
+
+    private String otherUID;
+    private Credentials otherCreds;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // create a first user and retrieve the UserManager from the session
+        // created for that new user.
+        Principal p = getTestPrincipal();
+        creds = buildCredentials(p);
+        UserImpl u = (UserImpl) userMgr.createUser(p.getName(), creds, p);
+        uID = u.getID();
+        uSession = helper.getRepository().login(creds);
+        uMgr = getUserManager(uSession);
+
+        // create a second user 'below' the first user.
+        p = getTestPrincipal();
+        otherCreds = buildCredentials(p);
+        User u2 = userMgr.createUser(p.getName(), otherCreds, p, u.getNode().getPath());
+        otherUID = u2.getID();
+    }
+
+    protected void tearDown() throws Exception {
+        try {
+            uSession.logout();
+        } finally {
+            Authorizable a = userMgr.getAuthorizable(uID);
+            if (a != null) a.remove();
+            a = userMgr.getAuthorizable(otherUID);
+            if (a != null) a.remove();
+        }
+        super.tearDown();
+    }
+
+    public void testModifyOwnImpersonation() throws RepositoryException, NotExecutableException {
+        User u = (User) uMgr.getAuthorizable(uID);
+
+        Principal otherP = uMgr.getAuthorizable(otherUID).getPrincipal();
+
+        assertTrue(u.getImpersonation().grantImpersonation(otherP));
+        assertTrue(u.getImpersonation().allows(buildSubject(otherP)));
+        assertTrue(u.getImpersonation().revokeImpersonation(otherP));
+        assertFalse(u.getImpersonation().allows(buildSubject(otherP)));
+    }
+
+    public void testModifyOthersImpersonators() throws RepositoryException {
+        Principal p = uMgr.getAuthorizable(uID).getPrincipal();
+
+        User other = (User) uMgr.getAuthorizable(otherUID);
+        try {
+            boolean success = other.getImpersonation().grantImpersonation(p);
+            assertFalse("A simple user may not add itself as impersonator to another user.",success);
+        } catch (AccessDeniedException e) {
+            // fine as well -> access denied.
+        }
+        assertFalse("A simple user may not add itself as impersonator to another user.", other.getImpersonation().allows(buildSubject(p)));
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,222 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.api.security.user.AbstractUserTest;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.Impersonation;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Iterator;
+
+/**
+ * <code>NotUserAdministratorTest</code>...
+ */
+public class NotUserAdministratorTest extends AbstractUserTest {
+
+    private static Logger log = LoggerFactory.getLogger(NotUserAdministratorTest.class);
+
+    // test user that is NOT user admin
+    private String uID;
+    private String uPath;
+    private Session uSession;
+    private UserManager uMgr;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // create a first user and retrieve the UserManager from the session
+        // created for that new user.
+        Principal p = getTestPrincipal();
+        Credentials creds = buildCredentials(p);
+        UserImpl u = (UserImpl) userMgr.createUser(p.getName(), creds, p);
+        uID = u.getID();
+        uPath = u.getNode().getPath();
+
+        // create a session for the other user.
+        uSession = helper.getRepository().login(creds);
+        uMgr = getUserManager(uSession);
+    }
+
+    protected void tearDown() throws Exception {
+        try {
+            if (uSession != null) {
+                uSession.logout();
+            }
+        } finally {
+            Authorizable a = userMgr.getAuthorizable(uID);
+            if (a != null) {
+                a.remove();
+            }
+        }
+        super.tearDown();
+    }
+
+    public void testCreateUser() {
+        try {
+            Principal p = getTestPrincipal();
+            User u = uMgr.createUser(p.getName(), buildCredentials(p), p);
+            fail("A non-UserAdmin should not be allowed to create a new User.");
+
+            // clean-up: let superuser remove the user created by fault.
+            userMgr.getAuthorizable(u.getID()).remove();
+        } catch (AuthorizableExistsException e) {
+            // should never get here.
+            fail(e.getMessage());
+        } catch (RepositoryException e) {
+            // success
+        }
+    }
+
+    public void testCreateUserWithItermediatePath() {
+        try {
+            Principal p = getTestPrincipal();
+            User u = uMgr.createUser(p.getName(), buildCredentials(p), p, "/any/intermediate/path");
+            fail("A non-UserAdmin should not be allowed to create a new User.");
+
+            // clean-up: let superuser remove the user created by fault.
+            userMgr.getAuthorizable(u.getID()).remove();
+        } catch (AuthorizableExistsException e) {
+            // should never get here.
+            fail(e.getMessage());
+        } catch (RepositoryException e) {
+            // success
+        }
+    }
+
+    public void testRemoveOwnAuthorizable() throws RepositoryException {
+        Authorizable himself = uMgr.getAuthorizable(uID);
+        try {
+            himself.remove();
+            fail("A user should not be allowed to remove him/herself.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    public void testRemoveChildUser() throws RepositoryException {
+        // let superuser create a child-user.
+        Principal p = getTestPrincipal();
+        String childID = userMgr.createUser(p.getName(), buildCredentials(p), p, uPath).getID();
+        try {
+            Authorizable a = uMgr.getAuthorizable(childID);
+            a.remove();
+            fail("A non-administrator user should not be allowed to remove a child-user.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // let superuser do clean up.
+        Authorizable child = userMgr.getAuthorizable(childID);
+        if (child != null) {
+            child.remove();
+        }
+    }
+
+    public void testRemoveOtherUser() throws RepositoryException {
+        // let superuser create a child-user.
+        Principal p = getTestPrincipal();
+        String childID = userMgr.createUser(p.getName(), buildCredentials(p), p, "/any/intermediate/path").getID();
+        try {
+            Authorizable a = uMgr.getAuthorizable(childID);
+            a.remove();
+            fail("A non-administrator user should not be allowed to remove another user.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // let superuser do clean up.
+        Authorizable child = userMgr.getAuthorizable(childID);
+        if (child != null) {
+            child.remove();
+        }
+    }
+
+    public void testModifyImpersonation() throws RepositoryException {
+        // let superuser create a child-user.
+        Principal p = getTestPrincipal();
+        Authorizable child = userMgr.createUser(p.getName(), buildCredentials(p), p, uPath);
+        try {
+            p = child.getPrincipal();
+
+            Authorizable himself = uMgr.getAuthorizable(uID);
+            Impersonation impers = ((User) himself).getImpersonation();
+
+            assertFalse(impers.allows(buildSubject(p)));
+            assertTrue(impers.grantImpersonation(p));
+            assertTrue(impers.allows(buildSubject(p)));
+            assertTrue(impers.revokeImpersonation(p));
+            assertFalse(impers.allows(buildSubject(p)));
+
+        } finally {
+            // let superuser do clean up.
+            child.remove();
+        }
+    }
+
+    public void testModifyImpersonationOfChildUser() throws RepositoryException {
+        // let superuser create a child-user.
+        Principal p = getTestPrincipal();
+        String childID = userMgr.createUser(p.getName(), buildCredentials(p), p, uPath).getID();
+        try {
+            Authorizable a = uMgr.getAuthorizable(childID);
+
+            Impersonation impers = ((User) a).getImpersonation();
+            Principal himselfP = uMgr.getAuthorizable(uID).getPrincipal();
+            assertFalse(impers.allows(buildSubject(himselfP)));
+            assertTrue(impers.grantImpersonation(himselfP));
+            assertFalse(impers.allows(buildSubject(himselfP)));
+            fail("A non-administrator user should not be allowed modify Impersonation of a child user.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // let superuser do clean up.
+        Authorizable child = userMgr.getAuthorizable(childID);
+        if (child != null) {
+            child.remove();
+        }
+    }
+
+    public void testAddToGroup() throws NotExecutableException, RepositoryException {
+        Iterator it = ((UserManagerImpl) uMgr).findGroups("");
+        if (!it.hasNext()) {
+            throw new NotExecutableException("Couldn't find any group");
+        }
+
+        Group gr = (Group) it.next();
+        try {
+            Authorizable auth = uMgr.getAuthorizable(uID);
+            gr.addMember(auth);
+            fail("a common user should not be allowed to modify any groups.");
+            gr.removeMember(auth);
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,44 @@
+/*
+ * 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.user;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class TestAll extends TestCase {
+
+    /**
+     * Returns a <code>Test</code> suite that executes all test in this package.
+     *
+     * @return a <code>Test</code> suite that executes all test in this package.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite("o.a.j.security.user tests");
+
+        suite.addTestSuite(UserManagerImplTest.class);
+        suite.addTestSuite(AuthorizableImplTest.class);
+        suite.addTestSuite(UserImplTest.class);
+        suite.addTestSuite(ImpersonationImplTest.class);
+
+        suite.addTestSuite(UserAdministratorTest.class);
+        suite.addTestSuite(NotUserAdministratorTest.class);
+        suite.addTestSuite(GroupAdministratorTest.class);
+
+        return suite;
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,322 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.api.security.user.AbstractUserTest;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.Impersonation;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.core.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.util.Text;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * <code>UserAdministratorTest</code>...
+ */
+public class UserAdministratorTest extends AbstractUserTest {
+
+    // user 'above'
+    private String uID;
+
+    // user-admin 'below'
+    private String otherUID;
+    private String otherPath;
+    private Session otherSession;
+
+    // the user-admin group
+    private Group uAdministrators;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // create a first user and retrieve the UserManager from the session
+        // created for that new user.
+        Principal p = getTestPrincipal();
+        UserImpl u = (UserImpl) userMgr.createUser(p.getName(), buildCredentials(p), p);
+        uID = u.getID();
+
+        // create a second user 'below' the first user.
+        p = getTestPrincipal();
+        Credentials otherCreds = buildCredentials(p);
+        User other = userMgr.createUser(p.getName(), otherCreds, p, u.getNode().getPath());
+        otherUID = other.getID();
+        otherPath = ((UserImpl) other).getNode().getPath();
+
+        // make other user a user-administrator:
+        Authorizable ua = userMgr.getAuthorizable(UserConstants.USER_ADMIN_GROUP_NAME);
+        if (ua == null || !ua.isGroup()) {
+            throw new NotExecutableException("Cannot execute test. User-Admin name has been changed by config.");
+        }
+        uAdministrators = (Group) ua;
+        uAdministrators.addMember(other);
+
+        // create a session for the other user.
+        otherSession = helper.getRepository().login(otherCreds);
+    }
+
+    protected void tearDown() throws Exception {
+        try {
+            if (otherSession != null) {
+                otherSession.logout();
+            }
+        } finally {
+            Authorizable a = userMgr.getAuthorizable(otherUID);
+            if (a != null) {
+                for (Iterator it = a.memberOf(); it.hasNext();) {
+                    Group gr = (Group) it.next();
+                    if (!gr.getPrincipal().equals(EveryonePrincipal.getInstance())) {
+                        gr.removeMember(a);
+                    }
+                }
+                a.remove();
+            }
+            a = userMgr.getAuthorizable(uID);
+            if (a != null) {
+                a.remove();
+            }
+        }
+        super.tearDown();
+    }
+
+    public void testUserIsUserAdmin() throws RepositoryException, NotExecutableException {
+        Set principals = getPrincipalSetFromSession(otherSession);
+        boolean isAdmin = false;
+        for (Iterator it = principals.iterator(); it.hasNext() && !isAdmin;) {
+           isAdmin = UserConstants.USER_ADMIN_GROUP_NAME.equals(((Principal) it.next()).getName());
+        }
+        assertTrue(isAdmin);
+    }
+
+    public void testCreateUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        UserImpl u = null;
+        // create a new user -> must succeed and user must be create below 'other'
+        try {
+            Principal p = getTestPrincipal();
+            u = (UserImpl) umgr.createUser(p.getName(), buildCredentials(p), p);
+            assertTrue(Text.isDescendant(otherPath, u.getNode().getPath()));
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
+
+    public void testCreateUserWithIntermediatePath() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        UserImpl u = null;
+        // create a new user with intermediate-path
+        // -> must succeed and user must be create below 'other'
+        try {
+            Principal p = getTestPrincipal();
+            u = (UserImpl) umgr.createUser(p.getName(), buildCredentials(p), p, "/some/intermediate/path");
+            assertTrue(Text.isDescendant(otherPath, u.getNode().getPath()));
+            assertTrue(Text.isDescendant(otherPath + "/some/intermediate/path", u.getNode().getPath()));
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
+
+    /*
+    public void testRemoveHimSelf() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+
+        Authorizable himself = umgr.getAuthorizable(otherUID);
+        try {
+            himself.remove();
+            fail("A UserAdministrator should not be allowed to remove himself.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+    */
+
+    public void testRemoveParentUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+
+        Authorizable parentuser = umgr.getAuthorizable(uID);
+        try {
+            parentuser.remove();
+            fail("A UserAdministrator should not be allowed to remove a 'parent' user.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    public void testModifyImpersonationOfChildUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        Principal otherP = umgr.getAuthorizable(otherUID).getPrincipal();
+
+        User u = null;
+        // create a new user -> must succeed and user must be create below 'other'
+        try {
+            Principal p = getTestPrincipal();
+            u = umgr.createUser(p.getName(), buildCredentials(p), p);
+
+            Impersonation impers = u.getImpersonation();
+            assertFalse(impers.allows(buildSubject(otherP)));
+            assertTrue(impers.grantImpersonation(otherP));
+            assertTrue(impers.allows(buildSubject(otherP)));
+        } finally {
+            // impersonation get removed while removing the user u.
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
+
+    public void testModifyImpersonationOfParentUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        User u = (User) umgr.getAuthorizable(uID);
+        Impersonation uImpl = u.getImpersonation();
+
+        Principal otherP = umgr.getAuthorizable(otherUID).getPrincipal();
+
+        if (!uImpl.allows(buildSubject(otherP))) {
+            // ... trying to modify 'impersonators of 'uid' must not succeed.
+            try {
+                assertFalse(uImpl.grantImpersonation(otherP));
+            } catch (AccessDeniedException e) {
+                // success
+            } finally {
+                assertFalse(uImpl.allows(buildSubject(otherP)));
+                uImpl.revokeImpersonation(otherP);
+            }
+        } else {
+            throw new NotExecutableException("Cannot execute test. OtherP can already impersonate UID-user.");
+        }
+    }
+
+    public void testModifyGroupForHimSelf() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+
+        User userHimSelf = (User) umgr.getAuthorizable(otherUID);
+        for (Iterator it = ((UserManagerImpl) umgr).findGroups(""); it.hasNext();) {
+            Group gr = (Group) it.next();
+            try {
+                assertFalse(gr.addMember(userHimSelf));
+            } catch (RepositoryException e) {
+                // success
+            }
+        }
+    }
+
+    public void testModifyGroupForParentUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+
+        User parentUser = (User) umgr.getAuthorizable(uID);
+        if (parentUser == null) {
+            throw new NotExecutableException();
+        } else {
+            for (Iterator it = ((UserManagerImpl) umgr).findGroups(""); it.hasNext();) {
+                Group gr = (Group) it.next();
+                try {
+                    assertFalse(gr.addMember(parentUser));
+                } catch (RepositoryException e) {
+                    // success
+                }
+            }
+        }
+    }
+
+    public void testModifyGroupForChildUser() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        Principal cp = getTestPrincipal();
+        User childU = null;
+        try {
+            childU = umgr.createUser(cp.getName(), buildCredentials(cp), cp);
+            for (Iterator it = ((UserManagerImpl) umgr).findGroups(""); it.hasNext();) {
+                Group gr = (Group) it.next();
+                try {
+                    assertFalse(gr.addMember(childU));
+                } catch (RepositoryException e) {
+                    // success
+                }
+            }
+        } finally {
+            if (childU != null) {
+                childU.remove();
+            }
+        }
+    }
+
+    public void testCreateGroup() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        try {
+            Group testGroup = umgr.createGroup(getTestPrincipal());
+            fail("UserAdmin should not be allowed to create a new Group.");
+            testGroup.remove();
+        } catch (RepositoryException e) {
+            // success.
+        }
+    }
+
+    public void testCreateGroupWithIntermediatePath() throws RepositoryException, NotExecutableException {
+        UserManager umgr = getUserManager(otherSession);
+        try {
+            Group testGroup = umgr.createGroup(getTestPrincipal(), "/any/intermediate/path");
+            fail("UserAdmin should not be allowed to create a new Group.");
+            testGroup.remove();
+        } catch (RepositoryException e) {
+            // success.
+        }
+    }
+
+    public void testAddToGroup() throws NotExecutableException, RepositoryException {
+        UserManager umgr = getUserManager(otherSession);
+        Iterator it = ((UserManagerImpl) umgr).findGroups("");
+        if (!it.hasNext()) {
+            throw new NotExecutableException("Couldn't find any group");
+        }
+
+        Group gr = (Group) it.next();
+        Authorizable auth = umgr.getAuthorizable(uID);
+        try {
+            assertFalse(gr.addMember(auth));
+        } catch (AccessDeniedException e) {
+            // success as well.
+        }
+
+        auth = umgr.getAuthorizable(otherUID);
+        try {
+            assertFalse(gr.addMember(auth));
+        } catch (AccessDeniedException e) {
+            // success as well.
+        }
+
+        // not even user-admin group
+        gr = (Group) umgr.getAuthorizable(uAdministrators.getID());
+        auth = umgr.getAuthorizable(otherUID);
+        try {
+            assertFalse(gr.addMember(auth));
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,95 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.api.security.user.AbstractUserTest;
+import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.value.StringValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Iterator;
+
+/**
+ * <code>UserImplTest</code>...
+ */
+public class UserImplTest extends AbstractUserTest {
+
+    private static Logger log = LoggerFactory.getLogger(UserImplTest.class);
+
+    private String uID;
+    private Credentials creds;
+    private Session uSession;
+    private UserManager uMgr;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Principal p = getTestPrincipal();
+        creds = buildCredentials(p);
+        User u = userMgr.createUser(p.getName(), creds, p);
+        uID = u.getID();
+        uSession = helper.getRepository().login(creds);
+        uMgr = getUserManager(uSession);
+    }
+
+    protected void tearDown() throws Exception {
+        try {
+            userMgr.getAuthorizable(uID).remove();
+        } finally {
+            uSession.logout();
+        }
+        super.tearDown();
+    }
+
+    public void testUserImplHasCryptedSimplCredentials() throws RepositoryException, NotExecutableException {
+        User user = getTestUser(superuser);
+        Iterator it = user.getCredentials();
+        assertTrue(it.hasNext());
+
+        Credentials crds = (Credentials) it.next();
+        assertTrue(crds instanceof CryptedSimpleCredentials);
+        assertEquals(((CryptedSimpleCredentials) crds).getUserID(), user.getID());
+    }
+
+    public void testIsUser() throws RepositoryException {
+        Authorizable auth = uMgr.getAuthorizable(uID);
+        assertFalse(auth.isGroup());
+    }
+
+    public void testUserCanModifyItsOwnProperties() throws RepositoryException {
+        User u = (User) uMgr.getAuthorizable(uID);
+
+        if (u == null) {
+            fail("User " +uID+ "hast not been removed and must be visible to the Session created with its credentials.");
+        }
+
+        u.setProperty("Email", new StringValue("tu@security.test"));
+        assertEquals("tu@security.test", u.getProperty("Email")[0].getString());
+
+        u.removeProperty("Email");
+        assertNull(u.getProperty("Email"));
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,347 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.security.TestPrincipal;
+import org.apache.jackrabbit.api.security.user.AbstractUserTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.ConstraintViolationException;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * <code>UserManagerImplTest</code>...
+ */
+public class UserManagerImplTest extends AbstractUserTest {
+
+    private static Logger log = LoggerFactory.getLogger(UserManagerImplTest.class);
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (!(userMgr instanceof UserManagerImpl)) {
+            throw new NotExecutableException("UserManagerImpl expected -> cannot perform test.");
+        }
+    }
+
+    private String getTestUserId(Principal p) throws RepositoryException {
+        String hint = "UID" + p.getName();
+        String userId = hint;
+        int i = 0;
+        while (userMgr.getAuthorizable(userId) != null) {
+            userId = hint + i++;
+        }
+        return userId;
+    }
+
+    public void testCreateNodesDirectly() throws NotExecutableException, RepositoryException {
+        User u = getTestUser(superuser);
+        if (u instanceof UserImpl) {
+            throw new NotExecutableException();
+        }
+
+        NodeImpl n = ((UserImpl)u).getNode();
+        try {
+            n.addNode("anyname", "rep:AuthorizableFolder");
+            fail("security nodes must be protected.");
+        } catch (ConstraintViolationException e) {
+            // success
+        } finally {
+            n.refresh(false);
+        }
+        try {
+            n.addNode("anyname", "rep:User");
+            fail("security nodes must be protected.");
+        } catch (ConstraintViolationException e) {
+            // success
+        } finally {
+            n.refresh(false);
+        }
+        try {
+            n.setProperty("rep:userId", "someotherUID");
+            fail("security nodes must be protected.");
+        } catch (ConstraintViolationException e) {
+            // success
+        } finally {
+            n.refresh(false);
+        }
+    }
+
+
+    public void testRemoveUserRemovesTree() throws RepositoryException {
+        // create 2 new users. the second as child of the first.
+        Principal p = getTestPrincipal();
+        User u = userMgr.createUser(p.getName(), buildCredentials(p), p);
+        String uID = u.getID();
+        p = getTestPrincipal();
+        User u2 = userMgr.createUser(p.getName(), buildCredentials(p), p, ((UserImpl)u).getNode().getPath());
+        String u2ID = u2.getID();
+
+        // removing the first user must also remove the child-users.
+        u.remove();
+
+        // make sure both users are gone
+        assertNull(userMgr.getAuthorizable(uID));
+        assertNull(userMgr.getAuthorizable(u2ID));
+    }
+
+    public void testCreateUserWithInvalidCredentials() throws RepositoryException {
+        Principal p = getTestPrincipal();
+        try {
+            Credentials creds = new Credentials() {};
+            User u = userMgr.createUser(p.getName(), creds, p);
+            u.remove();
+            fail("creating a user with 'unknown' credentials must fail.");
+        } catch (RepositoryException e) {
+            // success
+        }
+    }
+
+    public void testCreateUserWithUserIDNotMatchingCredentials() throws RepositoryException {
+        Principal p = getTestPrincipal();
+        String uid = getTestUserId(p);
+        try {
+            User u = userMgr.createUser(uid, buildCredentials(p), p);
+            u.remove();
+            fail("creating a user with UserID not matching uid from credentials must fail.");
+        } catch (RepositoryException e) {
+            // success
+        }
+    }
+
+    public void testCreateUserIdEqualsUserId() throws RepositoryException {
+        Principal p = getTestPrincipal();
+        User u = null;
+        try {
+            u = userMgr.createUser(p.getName(), buildCredentials(p), p);
+
+            String msg = "Implementation specific: User.getID() must return the userID pass to createUser.";
+            assertEquals(msg, u.getID(), p.getName());
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
+
+    public void testCreateUserIdDifferentFromPrincipalName() throws RepositoryException {
+        Principal p = getTestPrincipal();
+        String uid = getTestUserId(p);
+
+        User u = null;
+        try {
+            u = userMgr.createUser(uid, buildCredentials(uid, uid), p);
+
+            String msg = "Creating a User with principal-name distinct from Principal-name must succeed as long as both are unique.";
+            assertEquals(msg, u.getID(), uid);
+            assertEquals(msg, p.getName(), u.getPrincipal().getName());
+            assertFalse(msg, u.getID().equals(u.getPrincipal().getName()));
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
+
+    public void testCreatingGroupWithNameMatchingExistingUserId() throws RepositoryException {
+        Principal p = getTestPrincipal();
+        String uid = getTestUserId(p);
+
+        User u = null;
+        Group gr = null;
+        try {
+            u = userMgr.createUser(uid, buildCredentials(uid, uid), p);
+            gr = userMgr.createGroup(new TestPrincipal(uid));
+
+            String msg = "Creating a Group with a principal-name that exists as UserID -> must create new GroupID but keep PrincipalName.";
+            assertFalse(msg, gr.getID().equals(gr.getPrincipal().getName()));
+            assertFalse(msg, gr.getID().equals(uid));
+            assertFalse(msg, gr.getID().equals(u.getID()));
+            assertEquals(msg, uid, gr.getPrincipal().getName());
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+            if (gr != null) {
+                gr.remove();
+            }
+        }
+    }
+
+    public void testFindAuthorizable() throws RepositoryException, NotExecutableException {
+        Authorizable auth;
+        Set principals = getPrincipalSetFromSession(superuser);
+        for (Iterator it = principals.iterator(); it.hasNext();) {
+            Principal p = (Principal) it.next();
+            auth = userMgr.getAuthorizable(p);
+
+            if (auth != null) {
+                if (!auth.isGroup() && auth.hasProperty("rep:userId")) {
+                    String val = auth.getProperty("rep:userId")[0].getString();
+                    Iterator users = userMgr.findAuthorizable("rep:userId", val);
+
+                    // the result must contain 1 authorizable
+                    assertTrue(users.hasNext());
+                    Authorizable first = (Authorizable) users.next();
+                    assertEquals(first.getID(), val);
+
+                    // since id is unique -> there should be no more auths in
+                    // the iterator left
+                    assertFalse(users.hasNext());
+                }
+            }
+        }
+    }
+
+    public void testFindAuthorizableByAddedProperty() throws RepositoryException {
+        Principal p = getTestPrincipal();
+        Authorizable auth = null;
+
+        try {
+            auth= userMgr.createGroup(p);
+            auth.setProperty("E-Mail", new Value[] { superuser.getValueFactory().createValue("anyVal")});
+
+            boolean found = false;
+            Iterator result = userMgr.findAuthorizable("E-Mail", "anyVal");
+            while (result.hasNext()) {
+                Authorizable a = (Authorizable) result.next();
+                if (a.getID().equals(auth.getID())) {
+                    found = true;
+                }
+            }
+
+            assertTrue(found);
+        } finally {
+            // remove the create group again.
+            if (auth != null) {
+                auth.remove();
+            }
+        }
+    }
+
+    public void testFindUser() throws RepositoryException {
+        User u = null;
+        try {
+            Principal p = getTestPrincipal();
+            String uid = "UID" + p.getName();
+            Credentials c = buildCredentials(uid, uid);
+            u = userMgr.createUser(uid, c, p);
+
+            boolean found = false;
+            Iterator it = ((UserManagerImpl)userMgr).findUsers("");
+            while (it.hasNext() && !found) {
+                User nu = (User) it.next();
+                found = nu.getID().equals(uid);
+            }
+            assertTrue("Searching for \"\" must find the created user.", found);
+
+            it = ((UserManagerImpl)userMgr).findUsers(p.getName());
+            found = false;
+            while (it.hasNext() && !found) {
+                User nu = (User) it.next();
+                found = nu.getPrincipal().getName().equals(p.getName());
+            }
+            assertTrue("Searching for principal-name must find the created user.", found);
+
+            it = ((UserManagerImpl)userMgr).findUsers(uid);
+            found = false;
+            while (it.hasNext() && !found) {
+                User nu = (User) it.next();
+                found = nu.getID().equals(uid);
+            }
+            assertTrue("Searching for user id must find the created user.", found);
+
+            // but search groups should not find anything
+            it = ((UserManagerImpl)userMgr).findGroups(uid);
+            assertFalse(it.hasNext());
+
+            it = ((UserManagerImpl)userMgr).findGroups("");
+            while (it.hasNext()) {
+                if (((Authorizable) it.next()).getPrincipal().getName().equals(p.getName())) {
+                    fail("Searching for Groups should never find a user");
+                }
+            }
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
+
+    public void testFindGroup() throws RepositoryException {
+        Group gr = null;
+        try {
+            Principal p = getTestPrincipal();
+            gr = userMgr.createGroup(p);
+
+            boolean found = false;
+            Iterator it = ((UserManagerImpl)userMgr).findGroups("");
+            while (it.hasNext() && !found) {
+                Group ng = (Group) it.next();
+                found = ng.getPrincipal().getName().equals(p.getName());
+            }
+            assertTrue("Searching for \"\" must find the created group.", found);
+
+            it = ((UserManagerImpl)userMgr).findGroups(p.getName());
+            found = false;
+            while (it.hasNext() && !found) {
+                Group ng = (Group) it.next();
+                found = ng.getPrincipal().getName().equals(p.getName());
+            }
+            assertTrue("Searching for principal-name must find the created group.", found);
+
+            // but search users should not find anything
+            it = ((UserManagerImpl)userMgr).findUsers(p.getName());
+            assertFalse(it.hasNext());
+
+            it = ((UserManagerImpl)userMgr).findUsers("");
+            while (it.hasNext()) {
+                if (((Authorizable) it.next()).getPrincipal().getName().equals(p.getName())) {
+                    fail("Searching for Users should never find a group");
+                }
+            }
+        } finally {
+            if (gr != null) {
+                gr.remove();
+            }
+        }
+    }
+
+    public void testFindAllUsers() throws RepositoryException {
+        Iterator it = ((UserManagerImpl)userMgr).findUsers("");
+        while (it.hasNext()) {
+            assertFalse(((Authorizable) it.next()).isGroup());
+        }
+    }
+
+    public void testFindAllGroups() throws RepositoryException {
+        Iterator it = ((UserManagerImpl)userMgr).findGroups("");
+        while (it.hasNext()) {
+            assertTrue(((Authorizable) it.next()).isGroup());
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jackrabbit-core/src/test/repository/jaas.config
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/repository/jaas.config?rev=638834&r1=638833&r2=638834&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/repository/jaas.config (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/repository/jaas.config Wed Mar 19 06:56:13 2008
@@ -1,3 +1,3 @@
 Jackrabbit {
-  org.apache.jackrabbit.core.security.SimpleLoginModule required anonymousId="anonymous";
+  org.apache.jackrabbit.core.security.simple.SimpleLoginModule required anonymousId="anonymous" adminId="admin";
 };

Modified: jackrabbit/trunk/jackrabbit-core/src/test/repository/repository.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/repository/repository.xml?rev=638834&r1=638833&r2=638834&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/repository/repository.xml (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/repository/repository.xml Wed Mar 19 06:56:13 2008
@@ -15,8 +15,8 @@
    See the License for the specific language governing permissions and
    limitations under the License.
   -->
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.4//EN"
-                            "http://jackrabbit.apache.org/dtd/repository-1.4.dtd">
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.5//EN"
+                            "http://svn.apache.org/repos/asf/jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/config/repository-1.5.dtd">
 <!-- Example Repository Configuration File -->
 <Repository>
     <!--
@@ -32,16 +32,25 @@
     -->
     <Security appName="Jackrabbit">
         <!--
+            security manager:
+            class: FQN of class implementing the JackrabbitSecurityManager interface
+        -->
+        <SecurityManager class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager" workspaceName="security">
+            <!-- <param name="config" value="${rep.home}/security.xml"/> -->
+        </SecurityManager>
+
+        <!--
             access manager:
             class: FQN of class implementing the AccessManager interface
         -->
-        <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+        <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">
             <!-- <param name="config" value="${rep.home}/access.xml"/> -->
         </AccessManager>
 
-        <LoginModule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
+        <LoginModule class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
            <!-- anonymous user name ('anonymous' is the default value) -->
            <param name="anonymousId" value="anonymous"/>
+           <param name="adminId" value="admin"/>
            <!--
               default user name to be used instead of the anonymous user
               when no login credentials are provided (unset by default)

Added: jackrabbit/trunk/jackrabbit-core/src/test/repository/workspaces/security/workspace.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/repository/workspaces/security/workspace.xml?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/repository/workspaces/security/workspace.xml (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/repository/workspaces/security/workspace.xml Wed Mar 19 06:56:13 2008
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+   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.
+  -->
+<Workspace name="security">
+  <!--
+      virtual file system of the workspace:
+      class: FQN of class implementing FileSystem interface
+  -->
+  <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+    <param name="path" value="${wsp.home}" />
+  </FileSystem>
+  <!--
+      persistence of the workspace:
+      class: FQN of class implementing PersistenceManager interface
+  -->
+  <PersistenceManager class="org.apache.jackrabbit.core.persistence.db.DerbyPersistenceManager">
+     <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/>
+     <param name="schemaObjectPrefix" value="${wsp.name}_"/>
+  </PersistenceManager>
+  <!--
+      Search index and the file system it uses.
+  -->
+  <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+    <param name="path" value="${wsp.home}/index" />
+  </SearchIndex>
+</Workspace>

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/repository/workspaces/security/workspace.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/test/resources/repositoryStubImpl.properties
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/resources/repositoryStubImpl.properties?rev=638834&r1=638833&r2=638834&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/resources/repositoryStubImpl.properties (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/resources/repositoryStubImpl.properties Wed Mar 19 06:56:13 2008
@@ -27,10 +27,10 @@
 org.apache.jackrabbit.repository.jaas.config=src/test/repository/jaas.config
 
 # credential configuration
-javax.jcr.tck.superuser.name=superuser
-javax.jcr.tck.superuser.pwd=
+javax.jcr.tck.superuser.name=admin
+javax.jcr.tck.superuser.pwd=admin
 javax.jcr.tck.readwrite.name=user
-javax.jcr.tck.readwrite.pwd=
+javax.jcr.tck.readwrite.pwd=user
 javax.jcr.tck.readonly.name=anonymous
 javax.jcr.tck.readonly.pwd=
 

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/jaas.config
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/jaas.config?rev=638834&r1=638833&r2=638834&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/jaas.config (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/jaas.config Wed Mar 19 06:56:13 2008
@@ -1,3 +1,3 @@
 Jackrabbit {
-  org.apache.jackrabbit.core.security.SimpleLoginModule required anonymousId="anonymous";
+  org.apache.jackrabbit.core.security.simple.SimpleLoginModule required anonymousId="anonymous" adminId="admin";
 };

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/repository.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/repository.xml?rev=638834&r1=638833&r2=638834&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/repository.xml (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/resources/repository.xml Wed Mar 19 06:56:13 2008
@@ -15,8 +15,8 @@
    See the License for the specific language governing permissions and
    limitations under the License.
   -->
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.2//EN"
-                            "http://jackrabbit.apache.org/dtd/repository-1.2.dtd">
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.5//EN"
+                            "http://svn.apache.org/repos/asf/jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/config/repository-1.5.dtd">
 <!-- Example Repository Configuration File -->
 <Repository>
     <!--
@@ -32,16 +32,25 @@
     -->
     <Security appName="Jackrabbit">
         <!--
+            security manager:
+            class: FQN of class implementing the JackrabbitSecurityManager interface
+        -->
+        <SecurityManager class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager" workspaceName="security">
+            <!-- <param name="config" value="${rep.home}/security.xml"/> -->
+        </SecurityManager>
+
+        <!--
             access manager:
             class: FQN of class implementing the AccessManager interface
         -->
-        <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+        <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">
             <!-- <param name="config" value="${rep.home}/access.xml"/> -->
         </AccessManager>
 
-        <LoginModule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
+        <LoginModule class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
            <!-- anonymous user name ('anonymous' is the default value) -->
            <param name="anonymousId" value="anonymous"/>
+           <param name="adminId" value="admin"/>
            <!--
               default user name to be used instead of the anonymous user
               when no login credentials are provided (unset by default)
@@ -73,7 +82,6 @@
         <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager">
           <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/>
           <param name="schemaObjectPrefix" value="${wsp.name}_"/>
-          <param name="externalBLOBs" value="false"/>
         </PersistenceManager>
         <!--
             Search index and the file system it uses.
@@ -105,7 +113,6 @@
         <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager">
           <param name="url" value="jdbc:derby:${rep.home}/version/db;create=true"/>
           <param name="schemaObjectPrefix" value="version_"/>
-          <param name="externalBLOBs" value="false"/>
         </PersistenceManager>
     </Versioning>