jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r794702 [2/2] - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/ main/java/org/apache/jackrabbit/core/config/ main/java/org/apache/jackrabbit/core/security/user/ test/java/org/apache/jackrabbit/core/config/ te...
Date Thu, 16 Jul 2009 14:54:09 GMT
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IdResolverTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IdResolverTest.java?rev=794702&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IdResolverTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IdResolverTest.java
Thu Jul 16 14:54:08 2009
@@ -0,0 +1,298 @@
+/*
+ * 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.User;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.security.TestPrincipal;
+import org.apache.jackrabbit.util.Text;
+import org.apache.commons.collections.map.ListOrderedMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+import java.util.Properties;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * <code>IdResolverTest</code>...
+ */
+public class IdResolverTest extends AbstractUserTest {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(IdResolverTest.class);
+
+    private SessionImpl s;
+    private UserManagerImpl uMgr;
+    private List<NodeImpl> toRemove = new ArrayList();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        String workspaceName = ((RepositoryImpl) superuser.getRepository()).getConfig().getSecurityConfig().getSecurityManagerConfig().getWorkspaceName();
+        s = (SessionImpl) ((SessionImpl) superuser).createSession(workspaceName);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            for (NodeImpl node : toRemove) {
+                uMgr.removeProtectedItem(node, node.getParent());
+            }
+        } finally {
+            s.logout();
+        }
+        super.tearDown();
+    }
+
+    private void createUserManager(int depth, boolean expandTree, long size) throws RepositoryException
{
+        Properties props = new Properties();
+        props.put(UserManagerImpl.PARAM_DEFAULT_DEPTH, depth);
+        props.put(UserManagerImpl.PARAM_AUTO_EXPAND_TREE, expandTree);
+        props.put(UserManagerImpl.PARAM_AUTO_EXPAND_SIZE, size);
+
+        uMgr = new UserManagerImpl(s, "admin", props);
+    }
+
+
+    public void testRemoveTree() throws RepositoryException {
+        UserImpl u = (UserImpl) userMgr.createUser("z", "z");
+        UserImpl u2 = (UserImpl) userMgr.createUser("zz", "zz");
+
+        assertEquals(UserConstants.USERS_PATH + "/z/zz/z", u.getNode().getPath());
+
+        try {
+            NodeImpl folder = (NodeImpl) u.getNode().getParent().getParent();
+            ((UserManagerImpl) userMgr).removeProtectedItem(folder, folder.getParent());
+        } finally {
+            boolean fail = false;
+            if (userMgr.getAuthorizable("z") != null) {
+                fail = true;
+                u.remove();
+            }
+            if (userMgr.getAuthorizable("zz") != null) {
+                fail = true;
+                u2.remove();
+            }
+            if (fail) {
+                fail("Removing the top authorizable folder must remove all users contained.");
+            }
+        }
+    }
+
+    /**
+     * If auto-expand is false all users must be created on the second level.
+     */
+    public void testDefault() throws RepositoryException {
+        createUserManager(2, false, 0);
+
+        UserImpl u = (UserImpl) uMgr.createUser("z", "z");
+        // remember the z-folder for later removal
+        toRemove.add((NodeImpl) u.getNode().getParent().getParent());
+        assertEquals(UserConstants.USERS_PATH + "/z/zz/z", u.getNode().getPath());
+
+        Map<String, String> m = new ListOrderedMap();
+        m.put("zz",     "/z/zz/zz");
+        m.put("zzz",    "/z/zz/zzz");
+        m.put("zzzz",   "/z/zz/zzzz");
+        m.put("zZ",     "/z/zZ/zZ");
+        m.put("zH",     "/z/zH/zH");
+        m.put("zh",     "/z/zh/zh");
+        m.put("zHzh",   "/z/zH/zHzh");
+        m.put("z_Hz",   "/z/z_/z_Hz");
+        m.put("zŸrich", "/z/zŸ/zŸrich");
+
+        for (String uid : m.keySet()) {
+            u = (UserImpl) uMgr.createUser(uid, uid);
+            assertEquals(UserConstants.USERS_PATH + m.get(uid), u.getNode().getPath());
+        }
+    }
+
+    /**
+     * Having 3 default levels -> test uids again.
+     * 
+     * @throws RepositoryException
+     */
+    public void testChangedDefaultLevel() throws RepositoryException {
+        createUserManager(3, false, 0);
+
+        UserImpl u = (UserImpl) uMgr.createUser("z", "z");
+        // remember the z-folder for later removal
+        toRemove.add((NodeImpl) u.getNode().getParent().getParent().getParent());
+        assertEquals(UserConstants.USERS_PATH + "/z/zz/zzz/z", u.getNode().getPath());
+
+        Map<String, String> m = new ListOrderedMap();
+        m.put("zz",     "/z/zz/zzz/zz");
+        m.put("zzz",    "/z/zz/zzz/zzz");
+        m.put("zzzz",   "/z/zz/zzz/zzzz");
+        m.put("zZ",     "/z/zZ/zZZ/zZ");
+        m.put("zH",     "/z/zH/zHH/zH");
+        m.put("zh",     "/z/zh/zhh/zh");
+        m.put("zHzh",   "/z/zH/zHz/zHzh");
+        m.put("z_Hz",   "/z/z_/z_H/z_Hz");
+        m.put("zŸrich", "/z/zŸ/zŸr/zŸrich");
+
+        for (String uid : m.keySet()) {
+            u = (UserImpl) uMgr.createUser(uid, uid);
+            assertEquals(UserConstants.USERS_PATH + m.get(uid), u.getNode().getPath());
+        }
+    }
+
+    public void testIllegalChars() throws RepositoryException {
+        createUserManager(2, true, 2);
+
+        UserImpl u = (UserImpl) uMgr.createUser("z", "z");
+        // remember the z-folder for later removal
+        toRemove.add((NodeImpl) u.getNode().getParent().getParent());
+
+        String zu = Text.escapeIllegalJcrChars("z*");
+        String zur = Text.escapeIllegalJcrChars("z*r");
+
+        String zuri = Text.escapeIllegalJcrChars("z*.r.i");
+
+        Map<String, String> m = new ListOrderedMap();
+        // test illegal JCR chars in uid
+        // on level 2
+        m.put("z*rich", "/z/" + zu + "/" + Text.escapeIllegalJcrChars("z*rich"));
+        m.put("z*riq",  "/z/" + zu + "/" + Text.escapeIllegalJcrChars("z*riq"));
+        m.put("z*",     "/z/" + zu + "/" + zu);  // still on level 2 (too short for 3)
+        // on level 3
+        m.put("z*rik",  "/z/" + zu + "/" + zur + "/" + Text.escapeIllegalJcrChars("z*rik"));
+        m.put("z*.ri",  "/z/" + zu + "/" + Text.escapeIllegalJcrChars("z*.") + "/" + Text.escapeIllegalJcrChars("z*.ri"));
+
+        for (String uid : m.keySet()) {
+            u = (UserImpl) uMgr.createUser(uid, uid);
+            assertEquals(UserConstants.USERS_PATH + m.get(uid), u.getNode().getPath());
+            Authorizable ath = uMgr.getAuthorizable(uid);
+            assertNotNull("User with id " + uid + " must exist.", ath);
+            assertFalse("User with id " + uid + " must not be a group.", ath.isGroup());
+        }
+
+        // test for groups as well
+        GroupImpl gr = (GroupImpl) uMgr.createGroup(new TestPrincipal("z[x]"));
+        // remember the z-folder for later removal
+        toRemove.add((NodeImpl) gr.getNode().getParent().getParent());
+
+        assertEquals("z[x]", gr.getID());
+        String expectedPath = UserConstants.GROUPS_PATH + "/z/" + Text.escapeIllegalJcrChars("z[")
+ "/" + Text.escapeIllegalJcrChars("z[x]");
+        assertEquals(expectedPath, gr.getNode().getPath());
+        Authorizable ath = uMgr.getAuthorizable(gr.getID());
+        assertNotNull(ath);
+        assertTrue(ath.isGroup());
+
+        // test if conflicting authorizables are detected.
+        try {
+            uMgr.createUser("z[x]", "z[x]");
+            fail("A group \"z[x]\" already exists.");
+        } catch (AuthorizableExistsException e) {
+            // success
+        }
+
+        try {
+            uMgr.createGroup(new TestPrincipal("z*rik"));
+            fail("A user \"z*rik\" already exists");
+        } catch (AuthorizableExistsException e) {
+            // success
+        }
+    }
+
+    /**
+     * If auto-expand is true users must be distributed over more than default-depth
+     * levels if max-size is reached.
+     * In addition the special cases must be respected (see DefaultIdResolver).
+     *
+     * @throws RepositoryException
+     */
+    public void testAutoExpand() throws RepositoryException {
+        createUserManager(2, true, 5);
+
+        UserImpl u = (UserImpl) uMgr.createUser("z", "z");
+        // remember the z-folder for later removal
+        toRemove.add((NodeImpl) u.getNode().getParent().getParent());
+        assertEquals(UserConstants.USERS_PATH + "/z/zz/z", u.getNode().getPath());
+
+        Map<String, String> m = new ListOrderedMap();
+        m.put("zz", "/z/zz/zz");
+        // zzz -> potential conflict: must be added to 3rd level
+        m.put("zzz", "/z/zz/zzz/zzz");
+
+        // more users -> added to 2nd level until max-size (5) is reached.
+        m.put("zzABC", "/z/zz/zzABC");
+        m.put("zzzh", "/z/zz/zzzh");
+
+        // max-size on level 2 (zz) is reached -> added to 3rd level.
+        m.put("zzzzZ", "/z/zz/zzz/zzzzZ");
+        m.put("zzh", "/z/zz/zzh/zzh");
+        m.put("zzXyzzz", "/z/zz/zzX/zzXyzzz");
+
+        // zzzz, zzza -> potential conflicts on the 3rd level
+        // -> must be added to 4th level
+        m.put("zzzz", "/z/zz/zzz/zzzz/zzzz");
+        m.put("zzza", "/z/zz/zzz/zzza/zzza");
+
+
+        // zA -> to short for 3rd -> must be inserted at the 2nd level.
+        m.put("zA", "/z/zA/zA");
+
+        for (String uid : m.keySet()) {
+            u = (UserImpl) uMgr.createUser(uid, uid);
+            assertEquals(UserConstants.USERS_PATH + m.get(uid), u.getNode().getPath());
+        }
+    }
+
+    /**
+     * Find by ID must succeed.
+     * 
+     * @throws RepositoryException
+     */
+    public void testFindById() throws RepositoryException {
+        createUserManager(2, true, 2);
+
+        UserImpl u = (UserImpl) uMgr.createUser("z", "z");
+        // remember the z-folder for later removal
+        toRemove.add((NodeImpl) u.getNode().getParent().getParent());
+        assertEquals(UserConstants.USERS_PATH + "/z/zz/z", u.getNode().getPath());
+
+        Map<String, String> m = new ListOrderedMap();
+        // potential conflicting uid
+        m.put("zzz", "/z/zz/zzz/zzz");
+        // max-size (2) is reached
+        m.put("zzzuerich", "/z/zz/zzz/zzzuerich");
+        m.put("zzuerich", "/z/zz/zzu/zzuerich");
+        // too short for expanded folders
+        m.put("zz", "/z/zz/zz");
+
+        for (String uid : m.keySet()) {
+            u = (UserImpl) uMgr.createUser(uid, uid);
+            assertEquals(UserConstants.USERS_PATH + m.get(uid), u.getNode().getPath());
+
+            User us = (User) uMgr.getAuthorizable(uid);
+            assertNotNull(us);
+            assertEquals(uid, us.getID());
+        }
+    }
+}
\ No newline at end of file

