/* * Copyright 2005-2010 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.security.authentication; import java.util.List; import junit.framework.TestCase; import org.apache.log4j.Logger; import org.wamblee.security.authentication.UserMgtException.Reason; import org.wamblee.security.encryption.Md5HexMessageDigester; /** * 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")); } // Construction /** * 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()); } // Basic user admin: // void createUser(String aUser, String aPassword); // boolean checkUser(String aUser); // int getUserCount(); // List getUsers(); // void renameUser(String aOldUserName, String aUserName); // void removeUser(String aUser); public void testCreateUser() { assertFalse(admin.checkUser(USER1)); admin.createUser(USER1, PASS1); assertTrue(admin.checkUser(USER1)); assertEquals(1, admin.getUserCount()); assertTrue(admin.checkPassword(USER1, PASS1)); assertFalse(admin.checkPassword(USER1, PASS2)); } public void testCreateDuplicateUser() { admin.createUser(USER1, PASS1); try { admin.createUser(USER1, PASS2); fail(); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason()); assertEquals(1, admin.getUserCount()); } } /** * Constructs users with invalid names. Verifies that the appropriate * exception is thrown. * */ public void testCreateInvalidUserName() throws UserMgtException { createInvalidUser(""); createInvalidUser("0abc"); // should not start with digits createInvalidUser("a b"); // should not contain spaces createInvalidUser(" aa"); createInvalidUser("aa "); } public void testRenameUser() { admin.createUser(USER1, PASS1); admin.renameUser(USER1, USER2); List users = admin.getUsers(); assertEquals(1, users.size()); assertTrue(users.contains(USER2)); } public void testRenameUserInvalidUsername() { admin.createUser(USER1, PASS1); try { admin.renameUser(USER1, "a b"); fail(); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.INVALID_USERNAME); } } public void testRenameUserToItself() { admin.createUser(USER1, PASS1); admin.renameUser(USER1, USER1); assertTrue(admin.checkUser(USER1)); } public void testRenameUserDuplicateUser() { admin.createUser(USER1, PASS1); admin.createUser(USER2, PASS2); try { admin.renameUser(USER1, USER2); fail(); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.DUPLICATE_USER); } } // Basic group admin: // void createGroup(String aName); // boolean checkGroup(String aGroup); // int getGroupCount(); // List getGroups(); public void testCreateGroup() { admin.createGroup(GROUP1); List groups = admin.getGroups(); assertEquals(1, groups.size()); assertEquals(1, admin.getGroupCount()); assertTrue(groups.contains(GROUP1)); } public void testCreateGroupInvalidName() { createInvalidGroup(""); createInvalidGroup("0abc"); // should not start with digits createInvalidGroup("a b"); // should not contain spaces createInvalidGroup(" aa"); createInvalidGroup("aa "); } public void testCreateGroupDuplicateGroup() { admin.createGroup(GROUP1); try { admin.createGroup(GROUP1); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason()); assertEquals(1, admin.getGroupCount()); return; } fail(); } // Passwords. // boolean checkPassword(String aUser, String aPassword); // boolean changePassword(String aUser, String aOldPassword, String // aNewPassword); // void setPassword(String aUser, String aPassword); public void testChangePassword() { admin.createUser(USER1, PASS1); boolean changed = admin.changePassword(USER1, PASS1, PASS2); assertTrue(changed); assertTrue(admin.checkPassword(USER1, PASS2)); assertFalse(admin.checkPassword(USER1, PASS1)); } public void testChangePasswordWrongPassword() { admin.createUser(USER1, PASS1); boolean changed = admin.changePassword(USER1, PASS2, PASS1); assertFalse(changed); assertFalse(admin.checkPassword(USER1, PASS2)); assertTrue(admin.checkPassword(USER1, PASS1)); } public void testChangePasswordUnknownUser() { admin.createUser(USER1, PASS1); try { boolean changed = admin.changePassword(USER1 + "unknown", PASS2, PASS1); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.UNKNOWN_USER); } } public void testSetPassword() { admin.createUser(USER1, PASS1); admin.setPassword(USER1, PASS2); assertTrue(admin.checkPassword(USER1, PASS2)); assertFalse(admin.checkPassword(USER1, PASS1)); } public void testSetPasswordUnknownUser() { admin.createUser(USER1, PASS1); try { admin.setPassword(USER1 + "unknown", PASS2); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.UNKNOWN_USER); } } // Group membership // boolean isInGroup(String aUser, String aGroup); // List getUsers(String aGroup); // void addUserToGroup(String aUser, String aGroup); // void removeUserFromGroup(String aUser, String aGroup);} public void testAddUserToGroup() { admin.createUser(USER1, PASS1); assertFalse(admin.isInGroup(USER1, GROUP1)); admin.createGroup(GROUP1); admin.addUserToGroup(USER1, GROUP1); assertTrue(admin.isInGroup(USER1, GROUP1)); List users = admin.getUsers(GROUP1); assertEquals(1, users.size()); assertTrue(users.contains(USER1)); } public void testMultipleGroups() { admin.createUser(USER1, PASS1); admin.createGroup(GROUP1); admin.createGroup(GROUP2); assertFalse(admin.isInGroup(USER1, GROUP1)); assertFalse(admin.isInGroup(USER1, GROUP2)); admin.addUserToGroup(USER1, GROUP1); admin.addUserToGroup(USER1, GROUP2); assertTrue(admin.isInGroup(USER1, GROUP1)); assertTrue(admin.isInGroup(USER1, GROUP2)); } public void testAddUserToGroupUnknownUser() { admin.createGroup(GROUP2); try { admin.addUserToGroup(USER1, GROUP2); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.UNKNOWN_USER); } } public void testAddUserToGroupUnknownGroup() { admin.createUser(USER1, PASS1); try { admin.addUserToGroup(USER1, GROUP2); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.UNKNOWN_GROUP); } } public void testRemoveUserFromGroup() { admin.createUser(USER1, GROUP1); admin.createGroup(GROUP1); admin.addUserToGroup(USER1, GROUP1); assertTrue(admin.isInGroup(USER1, GROUP1)); admin.removeUserFromGroup(USER1, GROUP1); assertFalse(admin.isInGroup(USER1, GROUP1)); } public void testRemoveUserFromGroupUserNotInGroup() { admin.createUser(USER1, GROUP1); admin.createGroup(GROUP1); admin.createGroup(GROUP2); admin.addUserToGroup(USER1, GROUP1); try { admin.removeUserFromGroup(USER1, GROUP2); fail(); } catch (UserMgtException e) { assertEquals(Reason.USER_NOT_IN_GROUP, e.getReason()); } } public void testRemoveUserFromGroupUnknowUser() { admin.createGroup(GROUP1); try { admin.removeUserFromGroup(USER1, GROUP2); fail(); } catch (UserMgtException e) { assertEquals(Reason.UNKNOWN_USER, e.getReason()); } } public void testRemoveUserFromGroupUnknownGroup() { admin.createUser(USER1, PASS1); try { admin.removeUserFromGroup(USER1, GROUP2); fail(); } catch (UserMgtException e) { assertEquals(Reason.UNKNOWN_GROUP, e.getReason()); } } // void renameGroup(String aOldGroup, String aGroupName) public void testRenameGroup() { admin.createUser(USER1, PASS1); admin.createGroup(GROUP1); admin.addUserToGroup(USER1, GROUP1); admin.renameGroup(GROUP1, GROUP2); List groups = admin.getGroups(); assertEquals(1, groups.size()); assertTrue(groups.contains(GROUP2)); assertTrue(admin.isInGroup(USER1, GROUP2)); assertFalse(admin.isInGroup(USER1, GROUP1)); } public void testRenameGroupGroupNameInvalid() { admin.createGroup(GROUP1); try { admin.renameGroup(GROUP1, "a b"); fail(); } catch (UserMgtException e) { assertEquals(Reason.INVALID_GROUPNAME, e.getReason()); } } public void testRenameGroupGroupAlreadyExists() { admin.createGroup(GROUP1); admin.createGroup(GROUP2); try { admin.renameGroup(GROUP1, GROUP2); fail(); } catch (UserMgtException e) { assertEquals(Reason.DUPLICATE_GROUP, e.getReason()); } } // void removeGroup(String aGroup); public void testRemoveGroup() { admin.createGroup(GROUP1); admin.removeGroup(GROUP1); List groups = admin.getGroups(); assertEquals(0, groups.size()); } public void testRemoveGroupGroupDoesNotExist() { try { admin.removeGroup(GROUP1); fail(); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.UNKNOWN_GROUP); } } public void testRemoveGroupButStillUsersInGroup() { admin.createUser(USER1, PASS1); admin.createGroup(GROUP1); admin.addUserToGroup(USER1, GROUP1); try { admin.removeGroup(GROUP1); } catch (UserMgtException e) { assertEquals(e.getReason(), Reason.GROUP_STILL_OCCUPIED); } } private void createInvalidGroup(String aUsername) { try { admin.createGroup(aUsername); fail(); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e .getReason()); assertEquals(0, admin.getGroupCount()); } } private void createInvalidUser(String aUsername) { try { admin.createUser(aUsername, "pass"); fail(); } catch (UserMgtException e) { assertEquals(UserMgtException.Reason.INVALID_USERNAME, e .getReason()); assertEquals(0, admin.getUserCount()); } } /** * 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 { admin.createGroup(GROUP1); admin.createGroup(GROUP2); admin.createUser(USER1, PASS1); admin.addUserToGroup(USER1, GROUP1); admin.addUserToGroup(USER1, GROUP2); admin.createUser(USER2, PASS2); admin.addUserToGroup(USER2, GROUP2); List users = admin.getUsers(); assertEquals(2, users.size()); assertTrue(users.contains(USER1)); assertTrue(users.contains(USER2)); List groups = admin.getGroups(); assertEquals(2, groups.size()); assertTrue(groups.contains(GROUP1)); assertTrue(groups.contains(GROUP2)); assertTrue(admin.isInGroup(USER1, GROUP1)); assertTrue(admin.isInGroup(USER1, GROUP2)); assertFalse(admin.isInGroup(USER2, GROUP1)); assertTrue(admin.isInGroup(USER2, GROUP2)); List groups1 = admin.getGroups(USER1); assertEquals(2, groups1.size()); List groups2 = admin.getGroups(USER2); assertEquals(1, groups2.size()); } /** * Performance test. Finds a user by name. * */ public void testPerformanceFindUserByName() throws UserMgtException { admin.createGroup(GROUP1); admin.createUser(USER1, PASS1); admin.addUserToGroup(USER1, GROUP1); int n = 1000; long time = System.currentTimeMillis(); for (int i = 0; i < n; i++) { admin.checkUser(USER1); } LOGGER.info("Looked up a user " + n + " times in " + ((float) (System.currentTimeMillis() - time) / 1000.0)); } }