Java tutorial
/* * Adito * * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.adito.policyframework; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.util.LabelValueBean; import com.adito.properties.ProfilesFactory; import com.adito.properties.Property; import com.adito.properties.impl.systemconfig.SystemConfigKey; import com.adito.security.AuthenticationScheme; import com.adito.security.Constants; import com.adito.security.LogonControllerFactory; import com.adito.security.SessionInfo; import com.adito.security.SystemDatabaseFactory; import com.adito.security.User; /** * A set of utilities for dealing with <i>Resources</i> */ public class ResourceUtil { final static Log log = LogFactory.getLog(ResourceUtil.class); /* * Private constructor to prevent instantiation */ private ResourceUtil() { } /** * Filter a {@link List} of {@link Resource} objects, looking for either * resources owned by the supplied username, or global resources that have * the correct policy. * * @param user user * @param resources list of owned resources * @param includeSuperUser include super user permitted resources * @return list of filtered owned resources * @throws Exception on any error */ public static List filterResources(User user, List resources, boolean includeSuperUser) throws Exception { List validResources = new ArrayList(); for (Iterator i = resources.iterator(); i.hasNext();) { Resource p = (Resource) i.next(); // Include the resource if the current user created it if (p instanceof OwnedResource && ((OwnedResource) p).getOwnerUsername() != null && !((OwnedResource) p).getOwnerUsername().equals("")) { if (((OwnedResource) p).getOwnerUsername().equals(user.getPrincipalName())) { validResources.add(p); } } else { if (PolicyDatabaseFactory.getInstance().isPrincipalAllowed(user, p, includeSuperUser)) { validResources.add(p); } } } return validResources; } private static void addResources(User user, boolean includeSuperUser, List validResources, Resource p) throws Exception { // Include the resource if the current user created it if (p instanceof OwnedResource && ((OwnedResource) p).getOwnerUsername() != null && !((OwnedResource) p).getOwnerUsername().equals("")) { if (((OwnedResource) p).getOwnerUsername().equals(user.getPrincipalName())) { validResources.add(p); } } else { if (PolicyDatabaseFactory.getInstance().isPrincipalAllowed(user, p, includeSuperUser)) { validResources.add(p); } } } /** * Set the current list of available profiles for this session as a session * attribute. * * @param session session * @return the available profiles * @throws Exception */ public static List setAvailableProfiles(SessionInfo session) throws Exception { User user = LogonControllerFactory.getInstance().getUser(session.getHttpSession(), null); List profiles = filterResources(user, ProfilesFactory.getInstance().getPropertyProfiles( user.getPrincipalName(), true, session.getUser().getRealm().getResourceId()), false); session.getHttpSession().setAttribute(Constants.PROFILES, profiles); return profiles; } /** * Create a {@link List} or {@link org.apache.struts.util.LabelValueBean} * objects from a {@link List} of {@link Resource} objects. * * @param resourceList resource list * @return list of objects suitable for struts list components */ public static List resourceListAsLabelValueBeanList(List resourceList) { List l = new ArrayList(); Resource r; for (Iterator i = resourceList.iterator(); i.hasNext();) { r = (Resource) i.next(); l.add(new LabelValueBean(r.getResourceName(), String.valueOf(r.getResourceId()))); } return l; } /** * Filter a list of {@link OwnedResource} obects for those that do * <strong>not</strong> have an owner. * * @param resources resources * @return filtered resources */ public static List filterOwned(List resources) { List l = new ArrayList(); for (Iterator i = resources.iterator(); i.hasNext();) { Resource resource = (Resource) i.next(); if (resource instanceof OwnedResource && ((OwnedResource) resource).getOwnerUsername() == null) { l.add(resource); } } return l; } /** * Get if a single resource may be managed by the specified user. For a * resource to be manageable, a user must either be the super user or the * parent resource permission of the resource must be attached to a policy * that the specified user. A resource will also be manageable if one of its * parents is manageable. * <p> * If a permission is provided, any resource permission that matches must * contain the permission * * @param resource resource to test * @param user user * @param permission permission * @return <code>true</code> if the resource is manageable * @throws Exception on any error */ public static boolean isManageableResource(Resource resource, User user, Permission permission) throws Exception { boolean b = false; if (LogonControllerFactory.getInstance().isAdministrator(user)) { return true; } else { b = PolicyDatabaseFactory.getInstance().isPermitted(resource.getResourceType(), new Permission[] { permission }, user, false); } return b; } /** * Get if a single personal resource may be managed by the specified user. For a * resource to be manageable, a user must either be the super user or the * parent personal resource permission of the resource must be attached to the policy * of that user. The resource must be attached to the personal policy of * the specified user and only to this personal policy. * A resource will also be manageable if one of its * parents is manageable. * * @param resource resource to test * @param user user * @param permission permission * @return <code>true</code> if the resource is manageable * @throws Exception on any error */ public static boolean isManageablePersonalResource(Resource resource, User user, Permission permission) throws Exception { boolean b = false; if (LogonControllerFactory.getInstance().isAdministrator(user)) { return true; } else { b = PolicyDatabaseFactory.getInstance().isPersonalPermitted(resource, new Permission[] { permission }, user); } return b; } /** * Get if the list of {@link ResourceItem} objects contains any obects that * wrap the specified {@link Resource} * * @param items items to search * @param resource resource to search for * @return resource found */ public static boolean resourceItemListContainsResource(List items, Resource resource) { ResourceItem ri; for (Iterator i = items.iterator(); i.hasNext();) { ri = (ResourceItem) i.next(); if (ri.getResource().equals(resource)) { return true; } } return false; } /** * Check if the current resource may be managed (i.e. edited, removed etc) * taking into account the current navigation context, whether the resource * is owned and if rights to manage it have been delegated to the current * user * * @param resource resource * @param session session * @param permissions permissions required for management. if any of these * are assigned the the resource may be managed * @throws NoPermissionException if not allowed */ public static void checkResourceManagementRights(Resource resource, SessionInfo session, Permission[] permissions) throws NoPermissionException { for (int i = 0; i < permissions.length; i++) { try { ResourceType resourceType = resource.getResourceType(); // If in the management console, this resource must be // manageable if (session.getNavigationContext() == SessionInfo.MANAGEMENT_CONSOLE_CONTEXT) { try { if (!ResourceUtil.isManageableResource(resource, session.getUser(), permissions[i])) { throw new NoPermissionException("You do not have permission to manage this resource.", session.getUser(), resourceType); } } catch (NoPermissionException npe) { throw npe; } catch (Exception e) { throw new NoPermissionException("Failed to determine if resource is manangeable.", session.getUser(), resourceType); } } // If in the user console the resource must be owned else if (session.getNavigationContext() == SessionInfo.USER_CONSOLE_CONTEXT) { try { if (!(resource instanceof OwnedResource)) { if (!ResourceUtil.isManageablePersonalResource(resource, session.getUser(), permissions[i])) { throw new NoPermissionException("You may not managed this resource here.", session.getUser(), resourceType); } } else { if (!(session.getUser().getPrincipalName() .equals(((OwnedResource) resource).getOwnerUsername()))) { throw new NoPermissionException( "You do not have permission to manage this resource.", session.getUser(), resourceType); } } } catch (Exception e) { throw new NoPermissionException("Failed to determine if resource is manangeable.", session.getUser(), resourceType); } } else { throw new NoPermissionException("You may not manage this resource here.", session.getUser(), resourceType); } break; } catch (NoPermissionException npe) { if (i == (permissions.length - 1)) { throw npe; } } } } /** * Check if the current resource may be accessed taking into account the * current navigation context, whether the resource is owned and if rights * to access it have been assigned to the current user * * @param resource resource * @param session session * @throws NoPermissionException if not allowed */ public static void checkResourceAccessRights(Resource resource, SessionInfo session) throws NoPermissionException { ResourceType resourceType = resource.getResourceType(); // If in the management console, this resource must be manageable if (session.getNavigationContext() == SessionInfo.MANAGEMENT_CONSOLE_CONTEXT) { try { if (!ResourceUtil.isManageableResource(resource, session.getUser(), null)) { throw new NoPermissionException("You do not have permission to access this resource.", session.getUser(), resourceType); } } catch (NoPermissionException npe) { throw npe; } catch (Exception e) { throw new NoPermissionException("Failed to determine if resource is accessable.", session.getUser(), resourceType); } } // If in the user console the resource must be assigned or owned else if (session.getNavigationContext() == SessionInfo.USER_CONSOLE_CONTEXT) { if (!(resource instanceof OwnedResource) || (resource instanceof OwnedResource && ((OwnedResource) resource).getOwnerUsername() == null)) { try { // assigned if (!PolicyDatabaseFactory.getInstance().isPrincipalAllowed(session.getUser(), resource, false)) { throw new NoPermissionException("You may not access this resource here.", session.getUser(), resourceType); } } catch (NoPermissionException npe) { throw npe; } catch (Exception e) { throw new NoPermissionException("Failed to determine if resource is accessable.", session.getUser(), resourceType); } } else { // or owned if (!(session.getUser().getPrincipalName().equals(((OwnedResource) resource).getOwnerUsername()))) { throw new NoPermissionException("You do not have permission to access this resource.", session.getUser(), resourceType); } } } else { throw new NoPermissionException("You may not access this resource here.", session.getUser(), resourceType); } } /** * Check if {@link AccessRights} may be viewed, edited or removed. * If the <code>actionTarget</code> supplied is <strong>view</strong> * then a check is made to see if the resource permission is one that * permits the current user to perform actions. If <strong>edit</strong>, * <strong>remove</strong> or <strong>confirmRemove</strong> is supplied * then a check if made if the resource has a parent that the current user * has access to. * * @param resource resource to check * @param session session of current user * @param actionTarget action target * @throws NoPermissionException no permission excepion */ public static void checkAccessRightsValid(AccessRights resource, SessionInfo session, String actionTarget) throws NoPermissionException { if (actionTarget.equals("edit") || actionTarget.equals("remove") || actionTarget.equals("confirmRemove")) { ResourceUtil.checkResourceManagementRights(resource, session, new Permission[] {}); } else if (actionTarget.equals("view")) { try { List l = LogonControllerFactory.getInstance().isAdministrator(session.getUser()) ? new ArrayList() : PolicyDatabaseFactory.getInstance().getPermittingAccessRights(null, null, null, session.getUser()); if (!l.contains(resource)) { throw new NoPermissionException("Permission denied.", session.getUser(), PolicyConstants.ACCESS_RIGHTS_RESOURCE_TYPE); } } catch (NoPermissionException npe) { throw npe; } catch (Exception e) { throw new NoPermissionException("Failed to determine management rights.", session.getUser(), PolicyConstants.ACCESS_RIGHTS_RESOURCE_TYPE); } } else { throw new Error("checkValid() only supports edit, remove or view here, not '" + actionTarget + "'."); } } /** * @param user * @return List * @throws Exception */ public static List getSignonAuthenticationSchemeIDs(User user) throws Exception { List<Integer> resourceIds = PolicyDatabaseFactory.getInstance().getGrantedResourcesOfType(user, PolicyConstants.AUTHENTICATION_SCHEMES_RESOURCE_TYPE); List<Integer> filteredResourceIDs = new ArrayList<Integer>(); for (Integer integer : resourceIds) { AuthenticationScheme authenticationScheme = SystemDatabaseFactory.getInstance() .getAuthenticationSchemeSequence(integer); // Need to check for null because a plugin may have been removed that provided a previously valid scheme if (authenticationScheme != null && !authenticationScheme.isSystemScheme()) filteredResourceIDs.add(authenticationScheme.getResourceId()); } return filteredResourceIDs; } /** * Obtain a list of all resources assigned to a user. * @param session * @return * @throws Exception */ public static List getGrantedResources(SessionInfo session) throws Exception { List allResources = new ArrayList(); List types = PolicyDatabaseFactory.getInstance().getResourceTypes(null); for (Iterator it = types.iterator(); it.hasNext();) { ResourceType type = (ResourceType) it.next(); allResources.addAll(ResourceUtil.getGrantedResource(session, type)); } return allResources; } /** * Gets a list of {@link Resource} granted for use for the specified * session. * * @param session session * @param resourceType resource type * @return list of resources * @throws Exception */ public static List getGrantedResource(SessionInfo session, ResourceType resourceType) throws Exception { List l = new ArrayList(); List granted = PolicyDatabaseFactory.getInstance().getGrantedResourcesOfType(session.getUser(), resourceType); for (Iterator i = granted.iterator(); i.hasNext();) { Integer r = (Integer) i.next(); Resource resource = resourceType.getResourceById(r.intValue()); if (resource == null) { log.warn("Could not locate resource with ID of " + r.intValue() + " for type " + resourceType.getResourceTypeId()); } else { if (isPolicyResourceTypeEnforceable(resourceType) && Property .getPropertyBoolean(new SystemConfigKey("security.enforce.policy.resource.access"))) { for (Iterator iter = PolicyDatabaseFactory.getInstance() .getPoliciesAttachedToResource(resource, session.getUser().getRealm()).iterator(); iter .hasNext();) { Policy element = (Policy) iter.next(); List authSchemePolicies = (List) session.getHttpSession() .getAttribute("auth.scheme.policies"); if (authSchemePolicies != null && (authSchemePolicies).contains(element)) { l.add(resource); } } } else { l.add(resource); } } } return l; } public static boolean isPolicyResourceTypeEnforceable(ResourceType rt) { if (rt.equals(PolicyConstants.PROFILE_RESOURCE_TYPE) || rt.equals(PolicyConstants.ACCESS_RIGHTS_RESOURCE_TYPE) || rt.equals(PolicyConstants.POLICY_RESOURCE_TYPE) || rt.equals(PolicyConstants.AUTHENTICATION_SCHEMES_RESOURCE_TYPE)) return false; else return true; } /** * Filter a list of {@link Integer} objects containing resource ids for * those that have a global favorite. * * @param resources resources * @param resourceType resource type * @return filtered list of resources that have favorites * @throws Exception on any error */ public static List filterResourceIdsForGlobalFavorites(List resources, ResourceType resourceType) throws Exception { List l = new ArrayList(); for (Iterator i = resources.iterator(); i.hasNext();) { Integer r = (Integer) i.next(); if (SystemDatabaseFactory.getInstance().getFavorite(resourceType.getResourceTypeId(), null, r.intValue()) != null) { l.add(r); } } return l; } /** * Set whether a resource is a global favorite (available to all have * who policy to use it). * * @param resource resource * @param addToFavorites add to favorites * @throws Exception on any error */ public static void setResourceGlobalFavorite(Resource resource, boolean addToFavorites) throws Exception { if (addToFavorites != isResourceGlobalFavorite(resource)) { if (addToFavorites) { SystemDatabaseFactory.getInstance().addFavorite(resource.getResourceType().getResourceTypeId(), resource.getResourceId(), null); } else { SystemDatabaseFactory.getInstance().removeFavorite(resource.getResourceType().getResourceTypeId(), resource.getResourceId(), null); } } } /** * Get if a resource is added as a global favorite (available to all have * who policy to use it). * * @param resource resource * @return added as a favorite * @throws Exception */ public static boolean isResourceGlobalFavorite(Resource resource) throws Exception { return SystemDatabaseFactory.getInstance().getFavorite(resource.getResourceType().getResourceTypeId(), null, resource.getResourceId()) != null; } }