2 * Copyright 2005 the original author or authors.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.wamblee.usermgt;
21 import org.apache.log4j.Logger;
22 import org.wamblee.persistence.hibernate.HibernateMappingFiles;
23 import org.wamblee.security.encryption.Md5HexMessageDigester;
24 import org.wamblee.test.SpringConfigFiles;
25 import org.wamblee.test.SpringTestCase;
26 import org.wamblee.usermgt.UserMgtException.Reason;
29 * Test of user administration implementation.
31 public class UserAdministrationImplTest extends SpringTestCase {
33 private static final Logger LOGGER = Logger
34 .getLogger(UserAdministrationImplTest.class);
36 private static final String USER1 = "piet";
38 private static final String PASS1 = "passpiet";
40 private static final String USER2 = "kees";
42 private static final String PASS2 = "passkees";
44 private static final String GROUP1 = "cyclists";
46 private static final String GROUP2 = "runners";
48 private UserAdministration _admin;
50 public UserAdministrationImplTest() {
51 super(SpringConfigFiles.class, HibernateMappingFiles.class);
54 public UserAdministrationImplTest(
55 Class<? extends SpringConfigFiles> aSprings,
56 Class<? extends HibernateMappingFiles> aMappings) {
57 super(aSprings, aMappings);
63 * @see junit.framework.TestCase#setUp()
66 protected void setUp() throws Exception {
68 _admin = createAdmin();
71 protected UserAdministration createAdmin() {
72 UserSet users = new InMemoryUserSet( new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"),
73 new Md5HexMessageDigester());
74 GroupSet groups = new InMemoryGroupSet();
75 return new UserAdministrationImpl(users, groups,
76 new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
77 Reason.INVALID_USERNAME, "Invalid user"),
78 new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
79 Reason.INVALID_GROUPNAME, "Invalid group"));
82 protected User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException {
83 return UsermgtTestUtils.createUser(aName, aPassword, aGroup);
87 * Constructs the admin, verify it contains no users and no groups.
89 public void testConstruct() {
90 assertEquals(0, _admin.getUsers().size());
91 assertEquals(0, _admin.getGroups().size());
92 assertEquals(0, _admin.getUserCount());
93 assertEquals(0, _admin.getGroupCount());
97 * Creates a new group. Verifies the group is created correctly and that the
101 public void testCreateGroup() throws UserMgtException {
102 Group group = _admin.createGroup(GROUP1);
103 assertNotNull(group);
104 assertEquals(GROUP1, group.getName());
106 Set<Group> groups = _admin.getGroups();
107 assertEquals(1, groups.size());
108 assertEquals(1, _admin.getGroupCount());
109 assertTrue(groups.contains(group));
112 private void createInvalidGroup(String aUsername) {
114 _admin.createGroup(aUsername);
116 } catch (UserMgtException e) {
117 assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e
119 assertEquals(0, _admin.getGroupCount());
124 * Creates a new group with an invalid name. Verifies that the appropriate
125 * exception is thrown.
127 * @throws UserMgtException
129 public void testCreateInvalidGroupName() throws UserMgtException {
130 createInvalidGroup("");
131 createInvalidGroup("0abc"); // should not start with digits
132 createInvalidGroup("a b"); // should not contain spaces
133 createInvalidGroup(" aa");
134 createInvalidGroup("aa ");
138 * Creates a new group which conflicts with an existing one. Verifies that
139 * the UserMgtException is thrown and that no group is added.
142 public void testCreateDuplicateGroup() throws UserMgtException {
143 _admin.createGroup(GROUP1);
145 _admin.createGroup(GROUP1);
146 } catch (UserMgtException e) {
147 assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
148 assertEquals(1, _admin.getGroupCount());
155 * Creates a new user. Verifies the user is created correctly and that the
159 public void testCreateUser() throws UserMgtException {
160 Group group = _admin.createGroup(GROUP1);
161 User user = _admin.createUser(USER1, PASS1, group);
163 assertEquals(USER1, user.getName());
164 user.checkPassword(PASS1);
166 Set<User> users = _admin.getUsers();
167 assertEquals(1, users.size());
168 assertEquals(1, _admin.getUserCount());
169 assertTrue(users.contains(user));
172 private void createInvalidUser(String aUsername, Group aGroup) {
174 _admin.createUser(aUsername, "pass", aGroup);
176 } catch (UserMgtException e) {
177 assertEquals(UserMgtException.Reason.INVALID_USERNAME, e
179 assertEquals(0, _admin.getUserCount());
184 * Constructs users with invalid names. Verifies that the appropriate
185 * exception is thrown.
188 public void testCreateInvalidUserName() throws UserMgtException {
189 Group group = _admin.createGroup(GROUP1);
190 createInvalidUser("", group);
191 createInvalidUser("0abc", group); // should not start with digits
192 createInvalidUser("a b", group); // should not contain spaces
193 createInvalidUser(" aa", group);
194 createInvalidUser("aa ", group);
198 * Creates a new user which conflicts with an existing one. Verifies that
199 * the UserMgtException is thrown and that no user is added.
202 public void testCreateDuplicateUser() throws UserMgtException {
203 Group group = _admin.createGroup(GROUP1);
204 _admin.createUser(USER1, PASS1, group);
206 _admin.createUser(USER1, PASS2, group);
208 } catch (UserMgtException e) {
209 assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
210 assertEquals(1, _admin.getUserCount());
215 * Gets a known user by name. Verifies the correct user is obtained.
216 * Verifies that null is returned when trying to obtain an unknown user.
219 public void testGetUser() throws UserMgtException {
220 Group group = _admin.createGroup(GROUP1);
221 User user = _admin.createUser(USER1, PASS1, group);
222 User user2 = _admin.getUser(USER1);
223 assertTrue(user.equals(user2));
224 assertNull(_admin.getUser(USER2));
228 * Gets a known group by name. Verifies the correct group is obtained.
229 * Verifies that null is returned when the group is not known.
232 public void testGetGroup() throws UserMgtException {
233 Group group = _admin.createGroup(GROUP1);
234 Group group2 = _admin.getGroup(GROUP1);
235 assertTrue(group.equals(group2));
236 assertNull(_admin.getGroup(GROUP2));
240 * Adds a user to a group. Verifies that the user is added using several API
241 * calls. Verifies that an exception occurs if the user is not already part
245 public void testAddUserToGroup() throws UserMgtException {
247 Group group = _admin.createGroup(GROUP1);
248 User user = _admin.createUser(USER1, PASS1, group);
249 Group group2 = _admin.createGroup(GROUP2);
250 assertTrue(user.isInGroup(group));
251 assertFalse(user.isInGroup(group2));
252 _admin.addUserToGroup(user, group2);
253 assertTrue(user.isInGroup(group));
254 assertTrue(user.isInGroup(group2));
255 Set<User> users = _admin.getUsers(group2);
256 assertNotNull(users);
257 assertEquals(1, users.size());
258 assertTrue(users.contains(user));
261 _admin.addUserToGroup(user, group);
262 } catch (UserMgtException e) {
263 assertEquals(UserMgtException.Reason.USER_ALREADY_IN_GROUP, e
271 * Adds a user to a group where the user does not exist. Verifies that an
275 public void testAddUserToGroupUnknownUser() throws UserMgtException {
276 Group group = _admin.createGroup(GROUP1);
277 User user = createUser(USER1, PASS1, group);
279 _admin.addUserToGroup(user, group);
280 } catch (UserMgtException e) {
281 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
288 * Adds a user to a group where the user does not exist. Verifies that an
292 public void testAddUserToGroupUnknownGroup() throws UserMgtException {
293 Group group = _admin.createGroup(GROUP1);
294 User user = _admin.createUser(USER1, PASS1, group);
295 Group group2 = new Group(GROUP2);
297 _admin.addUserToGroup(user, group2);
298 } catch (UserMgtException e) {
299 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
306 * Removes a user from a group. Verifies that the user is removed from the
307 * group using several API calls. Verifies that an exception occurs if the
308 * user not part of the group or if the user is only part of one group.
310 public void testRemoveUserFromGroup() throws UserMgtException {
311 Group group = _admin.createGroup(GROUP1);
313 User user = _admin.createUser(USER1, PASS1, group);
314 Group group2 = _admin.createGroup(GROUP2);
315 _admin.addUserToGroup(user, group2);
316 Set<Group> groups = user.getGroups();
317 assertEquals(2, groups.size());
318 assertTrue(groups.contains(group));
319 assertTrue(groups.contains(group2));
321 _admin.removeUserFromGroup(user, group);
322 groups = user.getGroups();
323 assertEquals(1, groups.size());
324 assertTrue(groups.contains(group2));
325 assertFalse(groups.contains(group));
329 * Removes a user from a group where the user is not known. Verifies that an
330 * exception is thrown.
333 public void testRemoveUserFromGroupUnknownUser() throws UserMgtException {
334 Group group = _admin.createGroup(GROUP1);
335 User user = createUser(USER1, GROUP1, group);
337 _admin.removeUserFromGroup(user, group);
338 } catch (UserMgtException e) {
339 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
344 * Removes a user from a group where the group is not known. Verifies that
345 * an exception is thrown.
348 public void testRemoveUserFromGroupUnknownGroup() throws UserMgtException {
349 Group group = _admin.createGroup(GROUP1);
350 User user = _admin.createUser(USER1, PASS1, group);
351 Group group2 = new Group(GROUP2);
353 _admin.removeUserFromGroup(user, group2);
354 } catch (UserMgtException e) {
355 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
360 * Removes a user from a group where the user is only part of one group.
361 * Verifies that an exception is thrown.
363 public void testRemoveUserFromGroupOnlyGroup() throws UserMgtException {
364 Group group = _admin.createGroup(GROUP1);
365 User user = _admin.createUser(USER1, PASS1, group);
367 _admin.removeUserFromGroup(user, group);
368 } catch (UserMgtException e) {
369 assertEquals(UserMgtException.Reason.USER_MUST_BE_IN_A_GROUP, e
375 * Gets the list of users and groups. Verifies that the correct suers and
376 * groups are returned. Verifies also that the relations from user to group
380 public void testGetUsersAndGroups() throws UserMgtException {
381 Group group1 = _admin.createGroup(GROUP1);
382 Group group2 = _admin.createGroup(GROUP2);
384 User user1 = _admin.createUser(USER1, PASS1, group1);
385 _admin.addUserToGroup(user1, group2);
386 User user2 = _admin.createUser(USER2, PASS2, group2);
388 Set<User> users = _admin.getUsers();
389 assertEquals(2, users.size());
390 assertTrue(users.contains(user1));
391 assertTrue(users.contains(user2));
393 Set<Group> groups = _admin.getGroups();
394 assertEquals(2, groups.size());
395 assertTrue(groups.contains(group1));
396 assertTrue(groups.contains(group2));
398 assertTrue(user1.isInGroup(group1));
399 assertTrue(user1.isInGroup(group2));
400 assertFalse(user2.isInGroup(group1));
401 assertTrue(user2.isInGroup(group2));
403 Set<Group> groups1 = user1.getGroups();
404 assertEquals(2, groups1.size());
406 Set<Group> groups2 = user2.getGroups();
407 assertEquals(1, groups2.size());
411 * Renames a user. Verifies that the user is renamed. Verifies that
412 * exceptions are thrown when an attempt is made to rename the user to
413 * itself or to another existing user, or when the group does not exist.
416 public void testRenameUser() throws UserMgtException {
417 Group group = _admin.createGroup(GROUP1);
418 User user1 = _admin.createUser(USER1, PASS1, group);
419 _admin.renameUser(user1, USER2);
420 assertEquals(USER2, user1.getName());
421 assertEquals(user1, _admin.getUser(USER2));
423 _admin.createUser(USER1, PASS1, group);
426 _admin.renameUser(user1, USER1);
427 } catch (UserMgtException e) {
428 assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
430 // do a trivial reanem
432 _admin.renameUser(user1, user1.getName());
433 } catch (UserMgtException e2) {
434 assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
444 * Renames a user to a user with an invalid username. Verifies that the
445 * appropriate exception is thrown.
448 public void testRenameUserInvalidUsername() throws UserMgtException {
449 Group group = _admin.createGroup(GROUP1);
450 User user1 = _admin.createUser(USER1, PASS1, group);
452 _admin.renameUser(user1, USER2);
453 } catch (UserMgtException e) {
454 assertEquals(e.getReason(), Reason.INVALID_USERNAME);
459 * Renames a group. Verifies that the group is renamed. Verifies that
460 * exceptions are thrown when an attempt is made to rename the group to
461 * itself or to another existing group or when the group does not exist.
464 public void testRenameGroup() throws UserMgtException {
465 Group group = _admin.createGroup(GROUP1);
466 _admin.renameGroup(group, GROUP2);
467 assertEquals(GROUP2, group.getName());
468 assertEquals(group, _admin.getGroup(GROUP2));
470 _admin.createGroup(GROUP1);
472 _admin.renameGroup(group, GROUP1);
473 } catch (UserMgtException e) {
474 assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
476 // do a trivial reanem
478 _admin.renameGroup(group, group.getName());
479 } catch (UserMgtException e2) {
480 assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
491 * Renames a group to a group with an invalid name. Verifies that the
492 * appropriate exception is thrown.
495 public void testRenameGroupInvalidGroupname() throws UserMgtException {
496 Group group = _admin.createGroup(GROUP1);
498 _admin.renameGroup(group, "a b");
499 } catch (UserMgtException e) {
500 assertEquals(e.getReason(), Reason.INVALID_GROUPNAME);
505 * Removes a user. Verifies that the user is removed. Verifies that the an
506 * exception is thrown when the user does not exist.
509 public void testRemoveUser() throws UserMgtException {
510 Group group = _admin.createGroup(GROUP1);
511 User user = _admin.createUser(USER1, PASS1, group);
513 assertEquals(1, _admin.getUserCount());
514 _admin.removeUser(user);
515 assertEquals(0, _admin.getUserCount());
517 _admin.createUser(USER1, PASS1, group);
518 assertEquals(1, _admin.getUserCount());
520 User user2 = createUser(USER2, PASS2, group);
523 _admin.removeUser(user2);
524 } catch (UserMgtException e) {
525 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
530 * Removes a group. Verifies that the group is removed. Verifies that the an
531 * exception is thrown when the group does not exist or if there are still
532 * users in the group.
535 public void testRemoveGroup() throws UserMgtException {
536 Group group1 = _admin.createGroup(GROUP1);
537 assertEquals(1, _admin.getGroupCount());
538 _admin.removeGroup(group1);
539 assertEquals(0, _admin.getGroupCount());
540 group1 = _admin.createGroup(GROUP1);
542 _admin.createUser(USER1, PASS1, group1);
544 _admin.removeGroup(group1);
545 } catch (UserMgtException e) {
546 assertEquals(UserMgtException.Reason.GROUP_STILL_OCCUPIED, e
554 * Tries to remove an unknown group. Verifies that an exception is thrown.
557 public void testRemoveGroupUnknownGroup() throws UserMgtException {
558 Group group = _admin.createGroup(GROUP1);
559 Group group2 = new Group(GROUP2);
561 _admin.removeGroup(group2);
562 } catch (UserMgtException e) {
563 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
568 * Changes the password, verifies that this succeeds.
570 * @throws UserMgtException
572 public void testChangePassword() throws UserMgtException {
573 Group group = _admin.createGroup(GROUP1);
574 User user = _admin.createUser(USER1, PASS1, group);
575 user.changePassword(PASS1, PASS2);
577 // retrieve the user and verifies the password hasn't changed.
578 User user2 = _admin.getUser(USER1);
580 user2.checkPassword(PASS2);
581 fail(); // password should not have changed already.
582 } catch (UserMgtException e) {
586 // now notify the admin of the change in the user
587 _admin.userModified(user);
589 user2 = _admin.getUser(USER1);
590 user2.checkPassword(PASS2); // this time it should succeed.
595 * Performance test. Finds a user by name.
598 public void testPerformanceFindUserByName() throws UserMgtException {
599 Group group = _admin.createGroup(GROUP1);
600 _admin.createUser(USER1, PASS1, group);
603 long time = System.currentTimeMillis();
604 for (int i = 0; i < n; i++) {
605 _admin.getUser(USER1);
607 LOGGER.info("Looked up a user " + n + " times in "
608 + (float) (System.currentTimeMillis() - time) / 1000.0);