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