/* * Copyright 2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wamblee.usermgt; import java.util.Set; import junit.framework.TestCase; import org.apache.log4j.Logger; import org.wamblee.security.encryption.Md5HexMessageDigester; import org.wamblee.usermgt.UserMgtException.Reason; /** * Test of user administration implementation. * * @author Erik Brakkee */ public class UserAdministrationImplTest extends TestCase { private static final Logger LOGGER = Logger .getLogger(UserAdministrationImplTest.class); private static final String USER1 = "piet"; private static final String PASS1 = "passpiet"; private static final String USER2 = "kees"; private static final String PASS2 = "passkees"; private static final String GROUP1 = "cyclists"; private static final String GROUP2 = "runners"; private UserAdministration admin; /* * (non-Javadoc) * * @see junit.framework.TestCase#setUp() */ @Override protected void setUp() throws Exception { super.setUp(); admin = createAdmin(); } protected UserAdministration createAdmin() { UserSet users = new InMemoryUserSet( new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"), new Md5HexMessageDigester()); GroupSet groups = new InMemoryGroupSet(); return new UserAdministrationImpl(users, groups, new RegexpNameValidator(RegexpNameValidator.ID_PATTERN, Reason.INVALID_USERNAME, "Invalid user"), new RegexpNameValidator(RegexpNameValidator.ID_PATTERN, Reason.INVALID_GROUPNAME, "Invalid group")); } protected User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException { return UsermgtTestUtils.createUser(aName, aPassword, aGroup); } /** * Constructs the admin, verify it contains no users and no groups. */ public void testConstruct() { assertEquals(0, admin.getUsers().size()); assertEquals(0, admin.getGroups().size()); assertEquals(0, admin.getUserCount()); assertEquals(0, admin.getGroupCount()); } /** * Creates a new group. Verifies the group is created correctly and that the * user is added. * */ public void testCreateGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); assertNotNull(group); assertEquals(GROUP1, group.getName()); Set groups = admin.getGroups(); assertEquals(1, groups.size()); assertEquals(1, admin.getGroupCount()); assertTrue(groups.contains(group)); } private void createInvalidGroup(String aUsername) { try { admin.createGroup(aUsername); fail(); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e .getReason()); assertEquals(0, admin.getGroupCount()); } } /** * Creates a new group with an invalid name. Verifies that the appropriate * exception is thrown. * * @throws UserMgtException */ public void testCreateInvalidGroupName() throws UserMgtException { createInvalidGroup(""); createInvalidGroup("0abc"); // should not start with digits createInvalidGroup("a b"); // should not contain spaces createInvalidGroup(" aa"); createInvalidGroup("aa "); } /** * Creates a new group which conflicts with an existing one. Verifies that * the UserMgtException is thrown and that no group is added. * */ public void testCreateDuplicateGroup() throws UserMgtException { admin.createGroup(GROUP1); try { admin.createGroup(GROUP1); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason()); assertEquals(1, admin.getGroupCount()); return; } fail(); } /** * Creates a new user. Verifies the user is created correctly and that the * user is added. * */ public void testCreateUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); assertNotNull(user); assertEquals(USER1, user.getName()); user.checkPassword(PASS1); Set users = admin.getUsers(); assertEquals(1, users.size()); assertEquals(1, admin.getUserCount()); assertTrue(users.contains(user)); } private void createInvalidUser(String aUsername, Group aGroup) { try { admin.createUser(aUsername, "pass", aGroup); fail(); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.INVALID_USERNAME, e .getReason()); assertEquals(0, admin.getUserCount()); } } /** * Constructs users with invalid names. Verifies that the appropriate * exception is thrown. * */ public void testCreateInvalidUserName() throws UserMgtException { Group group = admin.createGroup(GROUP1); createInvalidUser("", group); createInvalidUser("0abc", group); // should not start with digits createInvalidUser("a b", group); // should not contain spaces createInvalidUser(" aa", group); createInvalidUser("aa ", group); } /** * Creates a new user which conflicts with an existing one. Verifies that * the UserMgtException is thrown and that no user is added. * */ public void testCreateDuplicateUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); admin.createUser(USER1, PASS1, group); try { admin.createUser(USER1, PASS2, group); fail(); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason()); assertEquals(1, admin.getUserCount()); } } /** * Gets a known user by name. Verifies the correct user is obtained. * Verifies that null is returned when trying to obtain an unknown user. * */ public void testGetUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); User user2 = admin.getUser(USER1); assertTrue(user.equals(user2)); assertNull(admin.getUser(USER2)); } /** * Gets a known group by name. Verifies the correct group is obtained. * Verifies that null is returned when the group is not known. * */ public void testGetGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); Group group2 = admin.getGroup(GROUP1); assertTrue(group.equals(group2)); assertNull(admin.getGroup(GROUP2)); } /** * Adds a user to a group. Verifies that the user is added using several API * calls. Verifies that an exception occurs if the user is not already part * of the group. * */ public void testAddUserToGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); Group group2 = admin.createGroup(GROUP2); assertTrue(user.isInGroup(group)); assertFalse(user.isInGroup(group2)); admin.addUserToGroup(user, group2); assertTrue(user.isInGroup(group)); assertTrue(user.isInGroup(group2)); Set users = admin.getUsers(group2); assertNotNull(users); assertEquals(1, users.size()); assertTrue(users.contains(user)); try { admin.addUserToGroup(user, group); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.USER_ALREADY_IN_GROUP, e .getReason()); return; } fail(); } /** * Adds a user to a group where the user does not exist. Verifies that an * exception occurs. * */ public void testAddUserToGroupUnknownUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = createUser(USER1, PASS1, group); try { admin.addUserToGroup(user, group); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason()); return; } fail(); } /** * Adds a user to a group where the user does not exist. Verifies that an * exception occurs. * */ public void testAddUserToGroupUnknownGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); Group group2 = new Group(GROUP2); try { admin.addUserToGroup(user, group2); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason()); return; } fail(); } /** * Removes a user from a group. Verifies that the user is removed from the * group using several API calls. Verifies that an exception occurs if the * user not part of the group or if the user is only part of one group. */ public void testRemoveUserFromGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); Group group2 = admin.createGroup(GROUP2); admin.addUserToGroup(user, group2); Set groups = user.getGroups(); assertEquals(2, groups.size()); assertTrue(groups.contains(group)); assertTrue(groups.contains(group2)); admin.removeUserFromGroup(user, group); groups = user.getGroups(); assertEquals(1, groups.size()); assertTrue(groups.contains(group2)); assertFalse(groups.contains(group)); } /** * Removes a user from a group where the user is not known. Verifies that an * exception is thrown. * */ public void testRemoveUserFromGroupUnknownUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = createUser(USER1, GROUP1, group); try { admin.removeUserFromGroup(user, group); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason()); } } /** * Removes a user from a group where the group is not known. Verifies that * an exception is thrown. * */ public void testRemoveUserFromGroupUnknownGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); Group group2 = new Group(GROUP2); try { admin.removeUserFromGroup(user, group2); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason()); } } /** * Removes a user from a group where the user is only part of one group. * Verifies that an exception is thrown. */ public void testRemoveUserFromGroupOnlyGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); try { admin.removeUserFromGroup(user, group); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.USER_MUST_BE_IN_A_GROUP, e .getReason()); } } /** * Gets the list of users and groups. Verifies that the correct suers and * groups are returned. Verifies also that the relations from user to group * are correct. * */ public void testGetUsersAndGroups() throws UserMgtException { Group group1 = admin.createGroup(GROUP1); Group group2 = admin.createGroup(GROUP2); User user1 = admin.createUser(USER1, PASS1, group1); admin.addUserToGroup(user1, group2); User user2 = admin.createUser(USER2, PASS2, group2); Set users = admin.getUsers(); assertEquals(2, users.size()); assertTrue(users.contains(user1)); assertTrue(users.contains(user2)); Set groups = admin.getGroups(); assertEquals(2, groups.size()); assertTrue(groups.contains(group1)); assertTrue(groups.contains(group2)); assertTrue(user1.isInGroup(group1)); assertTrue(user1.isInGroup(group2)); assertFalse(user2.isInGroup(group1)); assertTrue(user2.isInGroup(group2)); Set groups1 = user1.getGroups(); assertEquals(2, groups1.size()); Set groups2 = user2.getGroups(); assertEquals(1, groups2.size()); } /** * Renames a user. Verifies that the user is renamed. Verifies that * exceptions are thrown when an attempt is made to rename the user to * itself or to another existing user, or when the group does not exist. * */ public void testRenameUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user1 = admin.createUser(USER1, PASS1, group); admin.renameUser(user1, USER2); assertEquals(USER2, user1.getName()); assertEquals(user1, admin.getUser(USER2)); admin.createUser(USER1, PASS1, group); try { admin.renameUser(user1, USER1); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason()); // do a trivial reanem try { admin.renameUser(user1, user1.getName()); } catch (UserMgtException e2) { assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2 .getReason()); return; } fail(); } fail(); } /** * Renames a user to a user with an invalid username. Verifies that the * appropriate exception is thrown. * */ public void testRenameUserInvalidUsername() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user1 = admin.createUser(USER1, PASS1, group); try { admin.renameUser(user1, USER2); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.INVALID_USERNAME); } } /** * Renames a group. Verifies that the group is renamed. Verifies that * exceptions are thrown when an attempt is made to rename the group to * itself or to another existing group or when the group does not exist. * */ public void testRenameGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); admin.renameGroup(group, GROUP2); assertEquals(GROUP2, group.getName()); assertEquals(group, admin.getGroup(GROUP2)); admin.createGroup(GROUP1); try { admin.renameGroup(group, GROUP1); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason()); // do a trivial reanem try { admin.renameGroup(group, group.getName()); } catch (UserMgtException e2) { assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2 .getReason()); return; } fail(); return; } fail(); } /** * Renames a group to a group with an invalid name. Verifies that the * appropriate exception is thrown. * */ public void testRenameGroupInvalidGroupname() throws UserMgtException { Group group = admin.createGroup(GROUP1); try { admin.renameGroup(group, "a b"); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.INVALID_GROUPNAME); } } /** * Removes a user. Verifies that the user is removed. Verifies that the an * exception is thrown when the user does not exist. * */ public void testRemoveUser() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); assertEquals(1, admin.getUserCount()); admin.removeUser(user); assertEquals(0, admin.getUserCount()); admin.createUser(USER1, PASS1, group); assertEquals(1, admin.getUserCount()); User user2 = createUser(USER2, PASS2, group); try { admin.removeUser(user2); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason()); } } /** * Removes a group. Verifies that the group is removed. Verifies that the an * exception is thrown when the group does not exist or if there are still * users in the group. * */ public void testRemoveGroup() throws UserMgtException { Group group1 = admin.createGroup(GROUP1); assertEquals(1, admin.getGroupCount()); admin.removeGroup(group1); assertEquals(0, admin.getGroupCount()); group1 = admin.createGroup(GROUP1); admin.createUser(USER1, PASS1, group1); try { admin.removeGroup(group1); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.GROUP_STILL_OCCUPIED, e .getReason()); return; } fail(); } /** * Tries to remove an unknown group. Verifies that an exception is thrown. * */ public void testRemoveGroupUnknownGroup() throws UserMgtException { Group group = admin.createGroup(GROUP1); Group group2 = new Group(GROUP2); try { admin.removeGroup(group2); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason()); } } /** * Changes the password, verifies that this succeeds. * * @throws UserMgtException */ public void testChangePassword() throws UserMgtException { Group group = admin.createGroup(GROUP1); User user = admin.createUser(USER1, PASS1, group); user.changePassword(PASS1, PASS2); // retrieve the user and verifies the password hasn't changed. User user2 = admin.getUser(USER1); try { user2.checkPassword(PASS2); fail(); // password should not have changed already. } catch (UserMgtException e) { // ok. } // now notify the admin of the change in the user admin.userModified(user); user2 = admin.getUser(USER1); user2.checkPassword(PASS2); // this time it should succeed. } /** * Performance test. Finds a user by name. * */ public void testPerformanceFindUserByName() throws UserMgtException { Group group = admin.createGroup(GROUP1); admin.createUser(USER1, PASS1, group); int n = 1000; long time = System.currentTimeMillis(); for (int i = 0; i < n; i++) { admin.getUser(USER1); } LOGGER.info("Looked up a user " + n + " times in " + (float) (System.currentTimeMillis() - time) / 1000.0); } }