Modified: 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=794702&r1=794701&r2=794702&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
Thu Jul 16 14:54:08 2009
@@ -45,6 +45,8 @@
         suite.addTestSuite(IndexNodeResolverTest.class);
         suite.addTestSuite(TraversingNodeResolverTest.class);
 
+        suite.addTestSuite(IdResolverTest.class);
+
         return suite;
     }
 }

Modified: 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=794702&r1=794701&r2=794702&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java
Thu Jul 16 14:54:08 2009
@@ -24,7 +24,6 @@
 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;
@@ -59,11 +58,11 @@
         UserImpl u = (UserImpl) userMgr.createUser(p.getName(), buildPassword(p));
         uID = u.getID();
 
-        // create a second user 'below' the first user.
+        // create a second user
         p = getTestPrincipal();
         String pw = buildPassword(p);
         Credentials otherCreds = buildCredentials(p.getName(), pw);
-        User other = userMgr.createUser(p.getName(), pw, p, u.getNode().getPath());
+        User other = userMgr.createUser(p.getName(), pw);
         otherUID = other.getID();
         otherPath = ((UserImpl) other).getNode().getPath();
 
@@ -123,11 +122,10 @@
     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'
+        // create a new user -> must succeed.
         try {
             Principal p = getTestPrincipal();
             u = (UserImpl) umgr.createUser(p.getName(), buildPassword(p));
-            assertTrue(Text.isDescendant(otherPath, u.getNode().getPath()));
         } finally {
             if (u != null) {
                 u.remove();
@@ -139,12 +137,12 @@
         UserManager umgr = getUserManager(otherSession);
         UserImpl u = null;
         // create a new user with intermediate-path
-        // -> must succeed and user must be create below 'other'
+        // -> must succeed and user must be created
+        // -> intermediate path must be ignored.
         try {
             Principal p = getTestPrincipal();
             u = (UserImpl) umgr.createUser(p.getName(), buildPassword(p), p, "/some/intermediate/path");
-            assertTrue(Text.isDescendant(otherPath, u.getNode().getPath()));
-            assertTrue(Text.isDescendant(otherPath + "/some/intermediate/path", u.getNode().getPath()));
+            assertEquals(-1, u.getNode().getPath().indexOf("/some/intermediate/path"));
         } finally {
             if (u != null) {
                 u.remove();
@@ -164,24 +162,25 @@
         }
     }
 
-    public void testRemoveParentUser() throws RepositoryException, NotExecutableException
{
+    /**
+     * A member of 'usermanagers' must be able to remove another user.
+     * 
+     * @throws RepositoryException
+     * @throws NotExecutableException
+     */
+    public void testRemoveAnotherUser() 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
-        }
+        Authorizable user = umgr.getAuthorizable(uID);
+        user.remove();
     }
 
-    public void testModifyImpersonationOfChildUser() throws RepositoryException, NotExecutableException
{
+    public void testModifyImpersonationOfUser() throws RepositoryException, NotExecutableException
{
         UserManager umgr = getUserManager(otherSession);
         Principal otherP = umgr.getAuthorizable(otherUID).getPrincipal();
 
+        // modify impersonation of new user
         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(), buildPassword(p));
@@ -196,25 +195,15 @@
                 u.remove();
             }
         }
