/*
* Copyright 2000-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jetspeed.om.registry.base;
// Java imports
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.apache.jetspeed.om.registry.SecurityAccess;
import org.apache.jetspeed.om.registry.SecurityAllow;
import org.apache.jetspeed.om.registry.SecurityEntry;
import org.apache.jetspeed.services.security.GroupManagement;
import org.apache.jetspeed.services.security.RoleManagement;
/**
* Interface for manipulatin the Security Entry on the registry entries
*
* @author <a href="mailto:paulsp@apache.org">Paul Spencer</a>
* @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
* @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
* @version $Id: BaseSecurityEntry.java,v 1.15 2004/03/23 21:15:24 jford Exp $
*/
public class BaseSecurityEntry extends BaseRegistryEntry implements SecurityEntry, java.io.Serializable
{
/** Holds value of property accesses. */
private Vector accesses = new Vector();
private transient Map accessMap = null;
public static final String ALL_ACTIONS = "*";
public static final String ALL_ROLES = "*";
public static final String ALL_GROUPS = "*";
public static final String ALL_GROUP_ROLES = "*";
public static final String ALL_USERS = "*";
private static final String OWNER_MAP = "owner";
private static final String ROLE_MAP = "role";
private static final String GROUP_MAP = "group";
private static final String GROUP_ROLE_MAP = "grouprole";
private static final String USER_MAP = "user";
private static transient Object accessMapSync = new Object();
public BaseSecurityEntry()
{ }
/**
* Implements the equals operation so that 2 elements are equal if
* all their member values are equal.
*/
public boolean equals(Object object)
{
if (object == null)
{
return false;
}
BaseSecurityEntry obj = (BaseSecurityEntry) object;
Iterator i = accesses.iterator();
Iterator i2 = obj.accesses.iterator();
while (i.hasNext())
{
BaseSecurityAccess c1 = (BaseSecurityAccess) i.next();
BaseSecurityAccess c2 = null;
if (i2.hasNext())
{
c2 = (BaseSecurityAccess) i2.next();
}
else
{
return false;
}
if (!c1.equals(c2))
{
return false;
}
}
if (i2.hasNext())
{
return false;
}
return super.equals(object);
}
/** Getter for property accesses.
* @return Value of property accesses.
*/
public Vector getAccesses()
{
return accesses;
}
/** Setter for property accesses.
* @param accesses New value of property accesses.
*/
public void setAccesses(Vector accesses)
{
this.accesses = accesses;
buildAccessMap();
}
/**
* Aututhorizes action for a role.
*
* o If the requested action and the action ALL_ACTIONS
* do not exist, then return false.
*
* o If the requesting role and ALL_ROLES does not exist for the
* the action, then return false.
*
* @param role requesting action
* @param action being requested
* @return <CODE>true</CODE> if action is allowed for role
*/
public boolean allowsRole(String role, String action)
{
Map allowMap = null;
boolean allow = false;
if (accessMap == null)
{
buildAccessMap();
}
// Checked action
allowMap = (Map) accessMap.get(action);
allow = isInAllowMap(allowMap, ROLE_MAP, role, ALL_ROLES);
if (allow == true)
{
return allow;
}
// Checked all actions
allowMap = (Map) accessMap.get(ALL_ACTIONS);
allow = isInAllowMap(allowMap, ROLE_MAP, role, ALL_ROLES);
// Not allowed
return allow;
}
/**
* Aututhorizes action for a group.
*
* o If the requested action and the action ALL_ACTIONS
* do not exist, then return false.
*
* o If the requesting role and ALL_GROUP does not exist for the
* the action, then return false.
*
* @param group requesting action
* @param action being requested
* @return <CODE>true</CODE> if action is allowed for group
*/
public boolean allowsGroup(String group, String action)
{
Map allowMap = null;
boolean allow = false;
if (accessMap == null)
{
buildAccessMap();
}
// Checked action
allowMap = (Map) accessMap.get(action);
allow = isInAllowMap(allowMap, GROUP_MAP, group, ALL_GROUPS);
if (allow == true)
{
return allow;
}
// Checked all actions
allowMap = (Map) accessMap.get(ALL_ACTIONS);
allow = isInAllowMap(allowMap, GROUP_MAP, group, ALL_GROUPS);
// Not allowed
return allow;
}
/**
* Authorizes action for a group role.
*
* o If the requested action and the action ALL_ACTIONS
* do not exist, then return false.
*
* o If the requesting group role and ALL_GROUPS_ROLES does not exist for the
* the action, then return false.
*
* @param group requesting action
* @param role requesting action
* @param action being requested
* @return <CODE>true</CODE> if action is allowed for group role
*/
public boolean allowsGroupRole(String group, String role, String action)
{
Map allowMap = null;
boolean allow = false;
if (accessMap == null)
{
buildAccessMap();
}
// Checked action
allowMap = (Map) accessMap.get(action);
allow = isInAllowMap(allowMap, GROUP_ROLE_MAP, group+role, ALL_GROUP_ROLES);
if (allow == true)
{
return allow;
}
// Checked all actions
allowMap = (Map) accessMap.get(ALL_ACTIONS);
allow = isInAllowMap(allowMap, GROUP_ROLE_MAP, group+role, ALL_GROUP_ROLES);
// Not allowed
return allow;
}
/**
* Aututhorizes action for a named user
*
* @param userName requesting action
* @param action being requested
* @return <CODE>true</CODE> if action is allowed for named user
*/
public boolean allowsUser(String userName, String action)
{
return allowsUser(userName, action, null);
}
/**
* Aututhorizes action for a named user
*
* @param userName requesting action
* @param action being requested
* @param owner User
* @return <CODE>true</CODE> if action is allowed for named user
*/
public boolean allowsUser(String userName, String action, String owner)
{
Map allowMap = null;
boolean allow = false;
if (accessMap == null)
{
buildAccessMap();
}
if ((owner != null) && (owner.equals(userName)))
{
// Checked action
allowMap = (Map) accessMap.get(action);
allow = isInAllowMap(allowMap, OWNER_MAP, null, null);
if (allow == true)
{
return allow;
}
// Checked action
allowMap = (Map) accessMap.get(ALL_ACTIONS);
allow = isInAllowMap(allowMap, OWNER_MAP, null, null);
if (allow == true)
{
return allow;
}
}
// Checked action
allowMap = (Map) accessMap.get(action);
allow = isInAllowMap(allowMap, USER_MAP, userName, ALL_USERS);
if (allow == true)
{
return allow;
}
// Checked all actions
allowMap = (Map) accessMap.get(ALL_ACTIONS);
allow = isInAllowMap(allowMap, USER_MAP, userName, ALL_USERS);
// Not allowed
return allow;
}
/**
* Checks whether a role is specifically allowed to access the request action
* This method ignores the "*" action and is here to play a maintenance role.
*/
public boolean allowsSpecificRole( String action, String role)
{
SecurityAccess access = (SecurityAccess) getAccess(action);
if (access.getAllAllows() != null)
{
Iterator allAllows = access.getAllows().iterator();
while (allAllows.hasNext())
{
SecurityAllow allow = (SecurityAllow) allAllows.next();
if (allow.getRole() != null && allow.getRole().equals(role))
{
return true;
}
}
}
return false;
}
/**
* Checks whether a group is specifically allowed to access the request action
* This method ignores the "*" action and is here to play a maintenance role.
*/
public boolean allowsSpecificGroup(String action, String group)
{
SecurityAccess access = (SecurityAccess) getAccess(action);
if (access.getAllAllows() != null)
{
Iterator allAllows = access.getAllows().iterator();
while (allAllows.hasNext())
{
SecurityAllow allow = (SecurityAllow) allAllows.next();
if (allow.getGroup() != null && allow.getGroup().equals(group))
{
return true;
}
}
}
return false;
}
/**
* Checks whether a group role is specifically allowed to access the request action
* This method ignores the "*" action and is here to play a maintenance role.
*/
public boolean allowsSpecificGroupRole(String action, String group, String role)
{
SecurityAccess access = (SecurityAccess) getAccess(action);
if (access.getAllAllows() != null)
{
Iterator allAllows = access.getAllows().iterator();
while (allAllows.hasNext())
{
SecurityAllow allow = (SecurityAllow) allAllows.next();
if (allow.getGroup() != null &&
allow.getGroup().equals(group) &&
allow.getRole() != null &&
allow.getRole().equals(role))
{
return true;
}
}
}
return false;
}
/**
* Checks whether a role is specifically allowed to access the request action
* This method ignores the "*" action and is here to play a maintenance role.
* @param String action name of action to check
* @param String role name of role to verify access for
* @return boolean whether or not the <code>role</code> has access
* to this specific action.
*/
public boolean allowsSpecificUser(String action, String user)
{
BaseSecurityAccess access = (BaseSecurityAccess) getAccess(action);
if (access.getAllAllows() != null)
{
Iterator allAllows = access.getAllows().iterator();
while (allAllows.hasNext())
{
BaseSecurityAllow allow = (BaseSecurityAllow) allAllows.next();
if (allow.getUser() != null && allow.getUser().equals(user))
{
return true;
}
}
}
return false;
}
/**
* Returns the SecurityAccess object for the <code>action</code>
* requested or null if no specific access is defined for this action.
* The "*" does change this, if an action is not specifically defined
* in the registry, null is returned
* @param SecurityEntry entry SecurityEntry to check against
* @param String action The action we want the access for.
* @return SecurityAccess that is defined for this action or
* <code>null</code> if one is not <strong>specifically defined</strong>
*/
public SecurityAccess getAccess(String action)
{
Iterator itr = getAccesses().iterator();
while (itr.hasNext())
{
BaseSecurityAccess access = (BaseSecurityAccess) itr.next();
if (access.getAction().equals(action))
{
return access;
}
}
return null;
}
/**
* Grants access for a specific action to a specific role
* for this SecurityEntry. This grants specific access ignores
* "*" action, if it exists.
* @param String action The action we are granting access to.
* @param String role The role that will receive access to this action.
* @return boolean Whether or not the access was granted. Basically,
* a <code>false</code> means that this role already has specific access.
*/
public boolean grantRoleAccess(String action, String role)
{
if (!allowsSpecificRole(action, role))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null)
{
allows = new Vector();
}
BaseSecurityAllow allow = new BaseSecurityAllow();
allow.setRole(role);
allows.add(allow);
buildAccessMap();
return true;
}
return false;
}
/**
* Grants access for a specific action to a specific group
* for this SecurityEntry. This grants specific access ignores
* "*" action, if it exists.
* @param String action The action we are granting access to.
* @param String group The group that will receive access to this action.
* @return boolean Whether or not the access was granted. Basically,
* a <code>false</code> means that this group already has specific access.
*/
public boolean grantGroupAccess(String action, String group)
{
if (!allowsSpecificGroup(action, role))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null)
{
allows = new Vector();
}
BaseSecurityAllow allow = new BaseSecurityAllow();
allow.setGroup(group);
allows.add(allow);
buildAccessMap();
return true;
}
return false;
}
/**
* Grants access for a specific action to a specific group fole
* for this SecurityEntry. This grants specific access ignores
* "*" action, if it exists.
* @param String action The action we are granting access to.
* @param String group The group that will receive access to this action.
* @param String role The role that will receive access to this action.
* @return boolean Whether or not the access was granted. Basically,
* a <code>false</code> means that this group role already has specific access.
*/
public boolean grantGroupRoleAccess(String action, String group, String role)
{
if (!allowsSpecificGroupRole(action, group, role))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null)
{
allows = new Vector();
}
BaseSecurityAllow allow = new BaseSecurityAllow();
allow.setGroup(group);
allow.setRole(role);
allows.add(allow);
buildAccessMap();
return true;
}
return false;
}
/**
* Grants access for a specific action to a specific user
* for this SecurityEntry. This grants specific access ignores
* "*" action, if it exists.
* @param String action The action we are granting access to.
* @param String user The user that will receive access to this action.
* @return boolean Whether or not the access was granted. Basically,
* a <code>false</code> means that this role already has specific access.
*/
public boolean grantUserAccess(String action, String user)
{
if (!allowsSpecificUser(action, user))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null)
{
allows = new Vector();
}
BaseSecurityAllow allow = new BaseSecurityAllow();
allow.setUser(user);
allows.add(allow);
buildAccessMap();
return true;
}
return false;
}
/**
* Removes a role's access to a specific action.
* @param action Action to remove access from.
* @param role The role whose access we are revoking.
* @return boolean Whehter or not the access existed and
* was removed.
*/
public boolean revokeRoleAccess(String action, String role)
{
if (allowsSpecificRole(action, role))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null || allows.isEmpty())
{
revokeAccess(action);
return false;
}
for (int i = 0; i < allows.size(); i++)
{
BaseSecurityAllow allow = (BaseSecurityAllow) allows.get(i);
if (allow.getRole() != null && allow.getRole().equals(role))
{
allows.remove(i);
if (allows.isEmpty() && access.getOwnerAllows().isEmpty())
{
revokeAccess(action);
}
return true;
}
}
}
return false;
}
/**
* Removes a group's access to a specific action.
* @param action Action to remove access from.
* @param group The group whose access we are revoking.
* @return boolean Whehter or not the access existed and
* was removed.
*/
public boolean revokeGroupAccess(String action, String group)
{
if (allowsSpecificGroup(action, group))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null || allows.isEmpty())
{
revokeAccess(action);
return false;
}
for (int i = 0; i < allows.size(); i++)
{
BaseSecurityAllow allow = (BaseSecurityAllow) allows.get(i);
if (allow.getGroup() != null && allow.getGroup().equals(group))
{
allows.remove(i);
if (allows.isEmpty() && access.getOwnerAllows().isEmpty())
{
revokeAccess(action);
}
return true;
}
}
}
return false;
}
/**
* Removes a group role's access to a specific action.
* @param action Action to remove access from.
* @param group The group whose access we are revoking.
* @param role The role whose access we are revoking.
* @return boolean Whether or not the access existed and
* was removed.
*/
public boolean revokeGroupRoleAccess(String action, String group, String role)
{
if (allowsSpecificGroupRole(action, group, role))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null || allows.isEmpty())
{
revokeAccess(action);
return false;
}
for (int i = 0; i < allows.size(); i++)
{
BaseSecurityAllow allow = (BaseSecurityAllow) allows.get(i);
if (allow.getGroup() != null &&
allow.getGroup().equals(group) &&
allow.getRole() != null &&
allow.getRole().equals(role))
{
allows.remove(i);
if (allows.isEmpty() && access.getOwnerAllows().isEmpty())
{
revokeAccess(action);
}
return true;
}
}
}
return false;
}
/**
* Removes a user's access to a specific action.
* @param action Action to remove access from.
* @param role The role whose access we are revoking.
* @return boolean Whehter or not the access existed and
* was removed.
*/
public boolean revokeUserAccess(String action, String user)
{
if (allowsSpecificUser(action, user))
{
SecurityAccess access = getAccess(action);
List allows = access.getAllows();
if (allows == null || allows.isEmpty())
{
revokeAccess(action);
return false;
}
for (int i = 0; i < allows.size(); i++)
{
BaseSecurityAllow allow = (BaseSecurityAllow) allows.get(i);
if (allow.getUser() != null && allow.getUser().equals(user))
{
allows.remove(i);
if (allows.isEmpty() && access.getOwnerAllows().isEmpty())
{
revokeAccess(action);
}
return true;
}
}
}
return false;
}
/**
* Removes a security access for the named action.
* This does not take into account the "*" action when
* the "*" is not the named action.
* @param String access name of access to remove in its entirety
*/
public void revokeAccess(String action)
{
List list = getAccesses();
for (int i = 0; i < list.size(); i++)
{
BaseSecurityAccess access = (BaseSecurityAccess) list.get(i);
if (access.getAction().equals(action))
{
list.remove(i);
return;
}
}
}
private void buildAccessMap()
{
Map actionMap = null;
SecurityAccess accessElement = null;
synchronized (accessMapSync)
{
if (accessMap == null)
{
accessMap = new HashMap();
}
accessMap.clear();
}
// Build allow map
for (Iterator accessIterator = getAccesses().iterator(); accessIterator.hasNext();)
{
accessElement = (SecurityAccess) accessIterator.next();
// Get action map of the action. Create one if none exists
String action = accessElement.getAction();
if (action == null)
{
action = ALL_ACTIONS;
}
actionMap = (Map) accessMap.get(action);
if (actionMap == null)
{
actionMap = new HashMap();
accessMap.put(action, actionMap);
}
addAllows(actionMap, accessElement);
}
}
/**
* Add access elements to the access map. The elements will be
* appened to the appropiate map.
*
* @param accessMap to receive accessElements
* @param accessElement to copy to access map
*/
private void addAllows(Map accessMap, SecurityAccess accessElement)
{
SecurityAllow allowElement = null;
String role = null;
String group = null;
Map ownerMap = null; // Map of owner allowed
Map roleMap = null; // Map of roles allowed
Map groupMap = null; // Map of groups allowed
Map groupRoleMap = null; // Map of group role allowed
Map userMap = null; // Map of users allowed
String userName = null;
if (accessElement.getAllAllows() == null)
{
return;
}
// Add allows to the action Map
for (Iterator allowIterator = accessElement.getAllAllows().iterator(); allowIterator.hasNext();)
{
allowElement = (SecurityAllow) allowIterator.next();
role = null;
userName = null;
group = null;
// Add Owner
if (allowElement.isOwner() == true)
{
ownerMap = (Map) accessMap.get(OWNER_MAP);
if (ownerMap == null)
{
ownerMap = new HashMap();
accessMap.put(OWNER_MAP, ownerMap);
}
ownerMap.put(null, null);
}
// Add Role
role = allowElement.getRole();
if (role != null)
{
// Role map
roleMap = (Map) accessMap.get(ROLE_MAP);
if (roleMap == null)
{
roleMap = new HashMap();
accessMap.put(ROLE_MAP, roleMap);
}
roleMap.put(role, null);
// Group role map
groupRoleMap = (Map) accessMap.get(GROUP_ROLE_MAP);
if (groupRoleMap == null)
{
groupRoleMap = new HashMap();
accessMap.put(GROUP_ROLE_MAP, groupRoleMap);
}
if (group == null)
{
group = GroupManagement.DEFAULT_GROUP_NAME;
}
groupRoleMap.put(group+role, null);
}
// Add Group
group = allowElement.getGroup();
if (group != null)
{
// Group map
groupMap = (Map) accessMap.get(GROUP_MAP);
if (groupMap == null)
{
groupMap = new HashMap();
accessMap.put(GROUP_MAP, groupMap);
}
groupMap.put(group, null);
// Group role map
groupRoleMap = (Map) accessMap.get(GROUP_ROLE_MAP);
if (groupRoleMap == null)
{
groupRoleMap = new HashMap();
accessMap.put(GROUP_ROLE_MAP, groupRoleMap);
}
if (role == null)
{
role = RoleManagement.DEFAULT_ROLE_NAME;
}
groupRoleMap.put(group+role, null);
}
// Add User
userName = allowElement.getUser();
if (userName != null)
{
userMap = (Map) accessMap.get(USER_MAP);
if (userMap == null)
{
userMap = new HashMap();
accessMap.put(USER_MAP, userMap);
}
userMap.put(userName, null);
}
}
}
/**
* Search allow map of user/role or "all user/role"
*
* @param allowMap Map of allow-if
* @param mapType ROLE_MAP or USER_MAP or GROUP_MAP or GROUP_ROLE_MAP
* @param mapKey role or user to test
* @param allKey ALL_ROLE or ALL_USER or ALL_GROUP or ALL_GROUP_ROLE
* @return <CODE>true</CODE> or <CODE>false</CODE>
*/
private boolean isInAllowMap(Map allowMap, String mapType, String mapKey, String allKey)
{
boolean allow = false;
if (allowMap != null)
{
Map allowTypeMap = (Map) allowMap.get(mapType);
if (allowTypeMap == null)
{
return allowMap.isEmpty(); // If action exist and no allows, then grant permission
}
allow = allowTypeMap.containsKey(mapKey);
if (allow == false)
{
allow = allowTypeMap.containsKey(allKey);
}
return allow;
}
// Not allowed
return allow;
}
}