You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by ep...@apache.org on 2003/08/24 00:02:04 UTC
cvs commit: jakarta-turbine-fulcrum/security/src/java/org/apache/fulcrum/security/spi/memory/simple MemoryUserManagerImpl.java MemoryPermissionManagerImpl.java MemoryRoleManagerImpl.java MemoryGroupManagerImpl.java
epugh 2003/08/23 15:02:04
Added: security/src/java/org/apache/fulcrum/security/spi/memory/simple
MemoryUserManagerImpl.java
MemoryPermissionManagerImpl.java
MemoryRoleManagerImpl.java
MemoryGroupManagerImpl.java
Log:
Revision Changes Path
1.1 jakarta-turbine-fulcrum/security/src/java/org/apache/fulcrum/security/spi/memory/simple/MemoryUserManagerImpl.java
Index: MemoryUserManagerImpl.java
===================================================================
package org.apache.fulcrum.security.spi.memory.simple;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Turbine" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fulcrum.factory.FactoryService;
import org.apache.fulcrum.security.GroupManager;
import org.apache.fulcrum.security.RoleManager;
import org.apache.fulcrum.security.acl.AccessControlList;
import org.apache.fulcrum.security.acl.DefaultAccessControlList;
import org.apache.fulcrum.security.entity.Group;
import org.apache.fulcrum.security.entity.Role;
import org.apache.fulcrum.security.entity.User;
import org.apache.fulcrum.security.model.simple.entity.SimpleGroup;
import org.apache.fulcrum.security.model.simple.entity.SimpleRole;
import org.apache.fulcrum.security.model.simple.entity.SimpleUser;
import org.apache.fulcrum.security.model.simple.manager.*;
import org.apache.fulcrum.security.util.DataBackendException;
import org.apache.fulcrum.security.util.EntityExistsException;
import org.apache.fulcrum.security.util.GroupSet;
import org.apache.fulcrum.security.util.PasswordMismatchException;
import org.apache.fulcrum.security.util.RoleSet;
import org.apache.fulcrum.security.util.UnknownEntityException;
/**
* This implementation keeps all objects in memory. This is mostly meant to help
* with testing and prototyping of ideas.
*
* @todo Need to load up Crypto component and actually encrypt passwords!
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @version $Id: MemoryUserManagerImpl.java,v 1.1 2003/08/23 22:02:04 epugh Exp $
*/
public class MemoryUserManagerImpl extends AbstractLogEnabled implements SimpleUserManager, Composable
{
/** Logging */
private static Log log = LogFactory.getLog(MemoryUserManagerImpl.class);
private static List users = new ArrayList();
/** A factory to construct ACL Objects */
private FactoryService aclFactoryService = null;
private ComponentManager manager = null;
/** Our groupManager **/
private GroupManager groupManager;
/** Our roleManager **/
private RoleManager roleManager;
/** Our Unique ID counter */
private static int uniqueId = 0;
/**
* @return
*/
private GroupManager getGroupManager() throws ComponentException
{
if (groupManager == null)
{
groupManager = (GroupManager) manager.lookup(GroupManager.ROLE);
}
return groupManager;
}
/**
* @return
*/
private RoleManager getRoleManager() throws ComponentException
{
if (roleManager == null)
{
roleManager = (RoleManager) manager.lookup(RoleManager.ROLE);
}
return roleManager;
}
/**
* Check whether a specified user's account exists.
*
* The login name is used for looking up the account.
*
* @param user The user to be checked.
* @return true if the specified account exists
* @throws DataBackendException if there was an error accessing
* the data backend.
*/
public boolean checkExists(User user) throws DataBackendException
{
boolean exists = false;
for (Iterator i = users.iterator(); i.hasNext();)
{
User u = (User) i.next();
if (u.getName().equalsIgnoreCase(user.getName()) | u.getId() == user.getId())
{
exists = true;
}
}
return exists;
}
/**
* Check whether a specified user's account exists.
*
* The login name is used for looking up the account.
*
* @param userName The name of the user to be checked.
* @return true if the specified account exists
* @throws DataBackendException if there was an error accessing
* the data backend.
*/
public boolean checkExists(String userName) throws DataBackendException
{
List tempUsers = new ArrayList();
for (Iterator i = users.iterator(); i.hasNext();)
{
User user = (User) i.next();
if (user.getName().equalsIgnoreCase(userName))
{
tempUsers.add(user);
}
}
if (tempUsers.size() > 1)
{
throw new DataBackendException("Multiple Users with same username '" + userName + "'");
}
return (tempUsers.size() == 1);
}
/**
* Retrieve a user from persistent storage using username as the
* key.
*
* @param userName the name of the user.
* @return an User object.
* @exception UnknownEntityException if the user's account does not
* exist in the database.
* @exception DataBackendException if there is a problem accessing the
* storage.
*/
public User getUser(String userName) throws UnknownEntityException, DataBackendException
{
List tempUsers = new ArrayList();
for (Iterator i = users.iterator(); i.hasNext();)
{
User user = (User) i.next();
if (user.getName().equalsIgnoreCase(userName))
{
tempUsers.add(user);
}
}
if (tempUsers.size() > 1)
{
throw new DataBackendException("Multiple Users with same username '" + userName + "'");
}
if (tempUsers.size() == 1)
{
return (User) tempUsers.get(0);
}
throw new UnknownEntityException("Unknown user '" + userName + "'");
}
/**
* Retrieve a user from persistent storage using username as the
* key, and authenticate the user. The implementation may chose
* to authenticate to the server as the user whose data is being
* retrieved.
*
* @param userName the name of the user.
* @param password the user supplied password.
* @return an User object.
* @exception PasswordMismatchException if the supplied password was
* incorrect.
* @exception UnknownEntityException if the user's account does not
* exist in the database.
* @exception DataBackendException if there is a problem accessing the
* storage.
*/
public User getUser(String userName, String password)
throws PasswordMismatchException, UnknownEntityException, DataBackendException
{
User user = getUser(userName);
authenticate(user, password);
return user;
}
/**
* Authenticate an User with the specified password. If authentication
* is successful the method returns nothing. If there are any problems,
* exception was thrown.
*
* @param user an User object to authenticate.
* @param password the user supplied password.
* @exception PasswordMismatchException if the supplied password was
* incorrect.
* @exception UnknownEntityException if the user's account does not
* exist in the database.
* @exception DataBackendException if there is a problem accessing the
* storage.
*/
public void authenticate(User user, String password)
throws PasswordMismatchException, UnknownEntityException, DataBackendException
{
if (!checkExists(user))
{
throw new UnknownEntityException("The account '" + user.getName() + "' does not exist");
}
// log.debug("Supplied Pass: " + password);
// log.debug("User Pass: " + user.getPassword());
/*
* Unix crypt needs the existing, encrypted password text as
* salt for checking the supplied password. So we supply it
* into the checkPassword routine
*/
if (!password.equals(user.getPassword()))
{
throw new PasswordMismatchException("The passwords do not match");
}
}
/**
* Change the password for an User. The user must have supplied the
* old password to allow the change.
*
* @param user an User to change password for.
* @param oldPassword The old password to verify
* @param newPassword The new password to set
* @exception PasswordMismatchException if the supplied password was
* incorrect.
* @exception UnknownEntityException if the user's account does not
* exist in the database.
* @exception DataBackendException if there is a problem accessing the
* storage.
*/
public void changePassword(User user, String oldPassword, String newPassword)
throws PasswordMismatchException, UnknownEntityException, DataBackendException
{
if (!checkExists(user))
{
throw new UnknownEntityException("The account '" + user.getName() + "' does not exist");
}
if (!oldPassword.equals(user.getPassword()))
{
throw new PasswordMismatchException("The supplied old password for '" + user.getName() + "' was incorrect");
}
user.setPassword(newPassword);
// save the changes in the database imediately, to prevent the password
// being 'reverted' to the old value if the user data is lost somehow
// before it is saved at session's expiry.
saveUser(user);
}
/**
* Forcibly sets new password for an User.
*
* This is supposed by the administrator to change the forgotten or
* compromised passwords. Certain implementatations of this feature
* would require administrative level access to the authenticating
* server / program.
*
* @param user an User to change password for.
* @param password the new password.
* @exception UnknownEntityException if the user's record does not
* exist in the database.
* @exception DataBackendException if there is a problem accessing the
* storage.
*/
public void forcePassword(User user, String password) throws UnknownEntityException, DataBackendException
{
if (!checkExists(user))
{
throw new UnknownEntityException("The account '" + user.getName() + "' does not exist");
}
user.setPassword(password);
// save the changes in the database immediately, to prevent the
// password being 'reverted' to the old value if the user data
// is lost somehow before it is saved at session's expiry.
saveUser(user);
}
/**
* Creates new user account with specified attributes.
*
* @param user The object describing account to be created.
* @param initialPassword the password for the new account
* @throws DataBackendException if there was an error accessing
the data backend.
* @throws EntityExistsException if the user account already exists.
*/
public void createAccount(User user, String initialPassword) throws EntityExistsException, DataBackendException
{
if (StringUtils.isEmpty(user.getName()))
{
throw new DataBackendException("Could not create " + "an user with empty name!");
}
if (checkExists(user))
{
throw new EntityExistsException("The account '" + user.getName() + "' already exists");
}
user.setPassword(initialPassword);
try
{
users.remove(user);
user.setId(getUniqueId());
users.add(user);
}
catch (Exception e)
{
throw new DataBackendException("Failed to create account '" + user.getName() + "'", e);
}
}
/**
* Construct a blank User object.
*
* This method calls getUserClass, and then creates a new object using
* the default constructor.
*
* @return an object implementing User interface.
* @throws UnknownEntityException if the object could not be instantiated.
*/
public User getUserInstance() throws UnknownEntityException
{
User user;
try
{
user = (User) new SimpleUser();
}
catch (Exception e)
{
throw new UnknownEntityException("Failed instantiate an User implementation object", e);
}
return user;
}
/**
* Construct a blank User object.
*
* This method calls getUserClass, and then creates a new object using
* the default constructor.
*
* @param userName The name of the user.
*
* @return an object implementing User interface.
*
* @throws UnknownEntityException if the object could not be instantiated.
*/
public User getUserInstance(String userName) throws UnknownEntityException
{
User user = getUserInstance();
user.setName(userName);
return user;
}
/**
* Revokes all groups from a user
*
* This method is used when deleting an account.
*
* @param user the User.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the account is not present.
*/
public synchronized void revokeAll(User user) throws DataBackendException, UnknownEntityException
{
boolean userExists = false;
try
{
userExists = checkExists(user);
if (userExists)
{
((SimpleUser) user).setGroups(new GroupSet());
return;
}
}
catch (Exception e)
{
throw new DataBackendException("revokeAll(User) failed", e);
}
finally
{
}
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
/*-----------------------------------------------------------------------
Security management
-----------------------------------------------------------------------*/
/**
* Grant an User a Role in a Group.
*
* @param user the user.
* @param group the group.
* @param role the role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if user account, group or role is not
* present.
*/
/* public synchronized void grant(User user, Group group, Role role)
throws DataBackendException, UnknownEntityException
{
boolean userExists = false;
boolean groupExists = false;
boolean roleExists = false;
try
{
userExists = checkExists(user);
groupExists = checkExists(group);
roleExists = checkExists(role);
if (userExists && groupExists && roleExists)
{
((SimpleUser) user).addGroup(group);
((SimpleUser) user).addRole(role);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("grant(User,Group,Role) failed", e);
}
finally
{
}
if (!userExists)
{
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
}
*/
/**
* Revoke a Role in a Group from an User.
*
* @param user the user.
* @param group the group.
* @param role the role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if user account, group or role is not
* present.
*/
/*
*
public synchronized void revoke(User user, Group group, Role role)
throws DataBackendException, UnknownEntityException
{
boolean userExists = false;
boolean groupExists = false;
boolean roleExists = false;
try
{
userExists = checkExists(user);
groupExists = checkExists(group);
roleExists = checkExists(role);
if (userExists && groupExists && roleExists)
{
((SimpleUser) user).getGroups().remove(group);
((SimpleUser) user).getRoles().remove(role);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("revoke(User,Role,Group) failed", e);
}
finally
{
}
if (!userExists)
{
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
}
*/
/**
* Determines if the <code>Group</code> exists in the security system.
*
* @param group a <code>Group</code> value
* @return true if the group exists in the system, false otherwise
* @throws DataBackendException when more than one Group with
* the same name exists.
* @throws Exception A generic exception.
*/
private boolean checkExists(Group group) throws DataBackendException, Exception
{
return getGroupManager().checkExists(group);
}
/**
* Determines if the <code>Role</code> exists in the security system.
*
* @param role a <code>Role</code> value
* @return true if the role exists in the system, false otherwise
* @throws DataBackendException when more than one Role with
* the same name exists.
* @throws Exception A generic exception.
*/
private boolean checkExists(Role role) throws DataBackendException, Exception
{
return getRoleManager().checkExists(role);
}
/**
* This method provides client-side encryption of passwords.
*
* If <code>secure.passwords</code> are enabled in TurbineResources,
* the password will be encrypted, if not, it will be returned unchanged.
* The <code>secure.passwords.algorithm</code> property can be used
* to chose which digest algorithm should be used for performing the
* encryption. <code>SHA</code> is used by default.
*
* @param password the password to process
* @return processed password
*/
public String encryptPassword(String password)
{
return encryptPassword(password, null);
}
/**
* This method provides client-side encryption of passwords.
*
* If <code>secure.passwords</code> are enabled in TurbineResources,
* the password will be encrypted, if not, it will be returned unchanged.
* The <code>secure.passwords.algorithm</code> property can be used
* to chose which digest algorithm should be used for performing the
* encryption. <code>SHA</code> is used by default.
*
* The used algorithms must be prepared to accept null as a
* valid parameter for salt. All algorithms in the Fulcrum Cryptoservice
* accept this.
*
* @param password the password to process
* @param salt algorithms that needs a salt can provide one here
* @return processed password
*/
public String encryptPassword(String password, String salt)
{
//@todo need to tie into password utils.
return password + salt;
}
/**
* Checks if a supplied password matches the encrypted password
*
* @param checkpw The clear text password supplied by the user
* @param encpw The current, encrypted password
*
* @return true if the password matches, else false
*
*/
public boolean checkPassword(String checkpw, String encpw)
{
String result = encryptPassword(checkpw, encpw);
return (result == null) ? false : result.equals(encpw);
}
/**
* Construct a new ACL object.
*
* This constructs a new ACL object from the configured class and
* initializes it with the supplied roles and permissions.
*
* @param roles The roles that this ACL should contain
* @param permissions The permissions for this ACL
*
* @return an object implementing ACL interface.
* @throws UnknownEntityException if the object could not be instantiated.
*/
public AccessControlList getAclInstance(Map roles, Map permissions) throws UnknownEntityException
{
Object[] objects = { roles, permissions };
String[] signatures = { Map.class.getName(), Map.class.getName()};
AccessControlList accessControlList;
try
{
/*
*
@todo I think this is overkill for now..
accessControlList =
(AccessControlList) aclFactoryService.getInstance(aclClass.getName(), objects, signatures);
*/
accessControlList = new DefaultAccessControlList(roles,permissions);
}
catch (Exception e)
{
throw new UnknownEntityException("Failed to instantiate an ACL implementation object", e);
}
return accessControlList;
}
public AccessControlList getACL(User user)
{
Map roleSets = new HashMap();
Map permissionSets = new HashMap();
for (Iterator i = ((SimpleUser) user).getGroups().iterator(); i.hasNext();)
{
Group group = (Group) i.next();
RoleSet roleSet = (RoleSet) ((SimpleGroup) group).getRoles();
roleSets.put(group, roleSet);
for (Iterator j = roleSet.iterator(); j.hasNext();)
{
SimpleRole role = (SimpleRole) j.next();
permissionSets.put(role, role.getPermissions());
}
}
try
{
return getAclInstance(roleSets, permissionSets);
}
catch (UnknownEntityException uue)
{
throw new RuntimeException(uue.getMessage(), uue);
}
}
/**
* Removes an user account from the system.
*
* @param user the object describing the account to be removed.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the user account is not present.
*/
public void removeUser(User user) throws DataBackendException, UnknownEntityException
{
// revoke all roles form the user
revokeAll(user);
users.remove(user);
}
/**
* Creates new user account with specified attributes.
*
* @param user the object describing account to be created.
* @param password The password to use for the account.
*
* @throws DataBackendException if there was an error accessing the
* data backend.
* @throws EntityExistsException if the user account already exists.
*/
public void addUser(User user, String password) throws DataBackendException, EntityExistsException
{
createAccount(user, password);
}
/**
* Stores User attributes. The User is required to exist in the system.
*
* @param role The User to be stored.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the role does not exist.
*/
public void saveUser(User user) throws DataBackendException, UnknownEntityException
{
boolean userExists = false;
userExists = checkExists(user);
if (userExists)
{
users.remove(user);
users.add(user);
}
else
{
throw new UnknownEntityException("Unknown user '" + user + "'");
}
}
/**
* Puts a user in a group.
*
* This method is used when adding a user to a group
*
* @param user the User.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the account is not present.
*/
public void grant(User user, Group group) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
boolean userExists = false;
try
{
groupExists = checkExists(group);
userExists = checkExists(user);
if (groupExists && userExists)
{
((SimpleUser) user).addGroup(group);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("grant(Role,Permission) failed", e);
}
finally
{
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!userExists)
{
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
}
/**
* Removes a user in a group.
*
* This method is used when removing a user to a group
*
* @param user the User.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the user or group is not present.
*/
public void revoke(User user, Group group) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
boolean userExists = false;
try
{
groupExists = checkExists(group);
userExists = checkExists(user);
if (groupExists && userExists)
{
((SimpleUser) user).removeGroup(group);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("grant(Role,Permission) failed", e);
}
finally
{
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!userExists)
{
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
}
/**
* Avalon component lifecycle method
*/
public void compose(ComponentManager manager) throws ComponentException
{
this.manager = manager;
}
private int getUniqueId()
{
return ++uniqueId;
}
}
1.1 jakarta-turbine-fulcrum/security/src/java/org/apache/fulcrum/security/spi/memory/simple/MemoryPermissionManagerImpl.java
Index: MemoryPermissionManagerImpl.java
===================================================================
package org.apache.fulcrum.security.spi.memory.simple;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Turbine" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fulcrum.security.PermissionManager;
import org.apache.fulcrum.security.RoleManager;
import org.apache.fulcrum.security.entity.Permission;
import org.apache.fulcrum.security.entity.Role;
import org.apache.fulcrum.security.model.simple.entity.SimplePermission;
import org.apache.fulcrum.security.util.DataBackendException;
import org.apache.fulcrum.security.util.EntityExistsException;
import org.apache.fulcrum.security.util.PermissionSet;
import org.apache.fulcrum.security.util.UnknownEntityException;
/**
* This implementation keeps all objects in memory. This is mostly meant to help
* with testing and prototyping of ideas.
*
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @version $Id: MemoryPermissionManagerImpl.java,v 1.1 2003/08/23 22:02:04 epugh Exp $
*/
public class MemoryPermissionManagerImpl extends AbstractLogEnabled implements PermissionManager, Composable
{
/** Logging */
private static Log log = LogFactory.getLog(MemoryPermissionManagerImpl.class);
private static List permissions = new ArrayList();
private ComponentManager manager = null;
private RoleManager roleManager = null;
/** Our Unique ID counter */
private static int uniqueId = 0;
/**
* @return
*/
RoleManager getRoleManager() throws ComponentException
{
if (roleManager == null)
{
roleManager = (RoleManager) manager.lookup(RoleManager.ROLE);
}
return roleManager;
}
/**
* Construct a blank Permission object.
*
* This method calls getPermissionClass, and then creates a new object using
* the default constructor.
*
* @return an object implementing Permission interface.
* @throws UnknownEntityException if the object could not be instantiated.
*/
public Permission getPermissionInstance() throws UnknownEntityException
{
Permission permission;
try
{
permission = (Permission) new SimplePermission();
}
catch (Exception e)
{
throw new UnknownEntityException("Failed to instantiate a Permission implementation object", e);
}
return permission;
}
/**
* Construct a blank Permission object.
*
* This method calls getPermissionClass, and then creates a new object using
* the default constructor.
*
* @param permName The name of the permission.
*
* @return an object implementing Permission interface.
* @throws UnknownEntityException if the object could not be instantiated.
*/
public Permission getPermissionInstance(String permName) throws UnknownEntityException
{
Permission perm = getPermissionInstance();
perm.setName(permName);
return perm;
}
/**
* Retrieve a Permission object with specified name.
*
* @param name the name of the Permission.
* @return an object representing the Permission with specified name.
* @throws DataBackendException if there was an error accessing the
* data backend.
* @throws UnknownEntityException if the permission does not exist.
*/
public Permission getPermissionByName(String name) throws DataBackendException, UnknownEntityException
{
Permission permission = getAllPermissions().getPermissionByName(name);
if (permission == null)
{
throw new UnknownEntityException("The specified permission does not exist");
}
return permission;
}
/**
* Retrieve a Permission object with specified Id.
*
* @param name the name of the Permission.
*
* @return an object representing the Permission with specified name.
*
* @throws UnknownEntityException if the permission does not
* exist in the database.
* @throws DataBackendException if there is a problem accessing the
* storage.
*/
public Permission getPermissionById(int id) throws DataBackendException, UnknownEntityException
{
Permission permission = getAllPermissions().getPermissionById(id);
if (permission == null)
{
throw new UnknownEntityException("The specified permission does not exist");
}
return permission;
}
/**
* Retrieves all permissions defined in the system.
*
* @return the names of all roles defined in the system.
* @throws DataBackendException if there was an error accessing the
* data backend.
*/
public PermissionSet getAllPermissions() throws DataBackendException
{
return new PermissionSet(permissions);
}
/**
* Renames an existing Permission.
*
* @param permission The object describing the permission to be renamed.
* @param name the new name for the permission.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the permission does not exist.
*/
public synchronized void renamePermission(Permission permission, String name)
throws DataBackendException, UnknownEntityException
{
boolean permissionExists = false;
try
{
permissionExists = checkExists(permission);
if (permissionExists)
{
permissions.remove(permission);
permission.setName(name);
permissions.add(permission);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("renamePermission(Permission,name)", e);
}
finally
{
}
throw new UnknownEntityException("Unknown permission '" + permission + "'");
}
/**
* Determines if the <code>Permission</code> exists in the security system.
*
* @param permission a <code>Permission</code> value
* @return true if the permission exists in the system, false otherwise
* @throws DataBackendException when more than one Permission with
* the same name exists.
* @throws Exception A generic exception.
*/
public boolean checkExists(Permission permission) throws DataBackendException
{
boolean exists = false;
for (Iterator i = permissions.iterator(); i.hasNext();)
{
Permission p = (Permission) i.next();
if (p.getName().equalsIgnoreCase(permission.getName()) | p.getId() == permission.getId())
{
exists = true;
}
}
return exists;
}
/**
* Stores Permission's attributes. The Permissions is required to exist in
* the system.
*
* @param permission The Permission to be stored.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the permission does not exist.
*/
public void savePermission(Permission permission) throws DataBackendException, UnknownEntityException
{
boolean permissionExists = false;
try
{
permissionExists = checkExists(permission);
if (permissionExists)
{
permissions.remove(permission);
permissions.add(permission);
}
else
{
throw new UnknownEntityException("Unknown permission '" + permission + "'");
}
}
catch (Exception e)
{
throw new DataBackendException("savePermission(Permission) failed", e);
}
}
/**
* Removes a Permission from the system.
*
* @param permission The object describing the permission to be removed.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the permission does not exist.
*/
public synchronized void removePermission(Permission permission)
throws DataBackendException, UnknownEntityException
{
boolean permissionExists = false;
try
{
permissionExists = checkExists(permission);
if (permissionExists)
{
permissions.remove(permission);
}
else
{
throw new UnknownEntityException("Unknown permission '" + permission + "'");
}
}
catch (Exception e)
{
throw new DataBackendException("removePermission(Permission)", e);
}
finally
{
}
}
/**
* Creates a new permission with specified attributes.
*
* @param permission the object describing the permission to be created.
* @return a new Permission object that has id set up properly.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws EntityExistsException if the permission already exists.
*/
public synchronized Permission addPermission(Permission permission)
throws DataBackendException, EntityExistsException
{
boolean permissionExists = false;
if (StringUtils.isEmpty(permission.getName()))
{
throw new DataBackendException("Could not create a permission with empty name!");
}
if (permission.getId() > 0)
{
throw new DataBackendException("Could not create a permission with an id!");
}
try
{
permissionExists = checkExists(permission);
if (!permissionExists)
{
permission.setId(getUniqueId());
permissions.add(permission);
return permission;
}
}
catch (Exception e)
{
throw new DataBackendException("addPermission(Permission) failed", e);
}
finally
{
}
// the only way we could get here without return/throw tirggered
// is that the permissionExists was true.
throw new EntityExistsException("Permission '" + permission + "' already exists");
}
/**
* Retrieves all permissions associated with a role.
*
* @param role the role name, for which the permissions are to be retrieved.
* @return A Permission set for the Role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the role is not present.
*/
public PermissionSet getPermissions(Role role) throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
try
{
roleExists = checkExists(role);
if (roleExists)
{
return role.getPermissions();
}
}
catch (Exception e)
{
throw new DataBackendException("getPermissions(Role) failed", e);
}
finally
{
}
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
/**
* Determines if the <code>Role</code> exists in the security system.
*
* @param role a <code>Role</code> value
* @return true if the role exists in the system, false otherwise
* @throws DataBackendException when more than one Role with
* the same name exists.
* @throws Exception A generic exception.
*/
public boolean checkExists(Role role) throws DataBackendException
{
try
{
return getRoleManager().checkExists(role);
}
catch (ComponentException ce)
{
throw new DataBackendException("Problem accessing role manager", ce);
}
}
/**
* Avalon component lifecycle method
*/
public void compose(ComponentManager manager) throws ComponentException
{
this.manager = manager;
}
private int getUniqueId()
{
return ++uniqueId;
}
}
1.1 jakarta-turbine-fulcrum/security/src/java/org/apache/fulcrum/security/spi/memory/simple/MemoryRoleManagerImpl.java
Index: MemoryRoleManagerImpl.java
===================================================================
package org.apache.fulcrum.security.spi.memory.simple;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Turbine" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fulcrum.security.PermissionManager;
import org.apache.fulcrum.security.entity.Permission;
import org.apache.fulcrum.security.entity.Role;
import org.apache.fulcrum.security.model.simple.entity.SimpleRole;
import org.apache.fulcrum.security.model.simple.manager.*;
import org.apache.fulcrum.security.util.DataBackendException;
import org.apache.fulcrum.security.util.EntityExistsException;
import org.apache.fulcrum.security.util.PermissionSet;
import org.apache.fulcrum.security.util.RoleSet;
import org.apache.fulcrum.security.util.UnknownEntityException;
/**
*
* This implementation keeps all objects in memory. This is mostly meant to help
* with testing and prototyping of ideas.
*
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @version $Id: MemoryRoleManagerImpl.java,v 1.1 2003/08/23 22:02:04 epugh Exp $
*/
public class MemoryRoleManagerImpl extends AbstractLogEnabled implements SimpleRoleManager, Composable
{
boolean composed = false;
/** Logging */
private static Log log = LogFactory.getLog(MemoryRoleManagerImpl.class);
/** List to store all our roles in */
private static List roles = new ArrayList();
private ComponentManager manager = null;
/** Our permissionManager **/
private PermissionManager permissionManager;
/** Our Unique ID counter */
private static int uniqueId = 0;
/**
* @return
*/
PermissionManager getPermissionManager() throws ComponentException
{
if (permissionManager == null)
{
permissionManager = (PermissionManager) manager.lookup(PermissionManager.ROLE);
}
return permissionManager;
}
/**
* Construct a blank Role object.
*
* This method calls getRoleClass, and then creates a new object using
* the default constructor.
*
* @return an object implementing Role interface.
* @throws UnknownEntityException if the object could not be instantiated.
*/
public Role getRoleInstance() throws UnknownEntityException
{
Role role;
try
{
role = (Role) new SimpleRole();
}
catch (Exception e)
{
throw new UnknownEntityException("Failed to instantiate a Role implementation object", e);
}
return role;
}
/**
* Construct a blank Role object.
*
* This method calls getRoleClass, and then creates a new object using
* the default constructor.
*
* @param roleName The name of the role.
*
* @return an object implementing Role interface.
*
* @throws UnknownEntityException if the object could not be instantiated.
*/
public Role getRoleInstance(String roleName) throws UnknownEntityException
{
Role role = getRoleInstance();
role.setName(roleName);
return role;
}
/**
* Retrieve a Role object with specified name.
*
* @param name the name of the Role.
* @return an object representing the Role with specified name.
* @throws DataBackendException if there was an error accessing the
* data backend.
* @throws UnknownEntityException if the role does not exist.
*/
public Role getRoleByName(String name) throws DataBackendException, UnknownEntityException
{
Role role = getAllRoles().getRoleByName(name);
if (role == null)
{
throw new UnknownEntityException("The specified role does not exist");
}
role.setPermissions(getPermissions(role));
return role;
}
/**
* Retrieve a Role object with specified Id.
*
* @param name the name of the Role.
*
* @return an object representing the Role with specified name.
*
* @throws UnknownEntityException if the permission does not
* exist in the database.
* @throws DataBackendException if there is a problem accessing the
* storage.
*/
public Role getRoleById(int id) throws DataBackendException, UnknownEntityException
{
Role role = getAllRoles().getRoleById(id);
if (role == null)
{
throw new UnknownEntityException("The specified role does not exist");
}
role.setPermissions(getPermissions(role));
return role;
}
/**
* Grants a Role a Permission
*
* @param role the Role.
* @param permission the Permission.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if role or permission is not present.
*/
public synchronized void grant(Role role, Permission permission)
throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
boolean permissionExists = false;
try
{
roleExists = checkExists(role);
permissionExists = checkExists(permission);
if (roleExists && permissionExists)
{
((SimpleRole) role).addPermission(permission);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("grant(Role,Permission) failed", e);
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
if (!permissionExists)
{
throw new UnknownEntityException("Unknown permission '" + permission.getName() + "'");
}
}
/**
* Revokes a Permission from a Role.
*
* @param role the Role.
* @param permission the Permission.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if role or permission is not present.
*/
public synchronized void revoke(Role role, Permission permission)
throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
boolean permissionExists = false;
try
{
roleExists = checkExists(role);
permissionExists = checkExists(permission);
if (roleExists && permissionExists)
{
((SimpleRole) role).removePermission(permission);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("revoke(Role,Permission) failed", e);
}
finally
{
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
if (!permissionExists)
{
throw new UnknownEntityException("Unknown permission '" + permission.getName() + "'");
}
}
/**
* Revokes all permissions from a Role.
*
* This method is user when deleting a Role.
*
* @param role the Role
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the Role is not present.
*/
public synchronized void revokeAll(Role role) throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
try
{
roleExists = checkExists(role);
if (roleExists)
{
role.setPermissions(new PermissionSet());
return;
}
}
catch (Exception e)
{
throw new DataBackendException("revokeAll(Role) failed", e);
}
finally
{
}
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
/**
* Renames an existing Role.
*
* @param role The object describing the role to be renamed.
* @param name the new name for the role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the role does not exist.
*/
public synchronized void renameRole(Role role, String name) throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
try
{
roleExists = checkExists(role);
if (roleExists)
{
roles.remove(role);
role.setName(name);
roles.add(role);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("renameRole(Role,String)", e);
}
finally
{
}
throw new UnknownEntityException("Unknown role '" + role + "'");
}
/**
* Determines if the <code>Role</code> exists in the security system.
*
* @param role a <code>Role</code> value
* @return true if the role exists in the system, false otherwise
* @throws DataBackendException when more than one Role with
* the same name exists.
* @throws Exception A generic exception.
*/
public boolean checkExists(Role role) throws DataBackendException
{
boolean exists = false;
for (Iterator i = roles.iterator(); i.hasNext();)
{
Role r = (Role) i.next();
if (r.getName().equalsIgnoreCase(role.getName()) | r.getId() == role.getId())
{
exists = true;
}
}
return exists;
}
/**
* Retrieves all roles defined in the system.
*
* @return the names of all roles defined in the system.
* @throws DataBackendException if there was an error accessing the
* data backend.
*/
public RoleSet getAllRoles() throws DataBackendException
{
return new RoleSet(roles);
}
/**
* Retrieves all permissions associated with a role.
*
* @param role the role name, for which the permissions are to be retrieved.
* @return A Permission set for the Role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the role is not present.
*/
public PermissionSet getPermissions(Role role) throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
try
{
roleExists = checkExists(role);
if (roleExists)
{
return getPermissionManager().getPermissions(role);
}
}
catch (Exception e)
{
throw new DataBackendException("getPermissions(Role) failed", e);
}
finally
{
}
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
/**
* if the <code>Permission</code> exists in the security system.
*
* @param permission a <code>Permission</code> value
* @return true if the permission exists in the system, false otherwise
* @throws DataBackendException when more than one Permission with
* the same name exists.
* @throws Exception A generic exception.
*/
public boolean checkExists(Permission permission) throws DataBackendException
{
try
{
return getPermissionManager().checkExists(permission);
}
catch (ComponentException ce)
{
throw new DataBackendException("Problem getting permission manager", ce);
}
}
/**
* Creates a new role with specified attributes.
*
* @param role the object describing the role to be created.
* @return a new Role object that has id set up properly.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws EntityExistsException if the role already exists.
*/
public synchronized Role addRole(Role role) throws DataBackendException, EntityExistsException
{
boolean roleExists = false;
if (StringUtils.isEmpty(role.getName()))
{
throw new DataBackendException("Could not create a role with empty name!");
}
if (role.getId() > 0)
{
throw new DataBackendException("Could not create a role with an id!");
}
try
{
roleExists = checkExists(role);
if (!roleExists)
{
role.setId(getUniqueId());
roles.add(role);
// add the role to system-wide cache
getAllRoles().add(role);
// return the object with correct id
return role;
}
}
catch (Exception e)
{
throw new DataBackendException("addRole(Role) failed", e);
}
finally
{
}
// the only way we could get here without return/throw tirggered
// is that the roleExists was true.
throw new EntityExistsException("Role '" + role + "' already exists");
}
/**
* Stores Role's attributes. The Roles is required to exist in the system.
*
* @param role The Role to be stored.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the role does not exist.
*/
public void saveRole(Role role) throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
roleExists = checkExists(role);
if (roleExists)
{
roles.add(role);
}
else
{
throw new UnknownEntityException("Unknown role '" + role + "'");
}
}
/**
* Removes a Role from the system.
*
* @param role The object describing the role to be removed.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the role does not exist.
*/
public synchronized void removeRole(Role role) throws DataBackendException, UnknownEntityException
{
boolean roleExists = false;
try
{
roleExists = checkExists(role);
if (roleExists)
{
// revoke all permissions from the role to be deleted
revokeAll(role);
roles.remove(role);
getAllRoles().remove(role);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("removeRole(Role)", e);
}
finally
{
}
throw new UnknownEntityException("Unknown role '" + role + "'");
}
/**
* Avalon component lifecycle method
*/
public void compose(ComponentManager manager) throws ComponentException
{
this.manager = manager;
}
private int getUniqueId()
{
return ++uniqueId;
}
}
1.1 jakarta-turbine-fulcrum/security/src/java/org/apache/fulcrum/security/spi/memory/simple/MemoryGroupManagerImpl.java
Index: MemoryGroupManagerImpl.java
===================================================================
package org.apache.fulcrum.security.spi.memory.simple;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Turbine" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fulcrum.security.RoleManager;
import org.apache.fulcrum.security.entity.Group;
import org.apache.fulcrum.security.entity.Role;
import org.apache.fulcrum.security.model.simple.entity.SimpleGroup;
import org.apache.fulcrum.security.model.simple.manager.*;
import org.apache.fulcrum.security.util.DataBackendException;
import org.apache.fulcrum.security.util.EntityExistsException;
import org.apache.fulcrum.security.util.GroupSet;
import org.apache.fulcrum.security.util.UnknownEntityException;
/**
* This implementation keeps all objects in memory. This is mostly meant to help
* with testing and prototyping of ideas.
*
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @version $Id: MemoryGroupManagerImpl.java,v 1.1 2003/08/23 22:02:04 epugh Exp $
*/
public class MemoryGroupManagerImpl extends AbstractLogEnabled implements SimpleGroupManager, Composable
{
/** Logging */
private static Log log = LogFactory.getLog(MemoryGroupManagerImpl.class);
private static List groups = new ArrayList();
/** Our Unique ID counter */
private static int uniqueId = 0;
private ComponentManager manager = null;
/** Our role Manager **/
private RoleManager roleManager;
/**
* @return
*/
RoleManager getRoleManager() throws ComponentException
{
if (roleManager == null)
{
roleManager = (RoleManager) manager.lookup(RoleManager.ROLE);
}
return roleManager;
}
/**
* Construct a blank Group object.
*
* This method calls getGroupClass, and then creates a new object using
* the default constructor.
*
* @return an object implementing Group interface.
* @throws UnknownEntityException if the object could not be instantiated.
*/
public Group getGroupInstance() throws UnknownEntityException
{
Group group;
try
{
group = (Group) new SimpleGroup();
}
catch (Exception e)
{
throw new UnknownEntityException("Failed to instantiate a Group implementation object", e);
}
return group;
}
/**
* Construct a blank Group object.
*
* This method calls getGroupClass, and then creates a new object using
* the default constructor.
*
* @param groupName The name of the Group
*
* @return an object implementing Group interface.
*
* @throws UnknownEntityException if the object could not be instantiated.
*/
public Group getGroupInstance(String groupName) throws UnknownEntityException
{
Group group = getGroupInstance();
group.setName(groupName);
return group;
}
/**
* Retrieve a Group object with specified name.
*
* @param name the name of the Group.
* @return an object representing the Group with specified name.
* @throws DataBackendException if there was an error accessing the
* data backend.
* @throws UnknownEntityException if the group does not exist.
* @deprecated Use <a href="#getGroupByName">getGroupByName</a> instead.
*/
public Group getGroup(String name) throws DataBackendException, UnknownEntityException
{
return getGroupByName(name);
}
/**
* Retrieve a Group object with specified name.
*
* @param name the name of the Group.
* @return an object representing the Group with specified name.
* @throws DataBackendException if there was an error accessing the
* data backend.
* @throws UnknownEntityException if the group does not exist.
*/
public Group getGroupByName(String name) throws DataBackendException, UnknownEntityException
{
Group group = getAllGroups().getGroupByName(name);
if (group == null)
{
throw new UnknownEntityException("The specified group does not exist");
}
return group;
}
/**
* Retrieve a Group object with specified Id.
*
* @param name the name of the Group.
*
* @return an object representing the Group with specified name.
*
* @throws UnknownEntityException if the permission does not
* exist in the database.
* @throws DataBackendException if there is a problem accessing the
* storage.
*/
public Group getGroupById(int id) throws DataBackendException, UnknownEntityException
{
Group group = getAllGroups().getGroupById(id);
if (group == null)
{
throw new UnknownEntityException("The specified group does not exist");
}
return group;
}
/**
* Retrieves all groups defined in the system.
*
* @return the names of all groups defined in the system.
* @throws DataBackendException if there was an error accessing the
* data backend.
*/
public GroupSet getAllGroups() throws DataBackendException
{
return new GroupSet(groups);
}
/**
* Removes a Group from the system.
*
* @param group The object describing the group to be removed.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the group does not exist.
*/
public synchronized void removeGroup(Group group) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
try
{
groupExists = checkExists(group);
if (groupExists)
{
groups.remove(group);
return;
}
else
{
throw new UnknownEntityException("Unknown group '" + group + "'");
}
}
catch (Exception e)
{
log.error("Failed to delete a Group");
log.error(e);
throw new DataBackendException("removeGroup(Group) failed", e);
}
finally
{
}
}
/**
* Renames an existing Group.
*
* @param group The object describing the group to be renamed.
* @param name the new name for the group.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the group does not exist.
*/
public synchronized void renameGroup(Group group, String name) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
try
{
groupExists = checkExists(group);
if (groupExists)
{
groups.remove(group);
group.setName(name);
groups.add(group);
}
else
{
throw new UnknownEntityException("Unknown group '" + group + "'");
}
}
catch (Exception e)
{
throw new DataBackendException("renameGroup(Group,String)", e);
}
finally
{
}
}
/**
* Stores Group's attributes. The Groups is required to exist in the system.
*
* @param group The Group to be stored.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if the group does not exist.
*/
public void saveGroup(Group group) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
try
{
groupExists = checkExists(group);
if (groupExists)
{
groups.remove(group);
groups.add(group);
}
else
{
throw new UnknownEntityException("Unknown group '" + group + "'");
}
}
catch (Exception e)
{
throw new DataBackendException("saveGroup(Group) failed", e);
}
}
/**
* Determines if the <code>Group</code> exists in the security system.
*
* @param group a <code>Group</code> value
* @return true if the group exists in the system, false otherwise
* @throws DataBackendException when more than one Group with
* the same name exists.
* @throws Exception A generic exception.
*/
public boolean checkExists(Group group) throws DataBackendException
{
try
{
boolean exists = false;
for (Iterator i = groups.iterator(); i.hasNext();)
{
Group g = (Group) i.next();
if (g.getName().equalsIgnoreCase(group.getName()) | g.getId() == group.getId())
{
exists = true;
}
}
return exists;
//return groups.contains(group);
}
catch (Exception e)
{
throw new DataBackendException("Problem checking if groups exists", e);
}
}
/**
* Creates a new group with specified attributes.
*
* @param group the object describing the group to be created.
* @return a new Group object that has id set up properly.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws EntityExistsException if the group already exists.
*/
public synchronized Group addGroup(Group group) throws DataBackendException, EntityExistsException
{
boolean groupExists = false;
if (StringUtils.isEmpty(group.getName()))
{
throw new DataBackendException("Could not create a group with empty name!");
}
if (group.getId() > 0)
{
throw new DataBackendException("Could not create a group with an id!");
}
groupExists = checkExists(group);
if (!groupExists)
{
group.setId(getUniqueId());
groups.add(group);
// return the object with correct id
return group;
}
else
{
throw new EntityExistsException("Group '" + group + "' already exists");
}
}
/**
* Grants a Group a Role
*
* @param group the Group.
* @param role the Role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if group or role is not present.
*/
public synchronized void grant(Group group, Role role) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
boolean roleExists = false;
try
{
groupExists = checkExists(group);
roleExists = checkExists(role);
if (groupExists && roleExists)
{
((SimpleGroup) group).addRole(role);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("grant(Group,Role) failed", e);
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
}
/**
* Revokes a Role from a Group.
*
* @param group the Group.
* @param role the Role.
* @throws DataBackendException if there was an error accessing the data
* backend.
* @throws UnknownEntityException if group or role is not present.
*/
public synchronized void revoke(Group group, Role role) throws DataBackendException, UnknownEntityException
{
boolean groupExists = false;
boolean roleExists = false;
try
{
groupExists = checkExists(group);
roleExists = checkExists(role);
if (groupExists && roleExists)
{
((SimpleGroup) group).removeRole(role);
return;
}
}
catch (Exception e)
{
throw new DataBackendException("revoke(Group,Role) failed", e);
}
finally
{
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
}
/**
* Determines if the <code>Permission</code> exists in the security system.
*
* @param permission a <code>Permission</code> value
* @return true if the permission exists in the system, false otherwise
* @throws DataBackendException when more than one Permission with
* the same name exists.
* @throws Exception A generic exception.
*/
public boolean checkExists(Role role) throws DataBackendException
{
try
{
return getRoleManager().checkExists(role);
}
catch (ComponentException ce)
{
throw new DataBackendException("Problem getting role manager", ce);
}
}
/**
* Avalon component lifecycle method
*/
public void compose(ComponentManager manager) throws ComponentException
{
this.manager = manager;
}
private int getUniqueId()
{
return ++uniqueId;
}
}