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.spring.SpringConfigFiles;
25 import org.wamblee.test.spring.SpringTestCase;
26 import org.wamblee.usermgt.UserMgtException.Reason;
29 * Test of user administration implementation.
31 * @author Erik Brakkee
33 public class UserAdministrationImplTest extends SpringTestCase {
35 private static final Logger LOGGER = Logger
36 .getLogger(UserAdministrationImplTest.class);
38 private static final String USER1 = "piet";
40 private static final String PASS1 = "passpiet";
42 private static final String USER2 = "kees";
44 private static final String PASS2 = "passkees";
46 private static final String GROUP1 = "cyclists";
48 private static final String GROUP2 = "runners";
50 private UserAdministration _admin;
52 public UserAdministrationImplTest() {
53 super(SpringConfigFiles.class, HibernateMappingFiles.class);
56 public UserAdministrationImplTest(
57 Class<? extends SpringConfigFiles> aSprings,
58 Class<? extends HibernateMappingFiles> aMappings) {
59 super(aSprings, aMappings);
65 * @see junit.framework.TestCase#setUp()
68 protected void setUp() throws Exception {
70 _admin = createAdmin();
73 protected UserAdministration createAdmin() {
74 UserSet users = new InMemoryUserSet( new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"),
75 new Md5HexMessageDigester());
76 GroupSet groups = new InMemoryGroupSet();
77 return new UserAdministrationImpl(users, groups,
78 new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
79 Reason.INVALID_USERNAME, "Invalid user"),
80 new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
81 Reason.INVALID_GROUPNAME, "Invalid group"));
84 protected User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException {
85 return UsermgtTestUtils.createUser(aName, aPassword, aGroup);
89 * Constructs the admin, verify it contains no users and no groups.
91 public void testConstruct() {
92 assertEquals(0, _admin.getUsers().size());
93 assertEquals(0, _admin.getGroups().size());
94 assertEquals(0, _admin.getUserCount());
95 assertEquals(0, _admin.getGroupCount());
99 * Creates a new group. Verifies the group is created correctly and that the
103 public void testCreateGroup() throws UserMgtException {
104 Group group = _admin.createGroup(GROUP1);
105 assertNotNull(group);
106 assertEquals(GROUP1, group.getName());
108 Set<Group> groups = _admin.getGroups();
109 assertEquals(1, groups.size());
110 assertEquals(1, _admin.getGroupCount());
111 assertTrue(groups.contains(group));
114 private void createInvalidGroup(String aUsername) {
116 _admin.createGroup(aUsername);
118 } catch (UserMgtException e) {
119 assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e
121 assertEquals(0, _admin.getGroupCount());
126 * Creates a new group with an invalid name. Verifies that the appropriate
127 * exception is thrown.
129 * @throws UserMgtException
131 public void testCreateInvalidGroupName() throws UserMgtException {
132 createInvalidGroup("");
133 createInvalidGroup("0abc"); // should not start with digits
134 createInvalidGroup("a b"); // should not contain spaces
135 createInvalidGroup(" aa");
136 createInvalidGroup("aa ");
140 * Creates a new group which conflicts with an existing one. Verifies that
141 * the UserMgtException is thrown and that no group is added.
144 public void testCreateDuplicateGroup() throws UserMgtException {
145 _admin.createGroup(GROUP1);
147 _admin.createGroup(GROUP1);
148 } catch (UserMgtException e) {
149 assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
150 assertEquals(1, _admin.getGroupCount());
157 * Creates a new user. Verifies the user is created correctly and that the
161 public void testCreateUser() throws UserMgtException {
162 Group group = _admin.createGroup(GROUP1);
163 User user = _admin.createUser(USER1, PASS1, group);
165 assertEquals(USER1, user.getName());
166 user.checkPassword(PASS1);
168 Set<User> users = _admin.getUsers();
169 assertEquals(1, users.size());
170 assertEquals(1, _admin.getUserCount());
171 assertTrue(users.contains(user));
174 private void createInvalidUser(String aUsername, Group aGroup) {
176 _admin.createUser(aUsername, "pass", aGroup);
178 } catch (UserMgtException e) {
179 assertEquals(UserMgtException.Reason.INVALID_USERNAME, e
181 assertEquals(0, _admin.getUserCount());
186 * Constructs users with invalid names. Verifies that the appropriate
187 * exception is thrown.
190 public void testCreateInvalidUserName() throws UserMgtException {
191 Group group = _admin.createGroup(GROUP1);
192 createInvalidUser("", group);
193 createInvalidUser("0abc", group); // should not start with digits
194 createInvalidUser("a b", group); // should not contain spaces
195 createInvalidUser(" aa", group);
196 createInvalidUser("aa ", group);
200 * Creates a new user which conflicts with an existing one. Verifies that
201 * the UserMgtException is thrown and that no user is added.
204 public void testCreateDuplicateUser() throws UserMgtException {
205 Group group = _admin.createGroup(GROUP1);
206 _admin.createUser(USER1, PASS1, group);
208 _admin.createUser(USER1, PASS2, group);
210 } catch (UserMgtException e) {
211 assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
212 assertEquals(1, _admin.getUserCount());
217 * Gets a known user by name. Verifies the correct user is obtained.
218 * Verifies that null is returned when trying to obtain an unknown user.
221 public void testGetUser() throws UserMgtException {
222 Group group = _admin.createGroup(GROUP1);
223 User user = _admin.createUser(USER1, PASS1, group);
224 User user2 = _admin.getUser(USER1);
225 assertTrue(user.equals(user2));
226 assertNull(_admin.getUser(USER2));
230 * Gets a known group by name. Verifies the correct group is obtained.
231 * Verifies that null is returned when the group is not known.
234 public void testGetGroup() throws UserMgtException {
235 Group group = _admin.createGroup(GROUP1);
236 Group group2 = _admin.getGroup(GROUP1);
237 assertTrue(group.equals(group2));
238 assertNull(_admin.getGroup(GROUP2));
242 * Adds a user to a group. Verifies that the user is added using several API
243 * calls. Verifies that an exception occurs if the user is not already part
247 public void testAddUserToGroup() throws UserMgtException {
249 Group group = _admin.createGroup(GROUP1);
250 User user = _admin.createUser(USER1, PASS1, group);
251 Group group2 = _admin.createGroup(GROUP2);
252 assertTrue(user.isInGroup(group));
253 assertFalse(user.isInGroup(group2));
254 _admin.addUserToGroup(user, group2);
255 assertTrue(user.isInGroup(group));
256 assertTrue(user.isInGroup(group2));
257 Set<User> users = _admin.getUsers(group2);
258 assertNotNull(users);
259 assertEquals(1, users.size());
260 assertTrue(users.contains(user));
263 _admin.addUserToGroup(user, group);
264 } catch (UserMgtException e) {
265 assertEquals(UserMgtException.Reason.USER_ALREADY_IN_GROUP, e
273 * Adds a user to a group where the user does not exist. Verifies that an
277 public void testAddUserToGroupUnknownUser() throws UserMgtException {
278 Group group = _admin.createGroup(GROUP1);
279 User user = createUser(USER1, PASS1, group);
281 _admin.addUserToGroup(user, group);
282 } catch (UserMgtException e) {
283 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
290 * Adds a user to a group where the user does not exist. Verifies that an
294 public void testAddUserToGroupUnknownGroup() throws UserMgtException {
295 Group group = _admin.createGroup(GROUP1);
296 User user = _admin.createUser(USER1, PASS1, group);
297 Group group2 = new Group(GROUP2);
299 _admin.addUserToGroup(user, group2);
300 } catch (UserMgtException e) {
301 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
308 * Removes a user from a group. Verifies that the user is removed from the
309 * group using several API calls. Verifies that an exception occurs if the
310 * user not part of the group or if the user is only part of one group.
312 public void testRemoveUserFromGroup() throws UserMgtException {
313 Group group = _admin.createGroup(GROUP1);
315 User user = _admin.createUser(USER1, PASS1, group);
316 Group group2 = _admin.createGroup(GROUP2);
317 _admin.addUserToGroup(user, group2);
318 Set<Group> groups = user.getGroups();
319 assertEquals(2, groups.size());
320 assertTrue(groups.contains(group));
321 assertTrue(groups.contains(group2));
323 _admin.removeUserFromGroup(user, group);
324 groups = user.getGroups();
325 assertEquals(1, groups.size());
326 assertTrue(groups.contains(group2));
327 assertFalse(groups.contains(group));
331 * Removes a user from a group where the user is not known. Verifies that an
332 * exception is thrown.
335 public void testRemoveUserFromGroupUnknownUser() throws UserMgtException {
336 Group group = _admin.createGroup(GROUP1);
337 User user = createUser(USER1, GROUP1, group);
339 _admin.removeUserFromGroup(user, group);
340 } catch (UserMgtException e) {
341 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
346 * Removes a user from a group where the group is not known. Verifies that
347 * an exception is thrown.
350 public void testRemoveUserFromGroupUnknownGroup() throws UserMgtException {
351 Group group = _admin.createGroup(GROUP1);
352 User user = _admin.createUser(USER1, PASS1, group);
353 Group group2 = new Group(GROUP2);
355 _admin.removeUserFromGroup(user, group2);
356 } catch (UserMgtException e) {
357 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
362 * Removes a user from a group where the user is only part of one group.
363 * Verifies that an exception is thrown.
365 public void testRemoveUserFromGroupOnlyGroup() throws UserMgtException {
366 Group group = _admin.createGroup(GROUP1);
367 User user = _admin.createUser(USER1, PASS1, group);
369 _admin.removeUserFromGroup(user, group);
370 } catch (UserMgtException e) {
371 assertEquals(UserMgtException.Reason.USER_MUST_BE_IN_A_GROUP, e
377 * Gets the list of users and groups. Verifies that the correct suers and
378 * groups are returned. Verifies also that the relations from user to group
382 public void testGetUsersAndGroups() throws UserMgtException {
383 Group group1 = _admin.createGroup(GROUP1);
384 Group group2 = _admin.createGroup(GROUP2);
386 User user1 = _admin.createUser(USER1, PASS1, group1);
387 _admin.addUserToGroup(user1, group2);
388 User user2 = _admin.createUser(USER2, PASS2, group2);
390 Set<User> users = _admin.getUsers();
391 assertEquals(2, users.size());
392 assertTrue(users.contains(user1));
393 assertTrue(users.contains(user2));
395 Set<Group> groups = _admin.getGroups();
396 assertEquals(2, groups.size());
397 assertTrue(groups.contains(group1));
398 assertTrue(groups.contains(group2));
400 assertTrue(user1.isInGroup(group1));
401 assertTrue(user1.isInGroup(group2));
402 assertFalse(user2.isInGroup(group1));
403 assertTrue(user2.isInGroup(group2));
405 Set<Group> groups1 = user1.getGroups();
406 assertEquals(2, groups1.size());
408 Set<Group> groups2 = user2.getGroups();
409 assertEquals(1, groups2.size());
413 * Renames a user. Verifies that the user is renamed. Verifies that
414 * exceptions are thrown when an attempt is made to rename the user to
415 * itself or to another existing user, or when the group does not exist.
418 public void testRenameUser() throws UserMgtException {
419 Group group = _admin.createGroup(GROUP1);
420 User user1 = _admin.createUser(USER1, PASS1, group);
421 _admin.renameUser(user1, USER2);
422 assertEquals(USER2, user1.getName());
423 assertEquals(user1, _admin.getUser(USER2));
425 _admin.createUser(USER1, PASS1, group);
428 _admin.renameUser(user1, USER1);
429 } catch (UserMgtException e) {
430 assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
432 // do a trivial reanem
434 _admin.renameUser(user1, user1.getName());
435 } catch (UserMgtException e2) {
436 assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
446 * Renames a user to a user with an invalid username. Verifies that the
447 * appropriate exception is thrown.
450 public void testRenameUserInvalidUsername() throws UserMgtException {
451 Group group = _admin.createGroup(GROUP1);
452 User user1 = _admin.createUser(USER1, PASS1, group);
454 _admin.renameUser(user1, USER2);
455 } catch (UserMgtException e) {
456 assertEquals(e.getReason(), Reason.INVALID_USERNAME);
461 * Renames a group. Verifies that the group is renamed. Verifies that
462 * exceptions are thrown when an attempt is made to rename the group to
463 * itself or to another existing group or when the group does not exist.
466 public void testRenameGroup() throws UserMgtException {
467 Group group = _admin.createGroup(GROUP1);
468 _admin.renameGroup(group, GROUP2);
469 assertEquals(GROUP2, group.getName());
470 assertEquals(group, _admin.getGroup(GROUP2));
472 _admin.createGroup(GROUP1);
474 _admin.renameGroup(group, GROUP1);
475 } catch (UserMgtException e) {
476 assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
478 // do a trivial reanem
480 _admin.renameGroup(group, group.getName());
481 } catch (UserMgtException e2) {
482 assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
493 * Renames a group to a group with an invalid name. Verifies that the
494 * appropriate exception is thrown.
497 public void testRenameGroupInvalidGroupname() throws UserMgtException {
498 Group group = _admin.createGroup(GROUP1);
500 _admin.renameGroup(group, "a b");
501 } catch (UserMgtException e) {
502 assertEquals(e.getReason(), Reason.INVALID_GROUPNAME);
507 * Removes a user. Verifies that the user is removed. Verifies that the an
508 * exception is thrown when the user does not exist.
511 public void testRemoveUser() throws UserMgtException {
512 Group group = _admin.createGroup(GROUP1);
513 User user = _admin.createUser(USER1, PASS1, group);
515 assertEquals(1, _admin.getUserCount());
516 _admin.removeUser(user);
517 assertEquals(0, _admin.getUserCount());
519 _admin.createUser(USER1, PASS1, group);
520 assertEquals(1, _admin.getUserCount());
522 User user2 = createUser(USER2, PASS2, group);
525 _admin.removeUser(user2);
526 } catch (UserMgtException e) {
527 assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
532 * Removes a group. Verifies that the group is removed. Verifies that the an
533 * exception is thrown when the group does not exist or if there are still
534 * users in the group.
537 public void testRemoveGroup() throws UserMgtException {
538 Group group1 = _admin.createGroup(GROUP1);
539 assertEquals(1, _admin.getGroupCount());
540 _admin.removeGroup(group1);
541 assertEquals(0, _admin.getGroupCount());
542 group1 = _admin.createGroup(GROUP1);
544 _admin.createUser(USER1, PASS1, group1);
546 _admin.removeGroup(group1);
547 } catch (UserMgtException e) {
548 assertEquals(UserMgtException.Reason.GROUP_STILL_OCCUPIED, e
556 * Tries to remove an unknown group. Verifies that an exception is thrown.
559 public void testRemoveGroupUnknownGroup() throws UserMgtException {
560 Group group = _admin.createGroup(GROUP1);
561 Group group2 = new Group(GROUP2);
563 _admin.removeGroup(group2);
564 } catch (UserMgtException e) {
565 assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
570 * Changes the password, verifies that this succeeds.
572 * @throws UserMgtException
574 public void testChangePassword() throws UserMgtException {
575 Group group = _admin.createGroup(GROUP1);
576 User user = _admin.createUser(USER1, PASS1, group);
577 user.changePassword(PASS1, PASS2);
579 // retrieve the user and verifies the password hasn't changed.
580 User user2 = _admin.getUser(USER1);
582 user2.checkPassword(PASS2);
583 fail(); // password should not have changed already.
584 } catch (UserMgtException e) {
588 // now notify the admin of the change in the user
589 _admin.userModified(user);
591 user2 = _admin.getUser(USER1);
592 user2.checkPassword(PASS2); // this time it should succeed.
597 * Performance test. Finds a user by name.
600 public void testPerformanceFindUserByName() throws UserMgtException {
601 Group group = _admin.createGroup(GROUP1);
602 _admin.createUser(USER1, PASS1, group);
605 long time = System.currentTimeMillis();
606 for (int i = 0; i < n; i++) {
607 _admin.getUser(USER1);
609 LOGGER.info("Looked up a user " + n + " times in "
610 + (float) (System.currentTimeMillis() - time) / 1000.0);