From f4f8467b507b7bb401e4ad0749ea426208831846 Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Mon, 10 May 2010 20:10:13 +0000 Subject: [PATCH] now using the simplified user management interface. --- .../authentication/AbstractUserSet.java | 12 +- .../authentication/InMemoryUserSet.java | 63 +- .../authentication/JaasUserAccessor.java | 10 +- .../authentication/NameValidator.java | 5 +- .../authentication/RegexpNameValidator.java | 7 +- .../wamblee/security/authentication/User.java | 37 +- .../security/authentication/UserAccessor.java | 2 +- .../authentication/UserAdminInitializer.java | 14 +- .../authentication/UserAdministration.java | 117 +-- .../UserAdministrationImpl.java | 343 ++++----- .../authentication/UserMgtException.java | 5 +- .../security/authentication/UserSet.java | 16 +- .../authentication/jpa/JpaUserSet.java | 55 +- .../AbstractAuthorizationRule.java | 2 + .../authorization/AnyUserCondition.java | 17 +- .../authorization/AuthorizationRule.java | 13 +- .../authorization/AuthorizationService.java | 9 + .../DefaultAuthorizationService.java | 38 +- .../authorization/GroupUserCondition.java | 22 +- .../authorization/UrlAuthorizationRule.java | 15 +- .../security/authorization/UserCondition.java | 10 +- .../jpa/JpaAuthorizationService.java | 87 +-- .../UserAdministrationImplTest.java | 666 +++++++----------- .../authentication/UsermgtTestUtils.java | 4 +- .../AuthorizationServiceTest.java | 19 +- .../authorization/TestAuthorizationRule.java | 10 +- .../authorization/TestUserAccessor.java | 38 +- .../UrlAuthorizationRuleTest.java | 15 +- .../jpa/JpaAuthorizationServiceTest.java | 2 +- 29 files changed, 741 insertions(+), 912 deletions(-) diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/AbstractUserSet.java b/security/impl/src/main/java/org/wamblee/security/authentication/AbstractUserSet.java index 50635c1a..e629d0bb 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/AbstractUserSet.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/AbstractUserSet.java @@ -54,15 +54,9 @@ public abstract class AbstractUserSet implements UserSet { aUser.setPasswordEncoder(passwordEncoder); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#createUser(java.lang.String, - * java.lang.String, org.wamblee.usermgt.Group) - */ - public User createUser(String aUsername, String aPassword, Group aGroup) - throws UserMgtException { - User user = new User(aUsername, aPassword, aGroup, passwordValidator, + @Override + public User createUser(String aUsername, String aPassword) { + User user = new User(aUsername, aPassword, passwordValidator, passwordEncoder); if (contains(user)) { diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/InMemoryUserSet.java b/security/impl/src/main/java/org/wamblee/security/authentication/InMemoryUserSet.java index 6c296677..59129213 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/InMemoryUserSet.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/InMemoryUserSet.java @@ -41,99 +41,68 @@ public class InMemoryUserSet extends AbstractUserSet { users = new TreeSet(); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#userModified(org.wamblee.usermgt.User) - */ + @Override public void userModified(User aUser) { users.remove(aUser); setPasswordInfo(aUser); users.add(aUser); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#find(java.lang.String) - */ + @Override public User find(String aName) { for (User user : users) { if (user.getName().equals(aName)) { - return new User(user); + return user; } } return null; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#add(org.wamblee.usermgt.User) - */ + @Override public boolean add(User aUser) { setPasswordInfo(aUser); return users.add(aUser); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#contains(org.wamblee.usermgt.User) - */ + @Override public boolean contains(User aUser) { return users.contains(aUser); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#remove(org.wamblee.usermgt.User) - */ + @Override public boolean remove(User aUser) { return users.remove(aUser); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#list() - */ + @Override public Set list() { Set list = new TreeSet(); - - for (User user : users) { - list.add(new User(user)); - } - + list.addAll(users); return list; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#list(org.wamblee.usermgt.Group) - */ + @Override public Set list(Group aGroup) { Set result = new TreeSet(); for (User user : users) { if (user.getGroups().contains(aGroup)) { - result.add(new User(user)); + result.add(user); } } return result; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#size() - */ + @Override public int size() { return users.size(); } + + @Override + public void clearCache() { + // Empty + } } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/JaasUserAccessor.java b/security/impl/src/main/java/org/wamblee/security/authentication/JaasUserAccessor.java index 8387a600..9148268d 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/JaasUserAccessor.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/JaasUserAccessor.java @@ -63,12 +63,8 @@ public class JaasUserAccessor implements UserAccessor { } } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAccessor#getCurrentUser() - */ - public User getCurrentUser() { + @Override + public String getCurrentUser() { Subject subject = Subject.getSubject(AccessController.getContext()); if (subject == null) { @@ -77,7 +73,7 @@ public class JaasUserAccessor implements UserAccessor { Principal userPrincipal = getUserPrincipal(subject); - return admin.getUser(userPrincipal.getName()); + return userPrincipal.getName(); } /** diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/NameValidator.java b/security/impl/src/main/java/org/wamblee/security/authentication/NameValidator.java index b5935cb4..910b345e 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/NameValidator.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/NameValidator.java @@ -27,8 +27,7 @@ public interface NameValidator { * @param aName * Name * - * @throws UserMgtException - * In case the name is invalid. + * @return True iff the validationo is ok. */ - void validate(String aName) throws UserMgtException; + boolean validate(String aName); } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/RegexpNameValidator.java b/security/impl/src/main/java/org/wamblee/security/authentication/RegexpNameValidator.java index ebdd9131..7d31dbc6 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/RegexpNameValidator.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/RegexpNameValidator.java @@ -84,9 +84,8 @@ public class RegexpNameValidator implements NameValidator { * * @see org.wamblee.usermgt.NameValidator#validate(java.lang.String) */ - public void validate(String aName) throws UserMgtException { - if (!aName.matches(pattern)) { - throw new UserMgtException(reason, message); - } + @Override + public boolean validate(String aName) { + return aName.matches(pattern); } } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/User.java b/security/impl/src/main/java/org/wamblee/security/authentication/User.java index 03c15eea..82a77303 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/User.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/User.java @@ -98,18 +98,14 @@ public class User implements Serializable, Comparable { * User name. * @param aPassword * Password. - * @param aGroup - * Group the user belongs to. */ - User(String aName, String aPassword, Group aGroup, - NameValidator aPasswordValidator, MessageDigester aPasswordEncoder) - throws UserMgtException { + User(String aName, String aPassword, NameValidator aPasswordValidator, + MessageDigester aPasswordEncoder) { super(); name = aName; aPasswordValidator.validate(aPassword); password = aPasswordEncoder.hash(aPassword); groups = new TreeSet(); - groups.add(aGroup); passwordValidator = aPasswordValidator; passwordEncoder = aPasswordEncoder; } @@ -179,15 +175,12 @@ public class User implements Serializable, Comparable { * @param aPassword * Password to check. * - * @throws UserMgtException - * In case the password is incorrect. + * @return True iff the password is correct. */ - public void checkPassword(String aPassword) throws UserMgtException { + public boolean checkPassword(String aPassword) { String encoded = passwordEncoder.hash(aPassword); - if (!password.equals(encoded)) { - throw new UserMgtException(Reason.INVALID_PASSWORD, this); - } + return password.equals(encoded); } /** @@ -198,14 +191,15 @@ public class User implements Serializable, Comparable { * @param aNewPassword * New password. * - * @throws UserMgtException - * In case the old password is incorrect. + * @return True iff the password was changed successfully. */ - public void changePassword(String aOldPassword, String aNewPassword) - throws UserMgtException { - checkPassword(aOldPassword); + public boolean changePassword(String aOldPassword, String aNewPassword) { + if (!checkPassword(aOldPassword)) { + return false; + } passwordValidator.validate(aNewPassword); setPassword(aNewPassword); + return true; } /** @@ -214,7 +208,7 @@ public class User implements Serializable, Comparable { * The password to set. * */ - public void setPassword(String aPassword) throws UserMgtException { + public void setPassword(String aPassword) { passwordValidator.validate(aPassword); password = passwordEncoder.hash(aPassword); } @@ -336,16 +330,11 @@ public class User implements Serializable, Comparable { * @throws UserMgtException * In case the user does not belong to the group. */ - void removeGroup(Group aGroup) throws UserMgtException { + void removeGroup(Group aGroup) { if (!groups.contains(aGroup)) { throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup); } - if (groups.size() == 1) { - throw new UserMgtException(Reason.USER_MUST_BE_IN_A_GROUP, this, - aGroup); - } - groups.remove(aGroup); } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/UserAccessor.java b/security/impl/src/main/java/org/wamblee/security/authentication/UserAccessor.java index 61582945..37d5eb73 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/UserAccessor.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/UserAccessor.java @@ -26,5 +26,5 @@ public interface UserAccessor { * * @return Currently logged in user or null if no user is found. */ - User getCurrentUser(); + String getCurrentUser(); } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/UserAdminInitializer.java b/security/impl/src/main/java/org/wamblee/security/authentication/UserAdminInitializer.java index 2168d891..f716dfbd 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/UserAdminInitializer.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/UserAdminInitializer.java @@ -71,20 +71,16 @@ public class UserAdminInitializer { String group = aGroups[i]; String password = aPasswords[i]; - if (aAdmin.getUser(user) == null) { - // must create user. - Group groupObj = aAdmin.getGroup(group); - - if (groupObj == null) { + if (!aAdmin.checkUser(user)) { + if (!(aAdmin.checkGroup(group))) { // must create group LOGGER.info("Creating group: " + group); - groupObj = aAdmin.createGroup(group); + aAdmin.createGroup(group); } - assert groupObj != null; - LOGGER .info("Creating user: " + user + " password: " + password); - aAdmin.createUser(user, password, groupObj); + aAdmin.createUser(user, password); + aAdmin.addUserToGroup(user, group); } } } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministration.java b/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministration.java index 321481d0..ab8b8f1c 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministration.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministration.java @@ -15,8 +15,11 @@ */ package org.wamblee.security.authentication; +import java.util.List; import java.util.Set; +import org.wamblee.security.authentication.UserMgtException.Reason; + /** * Interface for user administration. Manages the users and groups. * @@ -30,16 +33,13 @@ public interface UserAdministration { * Username. * @param aPassword * Password. - * @param aGroup - * Group. * * @return User. * * @throws UserMgtException * In case there is a conflict with an existing user. */ - User createUser(String aUser, String aPassword, Group aGroup) - throws UserMgtException; + void createUser(String aUser, String aPassword); /** * Creates a new group. @@ -52,63 +52,88 @@ public interface UserAdministration { * @throws UserMgtException * In case there is a conflict with an existing group. */ - Group createGroup(String aName) throws UserMgtException; - + void createGroup(String aName); + /** + * Checks if a user exists. + * @param aUser User to check. + * @return True iff user exists. + */ + boolean checkUser(String aUser); + + + /** + * Check if a group exists. + * @param aGroup Group. + * @return True iff group exists. + */ + boolean checkGroup(String aGroup); + + /** + * Checks the password. * - * @return Number of users. + * @param aUser + * User to check password for. + * @param aPassword + * Password to check. + * @throws UserMgtException In case user does not exist. + * @return True iff password is ok. */ - int getUserCount(); + boolean checkPassword(String aUser, String aPassword); /** + * Changes the password. * - * @return Number of groups. + * @param aUser + * User. + * @param aOldPassword + * Old password. + * @param aNewPassword + * New password. + * + * @throws UserMgtException Inc ase the user does not exist. + * @return True if the password was changed. */ - int getGroupCount(); + boolean changePassword(String aUser, String aOldPassword, String aNewPassword); /** - * Must be called when the user is modified. * * @param aUser * User. - * @return The modified user. The user passed in to this call should be considered invalid. + * @param aPassword + * The password to set. + * + * @throws UserMgtException Inc ase the user does not exist. */ - void userModified(User aUser); + void setPassword(String aUser, String aPassword); /** - * Must be called when the group is modified. - * - * @param aGroup - * Group. + * Checks if the user belongs to the given group. + * @param aUser User + * @param aGroup Group. + * @return True iff user is in group + * @throws UserMgtException In case the user or group do not exist. */ - void groupModified(Group aGroup); + boolean isInGroup(String aUser, String aGroup); /** - * Gets the user for a given name. - * - * @param aName - * User name. * - * @return User or null if not found. + * @return Number of users. */ - User getUser(String aName); + int getUserCount(); /** - * Gets the group for a given group name. * - * @param aName - * Group name. - * - * @return Group or null if not found. + * @return Number of groups. */ - Group getGroup(String aName); + int getGroupCount(); /** * Get the users. * * @return All known users. */ - Set getUsers(); + List getUsers(); /** * Gets the users for a given group. @@ -117,20 +142,28 @@ public interface UserAdministration { * Group. * @return Set of users (always non-null). */ - Set getUsers(Group aGroup); + List getUsers(String aGroup); /** - * Gets all known groups. + * Gets all groups. * * @return Groups. */ - Set getGroups(); + List getGroups(); + /** + * Gets all groups for a given user. + * + * @param aUser user. + * @return Groups. + */ + List getGroups(String aUser); + /** * Renames a user. * - * @param aUser - * User object for which user name must be changed. + * @param aOldUserName + * Current user name. * @param aUserName * New user name. * @@ -138,7 +171,7 @@ public interface UserAdministration { * In case the user is not known or the new user name is already * in use by another user. */ - void renameUser(User aUser, String aUserName) throws UserMgtException; + void renameUser(String aOldUserName, String aUserName); /** * Renames a group. @@ -152,7 +185,7 @@ public interface UserAdministration { * In case the new group name is already used by another group * of if the existing group is unknown. */ - void renameGroup(Group aGroup, String aGroupName) throws UserMgtException; + void renameGroup(String aOldGroup, String aGroupName); /** * Removes the user. @@ -163,7 +196,7 @@ public interface UserAdministration { * @throws UserMgtException * In case the user does not exist. */ - void removeUser(User aUser) throws UserMgtException; + void removeUser(String aUser); /** * Removes the group. @@ -174,7 +207,7 @@ public interface UserAdministration { * @throws UserMgtException * In case there are still users that are in the given group. */ - void removeGroup(Group aGroup) throws UserMgtException; + void removeGroup(String aGroup); /** * Adds a user to a group. @@ -188,7 +221,7 @@ public interface UserAdministration { * In case the user or group or not known or if the user is * already part of the group. */ - void addUserToGroup(User aUser, Group aGroup) throws UserMgtException; + void addUserToGroup(String aUser, String aGroup); /** * Removes a user from a group. @@ -202,5 +235,5 @@ public interface UserAdministration { * In case the user or group are unknown or if the user is not * part of the group. */ - void removeUserFromGroup(User aUser, Group aGroup) throws UserMgtException; + void removeUserFromGroup(String aUser, String aGroup); } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministrationImpl.java b/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministrationImpl.java index a06580cc..bbec0055 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministrationImpl.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/UserAdministrationImpl.java @@ -17,9 +17,13 @@ package org.wamblee.security.authentication; import static org.wamblee.security.authentication.UserMgtException.Reason.*; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; +import org.wamblee.security.authentication.UserMgtException.Reason; + /** * Administration of users and groups. * @@ -64,14 +68,13 @@ public class UserAdministrationImpl implements UserAdministration { * @see org.wamblee.usermgt.UserAdministration#createUser(java.lang.String, * java.lang.String) */ - public User createUser(String aUser, String aPassword, Group aGroup) - throws UserMgtException { - userValidator.validate(aUser); - checkGroup(aGroup); - - User user = users.createUser(aUser, aPassword, aGroup); + @Override + public void createUser(String aUser, String aPassword) { + if (!userValidator.validate(aUser)) { + throw new UserMgtException(Reason.INVALID_USERNAME, aUser); + } - return new User(user); + users.createUser(aUser, aPassword); } /* @@ -79,8 +82,11 @@ public class UserAdministrationImpl implements UserAdministration { * * @see org.wamblee.usermgt.UserAdministration#createGroup(java.lang.String) */ - public Group createGroup(String aName) throws UserMgtException { - groupValidator.validate(aName); + @Override + public void createGroup(String aName) { + if (!groupValidator.validate(aName)) { + throw new UserMgtException(Reason.INVALID_GROUPNAME, aName); + } Group group = new Group(aName); @@ -89,247 +95,190 @@ public class UserAdministrationImpl implements UserAdministration { } groups.add(group); + } - return new Group(group); + @Override + public boolean checkUser(String aUser) { + return users.find(aUser) != null; } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#userModified(org.wamblee.usermgt - * .User) - */ - public void userModified(User aUser) { - users.userModified(aUser); + @Override + public boolean checkGroup(String aGroup) { + return groups.find(aGroup) != null; } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#groupModified(org.wamblee.usermgt - * .Group) - */ - public void groupModified(Group aGroup) { - groups.groupModified(aGroup); + @Override + public boolean checkPassword(String aUser, String aPassword) { + User user = requireUser(aUser, "While checking password"); + return user.checkPassword(aPassword); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAdministration#getUser(java.lang.String) - */ - public User getUser(String aName) { - User user = users.find(aName); + private User requireUser(String aUser, String aMsg) { + User user = users.find(aUser); if (user == null) { - return user; + throw new UserMgtException(Reason.UNKNOWN_USER, aMsg); } - return new User(user); + return user; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAdministration#getGroup(java.lang.String) - */ - public Group getGroup(String aName) { - Group group = groups.find(aName); - if ( group == null ) { - return group; + private Group requireGroup(String aGroup, String aMsg) { + Group group = groups.find(aGroup); + if (group == null) { + throw new UserMgtException(Reason.UNKNOWN_GROUP, aMsg); } - return new Group(group); + return group; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAdministration#getUsers() - */ - public Set getUsers() { - Set res = new HashSet(); - for (User user: users.list()) { - res.add(new User(user)); - } - return res; + @Override + public boolean changePassword(String aUser, String aOldPassword, + String aNewPassword) { + User user = requireUser(aUser, "While checking password"); + boolean res = user.changePassword(aOldPassword, aNewPassword); + users.userModified(user); + return res; } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#getUsers(org.wamblee.usermgt.Group - * ) - */ - public Set getUsers(Group aGroup) { - Set res = new HashSet(); - for (User user: users.list(aGroup)) { - res.add(new User(user)); + @Override + public void setPassword(String aUser, String aPassword) { + User user = requireUser(aUser, "While setting password"); + user.setPassword(aPassword); + users.userModified(user); + } + + @Override + public boolean isInGroup(String aUser, String aGroup) { + User user = requireUser(aUser, + "While checking whether user belongs to group"); + return user.isInGroup(aGroup); + } + + @Override + public int getUserCount() { + return users.size(); + } + + @Override + public int getGroupCount() { + return groups.size(); + } + + @Override + public List getUsers() { + List res = new ArrayList(); + for (User user : users.list()) { + res.add(user.getName()); } return res; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAdministration#getGroups() - */ - public Set getGroups() { - Set res = new HashSet(); - for (Group group: groups.list()) { - res.add(new Group(group)); + @Override + public List getUsers(String aGroup) { + Group group = requireGroup(aGroup, "While finding users for group"); + List res = new ArrayList(); + for (User user : users.list(group)) { + res.add(user.getName()); } - return res; + return res; } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#removeUser(org.wamblee.usermgt - * .User) - */ - public void removeUser(User aUser) throws UserMgtException { - checkUser(aUser); - users.remove(aUser); + @Override + public List getGroups() { + List res = new ArrayList(); + for (Group group : groups.list()) { + res.add(group.getName()); + } + return res; } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#removeGroup(org.wamblee.usermgt - * .Group) - */ - public void removeGroup(Group aGroup) throws UserMgtException { - checkGroup(aGroup); - - if (getUsers(aGroup).size() > 0) { - throw new UserMgtException(GROUP_STILL_OCCUPIED, aGroup); + @Override + public List getGroups(String aUser) { + User user = requireUser(aUser, "While getting list of groups"); + List res = new ArrayList(); + for (Group g : user.getGroups()) { + res.add(g.getName()); } - - groups.remove(aGroup); + return res; } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#renameUser(org.wamblee.usermgt - * .User, java.lang.String) - */ - public void renameUser(User aUser, String aUserName) - throws UserMgtException { - checkUser(aUser); + @Override + public void renameUser(String aOldUsername, String aNewUsername) { + User user = requireUser(aOldUsername, "While renaming user"); - if (aUser.getName().equals(aUserName)) { - throw new UserMgtException(TRIVIAL_RENAME, aUser); + if (aOldUsername.equals(aNewUsername)) { + return; // nothing to do. } - if (users.find(aUserName) != null) { - throw new UserMgtException(DUPLICATE_USER, aUser); + if (users.find(aNewUsername) != null) { + throw new UserMgtException(DUPLICATE_USER, aNewUsername); } - userValidator.validate(aUserName); + if (!userValidator.validate(aNewUsername)) { + throw new UserMgtException(Reason.INVALID_USERNAME, aNewUsername); + } - aUser.setName(aUserName); - users.userModified(aUser); + user.setName(aNewUsername); + users.userModified(user); } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#renameGroup(org.wamblee.usermgt - * .Group, java.lang.String) - */ - public void renameGroup(Group aGroup, String aGroupName) - throws UserMgtException { - checkGroup(aGroup); + @Override + public void renameGroup(String aOldGroup, String aNewGroup) { + Group group = requireGroup(aOldGroup, "While renaming group"); - if (aGroup.getName().equals(aGroupName)) { - throw new UserMgtException(TRIVIAL_RENAME, aGroup); + if (aOldGroup.equals(aNewGroup)) { + return; // OK. } - if (groups.find(aGroupName) != null) { - throw new UserMgtException(DUPLICATE_GROUP, aGroup); + if (groups.find(aNewGroup) != null) { + throw new UserMgtException(DUPLICATE_GROUP, aNewGroup); } - groupValidator.validate(aGroupName); + if (!groupValidator.validate(aNewGroup)) { + throw new UserMgtException(Reason.INVALID_GROUPNAME, aNewGroup); + } - aGroup.setName(aGroupName); - groups.groupModified(aGroup); + group.setName(aNewGroup); + groups.groupModified(group); + // Because a group has changed, a cached user could contain reference to an old copy of the + // group. Therefore, we clear the cache in this case. + users.clearCache(); } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#addUserToGroup(org.wamblee.usermgt - * .User, org.wamblee.usermgt.Group) - */ - public void addUserToGroup(User aUser, Group aGroup) - throws UserMgtException { - checkUser(aUser); - checkGroup(aGroup); - aUser.addGroup(aGroup); - users.userModified(aUser); + @Override + public void removeUser(String aUser) { + User user = requireUser(aUser, "While removing user"); + boolean removed = users.remove(user); + if (!removed) { + throw new UserMgtException(Reason.UNKNOWN_USER, aUser); + } } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.usermgt.UserAdministration#removeUserFromGroup(org.wamblee - * .usermgt.User, org.wamblee.usermgt.Group) - */ - public void removeUserFromGroup(User aUser, Group aGroup) - throws UserMgtException { - checkUser(aUser); - checkGroup(aGroup); - aUser.removeGroup(aGroup); - users.userModified(aUser); - } + @Override + public void removeGroup(String aGroup) { + Group group = requireGroup(aGroup, "While removing group"); - /** - * - * @param aUser - * - * @throws UserMgtException - */ - private void checkUser(User aUser) throws UserMgtException { - if (!users.contains(aUser)) { - throw new UserMgtException(UNKNOWN_USER, aUser); + if (getUsers(aGroup).size() > 0) { + throw new UserMgtException(GROUP_STILL_OCCUPIED, aGroup); } - } - /** - * - * @param aGroup - * - * @throws UserMgtException - */ - private void checkGroup(Group aGroup) throws UserMgtException { - if (!groups.contains(aGroup)) { - throw new UserMgtException(UNKNOWN_GROUP, aGroup); + boolean removed = groups.remove(group); + if (!removed) { + throw new UserMgtException(Reason.UNKNOWN_GROUP, aGroup); } } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAdministration#getUserCount() - */ - public int getUserCount() { - return users.size(); + @Override + public void addUserToGroup(String aUser, String aGroup) { + User user = requireUser(aUser, "While adding user to group"); + Group group = requireGroup(aGroup, "While adding user to group"); + user.addGroup(group); + users.userModified(user); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAdministration#getGroupCount() - */ - public int getGroupCount() { - return groups.size(); + @Override + public void removeUserFromGroup(String aUser, String aGroup) { + User user = requireUser(aUser, "While removing user from group"); + Group group = requireGroup(aGroup, "While removing user from group"); + user.removeGroup(group); + users.userModified(user); } } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/UserMgtException.java b/security/impl/src/main/java/org/wamblee/security/authentication/UserMgtException.java index 094d3a53..744c0d8a 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/UserMgtException.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/UserMgtException.java @@ -22,7 +22,7 @@ import java.util.EnumMap; * * @author Erik Brakkee */ -public class UserMgtException extends Exception { +public class UserMgtException extends RuntimeException { static final long serialVersionUID = 5585349754997507529L; /** @@ -38,7 +38,6 @@ public class UserMgtException extends Exception { MESSAGES.put(Reason.DUPLICATE_GROUP, "Duplicate group"); MESSAGES.put(Reason.USER_ALREADY_IN_GROUP, "User already in group"); MESSAGES.put(Reason.USER_NOT_IN_GROUP, "User not in group"); - MESSAGES.put(Reason.TRIVIAL_RENAME, "Trivial rename"); MESSAGES.put(Reason.INVALID_PASSWORD, "Invalid password"); MESSAGES.put(Reason.GROUP_STILL_OCCUPIED, "Group still occupied"); MESSAGES.put(Reason.USER_MUST_BE_IN_A_GROUP, @@ -132,6 +131,6 @@ public class UserMgtException extends Exception { * */ public enum Reason { - UNKNOWN_USER, UNKNOWN_GROUP, DUPLICATE_USER, DUPLICATE_GROUP, USER_ALREADY_IN_GROUP, USER_NOT_IN_GROUP, TRIVIAL_RENAME, INVALID_PASSWORD, GROUP_STILL_OCCUPIED, USER_MUST_BE_IN_A_GROUP, INVALID_USERNAME, INVALID_GROUPNAME; + UNKNOWN_USER, UNKNOWN_GROUP, DUPLICATE_USER, DUPLICATE_GROUP, USER_ALREADY_IN_GROUP, USER_NOT_IN_GROUP, INVALID_PASSWORD, GROUP_STILL_OCCUPIED, USER_MUST_BE_IN_A_GROUP, INVALID_USERNAME, INVALID_GROUPNAME; } } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/UserSet.java b/security/impl/src/main/java/org/wamblee/security/authentication/UserSet.java index 90b3f897..7e6f9721 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/UserSet.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/UserSet.java @@ -32,15 +32,13 @@ public interface UserSet { * User name. * @param aPassword * Password. - * @param aGroup - * Group. * * @return New user. * * @throws UserMgtException * In case the user cannot be created. */ - User createUser(String aUsername, String aPassword, Group aGroup) + User createUser(String aUsername, String aPassword) throws UserMgtException; /** @@ -83,9 +81,10 @@ public interface UserSet { boolean add(User aUser); /** - * Removes a user. If the user does not exist, nothing happens. - * - * @param aUser + * Removes a user. + * + * @param aUser User to remove + * @return True iff user was removed. * */ boolean remove(User aUser); @@ -111,4 +110,9 @@ public interface UserSet { * @return The number of users. */ int size(); + + /** + * Clears the user cache. + */ + void clearCache(); } diff --git a/security/impl/src/main/java/org/wamblee/security/authentication/jpa/JpaUserSet.java b/security/impl/src/main/java/org/wamblee/security/authentication/jpa/JpaUserSet.java index 9f8edb1d..167e6f4d 100644 --- a/security/impl/src/main/java/org/wamblee/security/authentication/jpa/JpaUserSet.java +++ b/security/impl/src/main/java/org/wamblee/security/authentication/jpa/JpaUserSet.java @@ -24,6 +24,7 @@ import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import org.wamblee.cache.Cache; +import org.wamblee.cache.ZeroCache; import org.wamblee.persistence.JpaMergeSupport; import org.wamblee.security.authentication.AbstractUserSet; import org.wamblee.security.authentication.Group; @@ -60,11 +61,7 @@ public class JpaUserSet extends AbstractUserSet { entityManager = aEntityManager; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#userModified(org.wamblee.usermgt.User) - */ + @Override public void userModified(User aUser) { assert aUser.getPrimaryKey() != null; User merged = entityManager.merge(aUser); @@ -76,11 +73,7 @@ public class JpaUserSet extends AbstractUserSet { cache.put(aUser.getName(), new User(aUser)); } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#find(java.lang.String) - */ + @Override public User find(String aName) { User user = cache.get(aName); @@ -93,7 +86,6 @@ public class JpaUserSet extends AbstractUserSet { query.setParameter(User.NAME_PARAM, aName); try { user = query.getSingleResult(); - user = new User(user); setPasswordInfo(user); cache.put(aName, user); return user; @@ -102,20 +94,12 @@ public class JpaUserSet extends AbstractUserSet { } } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#contains(org.wamblee.usermgt.User) - */ + @Override public boolean contains(User aUser) { return find(aUser.getName()) != null; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#add(org.wamblee.usermgt.User) - */ + @Override public boolean add(User aUser) { assert aUser.getPrimaryKey() == null; @@ -131,11 +115,7 @@ public class JpaUserSet extends AbstractUserSet { return true; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#remove(org.wamblee.usermgt.User) - */ + @Override public boolean remove(User aUser) { if (!contains(aUser)) { return false; @@ -148,11 +128,7 @@ public class JpaUserSet extends AbstractUserSet { return true; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#list() - */ + @Override public Set list() { Set users = new TreeSet(); List list = entityManager.createNamedQuery(User.QUERY_ALL_USERS, @@ -166,11 +142,7 @@ public class JpaUserSet extends AbstractUserSet { return users; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#list(org.wamblee.usermgt.Group) - */ + @Override public Set list(Group aGroup) { Set users = new TreeSet(); TypedQuery query = entityManager.createNamedQuery( @@ -186,13 +158,14 @@ public class JpaUserSet extends AbstractUserSet { return users; } - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserSet#size() - */ + @Override public int size() { Long result = entityManager.createNamedQuery(User.QUERY_COUNT_USERS, Long.class).getSingleResult(); return result.intValue(); } + + @Override + public void clearCache() { + cache.clear(); + } } diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/AbstractAuthorizationRule.java b/security/impl/src/main/java/org/wamblee/security/authorization/AbstractAuthorizationRule.java index 69d51b9f..ebd52882 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/AbstractAuthorizationRule.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/AbstractAuthorizationRule.java @@ -23,9 +23,11 @@ import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; +import javax.persistence.Transient; import javax.persistence.Version; import org.wamblee.security.authentication.User; +import org.wamblee.security.authentication.UserAdministration; /** * Represents an authorization rule to determine whether an operation is allowed diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/AnyUserCondition.java b/security/impl/src/main/java/org/wamblee/security/authorization/AnyUserCondition.java index 58457c13..0dfe29ae 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/AnyUserCondition.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/AnyUserCondition.java @@ -20,6 +20,7 @@ import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import org.wamblee.security.authentication.User; +import org.wamblee.security.authentication.UserAdministration; /** * Matches any user. @@ -36,15 +37,14 @@ public class AnyUserCondition extends AbstractUserCondition { public AnyUserCondition() { // Empty. } + + @Override + public void setUserAdmin(UserAdministration aAdmin) { + // Empty. Don't need user admin. + } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.security.authorization.UserCondition#matches(org.wamblee. - * usermgt.User) - */ - public boolean matches(User aUser) { + @Override + public boolean matches(String aUser) { return true; } @@ -57,4 +57,5 @@ public class AnyUserCondition extends AbstractUserCondition { public String toString() { return "AnyUserCondition()"; } + } diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationRule.java b/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationRule.java index 46ef04b9..709591df 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationRule.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationRule.java @@ -16,6 +16,7 @@ package org.wamblee.security.authorization; import org.wamblee.security.authentication.User; +import org.wamblee.security.authentication.UserAdministration; /** * Represents an authorization rule to determine whether an operation is allowed @@ -24,6 +25,12 @@ import org.wamblee.security.authentication.User; * @author Erik Brakkee */ public interface AuthorizationRule { + + /** + * Sets the user admnistration to use. + * @param aAdmin User administration. + */ + void setUserAdministration(UserAdministration aAdmin); /** * Returns the supported object types for which this authorization rule @@ -31,7 +38,7 @@ public interface AuthorizationRule { * * @return Array of supported types. */ - public abstract Class[] getSupportedTypes(); + Class[] getSupportedTypes(); /** * Determines whether an operation is allowed on a certain resource. The @@ -48,7 +55,7 @@ public interface AuthorizationRule { * * @return Authorization result. */ - public abstract AuthorizationResult isAllowed(Object aResource, - Operation aOperation, User aUser); + AuthorizationResult isAllowed(Object aResource, + Operation aOperation, String aUser); } \ No newline at end of file diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationService.java b/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationService.java index c9e3de5d..bfbe0f84 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationService.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/AuthorizationService.java @@ -16,6 +16,7 @@ package org.wamblee.security.authorization; import org.wamblee.security.authentication.UserAccessor; +import org.wamblee.security.authentication.UserAdministration; /** * Service to determine if access to a certain resource is allowed. @@ -92,5 +93,13 @@ public interface AuthorizationService { * User accessor. */ void setUserAccessor(UserAccessor aUserAccessor); + + /** + * Sets the user administration so that the authorization service can check + * information for the the current user. + * + * @param aUserAdmin User administration. + */ + void setUserAdministration(UserAdministration aUserAdmin); } \ No newline at end of file diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/DefaultAuthorizationService.java b/security/impl/src/main/java/org/wamblee/security/authorization/DefaultAuthorizationService.java index 2acc3cfd..7686c334 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/DefaultAuthorizationService.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/DefaultAuthorizationService.java @@ -28,6 +28,7 @@ import javax.persistence.Transient; import org.wamblee.security.authentication.User; import org.wamblee.security.authentication.UserAccessor; +import org.wamblee.security.authentication.UserAdministration; /** * Default implementation of an authorization service. To determine whether @@ -42,8 +43,7 @@ import org.wamblee.security.authentication.UserAccessor; @Entity @DiscriminatorValue("DEFAULT") public class DefaultAuthorizationService extends AbstractAuthorizationService { - - + /** * List of ordered authorization rules. */ @@ -57,18 +57,25 @@ public class DefaultAuthorizationService extends AbstractAuthorizationService { @Transient private UserAccessor userAccessor; + @Transient + private UserAdministration userAdmin; + /** * Constructs the service. * * @param aAccessor * User accessor. + * @param aUserAdmin + * User administration. * @param aName * Name of this instance of the service. */ - public DefaultAuthorizationService(UserAccessor aAccessor, String aName) { + public DefaultAuthorizationService(UserAccessor aAccessor, + UserAdministration aUserAdmin, String aName) { super(aName); rules = new ArrayList(); userAccessor = aAccessor; + userAdmin = aUserAdmin; } /** @@ -77,18 +84,24 @@ public class DefaultAuthorizationService extends AbstractAuthorizationService { public DefaultAuthorizationService() { rules = new ArrayList(); userAccessor = null; + userAdmin = null; } - /** - * Sets the user accessor. - * - * @param aUserAccessor - * User accessor. - */ + @Override public void setUserAccessor(UserAccessor aUserAccessor) { userAccessor = aUserAccessor; } + + @Override + public void setUserAdministration(UserAdministration aUserAdmin) { + userAdmin = aUserAdmin; + System.out.println("Setting userAdmin"); + for (AuthorizationRule rule: rules) { + System.out.println("Setting useradmin on " + rule); + rule.setUserAdministration(userAdmin); + } + } /* * (non-Javadoc) @@ -98,7 +111,7 @@ public class DefaultAuthorizationService extends AbstractAuthorizationService { * .lang.Object, org.wamblee.security.authorization.Operation) */ public boolean isAllowed(Object aResource, Operation aOperation) { - User user = userAccessor.getCurrentUser(); + String user = userAccessor.getCurrentUser(); for (AuthorizationRule rule : rules) { switch (rule.isAllowed(aResource, aOperation, user)) { @@ -144,6 +157,7 @@ public class DefaultAuthorizationService extends AbstractAuthorizationService { * .wamblee.security.authorization.AuthorizationRule) */ public void appendRule(AuthorizationRule aRule) { + aRule.setUserAdministration(userAdmin); rules.add(aRule); } @@ -155,6 +169,7 @@ public class DefaultAuthorizationService extends AbstractAuthorizationService { * (int, org.wamblee.security.authorization.AuthorizationRule) */ public void insertRuleAfter(int aIndex, AuthorizationRule aRule) { + aRule.setUserAdministration(userAdmin); rules.add(aIndex, aRule); } @@ -185,5 +200,8 @@ public class DefaultAuthorizationService extends AbstractAuthorizationService { */ protected void setMappedRules(List aRules) { rules = aRules; + for (AuthorizationRule rule: rules) { + rule.setUserAdministration(userAdmin); + } } } diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/GroupUserCondition.java b/security/impl/src/main/java/org/wamblee/security/authorization/GroupUserCondition.java index 5b39387e..8386d35b 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/GroupUserCondition.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/GroupUserCondition.java @@ -19,8 +19,10 @@ package org.wamblee.security.authorization; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; +import javax.persistence.Transient; import org.wamblee.security.authentication.User; +import org.wamblee.security.authentication.UserAdministration; /** @@ -36,6 +38,9 @@ public class GroupUserCondition extends AbstractUserCondition { */ @Column(name = "GRP") private String group; + + @Transient + private UserAdministration admin; /** * Constructs the condition. @@ -54,16 +59,15 @@ public class GroupUserCondition extends AbstractUserCondition { protected GroupUserCondition() { group = null; } + + @Override + public void setUserAdmin(UserAdministration aAdmin) { + admin = aAdmin; + } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.security.authorization.UserCondition#matches(org.wamblee. - * usermgt.UserAccessor) - */ - public boolean matches(User aUser) { - return aUser.isInGroup(group); + @Override + public boolean matches(String aUser) { + return admin.isInGroup(aUser, group); } /** diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/UrlAuthorizationRule.java b/security/impl/src/main/java/org/wamblee/security/authorization/UrlAuthorizationRule.java index 8e9d1353..3ed810df 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/UrlAuthorizationRule.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/UrlAuthorizationRule.java @@ -31,6 +31,7 @@ import javax.persistence.Transient; import org.apache.log4j.Logger; import org.wamblee.security.authentication.User; +import org.wamblee.security.authentication.UserAdministration; /** * Utility base class for implementation of authentication rules based on the @@ -156,14 +157,14 @@ public abstract class UrlAuthorizationRule extends AbstractAuthorizationRule { * .Object, org.wamblee.security.authorization.Operation) */ public AuthorizationResult isAllowed(Object aResource, - Operation aOperation, User aUser) { + Operation aOperation, String aUser) { if (!resourceClass.isInstance(aResource)) { return UNSUPPORTED_RESOURCE; } String path = getResourcePath(aResource); - return isAllowed(path, aOperation, aUser); + return isAllowedWithPath(path, aOperation, aUser); } /** @@ -178,8 +179,8 @@ public abstract class UrlAuthorizationRule extends AbstractAuthorizationRule { * * @return Authorization result, */ - protected AuthorizationResult isAllowed(String aPath, Operation aOperation, - User aUser) { + protected AuthorizationResult isAllowedWithPath(String aPath, Operation aOperation, + String aUser) { if (!pathCondition.matches(aPath)) { return UNDECIDED; } @@ -317,4 +318,10 @@ public abstract class UrlAuthorizationRule extends AbstractAuthorizationRule { protected void setUserCondition(UserCondition aUserCondition) { userCondition = aUserCondition; } + + @Override + public void setUserAdministration(UserAdministration aAdmin) { + userCondition.setUserAdmin(aAdmin); + } + } diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/UserCondition.java b/security/impl/src/main/java/org/wamblee/security/authorization/UserCondition.java index 7f52e0d1..76387276 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/UserCondition.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/UserCondition.java @@ -16,6 +16,8 @@ package org.wamblee.security.authorization; import org.wamblee.security.authentication.User; +import org.wamblee.security.authentication.UserAdminInitializer; +import org.wamblee.security.authentication.UserAdministration; /** * Condition used to match a user against a specified set of users. @@ -23,6 +25,12 @@ import org.wamblee.security.authentication.User; * @author Erik Brakkee */ public interface UserCondition { + + /** + * Sets the user administration object. + * @param aAdmin User administration. + */ + void setUserAdmin(UserAdministration aAdmin); /** * Determines if the condition matches. @@ -32,6 +40,6 @@ public interface UserCondition { * * @return True if the condition matches, false otherwise. */ - public abstract boolean matches(User aUser); + boolean matches(String aUser); } \ No newline at end of file diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java b/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java index 9683888f..4bce7aef 100644 --- a/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java +++ b/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java @@ -21,6 +21,7 @@ import javax.persistence.NonUniqueResultException; import org.wamblee.persistence.JpaMergeSupport; import org.wamblee.security.authentication.UserAccessor; +import org.wamblee.security.authentication.UserAdministration; import org.wamblee.security.authorization.AbstractAuthorizationService; import org.wamblee.security.authorization.AbstractAuthorizationRule; import org.wamblee.security.authorization.AuthorizationRule; @@ -51,6 +52,11 @@ public class JpaAuthorizationService implements AuthorizationService { * User accessor. */ private UserAccessor userAccessor; + + /** + * User administration. + */ + private UserAdministration userAdmin; /** * Name of the service. @@ -76,16 +82,18 @@ public class JpaAuthorizationService implements AuthorizationService { * Entity manager. * @param aAccessor * User accessor. + * @param aUserAdmin User administration. * @param aRefresh * Whether or not to refresh the state of the service at the * start of every operation. */ public JpaAuthorizationService(String aName, EntityManager aEntityManager, - UserAccessor aAccessor, long aRefreshInterval) { + UserAccessor aAccessor, UserAdministration aUserAdmin, long aRefreshInterval) { entityManager = aEntityManager; refreshInterval = aRefreshInterval; lastRefreshTime = System.currentTimeMillis(); userAccessor = aAccessor; + userAdmin = aUserAdmin; name = aName; } @@ -93,33 +101,32 @@ public class JpaAuthorizationService implements AuthorizationService { public void setUserAccessor(UserAccessor aUserAccessor) { userAccessor = aUserAccessor; } - - /** - * Initialize service if needed. - * - */ - private void initialize() { - if (service == null) { - service = refreshByReload(); - } + + @Override + public void setUserAdministration(UserAdministration aUserAdmin) { + userAdmin = aUserAdmin; } private AuthorizationService refreshByReload() { - AuthorizationService service; + if ( userAdmin == null ) { + throw new IllegalArgumentException("useradmin is null"); + } + AuthorizationService svc; try { - service = entityManager.createNamedQuery( + svc = entityManager.createNamedQuery( AbstractAuthorizationService.QUERY_FIND_BY_NAME, AbstractAuthorizationService.class).setParameter( DefaultAuthorizationService.NAME_PARAM, name).getSingleResult(); - service.setUserAccessor(userAccessor); + svc.setUserAccessor(userAccessor); + svc.setUserAdministration(userAdmin); } catch (NonUniqueResultException e) { throw new IllegalArgumentException( "Returned more than one service for name '" + name + "'"); } catch (NoResultException e) { - service = new DefaultAuthorizationService(userAccessor, name); - entityManager.persist(service); + svc = new DefaultAuthorizationService(userAccessor, userAdmin, name); + entityManager.persist(svc); } - return service; + return svc; } /* @@ -130,7 +137,6 @@ public class JpaAuthorizationService implements AuthorizationService { * .lang.Object, org.wamblee.security.authorization.Operation) */ public boolean isAllowed(Object aResource, Operation aOperation) { - initialize(); refresh(); return service.isAllowed(aResource, aOperation); @@ -143,7 +149,6 @@ public class JpaAuthorizationService implements AuthorizationService { * org.wamblee.security.authorization.Operation) */ public T check(T aResource, Operation aOperation) { - initialize(); refresh(); return service.check(aResource, aOperation); @@ -155,7 +160,6 @@ public class JpaAuthorizationService implements AuthorizationService { * @see org.wamblee.security.authorization.AuthorizationService#getRules() */ public AuthorizationRule[] getRules() { - initialize(); refresh(); return service.getRules(); @@ -169,12 +173,22 @@ public class JpaAuthorizationService implements AuthorizationService { * .wamblee.security.authorization.AuthorizationRule) */ public void appendRule(AuthorizationRule aRule) { - initialize(); - refresh(); - service.appendRule(aRule); - save(); // service might still be detached as service is cached. + AuthorizationService svc = refreshByReload(); + svc.appendRule(aRule); + // Setting service to null will force reload the next time the + // service is used. This deals effectively with the case where the + // current transaction would roll back and the change would not have been made. + setService(null); } - + + private synchronized AuthorizationService getService() { + return service; + } + + private synchronized void setService(AuthorizationService aSvc) { + service = aSvc; + } + /* * (non-Javadoc) * @@ -182,10 +196,9 @@ public class JpaAuthorizationService implements AuthorizationService { * org.wamblee.security.authorization.AuthorizationService#removeRule(int) */ public void removeRule(int aIndex) { - initialize(); - refresh(); - service.removeRule(aIndex); - save(); // service might still be detached as service is cached. + AuthorizationService svc = refreshByReload(); + svc.removeRule(aIndex); + setService(null); } /* @@ -196,10 +209,9 @@ public class JpaAuthorizationService implements AuthorizationService { * (int, org.wamblee.security.authorization.AuthorizationRule) */ public void insertRuleAfter(int aIndex, AuthorizationRule aRule) { - initialize(); - refresh(); - service.insertRuleAfter(aIndex, aRule); - save(); // service might still be detached as service is cached. + AuthorizationService svc = refreshByReload(); + svc.insertRuleAfter(aIndex, aRule); + setService(null); } /** @@ -208,18 +220,9 @@ public class JpaAuthorizationService implements AuthorizationService { private synchronized void refresh() { long time = System.currentTimeMillis(); - if ((time - lastRefreshTime) > refreshInterval) { + if (service == null || (time - lastRefreshTime) > refreshInterval) { service = refreshByReload(); lastRefreshTime = time; } } - - /** - * Saves any changes to the service state if necessary. - */ - private void save() { - AuthorizationService merged = entityManager.merge(service); - entityManager.flush(); - JpaMergeSupport.merge(merged, service); - } } diff --git a/security/impl/src/test/java/org/wamblee/security/authentication/UserAdministrationImplTest.java b/security/impl/src/test/java/org/wamblee/security/authentication/UserAdministrationImplTest.java index 281684b4..76e7b46f 100644 --- a/security/impl/src/test/java/org/wamblee/security/authentication/UserAdministrationImplTest.java +++ b/security/impl/src/test/java/org/wamblee/security/authentication/UserAdministrationImplTest.java @@ -12,12 +12,13 @@ * 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 junit.framework.TestCase; import org.apache.log4j.Logger; +import org.junit.Test; import org.wamblee.security.authentication.Group; import org.wamblee.security.authentication.GroupSet; @@ -32,7 +33,7 @@ import org.wamblee.security.authentication.UserSet; import org.wamblee.security.authentication.UserMgtException.Reason; import org.wamblee.security.encryption.Md5HexMessageDigester; - +import java.util.List; import java.util.Set; /** @@ -83,10 +84,7 @@ public class UserAdministrationImplTest extends TestCase { Reason.INVALID_GROUPNAME, "Invalid group")); } - protected User createUser(String aName, String aPassword, Group aGroup) - throws UserMgtException { - return UsermgtTestUtils.createUser(aName, aPassword, aGroup); - } + // Construction /** * Constructs the admin, verify it contains no users and no groups. @@ -98,179 +96,112 @@ public class UserAdministrationImplTest extends TestCase { 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)); + // 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)); } - private void createInvalidGroup(String aUsername) { + public void testCreateDuplicateUser() { + admin.createUser(USER1, PASS1); + try { - admin.createGroup(aUsername); + admin.createUser(USER1, PASS2); fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e - .getReason()); - assertEquals(0, admin.getGroupCount()); + assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason()); + assertEquals(1, admin.getUserCount()); } } /** - * Creates a new group with an invalid name. Verifies that the appropriate + * Constructs users with invalid names. 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(); + public void testCreateInvalidUserName() throws UserMgtException { + createInvalidUser(""); + createInvalidUser("0abc"); // should not start with digits + createInvalidUser("a b"); // should not contain spaces + createInvalidUser(" aa"); + createInvalidUser("aa "); } - /** - * 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(); + public void testRenameUser() { + admin.createUser(USER1, PASS1); + admin.renameUser(USER1, USER2); + List users = admin.getUsers(); assertEquals(1, users.size()); - assertEquals(1, admin.getUserCount()); - assertTrue(users.contains(user)); + assertTrue(users.contains(USER2)); } - private void createInvalidUser(String aUsername, Group aGroup) { + public void testRenameUserInvalidUsername() { + admin.createUser(USER1, PASS1); try { - admin.createUser(aUsername, "pass", aGroup); + admin.renameUser(USER1, "a b"); fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.INVALID_USERNAME, e - .getReason()); - assertEquals(0, admin.getUserCount()); + assertEquals(e.getReason(), Reason.INVALID_USERNAME); } } - /** - * 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); + public void testRenameUserToItself() { + admin.createUser(USER1, PASS1); + admin.renameUser(USER1, USER1); + assertTrue(admin.checkUser(USER1)); } - /** - * 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); - + public void testRenameUserDuplicateUser() { + admin.createUser(USER1, PASS1); + admin.createUser(USER2, PASS2); try { - admin.createUser(USER1, PASS2, group); + admin.renameUser(USER1, USER2); fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason()); - assertEquals(1, admin.getUserCount()); + assertEquals(e.getReason(), Reason.DUPLICATE_USER); } } - /** - * 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)); + // 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)); } - /** - * 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)); + public void testCreateGroupInvalidName() { + createInvalidGroup(""); + createInvalidGroup("0abc"); // should not start with digits + createInvalidGroup("a b"); // should not contain spaces + createInvalidGroup(" aa"); + createInvalidGroup("aa "); } - /** - * 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)); + public void testCreateGroupDuplicateGroup() { + admin.createGroup(GROUP1); try { - admin.addUserToGroup(user, group); + admin.createGroup(GROUP1); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.USER_ALREADY_IN_GROUP, e - .getReason()); + assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason()); + assertEquals(1, admin.getGroupCount()); return; } @@ -278,353 +209,267 @@ public class UserAdministrationImplTest extends TestCase { 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); + // 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 { - admin.addUserToGroup(user, group); + boolean changed = admin.changePassword(USER1 + "unknown", PASS2, + PASS1); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason()); - - return; + assertEquals(e.getReason(), Reason.UNKNOWN_USER); } - - 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); + 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.addUserToGroup(user, group2); + admin.setPassword(USER1 + "unknown", PASS2); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason()); - - return; + assertEquals(e.getReason(), Reason.UNKNOWN_USER); } - - 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); + // Group membership + // boolean isInGroup(String aUser, String aGroup); + // List getUsers(String aGroup); + // void addUserToGroup(String aUser, String aGroup); + // void removeUserFromGroup(String aUser, String aGroup);} - 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)); + 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)); } - /** - * 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); + 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.removeUserFromGroup(user, group); + admin.addUserToGroup(USER1, GROUP2); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason()); + assertEquals(e.getReason(), Reason.UNKNOWN_USER); } - } - /** - * 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); + } + public void testAddUserToGroupUnknownGroup() { + admin.createUser(USER1, PASS1); try { - admin.removeUserFromGroup(user, group2); + admin.addUserToGroup(USER1, GROUP2); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason()); + assertEquals(e.getReason(), Reason.UNKNOWN_GROUP); } } - /** - * 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); + 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(user, group); + admin.removeUserFromGroup(USER1, GROUP2); + fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.USER_MUST_BE_IN_A_GROUP, e - .getReason()); + assertEquals(Reason.USER_NOT_IN_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)); - + public void testRemoveUserFromGroupUnknowUser() { + admin.createGroup(GROUP1); 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; - } - + admin.removeUserFromGroup(USER1, GROUP2); fail(); + } catch (UserMgtException e) { + assertEquals(Reason.UNKNOWN_USER, e.getReason()); } - - 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); - + public void testRemoveUserFromGroupUnknownGroup() { + admin.createUser(USER1, PASS1); try { - admin.renameUser(user1, USER2); + admin.removeUserFromGroup(USER1, GROUP2); + fail(); } catch (UserMgtException e) { - assertEquals(e.getReason(), Reason.INVALID_USERNAME); + assertEquals(Reason.UNKNOWN_GROUP, e.getReason()); } } - /** - * 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)); + // 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(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; - } - + admin.renameGroup(GROUP1, "a b"); fail(); - - return; + } catch (UserMgtException e) { + assertEquals(Reason.INVALID_GROUPNAME, e.getReason()); } - - 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); - + public void testRenameGroupGroupAlreadyExists() { + admin.createGroup(GROUP1); + admin.createGroup(GROUP2); try { - admin.renameGroup(group, "a b"); + admin.renameGroup(GROUP1, GROUP2); + fail(); } catch (UserMgtException e) { - assertEquals(e.getReason(), Reason.INVALID_GROUPNAME); + assertEquals(Reason.DUPLICATE_GROUP, e.getReason()); } } - /** - * 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()); + // void removeGroup(String aGroup); - User user2 = createUser(USER2, PASS2, group); + public void testRemoveGroup() { + admin.createGroup(GROUP1); + admin.removeGroup(GROUP1); + List groups = admin.getGroups(); + assertEquals(0, groups.size()); + } + public void testRemoveGroupGroupDoesNotExist() { try { - admin.removeUser(user2); + admin.removeGroup(GROUP1); + fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason()); + assertEquals(e.getReason(), Reason.UNKNOWN_GROUP); } } - /** - * 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); + 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.removeGroup(group1); + admin.createGroup(aUsername); + fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.GROUP_STILL_OCCUPIED, e + assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e .getReason()); - - return; + assertEquals(0, admin.getGroupCount()); } - - 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); - + private void createInvalidUser(String aUsername) { try { - admin.removeGroup(group2); + admin.createUser(aUsername, "pass"); + fail(); } catch (UserMgtException e) { - assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason()); + assertEquals(UserMgtException.Reason.INVALID_USERNAME, e + .getReason()); + assertEquals(0, admin.getUserCount()); } } /** - * Changes the password, verifies that this succeeds. + * 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. * - * @throws UserMgtException */ - public void testChangePassword() throws UserMgtException { - Group group = admin.createGroup(GROUP1); - User user = admin.createUser(USER1, PASS1, group); - user.changePassword(PASS1, PASS2); + public void testGetUsersAndGroups() throws UserMgtException { + admin.createGroup(GROUP1); + admin.createGroup(GROUP2); - // retrieve the user and verifies the password hasn't changed. - User user2 = admin.getUser(USER1); + admin.createUser(USER1, PASS1); + admin.addUserToGroup(USER1, GROUP1); + admin.addUserToGroup(USER1, GROUP2); - try { - user2.checkPassword(PASS2); - fail(); // password should not have changed already. - } catch (UserMgtException e) { - // ok. - } + admin.createUser(USER2, PASS2); + admin.addUserToGroup(USER2, GROUP2); - // now notify the admin of the change in the user - admin.userModified(user); + List users = admin.getUsers(); + assertEquals(2, users.size()); + assertTrue(users.contains(USER1)); + assertTrue(users.contains(USER2)); - user2 = admin.getUser(USER1); - user2.checkPassword(PASS2); // this time it should succeed. + 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()); } /** @@ -632,14 +477,15 @@ public class UserAdministrationImplTest extends TestCase { * */ public void testPerformanceFindUserByName() throws UserMgtException { - Group group = admin.createGroup(GROUP1); - admin.createUser(USER1, PASS1, group); + 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.getUser(USER1); + admin.checkUser(USER1); } LOGGER.info("Looked up a user " + n + " times in " + diff --git a/security/impl/src/test/java/org/wamblee/security/authentication/UsermgtTestUtils.java b/security/impl/src/test/java/org/wamblee/security/authentication/UsermgtTestUtils.java index c6bc3a3d..c1dedaa4 100644 --- a/security/impl/src/test/java/org/wamblee/security/authentication/UsermgtTestUtils.java +++ b/security/impl/src/test/java/org/wamblee/security/authentication/UsermgtTestUtils.java @@ -53,9 +53,11 @@ public class UsermgtTestUtils { public static User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException { - return new User(aName, aPassword, aGroup, new RegexpNameValidator( + User user = new User(aName, aPassword, new RegexpNameValidator( RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must be at least 6 chars"), new Md5HexMessageDigester()); + user.addGroup(aGroup); + return user; } public static void addUserToGroup(User aUser, Group aGroup) diff --git a/security/impl/src/test/java/org/wamblee/security/authorization/AuthorizationServiceTest.java b/security/impl/src/test/java/org/wamblee/security/authorization/AuthorizationServiceTest.java index 4fbef86e..50c73dca 100644 --- a/security/impl/src/test/java/org/wamblee/security/authorization/AuthorizationServiceTest.java +++ b/security/impl/src/test/java/org/wamblee/security/authorization/AuthorizationServiceTest.java @@ -19,7 +19,9 @@ import junit.framework.TestCase; import static org.wamblee.security.authorization.AuthorizationResult.DENIED; import static org.wamblee.security.authorization.AuthorizationResult.GRANTED; +import org.junit.Ignore; import org.wamblee.security.authentication.UserAccessor; +import org.wamblee.security.authentication.UserAdministration; /** * Tests the authorization service. @@ -35,6 +37,9 @@ public class AuthorizationServiceTest extends TestCase { private AuthorizationService service; + private TestUserAccessor userAccessor; + + protected AuthorizationService getService() { return service; } @@ -48,6 +53,8 @@ public class AuthorizationServiceTest extends TestCase { protected void setUp() throws Exception { super.setUp(); + userAccessor = new TestUserAccessor(); + rule1 = createRule(GRANTED, "users", "/oni/", AllOperation.class); rule2 = createRule(DENIED, "users", "/abc/", ReadOperation.class); rule3 = createRule(GRANTED, "users", "/abc/", AllOperation.class); @@ -65,8 +72,12 @@ public class AuthorizationServiceTest extends TestCase { ((TestAuthorizationRule) rule3).reset(); } - protected UserAccessor createUserAccessor() { - return new TestUserAccessor(); + protected UserAccessor getUserAccessor() { + return userAccessor; + } + + protected UserAdministration getUserAdministration() { + return userAccessor.getUserAdmin(); } /** @@ -76,8 +87,8 @@ public class AuthorizationServiceTest extends TestCase { */ protected AuthorizationService createService() { DefaultAuthorizationService service = new DefaultAuthorizationService(); - service.setUserAccessor(createUserAccessor()); - + service.setUserAccessor(getUserAccessor()); + service.setUserAdministration(getUserAdministration()); return service; } diff --git a/security/impl/src/test/java/org/wamblee/security/authorization/TestAuthorizationRule.java b/security/impl/src/test/java/org/wamblee/security/authorization/TestAuthorizationRule.java index 9eac9550..2cae2732 100644 --- a/security/impl/src/test/java/org/wamblee/security/authorization/TestAuthorizationRule.java +++ b/security/impl/src/test/java/org/wamblee/security/authorization/TestAuthorizationRule.java @@ -69,17 +69,9 @@ public class TestAuthorizationRule extends UrlAuthorizationRule { return ((TestResource) aResource).getPath(); } - /* - * (non-Javadoc) - * - * @see - * org.wamblee.security.authorization.UrlAuthorizationRule#isAllowed(java - * .lang.Object, org.wamblee.security.authorization.Operation, - * org.wamblee.usermgt.UserAccessor) - */ @Override public AuthorizationResult isAllowed(Object aResource, - Operation aOperation, User aUser) { + Operation aOperation, String aUser) { AuthorizationResult result = super.isAllowed(aResource, aOperation, aUser); diff --git a/security/impl/src/test/java/org/wamblee/security/authorization/TestUserAccessor.java b/security/impl/src/test/java/org/wamblee/security/authorization/TestUserAccessor.java index f65609ef..73ed12c8 100644 --- a/security/impl/src/test/java/org/wamblee/security/authorization/TestUserAccessor.java +++ b/security/impl/src/test/java/org/wamblee/security/authorization/TestUserAccessor.java @@ -42,13 +42,10 @@ public class TestUserAccessor implements UserAccessor { private static final String GROUP = "users"; - /* - * (non-Javadoc) - * - * @see org.wamblee.usermgt.UserAccessor#getCurrentUser() - */ - public User getCurrentUser() { - UserAdministration admin = new UserAdministrationImpl( + private UserAdministration userAdmin; + + public TestUserAccessor() { + userAdmin = new UserAdministrationImpl( new InMemoryUserSet(new RegexpNameValidator( RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"), @@ -58,13 +55,24 @@ public class TestUserAccessor implements UserAccessor { new RegexpNameValidator(RegexpNameValidator.ID_PATTERN, Reason.INVALID_GROUPNAME, "Invalid group")); - try { - Group group = admin.createGroup(GROUP); - - return admin.createUser(USER, PASSWORD, group); - } catch (UserMgtException e) { - TestCase.fail(e.getMessage()); - throw new RuntimeException(e); - } + userAdmin.createGroup(GROUP); + userAdmin.createUser(USER, PASSWORD); + userAdmin.addUserToGroup(USER, GROUP); + } + + // NOTE: This is only for test. Normally the user accessor would not depend + // on user administration. This just ensures that a user administration is created + // that knows about the given user. + public UserAdministration getUserAdmin() { + return userAdmin; + } + + /* + * (non-Javadoc) + * + * @see org.wamblee.usermgt.UserAccessor#getCurrentUser() + */ + public String getCurrentUser() { + return USER; } } diff --git a/security/impl/src/test/java/org/wamblee/security/authorization/UrlAuthorizationRuleTest.java b/security/impl/src/test/java/org/wamblee/security/authorization/UrlAuthorizationRuleTest.java index 1f7b6369..8625f9ed 100644 --- a/security/impl/src/test/java/org/wamblee/security/authorization/UrlAuthorizationRuleTest.java +++ b/security/impl/src/test/java/org/wamblee/security/authorization/UrlAuthorizationRuleTest.java @@ -29,6 +29,14 @@ import org.wamblee.security.authentication.User; * @author Erik Brakkee */ public class UrlAuthorizationRuleTest extends TestCase { + + private TestUserAccessor userAccessor; + + public void setUp() { + userAccessor = new TestUserAccessor(); + + } + /** * Constructs the rule with a result of UNDECIDED. Verifies that an * IllegalArgumentException is thrown. @@ -64,14 +72,16 @@ public class UrlAuthorizationRuleTest extends TestCase { public void testUnsupportedObject() { AuthorizationRule rule = new TestAuthorizationRule(GRANTED, "users", "/path", ReadOperation.class); + rule.setUserAdministration(userAccessor.getUserAdmin()); assertEquals(UNSUPPORTED_RESOURCE, rule.isAllowed("hello", - new ReadOperation(), new TestUserAccessor().getCurrentUser())); + new ReadOperation(), userAccessor.getCurrentUser())); } public void testMatchingScenarios() { AuthorizationRule rule = new TestAuthorizationRule(GRANTED, "users", "/path/", ReadOperation.class); - User user = new TestUserAccessor().getCurrentUser(); + rule.setUserAdministration(userAccessor.getUserAdmin()); + String user = userAccessor.getCurrentUser(); // everything matches assertEquals(GRANTED, rule.isAllowed(new TestResource("/path/a"), @@ -90,6 +100,7 @@ public class UrlAuthorizationRuleTest extends TestCase { // group does not match. AuthorizationRule rule2 = new TestAuthorizationRule(GRANTED, "users2", "/path/", ReadOperation.class); + rule2.setUserAdministration(userAccessor.getUserAdmin()); assertEquals(UNDECIDED, rule2.isAllowed(new TestResource("/path/a"), new ReadOperation(), user)); } diff --git a/security/jpatest/src/test/java/org/wamblee/security/authorization/jpa/JpaAuthorizationServiceTest.java b/security/jpatest/src/test/java/org/wamblee/security/authorization/jpa/JpaAuthorizationServiceTest.java index 2eac1c5b..afb0d405 100644 --- a/security/jpatest/src/test/java/org/wamblee/security/authorization/jpa/JpaAuthorizationServiceTest.java +++ b/security/jpatest/src/test/java/org/wamblee/security/authorization/jpa/JpaAuthorizationServiceTest.java @@ -82,7 +82,7 @@ public class JpaAuthorizationServiceTest extends AuthorizationServiceTest { jpaTester.getJpaBuilder(), AuthorizationService.class); JpaAuthorizationService service = new JpaAuthorizationService( "DEFAULT", factory.getTransactionScopedEntityManager(), - createUserAccessor(), 10000); + getUserAccessor(), getUserAdministration(), 10000); return factory.getProxy(service); } -- 2.31.1