(no commit message)
[utils] / security / usermgt / src / test / java / org / wamblee / security / authentication / UserAdministrationImplTest.java
1 /*
2  * Copyright 2005-2010 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.security.authentication;
17
18 import java.util.List;
19
20 import junit.framework.TestCase;
21
22 import org.apache.log4j.Logger;
23 import org.wamblee.security.authentication.UserMgtException.Reason;
24 import org.wamblee.security.encryption.Md5HexMessageDigester;
25
26 /**
27  * Test of user administration implementation.
28  * 
29  * @author Erik Brakkee
30  */
31 public class UserAdministrationImplTest extends TestCase {
32     private static final Logger LOGGER = Logger
33         .getLogger(UserAdministrationImplTest.class);
34
35     private static final String USER1 = "piet";
36
37     private static final String PASS1 = "passpiet";
38
39     private static final String USER2 = "kees";
40
41     private static final String PASS2 = "passkees";
42
43     private static final String GROUP1 = "cyclists";
44
45     private static final String GROUP2 = "runners";
46
47     private UserAdministration admin;
48
49     /*
50      * (non-Javadoc)
51      * 
52      * @see junit.framework.TestCase#setUp()
53      */
54     @Override
55     protected void setUp() throws Exception {
56         super.setUp();
57         admin = createAdmin();
58     }
59
60     protected UserAdministration createAdmin() {
61         UserSet users = new InMemoryUserSet(new RegexpNameValidator(
62             RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD,
63             "Password must contain at least 6 characters"),
64             new Md5HexMessageDigester());
65         GroupSet groups = new InMemoryGroupSet();
66
67         return new UserAdministrationImpl(users, groups,
68             new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
69                 Reason.INVALID_USERNAME, "Invalid user"),
70             new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
71                 Reason.INVALID_GROUPNAME, "Invalid group"));
72     }
73
74     // Construction
75
76     /**
77      * Constructs the admin, verify it contains no users and no groups.
78      */
79     public void testConstruct() {
80         assertEquals(0, admin.getUsers().size());
81         assertEquals(0, admin.getGroups().size());
82         assertEquals(0, admin.getUserCount());
83         assertEquals(0, admin.getGroupCount());
84     }
85
86     // Basic user admin:
87     // void createUser(String aUser, String aPassword);
88     // boolean checkUser(String aUser);
89     // int getUserCount();
90     // List<String> getUsers();
91     // void renameUser(String aOldUserName, String aUserName);
92     // void removeUser(String aUser);
93     public void testCreateUser() {
94         assertFalse(admin.checkUser(USER1));
95         admin.createUser(USER1, PASS1);
96         assertTrue(admin.checkUser(USER1));
97         assertEquals(1, admin.getUserCount());
98         assertTrue(admin.checkPassword(USER1, PASS1));
99         assertFalse(admin.checkPassword(USER1, PASS2));
100     }
101
102     public void testCreateDuplicateUser() {
103         admin.createUser(USER1, PASS1);
104
105         try {
106             admin.createUser(USER1, PASS2);
107             fail();
108         } catch (UserMgtException e) {
109             assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
110             assertEquals(1, admin.getUserCount());
111         }
112     }
113
114     /**
115      * Constructs users with invalid names. Verifies that the appropriate
116      * exception is thrown.
117      * 
118      */
119     public void testCreateInvalidUserName() throws UserMgtException {
120         createInvalidUser("");
121         createInvalidUser("0abc"); // should not start with digits
122         createInvalidUser("a b"); // should not contain spaces
123         createInvalidUser(" aa");
124         createInvalidUser("aa ");
125     }
126
127     public void testRenameUser() {
128         admin.createUser(USER1, PASS1);
129         admin.renameUser(USER1, USER2);
130         List<String> users = admin.getUsers();
131         assertEquals(1, users.size());
132         assertTrue(users.contains(USER2));
133     }
134
135     public void testRenameUserInvalidUsername() {
136         admin.createUser(USER1, PASS1);
137         try {
138             admin.renameUser(USER1, "a b");
139             fail();
140         } catch (UserMgtException e) {
141             assertEquals(e.getReason(), Reason.INVALID_USERNAME);
142         }
143     }
144
145     public void testRenameUserToItself() {
146         admin.createUser(USER1, PASS1);
147         admin.renameUser(USER1, USER1);
148         assertTrue(admin.checkUser(USER1));
149     }
150
151     public void testRenameUserDuplicateUser() {
152         admin.createUser(USER1, PASS1);
153         admin.createUser(USER2, PASS2);
154         try {
155             admin.renameUser(USER1, USER2);
156             fail();
157         } catch (UserMgtException e) {
158             assertEquals(e.getReason(), Reason.DUPLICATE_USER);
159         }
160     }
161
162     // Basic group admin:
163     // void createGroup(String aName);
164     // boolean checkGroup(String aGroup);
165     // int getGroupCount();
166     // List<String> getGroups();
167
168     public void testCreateGroup() {
169         admin.createGroup(GROUP1);
170         List<String> groups = admin.getGroups();
171         assertEquals(1, groups.size());
172         assertEquals(1, admin.getGroupCount());
173         assertTrue(groups.contains(GROUP1));
174     }
175
176     public void testCreateGroupInvalidName() {
177         createInvalidGroup("");
178         createInvalidGroup("0abc"); // should not start with digits
179         createInvalidGroup("a b"); // should not contain spaces
180         createInvalidGroup(" aa");
181         createInvalidGroup("aa ");
182     }
183
184     public void testCreateGroupDuplicateGroup() {
185         admin.createGroup(GROUP1);
186
187         try {
188             admin.createGroup(GROUP1);
189         } catch (UserMgtException e) {
190             assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
191             assertEquals(1, admin.getGroupCount());
192
193             return;
194         }
195
196         fail();
197     }
198
199     // Passwords.
200     // boolean checkPassword(String aUser, String aPassword);
201     // boolean changePassword(String aUser, String aOldPassword, String
202     // aNewPassword);
203     // void setPassword(String aUser, String aPassword);
204
205     public void testChangePassword() {
206         admin.createUser(USER1, PASS1);
207         boolean changed = admin.changePassword(USER1, PASS1, PASS2);
208         assertTrue(changed);
209         assertTrue(admin.checkPassword(USER1, PASS2));
210         assertFalse(admin.checkPassword(USER1, PASS1));
211     }
212
213     public void testChangePasswordWrongPassword() {
214         admin.createUser(USER1, PASS1);
215         boolean changed = admin.changePassword(USER1, PASS2, PASS1);
216         assertFalse(changed);
217         assertFalse(admin.checkPassword(USER1, PASS2));
218         assertTrue(admin.checkPassword(USER1, PASS1));
219     }
220
221     public void testChangePasswordUnknownUser() {
222         admin.createUser(USER1, PASS1);
223         try {
224             boolean changed = admin.changePassword(USER1 + "unknown", PASS2,
225                 PASS1);
226         } catch (UserMgtException e) {
227             assertEquals(e.getReason(), Reason.UNKNOWN_USER);
228         }
229     }
230
231     public void testSetPassword() {
232         admin.createUser(USER1, PASS1);
233         admin.setPassword(USER1, PASS2);
234         assertTrue(admin.checkPassword(USER1, PASS2));
235         assertFalse(admin.checkPassword(USER1, PASS1));
236     }
237
238     public void testSetPasswordUnknownUser() {
239         admin.createUser(USER1, PASS1);
240         try {
241             admin.setPassword(USER1 + "unknown", PASS2);
242         } catch (UserMgtException e) {
243             assertEquals(e.getReason(), Reason.UNKNOWN_USER);
244         }
245     }
246
247     // Group membership
248     // boolean isInGroup(String aUser, String aGroup);
249     // List<String> getUsers(String aGroup);
250     // void addUserToGroup(String aUser, String aGroup);
251     // void removeUserFromGroup(String aUser, String aGroup);}
252
253     public void testAddUserToGroup() {
254         admin.createUser(USER1, PASS1);
255         assertFalse(admin.isInGroup(USER1, GROUP1));
256         admin.createGroup(GROUP1);
257         admin.addUserToGroup(USER1, GROUP1);
258         assertTrue(admin.isInGroup(USER1, GROUP1));
259         List<String> users = admin.getUsers(GROUP1);
260         assertEquals(1, users.size());
261         assertTrue(users.contains(USER1));
262     }
263
264     public void testMultipleGroups() {
265         admin.createUser(USER1, PASS1);
266         admin.createGroup(GROUP1);
267         admin.createGroup(GROUP2);
268         assertFalse(admin.isInGroup(USER1, GROUP1));
269         assertFalse(admin.isInGroup(USER1, GROUP2));
270         admin.addUserToGroup(USER1, GROUP1);
271         admin.addUserToGroup(USER1, GROUP2);
272         assertTrue(admin.isInGroup(USER1, GROUP1));
273         assertTrue(admin.isInGroup(USER1, GROUP2));
274     }
275
276     public void testAddUserToGroupUnknownUser() {
277         admin.createGroup(GROUP2);
278         try {
279             admin.addUserToGroup(USER1, GROUP2);
280         } catch (UserMgtException e) {
281             assertEquals(e.getReason(), Reason.UNKNOWN_USER);
282         }
283
284     }
285
286     public void testAddUserToGroupUnknownGroup() {
287         admin.createUser(USER1, PASS1);
288         try {
289             admin.addUserToGroup(USER1, GROUP2);
290         } catch (UserMgtException e) {
291             assertEquals(e.getReason(), Reason.UNKNOWN_GROUP);
292         }
293     }
294
295     public void testRemoveUserFromGroup() {
296         admin.createUser(USER1, GROUP1);
297         admin.createGroup(GROUP1);
298         admin.addUserToGroup(USER1, GROUP1);
299         assertTrue(admin.isInGroup(USER1, GROUP1));
300         admin.removeUserFromGroup(USER1, GROUP1);
301         assertFalse(admin.isInGroup(USER1, GROUP1));
302     }
303
304     public void testRemoveUserFromGroupUserNotInGroup() {
305         admin.createUser(USER1, GROUP1);
306         admin.createGroup(GROUP1);
307         admin.createGroup(GROUP2);
308         admin.addUserToGroup(USER1, GROUP1);
309         try {
310             admin.removeUserFromGroup(USER1, GROUP2);
311             fail();
312         } catch (UserMgtException e) {
313             assertEquals(Reason.USER_NOT_IN_GROUP, e.getReason());
314         }
315     }
316
317     public void testRemoveUserFromGroupUnknowUser() {
318         admin.createGroup(GROUP1);
319         try {
320             admin.removeUserFromGroup(USER1, GROUP2);
321             fail();
322         } catch (UserMgtException e) {
323             assertEquals(Reason.UNKNOWN_USER, e.getReason());
324         }
325     }
326
327     public void testRemoveUserFromGroupUnknownGroup() {
328         admin.createUser(USER1, PASS1);
329         try {
330             admin.removeUserFromGroup(USER1, GROUP2);
331             fail();
332         } catch (UserMgtException e) {
333             assertEquals(Reason.UNKNOWN_GROUP, e.getReason());
334         }
335     }
336
337     // void renameGroup(String aOldGroup, String aGroupName)
338
339     public void testRenameGroup() {
340         admin.createUser(USER1, PASS1);
341         admin.createGroup(GROUP1);
342         admin.addUserToGroup(USER1, GROUP1);
343         admin.renameGroup(GROUP1, GROUP2);
344         List<String> groups = admin.getGroups();
345         assertEquals(1, groups.size());
346         assertTrue(groups.contains(GROUP2));
347         assertTrue(admin.isInGroup(USER1, GROUP2));
348         assertFalse(admin.isInGroup(USER1, GROUP1));
349     }
350
351     public void testRenameGroupGroupNameInvalid() {
352         admin.createGroup(GROUP1);
353         try {
354             admin.renameGroup(GROUP1, "a b");
355             fail();
356         } catch (UserMgtException e) {
357             assertEquals(Reason.INVALID_GROUPNAME, e.getReason());
358         }
359     }
360
361     public void testRenameGroupGroupAlreadyExists() {
362         admin.createGroup(GROUP1);
363         admin.createGroup(GROUP2);
364         try {
365             admin.renameGroup(GROUP1, GROUP2);
366             fail();
367         } catch (UserMgtException e) {
368             assertEquals(Reason.DUPLICATE_GROUP, e.getReason());
369         }
370     }
371
372     // void removeGroup(String aGroup);
373
374     public void testRemoveGroup() {
375         admin.createGroup(GROUP1);
376         admin.removeGroup(GROUP1);
377         List<String> groups = admin.getGroups();
378         assertEquals(0, groups.size());
379     }
380
381     public void testRemoveGroupGroupDoesNotExist() {
382         try {
383             admin.removeGroup(GROUP1);
384             fail();
385         } catch (UserMgtException e) {
386             assertEquals(e.getReason(), Reason.UNKNOWN_GROUP);
387         }
388     }
389
390     public void testRemoveGroupButStillUsersInGroup() {
391         admin.createUser(USER1, PASS1);
392         admin.createGroup(GROUP1);
393         admin.addUserToGroup(USER1, GROUP1);
394         try {
395             admin.removeGroup(GROUP1);
396         } catch (UserMgtException e) {
397             assertEquals(e.getReason(), Reason.GROUP_STILL_OCCUPIED);
398         }
399     }
400
401     private void createInvalidGroup(String aUsername) {
402         try {
403             admin.createGroup(aUsername);
404             fail();
405         } catch (UserMgtException e) {
406             assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e
407                 .getReason());
408             assertEquals(0, admin.getGroupCount());
409         }
410     }
411
412     private void createInvalidUser(String aUsername) {
413         try {
414             admin.createUser(aUsername, "pass");
415             fail();
416         } catch (UserMgtException e) {
417             assertEquals(UserMgtException.Reason.INVALID_USERNAME, e
418                 .getReason());
419             assertEquals(0, admin.getUserCount());
420         }
421     }
422
423     /**
424      * Gets the list of users and groups. Verifies that the correct suers and
425      * groups are returned. Verifies also that the relations from user to group
426      * are correct.
427      * 
428      */
429     public void testGetUsersAndGroups() throws UserMgtException {
430         admin.createGroup(GROUP1);
431         admin.createGroup(GROUP2);
432
433         admin.createUser(USER1, PASS1);
434         admin.addUserToGroup(USER1, GROUP1);
435         admin.addUserToGroup(USER1, GROUP2);
436
437         admin.createUser(USER2, PASS2);
438         admin.addUserToGroup(USER2, GROUP2);
439
440         List<String> users = admin.getUsers();
441         assertEquals(2, users.size());
442         assertTrue(users.contains(USER1));
443         assertTrue(users.contains(USER2));
444
445         List<String> groups = admin.getGroups();
446         assertEquals(2, groups.size());
447         assertTrue(groups.contains(GROUP1));
448         assertTrue(groups.contains(GROUP2));
449
450         assertTrue(admin.isInGroup(USER1, GROUP1));
451         assertTrue(admin.isInGroup(USER1, GROUP2));
452         assertFalse(admin.isInGroup(USER2, GROUP1));
453         assertTrue(admin.isInGroup(USER2, GROUP2));
454
455         List<String> groups1 = admin.getGroups(USER1);
456         assertEquals(2, groups1.size());
457
458         List<String> groups2 = admin.getGroups(USER2);
459         assertEquals(1, groups2.size());
460     }
461
462     /**
463      * Performance test. Finds a user by name.
464      * 
465      */
466     public void testPerformanceFindUserByName() throws UserMgtException {
467         admin.createGroup(GROUP1);
468         admin.createUser(USER1, PASS1);
469         admin.addUserToGroup(USER1, GROUP1);
470
471         int n = 1000;
472         long time = System.currentTimeMillis();
473
474         for (int i = 0; i < n; i++) {
475             admin.checkUser(USER1);
476         }
477
478         LOGGER.info("Looked up a user " + n + " times in " +
479             ((float) (System.currentTimeMillis() - time) / 1000.0));
480     }
481 }