1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.security;
18  
19  import java.security.Principal;
20  import java.util.Collection;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.ArrayList;
24  import java.util.prefs.Preferences;
25  import java.security.Principal;
26  
27  import javax.security.auth.Subject;
28  import javax.security.auth.login.LoginContext;
29  import javax.security.auth.login.LoginException;
30  
31  import junit.framework.Test;
32  import junit.framework.TestSuite;
33  
34  import org.apache.jetspeed.security.impl.PassiveCallbackHandler;
35  import org.apache.jetspeed.security.util.test.AbstractSecurityTestcase;
36  
37  /***
38   * <p>
39   * Unit testing for {@link UserManager}.
40   * </p>
41   * 
42   * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
43   */
44  public class TestUserManager extends AbstractSecurityTestcase
45  {
46  
47      /***
48       * @see junit.framework.TestCase#setUp()
49       */
50      protected void setUp() throws Exception
51      {
52          super.setUp();
53          destroyUserObject();
54      }
55  
56      /***
57       * @see junit.framework.TestCase#tearDown()
58       */
59      public void tearDown() throws Exception
60      {
61          destroyUserObject();
62          super.tearDown();
63      }
64  
65      public static Test suite()
66      {
67          return new TestSuite(TestUserManager.class);
68      }
69  
70      /***
71       * <p>
72       * Test add/remove user.
73       * </p>
74       */
75      public void testAddRemoveUser()
76      {
77          try
78          {
79              ums.addUser("anon", "password");
80          }
81          catch (SecurityException sex)
82          {
83              assertTrue("user already exists. exception caught: " + sex, false);
84          }
85  
86          try
87          {
88              ums.addUser("anon", "password");
89              assertTrue("user should already exists. exception not thrown.", false);
90          }
91          catch (SecurityException sex)
92          {
93          }
94          try
95          {
96              ums.removeUser("anon");
97          }
98          catch (SecurityException sex)
99          {
100             assertTrue("could not remove user. exception caught: " + sex, false);
101         }
102         if (ums.userExists("anon"))
103         {
104             assertTrue("user should have been removed: ", false);
105         }
106 
107     }
108 
109     /***
110      * <p>
111      * Test get user.
112      * </p>
113      */
114     public void testGetUser()
115     {
116         // Test when the user does not exist.
117         try
118         {
119             ums.getUser("test");
120             assertTrue("user does not exist. should have thrown an exception.", false);
121         }
122         catch (SecurityException sex)
123         {
124         }
125         // Test when the user exists.
126         User user = null;
127         try
128         {
129             ums.addUser("test", "password");
130             user = ums.getUser("test");
131         }
132         catch (SecurityException sex)
133         {
134             assertTrue("user exists. should not have thrown an exception.", false);
135         }
136         assertNotNull("user is null", user);
137         // Test the User JSSubject
138         Subject subject = user.getSubject();
139         assertNotNull("subject is null", subject);
140         // Asset user principal.
141         Principal userPrincipal = SecurityHelper.getPrincipal(subject, UserPrincipal.class);
142         assertNotNull("user principal is null", userPrincipal);
143         assertEquals("expected user principal full path == /user/test", "/user/test", SecurityHelper
144                 .getPreferencesFullPath(userPrincipal));
145         assertEquals("expected user principal name == test", "test", userPrincipal.getName());
146 
147         // Test the User Preferences.
148         Preferences preferences = user.getPreferences();
149         assertEquals("expected user node == /user/test", "/user/test", preferences.absolutePath());
150         
151         // Test if roles are inheritable to a user via groups
152         try
153         {
154             // If user 'inheritedUser' belongs to group 'inheritingGroup' and group 'group' has role 'assignedRole', then
155             // the role 'assignedRole' can be inherited to the user 'inheritedUser' via group 'inheritingGroup'.
156             
157             ums.addUser("inheritedUser", "password");
158             gms.addGroup("inheritingGroup");
159             gms.addUserToGroup("inheritedUser", "inheritingGroup");
160             rms.addRole("assignedRole");
161             rms.addRoleToGroup("assignedRole", "inheritingGroup");
162             User testUser = ums.getUser("inheritedUser");
163 
164             List principalNames = new ArrayList();
165             for (Iterator it = testUser.getSubject().getPrincipals().iterator(); it.hasNext(); )
166             {
167                 Principal p = (Principal) it.next();
168                 principalNames.add(p.getName());
169             }
170             
171             assertTrue("user is expected to have a user principal named inheritedUser.", principalNames.contains("inheritedUser"));
172             assertTrue("user is expected to have a group principal named inheritingGroup.", principalNames.contains("inheritingGroup"));
173             assertTrue("user is expected to have a role principal named assignedRole which is inherited via the group.", principalNames.contains("assignedRole"));
174             
175             // However, roles from role manager should not contain the role 'assignedRole'
176             // because the role 'assignedRole' is not directly assigned to user 'inheritedUser'.
177             // For example, the Users Admin portlet uses RoleManager to retrieve roles directly assigned to a user.
178             
179             List userRoleNames = new ArrayList();
180             for (Iterator it = rms.getRolesForUser("inheritedUser").iterator(); it.hasNext(); )
181             {
182                 Role role = (Role) it.next();
183                 userRoleNames.add(role.getPrincipal().getName());
184             }
185             
186             assertFalse("role 'assignedRole' is not expected to be retrieved because the role 'assignedRole' is not directly assigned to user 'inheritedUser'.", userRoleNames.contains("assignedRole"));
187         }
188         catch (SecurityException sex)
189         {
190             assertTrue("failed to test 'rolesInheritableViaGroups' mode in testGetUser(), " + sex, false);
191         }
192         finally
193         {
194             // Cleanup test.
195             try
196             {
197                 rms.removeRole("assignedRole");
198             }
199             catch (SecurityException sex)
200             {
201             }
202             
203             try
204             {
205                 gms.removeGroup("inheritingGroup");
206             }
207             catch (SecurityException sex)
208             {
209             }
210             
211             try
212             {
213                 ums.removeUser("inheritedUser");
214             }
215             catch (SecurityException sex)
216             {
217             }
218         }
219 
220     }
221 
222     /***
223      * <p>
224      * Test get users in role.
225      * </p>
226      */
227     public void testGetUsersInRole()
228     {
229         // Init test.
230         try
231         {
232             ums.addUser("anonuser3", "password");
233             ums.addUser("anonuser4", "password");
234             rms.addRole("testuserrolemapping");
235             rms.addRole("testuserrolemapping.role1");
236             rms.addRole("testuserrolemapping.role2");
237             rms.addRoleToUser("anonuser3", "testuserrolemapping");
238             rms.addRoleToUser("anonuser3", "testuserrolemapping.role1");
239             rms.addRoleToUser("anonuser3", "testuserrolemapping.role2");
240             rms.addRoleToUser("anonuser4", "testuserrolemapping");
241         }
242         catch (SecurityException sex)
243         {
244             assertTrue("failed to init testGetUsersInRole(), " + sex, false);
245         }
246 
247         try
248         {
249             Collection users = ums.getUsersInRole("testuserrolemapping");
250             assertEquals("users size should be == 2", 2, users.size());
251         }
252         catch (SecurityException sex)
253         {
254             assertTrue("role exists. should not have thrown an exception: " + sex, false);
255         }
256 
257         // Cleanup test.
258         try
259         {
260             ums.removeUser("anonuser3");
261             ums.removeUser("anonuser4");
262             rms.removeRole("testuserrolemapping");
263         }
264         catch (SecurityException sex)
265         {
266             assertTrue("could not remove user and role. exception caught: " + sex, false);
267         }
268     }
269 
270     /***
271      * <p>
272      * Test get users in group.
273      * </p>
274      */
275     public void testGetUsersInGroup()
276     {
277         // Init test.
278         try
279         {
280             ums.addUser("anonuser2", "password");
281             ums.addUser("anonuser3", "password");
282             ums.addUser("anonuser4", "password");
283             gms.addGroup("testgroup1");
284             gms.addGroup("testgroup1.group1");
285             gms.addUserToGroup("anonuser2", "testgroup1.group1");
286             gms.addUserToGroup("anonuser3", "testgroup1.group1");
287             gms.addUserToGroup("anonuser4", "testgroup1.group1");
288         }
289         catch (SecurityException sex)
290         {
291             assertTrue("failed to init testGetUsersInGroup(), " + sex, false);
292         }
293 
294         try
295         {
296             Collection users = ums.getUsersInGroup("testgroup1.group1");
297             assertEquals("users size should be == 3", 3, users.size());
298         }
299         catch (SecurityException sex)
300         {
301             assertTrue("group exists. should not have thrown an exception: " + sex, false);
302         }
303 
304         // Cleanup test.
305         try
306         {
307             ums.removeUser("anonuser2");
308             ums.removeUser("anonuser3");
309             ums.removeUser("anonuser4");
310             gms.removeGroup("testgroup1");
311         }
312         catch (SecurityException sex)
313         {
314             assertTrue("could not remove user and group. exception caught: " + sex, false);
315         }
316     }
317 
318     /***
319      * <p>
320      * Test set password.
321      * </p>
322      */
323     public void testSetPassword()
324     {
325         try
326         {
327             ums.addUser("anon", "password");
328             ums.setPassword("anon", "password", "newpassword");
329 
330             LoginContext loginContext = null;
331             // Test that the user can log in with the new password.
332             try
333             {
334                 PassiveCallbackHandler pch = new PassiveCallbackHandler("anon", "newpassword");
335                 loginContext = new LoginContext("Jetspeed", pch);
336                 loginContext.login();
337                 loginContext.logout();
338             }
339             catch (LoginException le)
340             {
341                 le.printStackTrace();
342                 assertTrue("failed to login user with new password.", false);
343             }
344         }
345         catch (SecurityException sex)
346         {
347         }
348     }
349 
350     /***
351      * <p>
352      * Test get users.
353      * </p>
354      * 
355      * @throws Exception Throws an exception.
356      */
357     public void testGetUsers() throws Exception
358     {
359         ums.addUser("one", "one-pw");
360         ums.addUser("two", "two-pw");
361         ums.addUser("three", "three-pw");
362         int count = 0;
363         Iterator it = ums.getUsers("");
364         while (it.hasNext())
365         {
366             User user = (User) it.next();
367             Iterator principals = user.getSubject().getPrincipals().iterator();
368             while (principals.hasNext())
369             {
370                 Principal principal = (Principal) principals.next();
371                 System.out.println("principal = " + principal.getName());
372                 if (principal.getName().equals("one"))
373                 {
374                     count++;
375                 }
376                 else if (principal.getName().equals("two"))
377                 {
378                     count++;
379                 }
380                 else if (principal.getName().equals("three"))
381                 {
382                     count++;
383                 }
384             }
385         }
386         assertTrue("user count should be 3", count == 3);
387         ums.removeUser("one");
388         ums.removeUser("two");
389         ums.removeUser("three");
390     }
391 
392     /***
393      * <p>
394      * Destroy user test object.
395      * </p>
396      */
397     protected void destroyUserObject()
398     {
399         try
400         {
401             if (ums.userExists("anon"))
402                 ums.removeUser("anon");
403             if (ums.userExists("test"))
404                 ums.removeUser("test");
405         }
406         catch (SecurityException sex)
407         {
408             System.out.println("could not remove test users. exception caught: " + sex);
409         }
410     }
411 
412 }