-    }
 
-    public void testModifyImpersonationOfParentUser() throws RepositoryException, NotExecutableException
{
-        UserManager umgr = getUserManager(otherSession);
-        User u = (User) umgr.getAuthorizable(uID);
+        // modify impersonation of another 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);
-            }
+            // ... trying to modify 'impersonators of another user must succeed
+            assertTrue(uImpl.grantImpersonation(otherP));
+            assertTrue(uImpl.allows(buildSubject(otherP)));
+            uImpl.revokeImpersonation(otherP);
         } else {
             throw new NotExecutableException("Cannot execute test. OtherP can already impersonate
UID-user.");
         }
@@ -232,7 +221,7 @@
         }
     }
 
-    public void testModifyGroupForParentUser() throws RepositoryException, NotExecutableException
{
+    public void testModifyGroup() throws RepositoryException, NotExecutableException {
         UserManager umgr = getUserManager(otherSession);
 
         User parentUser = (User) umgr.getAuthorizable(uID);
@@ -241,22 +230,19 @@
         } else {
             Group gr = getGroupAdminGroup(umgr);
             try {
-                assertFalse(gr.addMember(parentUser));
+                assertFalse("A UserAdmin must not be allowed to modify group memberships",
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(), buildPassword(cp));
             Group gr = getGroupAdminGroup(umgr);
             try {
-                assertFalse(gr.addMember(childU));
+                assertFalse("A UserAdmin must not be allowed to modify group memberships",
gr.addMember(childU));
             } catch (RepositoryException e) {
                 // success
             }
@@ -289,6 +275,22 @@
         }
     }
 
+    public void testRemoveGroup() throws NotExecutableException, RepositoryException {
+        UserManager umgr = getUserManager(otherSession);
+        Group g = null;
+        try {
+            g = userMgr.createGroup(getTestPrincipal());
+            umgr.getAuthorizable(g.getID()).remove();
+            fail("UserAdmin should not be allowed to remove a Group.");
+        } catch (RepositoryException e) {
+            // success.
+        } finally {
+            if (g != null) {
+                g.remove();
+            }
+        }
+    }
+
     public void testAddToGroup() throws NotExecutableException, RepositoryException {
         UserManager umgr = getUserManager(otherSession);
         Group gr = getGroupAdminGroup(umgr);
@@ -316,4 +318,22 @@
             // success
         }
     }
+
+    public void testPersisted() throws NotExecutableException, RepositoryException {
+        UserManager umgr = getUserManager(otherSession);
+        UserImpl u = null;
+        // create a new user -> must succeed.
+        try {
+            Principal p = getTestPrincipal();
+            u = (UserImpl) umgr.createUser(p.getName(), buildPassword(p));
+
+            Authorizable az = userMgr.getAuthorizable(u.getID());
+            assertNotNull(az);
+            assertEquals(u.getID(), az.getID());
+        } finally {
+            if (u != null) {
+                u.remove();
+            }
+        }
+    }
 }
\ No newline at end of file

Modified: 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=794702&r1=794701&r2=794702&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
Thu Jul 16 14:54:08 2009
@@ -98,24 +98,6 @@
         }
     }
 
-
-    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(), buildPassword(p));
-        String uID = u.getID();
-        p = getTestPrincipal();
-        User u2 = userMgr.createUser(p.getName(), buildPassword(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 testPrincipalNameEqualsUserID() throws RepositoryException {
         Principal p = getTestPrincipal();
         User u = null;



Mime
View raw message