2 * Copyright 2005-2010 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.
16 package org.wamblee.security.authentication;
18 import junit.framework.TestCase;
20 import org.apache.log4j.Logger;
22 import org.wamblee.security.authentication.Group;
23 import org.wamblee.security.authentication.GroupSet;
24 import org.wamblee.security.authentication.InMemoryGroupSet;
25 import org.wamblee.security.authentication.InMemoryUserSet;
26 import org.wamblee.security.authentication.RegexpNameValidator;
27 import org.wamblee.security.authentication.User;
28 import org.wamblee.security.authentication.UserAdministration;
29 import org.wamblee.security.authentication.UserAdministrationImpl;
30 import org.wamblee.security.authentication.UserMgtException;
31 import org.wamblee.security.authentication.UserSet;
32 import org.wamblee.security.authentication.UserMgtException.Reason;
33 import org.wamblee.security.encryption.Md5HexMessageDigester;
39 * Test of user administration implementation.
41 * @author Erik Brakkee
43 public class UserAdministrationImplTest extends TestCase {
44 private static final Logger LOGGER = Logger
45 .getLogger(UserAdministrationImplTest.class);
47 private static final String USER1 = "piet";
49 private static final String PASS1 = "passpiet";
51 private static final String USER2 = "kees";
53 private static final String PASS2 = "passkees";
55 private static final String GROUP1 = "cyclists";
57 private static final String GROUP2 = "runners";
59 private UserAdministration admin;
64 * @see junit.framework.TestCase#setUp()
67 protected void setUp() throws Exception {
69 admin = createAdmin();
72 protected UserAdministration createAdmin() {
73 UserSet users = new InMemoryUserSet(new RegexpNameValidator(
74 RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD,
75 "Password must contain at least 6 characters"),
76 new Md5HexMessageDigester());
77 GroupSet groups = new InMemoryGroupSet();
79 return new UserAdministrationImpl(users, groups,
80 new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
81 Reason.INVALID_USERNAME, "Invalid user"),
82 new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
83 Reason.INVALID_GROUPNAME, "Invalid group"));
86 protected User createUser(String aName, String aPassword, Group aGroup)
87 throws UserMgtException {
88 return UsermgtTestUtils.createUser(aName, aPassword, aGroup);
92 * Constructs the admin, verify it contains no users and no groups.
94 public void testConstruct() {
95 assertEquals(0, admin.getUsers().size());
96 assertEquals(0, admin.getGroups().size());
97 assertEquals(0, admin.getUserCount());
98 assertEquals(0, admin.getGroupCount());
102 * Creates a new group. Verifies the group is created correctly and that the
106 public void testCreateGroup() throws UserMgtException {
107 Group group = admin.createGroup(GROUP1);
108 assertNotNull(group);
109 assertEquals(GROUP1, group.getName());
111 Set<Group> groups = admin.getGroups();
112 assertEquals(1, groups.size());
113 assertEquals(1, admin.getGroupCount());
114 assertTrue(groups.contains(group));
117 private void createInvalidGroup(String aUsername) {
119 admin.createGroup(aUsername);
121 } catch (UserMgtException e) {
122 assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e
124 assertEquals(0, admin.getGroupCount());
129 * Creates a new group with an invalid name. Verifies that the appropriate
130 * exception is thrown.
132 * @throws UserMgtException
134 public void testCreateInvalidGroupName() throws UserMgtException {
135 createInvalidGroup("");
136 createInvalidGroup("0abc"); // should not start with digits
137 createInvalidGroup("a b"); // should not contain spaces
138 createInvalidGroup(" aa");
139 createInvalidGroup("aa ");
143 * Creates a new group which conflicts with an existing one. Verifies that
144 * the UserMgtException is thrown and that no group is added.
147 public void testCreateDuplicateGroup() throws UserMgtException {
148 admin.createGroup(GROUP1);
151 admin.createGroup(GROUP1);
152 } catch (UserMgtException e) {
153 assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
154 assertEquals(1, admin.getGroupCount());
163 * Creates a new user. Verifies the user is created correctly and that the
167 public void testCreateUser() throws UserMgtException {
168 Group group = admin.createGroup(GROUP1);
169 User user = admin.createUser(USER1, PASS1, group);
171 assertEquals(USER1, user.getName());
172 user.checkPassword(PASS1);
174 Set<User> users = admin.getUsers();
175 assertEquals(1, users.size());
176 assertEquals(1, admin.getUserCount());
177 assertTrue(users.contains(user));
180 private void createInvalidUser(String aUsername, Group aGroup) {
182 admin.createUser(aUsername, "pass", aGroup);
184 } catch (UserMgtException e) {
185 assertEquals(UserMgtException.Reason.INVALID_USERNAME, e
187 assertEquals(0, admin.getUserCount());
192 * Constructs users with invalid names. Verifies that the appropriate
193 * exception is thrown.
196 public void testCreateInvalidUserName() throws UserMgtException {
197 Group group = admin.createGroup(GROUP1);
198 createInvalidUser("", group);
199 createInvalidUser("0abc", group); // should not start with digits
200 createInvalidUser("a b", group); // should not contain spaces
201 createInvalidUser(" aa", group);
202 createInvalidUser("aa ", group);
206 * Creates a new user which conflicts with an existing one. Verifies that
207 * the UserMgtException is thrown and that no user is added.
210 public void testCreateDuplicateUser() throws UserMgtException {
211 Group group = admin.createGroup(GROUP1);
212 admin.createUser(USER1, PASS1, group);
215 admin.createUser(USER1, PASS2, group);
217 } catch (UserMgtException e) {
218 assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
219 assertEquals(1, admin.getUserCount());
224 * Gets a known user by name. Verifies the correct user is obtained.
225 * Verifies that null is returned when trying to obtain an unknown user.
228 public void testGetUser() throws UserMgtException {
229 Group group = admin.createGroup(GROUP1);
230 User user = admin.createUser(USER1, PASS1, group);
231 User user2 = admin.getUser(USER1);
232 assertTrue(user.equals(user2));
233 assertNull(admin.getUser(USER2));
237 * Gets a known group by name. Verifies the correct group is obtained.
238 * Verifies that null is returned when the group is not known.
241 public void testGetGroup() throws UserMgtException {
242 Group group = admin.createGroup(GROUP1);
243 Group group2 = admin.getGroup(GROUP1);
244 assertTrue(group.equals(group2));
245 assertNull(admin.getGroup(GROUP2));
249 * Adds a user to a group. Verifies that the user is added using several API
250 * calls. Verifies that an exception occurs if the user is not already part
254 public void testAddUserToGroup() throws UserMgtException {
255 Group group = admin.createGroup(GROUP1);
256 User user = admin.createUser(USER1, PASS1, group);
257 Group group2 = admin.createGroup(GROUP2);
258 assertTrue(user.isInGroup(group));
259 assertFalse(user.isInGroup(group2));
260 admin.addUserToGroup(user, group2);
261 assertTrue(user.isInGroup(group));
262 assertTrue(user.isInGroup(group2));
264 Set<User> users = admin.getUsers(group2);
265 assertNotNull(users);
266 assertEquals(1, users.size());
267 assertTrue(users.contains(user));
270 admin.addUserToGroup(user, group);
271 } catch (UserMgtException e) {
272 assertEquals(UserMgtException.Reason.USER_ALREADY_IN_GROUP, e
282 * Adds a user to a group where the user does not exist. Verifies that an
286 public void testAddUserToGroupUnknownUser() throws UserMgtException {
287 Group group = admin.createGroup(GROUP1);
288 User user = createUser(USER1, PASS1, group);
291 admin.addUserToGroup(user, group);
292 } catch (UserMgtException e) {
293 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
302 * Adds a user to a group where the user does not exist. Verifies that an
306 public void testAddUserToGroupUnknownGroup() throws UserMgtException {
307 Group group = admin.createGroup(GROUP1);
308 User user = admin.createUser(USER1, PASS1, group);
309 Group group2 = new Group(GROUP2);
312 admin.addUserToGroup(user, group2);
313 } catch (UserMgtException e) {
314 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
323 * Removes a user from a group. Verifies that the user is removed from the
324 * group using several API calls. Verifies that an exception occurs if the
325 * user not part of the group or if the user is only part of one group.
328 public void testRemoveUserFromGroup() throws UserMgtException {
329 Group group = admin.createGroup(GROUP1);
331 User user = admin.createUser(USER1, PASS1, group);
332 Group group2 = admin.createGroup(GROUP2);
333 admin.addUserToGroup(user, group2);
335 Set<Group> groups = user.getGroups();
336 assertEquals(2, groups.size());
337 assertTrue(groups.contains(group));
338 assertTrue(groups.contains(group2));
340 admin.removeUserFromGroup(user, group);
341 groups = user.getGroups();
342 assertEquals(1, groups.size());
343 assertTrue(groups.contains(group2));
344 assertFalse(groups.contains(group));
348 * Removes a user from a group where the user is not known. Verifies that an
349 * exception is thrown.
352 public void testRemoveUserFromGroupUnknownUser() throws UserMgtException {
353 Group group = admin.createGroup(GROUP1);
354 User user = createUser(USER1, GROUP1, group);
357 admin.removeUserFromGroup(user, group);
358 } catch (UserMgtException e) {
359 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
364 * Removes a user from a group where the group is not known. Verifies that
365 * an exception is thrown.
368 public void testRemoveUserFromGroupUnknownGroup() throws UserMgtException {
369 Group group = admin.createGroup(GROUP1);
370 User user = admin.createUser(USER1, PASS1, group);
371 Group group2 = new Group(GROUP2);
374 admin.removeUserFromGroup(user, group2);
375 } catch (UserMgtException e) {
376 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
381 * Removes a user from a group where the user is only part of one group.
382 * Verifies that an exception is thrown.
385 public void testRemoveUserFromGroupOnlyGroup() throws UserMgtException {
386 Group group = admin.createGroup(GROUP1);
387 User user = admin.createUser(USER1, PASS1, group);
390 admin.removeUserFromGroup(user, group);
391 } catch (UserMgtException e) {
392 assertEquals(UserMgtException.Reason.USER_MUST_BE_IN_A_GROUP, e
398 * Gets the list of users and groups. Verifies that the correct suers and
399 * groups are returned. Verifies also that the relations from user to group
403 public void testGetUsersAndGroups() throws UserMgtException {
404 Group group1 = admin.createGroup(GROUP1);
405 Group group2 = admin.createGroup(GROUP2);
407 User user1 = admin.createUser(USER1, PASS1, group1);
408 admin.addUserToGroup(user1, group2);
410 User user2 = admin.createUser(USER2, PASS2, group2);
412 Set<User> users = admin.getUsers();
413 assertEquals(2, users.size());
414 assertTrue(users.contains(user1));
415 assertTrue(users.contains(user2));
417 Set<Group> groups = admin.getGroups();
418 assertEquals(2, groups.size());
419 assertTrue(groups.contains(group1));
420 assertTrue(groups.contains(group2));
422 assertTrue(user1.isInGroup(group1));
423 assertTrue(user1.isInGroup(group2));
424 assertFalse(user2.isInGroup(group1));
425 assertTrue(user2.isInGroup(group2));
427 Set<Group> groups1 = user1.getGroups();
428 assertEquals(2, groups1.size());
430 Set<Group> groups2 = user2.getGroups();
431 assertEquals(1, groups2.size());
435 * Renames a user. Verifies that the user is renamed. Verifies that
436 * exceptions are thrown when an attempt is made to rename the user to
437 * itself or to another existing user, or when the group does not exist.
440 public void testRenameUser() throws UserMgtException {
441 Group group = admin.createGroup(GROUP1);
442 User user1 = admin.createUser(USER1, PASS1, group);
443 admin.renameUser(user1, USER2);
444 assertEquals(USER2, user1.getName());
445 assertEquals(user1, admin.getUser(USER2));
448 admin.renameUser(user1, USER1);
449 } catch (UserMgtException e) {
450 assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
452 // do a trivial reanem
454 admin.renameUser(user1, user1.getName());
455 } catch (UserMgtException e2) {
456 assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
469 * Renames a user to a user with an invalid username. Verifies that the
470 * appropriate exception is thrown.
473 public void testRenameUserInvalidUsername() throws UserMgtException {
474 Group group = admin.createGroup(GROUP1);
475 User user1 = admin.createUser(USER1, PASS1, group);
478 admin.renameUser(user1, USER2);
479 } catch (UserMgtException e) {
480 assertEquals(e.getReason(), Reason.INVALID_USERNAME);
485 * Renames a group. Verifies that the group is renamed. Verifies that
486 * exceptions are thrown when an attempt is made to rename the group to
487 * itself or to another existing group or when the group does not exist.
490 public void testRenameGroup() throws UserMgtException {
491 Group group = admin.createGroup(GROUP1);
492 admin.renameGroup(group, GROUP2);
493 assertEquals(GROUP2, group.getName());
494 assertEquals(group, admin.getGroup(GROUP2));
496 admin.createGroup(GROUP1);
499 admin.renameGroup(group, GROUP1);
500 } catch (UserMgtException e) {
501 assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
503 // do a trivial reanem
505 admin.renameGroup(group, group.getName());
506 } catch (UserMgtException e2) {
507 assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
522 * Renames a group to a group with an invalid name. Verifies that the
523 * appropriate exception is thrown.
526 public void testRenameGroupInvalidGroupname() throws UserMgtException {
527 Group group = admin.createGroup(GROUP1);
530 admin.renameGroup(group, "a b");
531 } catch (UserMgtException e) {
532 assertEquals(e.getReason(), Reason.INVALID_GROUPNAME);
537 * Removes a user. Verifies that the user is removed. Verifies that the an
538 * exception is thrown when the user does not exist.
541 public void testRemoveUser() throws UserMgtException {
542 Group group = admin.createGroup(GROUP1);
543 User user = admin.createUser(USER1, PASS1, group);
545 assertEquals(1, admin.getUserCount());
546 admin.removeUser(user);
547 assertEquals(0, admin.getUserCount());
549 admin.createUser(USER1, PASS1, group);
550 assertEquals(1, admin.getUserCount());
552 User user2 = createUser(USER2, PASS2, group);
555 admin.removeUser(user2);
556 } catch (UserMgtException e) {
557 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
562 * Removes a group. Verifies that the group is removed. Verifies that the an
563 * exception is thrown when the group does not exist or if there are still
564 * users in the group.
567 public void testRemoveGroup() throws UserMgtException {
568 Group group1 = admin.createGroup(GROUP1);
569 assertEquals(1, admin.getGroupCount());
570 admin.removeGroup(group1);
571 assertEquals(0, admin.getGroupCount());
572 group1 = admin.createGroup(GROUP1);
574 admin.createUser(USER1, PASS1, group1);
577 admin.removeGroup(group1);
578 } catch (UserMgtException e) {
579 assertEquals(UserMgtException.Reason.GROUP_STILL_OCCUPIED, e
589 * Tries to remove an unknown group. Verifies that an exception is thrown.
592 public void testRemoveGroupUnknownGroup() throws UserMgtException {
593 Group group = admin.createGroup(GROUP1);
594 Group group2 = new Group(GROUP2);
597 admin.removeGroup(group2);
598 } catch (UserMgtException e) {
599 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
604 * Changes the password, verifies that this succeeds.
606 * @throws UserMgtException
608 public void testChangePassword() throws UserMgtException {
609 Group group = admin.createGroup(GROUP1);
610 User user = admin.createUser(USER1, PASS1, group);
611 user.changePassword(PASS1, PASS2);
613 // retrieve the user and verifies the password hasn't changed.
614 User user2 = admin.getUser(USER1);
617 user2.checkPassword(PASS2);
618 fail(); // password should not have changed already.
619 } catch (UserMgtException e) {
623 // now notify the admin of the change in the user
624 admin.userModified(user);
626 user2 = admin.getUser(USER1);
627 user2.checkPassword(PASS2); // this time it should succeed.
631 * Performance test. Finds a user by name.
634 public void testPerformanceFindUserByName() throws UserMgtException {
635 Group group = admin.createGroup(GROUP1);
636 admin.createUser(USER1, PASS1, group);
639 long time = System.currentTimeMillis();
641 for (int i = 0; i < n; i++) {
642 admin.getUser(USER1);
645 LOGGER.info("Looked up a user " + n + " times in " +
646 ((float) (System.currentTimeMillis() - time) / 1000.0));