Package org.jasig.portal.security.provider

Source Code of org.jasig.portal.security.provider.AuthorizationImpl

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you 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.jasig.portal.security.provider;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.AuthorizationException;
import org.jasig.portal.ChannelCategory;
import org.jasig.portal.ChannelRegistryStoreFactory;
import org.jasig.portal.EntityTypes;
import org.jasig.portal.IChannelRegistryStore;
import org.jasig.portal.channel.ChannelLifecycleState;
import org.jasig.portal.channel.IChannelDefinition;
import org.jasig.portal.concurrency.CachingException;
import org.jasig.portal.groups.GroupsException;
import org.jasig.portal.groups.IEntityGroup;
import org.jasig.portal.groups.IGroupMember;
import org.jasig.portal.properties.PropertiesManager;
import org.jasig.portal.security.IAuthorizationPrincipal;
import org.jasig.portal.security.IAuthorizationService;
import org.jasig.portal.security.IPermission;
import org.jasig.portal.security.IPermissionManager;
import org.jasig.portal.security.IPermissionPolicy;
import org.jasig.portal.security.IPermissionSet;
import org.jasig.portal.security.IPermissionStore;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.security.IUpdatingPermissionManager;
import org.jasig.portal.services.EntityCachingService;
import org.jasig.portal.services.GroupService;
import org.jasig.portal.utils.cache.CacheFactory;
import org.jasig.portal.utils.cache.CacheFactoryLocator;

/**
* @author Bernie Durfee, bdurfee@interactivebusiness.com
* @author Dan Ellentuck
* @author Scott Battaglia
* @version $Revision: 21117 $ $Date: 2010-07-16 13:19:07 -0500 (Fri, 16 Jul 2010) $
*/
public class AuthorizationImpl implements IAuthorizationService {

    /** Instance of log in order to log events. */
    protected final Log log = LogFactory.getLog(getClass());

    /** Constant representing the separator used in the principal key. */
    private static final String PRINCIPAL_SEPARATOR = ".";

    /** The static instance of the AuthorizationImpl for purposes of creating a AuthorizationImpl singleton. */
    private static final IAuthorizationService singleton;

    /** Instance of the Permission Store for storing permission information. */
    private IPermissionStore permissionStore;

    /** The default Permission Policy this Authorization implementation will use. */
    private IPermissionPolicy defaultPermissionPolicy;
   
    /** Spring-configured channel registry store instance */
    protected final IChannelRegistryStore channelRegistryStore;

    /** The cache to hold the list of principals. */
    private Map<String, IAuthorizationPrincipal> principalCache = CacheFactoryLocator.getCacheFactory().getCache(CacheFactory.PRINCIPAL_CACHE);

    /** The cache to hold the list of principals. */
    private Map<String, Set<String>> entityParentsCache = CacheFactoryLocator.getCacheFactory().getCache(CacheFactory.ENTITY_PARENTS_CACHE);

    /** The class representing the permission set type. */
    private Class PERMISSION_SET_TYPE;

    /** variable to determine if we should cache permissions or not. */
    private boolean cachePermissions;

    static {
        singleton = new AuthorizationImpl();
    }

  /**
   *
   */
    protected AuthorizationImpl ()
    {
        super();
        initialize();
        this.channelRegistryStore = ChannelRegistryStoreFactory.getChannelRegistryStoreImpl();
    }
/**
* Adds <code>IPermissions</code> to the back end store.
* @param permissions IPermission[]
* @exception AuthorizationException
*/
public void addPermissions(IPermission[] permissions)
throws AuthorizationException
{
    if (permissions.length > 0)
    {
        getPermissionStore().add(permissions);
        if ( this.cachePermissions )
            { removeFromPermissionsCache(permissions); }
    }
}

/**
* Adds the <code>IPermissionSet</code> to the entity cache.
*/
protected void cacheAdd(IPermissionSet ps) throws AuthorizationException
{
    try
        { EntityCachingService.getEntityCachingService().add(ps); }
    catch (CachingException ce)
        { throw new AuthorizationException("Problem adding permissions for " + ps + " to cache", ce); }
}

/**
* Retrieves the <code>IPermissionSet</code> for the <code>IPermissionSet</code>
* from the entity cache.
*/
protected IPermissionSet cacheGet(IAuthorizationPrincipal principal)
throws AuthorizationException
{
    try
    {
        return (IPermissionSet)
          EntityCachingService.getEntityCachingService().get(this.PERMISSION_SET_TYPE, principal.getPrincipalString());
    }
    catch (CachingException ce)
        { throw new AuthorizationException("Problem getting permissions for " + principal + " from cache", ce); }
}

/**
* Removes the <code>IPermissionSet</code> for this principal from the
* entity cache.
*/
protected void cacheRemove(IAuthorizationPrincipal ap) throws AuthorizationException
{
    try
        { EntityCachingService.getEntityCachingService().remove(this.PERMISSION_SET_TYPE, ap.getPrincipalString()); }
    catch (CachingException ce)
        { throw new AuthorizationException("Problem removing permissions for " + ap + " from cache", ce); }
}

/**
* Updates the <code>IPermissionSet</code> in the entity cache.
*/
protected void cacheUpdate(IPermissionSet ps) throws AuthorizationException
{
    try
        { EntityCachingService.getEntityCachingService().update(ps); }
    catch (CachingException ce)
        { throw new AuthorizationException("Problem updating permissions for " + ps + " in cache", ce); }
}

@Override
public boolean canPrincipalConfigure(IAuthorizationPrincipal principal, int channelPublishId) throws AuthorizationException {
    String owner = IPermission.PORTAL_FRAMEWORK;
    String target = IPermission.CHANNEL_PREFIX + channelPublishId;
   
    // retrieve the indicated channel from the channel registry store and
    // determine its current lifecycle state
    IChannelDefinition channel = this.channelRegistryStore.getChannelDefinition(channelPublishId);
    if (channel == null){
        throw new AuthorizationException("Unable to locate channel " + channelPublishId);
    }
   
    final String activity = IPermission.PORTLET_MODE_CONFIG;
    return doesPrincipalHavePermission(principal, owner, activity, IPermission.ALL_CHANNELS_TARGET) ||
        doesPrincipalHavePermission(principal, owner, activity, target);
}
/**
* Answers if the principal has permission to MANAGE this Channel.
* @return boolean
* @param principal IAuthorizationPrincipal
* @param channelPublishId int
* @exception AuthorizationException indicates authorization information could not be retrieved.
*/
public boolean canPrincipalManage(IAuthorizationPrincipal principal, int channelPublishId)
throws AuthorizationException
{
    String owner = IPermission.PORTAL_FRAMEWORK;
    String target = IPermission.CHANNEL_PREFIX + channelPublishId;
   
    // retrieve the indicated channel from the channel registry store and
    // determine its current lifecycle state
  IChannelDefinition channel = this.channelRegistryStore
        .getChannelDefinition(channelPublishId);
    if (channel == null){
      return doesPrincipalHavePermission(principal, owner,
        IPermission.CHANNEL_MANAGER_APPROVED_ACTIVITY, target);
//      throw new AuthorizationException("Unable to locate channel " + channelPublishId);
    }   
    ChannelLifecycleState state = channel.getLifecycleState();
    int order = state.getOrder();
   
    /*
     * The following code assumes that later lifecycle states imply permission
     * for earlier lifecycle states.  For example, if a user has permission to
     * manage an expired channel, we assume s/he also has permission to
     * create, approve, and publish channels.  The following code counts
     * channels with auto-publish or auto-expiration dates set as requiring
     * publish or expiration permissions for management, even though the channel
     * may not yet be published or expired.
     */
   
    String all = IPermission.ALL_CHANNELS_TARGET;
    String activity = IPermission.CHANNEL_MANAGER_EXPIRED_ACTIVITY;
  if ((order <= ChannelLifecycleState.EXPIRED.getOrder()
      || channel.getExpirationDate() != null)
      && (doesPrincipalHavePermission(principal, owner, activity, all)
        || doesPrincipalHavePermission(principal, owner,
            activity, target))) {
    return true;
    }
 
  activity = IPermission.CHANNEL_MANAGER_ACTIVITY;
  if ((order <= ChannelLifecycleState.PUBLISHED.getOrder()
        || channel.getPublishDate() != null)
      && (doesPrincipalHavePermission(principal, owner, activity, all)
        || doesPrincipalHavePermission(principal, owner,
            activity, target))) {
      return true;
    }
 
  activity = IPermission.CHANNEL_MANAGER_APPROVED_ACTIVITY;
  log.debug("order: " + order + ", approved order: " + ChannelLifecycleState.APPROVED.getOrder());
  if (order <= ChannelLifecycleState.APPROVED.getOrder()
      && (doesPrincipalHavePermission(principal, owner, activity, all)
        || doesPrincipalHavePermission(principal, owner,
            activity, target))) {
      return true;
    }
 
  activity = IPermission.CHANNEL_MANAGER_CREATED_ACTIVITY;
  if (order <= ChannelLifecycleState.CREATED.getOrder()
      && (doesPrincipalHavePermission(principal, owner, activity, all)
        || doesPrincipalHavePermission(principal, owner,
            activity, target))) {
      return true;
    }
     
  // if no permissions were found, return false
  return false;
}

/**
* This checks if the framework has granted principal a right to publish.  DO WE WANT SOMETHING THIS COARSE (de)?
* @param principal IAuthorizationPrincipal
* @return boolean
*/
public boolean canPrincipalManage(IAuthorizationPrincipal principal, ChannelLifecycleState state, String categoryId) throws AuthorizationException
{
//    return doesPrincipalHavePermission
//      (principal, IPermission.PORTAL_FRAMEWORK, IPermission.CHANNEL_PUBLISHER_ACTIVITY, null);
    String owner = IPermission.PORTAL_FRAMEWORK;
   
    // retrieve the indicated channel from the channel registry store and
    // determine its current lifecycle state
    ChannelCategory category = this.channelRegistryStore.getChannelCategory(categoryId);
    if (category == null){
//      return doesPrincipalHavePermission(principal, owner,
//        IPermission.CHANNEL_MANAGER_APPROVED_ACTIVITY, target);
      throw new AuthorizationException("Unable to locate category " + categoryId);
    }   
    int order = state.getOrder();
   
    String all = IPermission.ALL_CHANNELS_TARGET;
    String activity = IPermission.CHANNEL_MANAGER_EXPIRED_ACTIVITY;
  if (order <= ChannelLifecycleState.EXPIRED.getOrder()
      && (doesPrincipalHavePermission(principal, owner, activity, all)
        || doesPrincipalHavePermission(principal, owner,
          activity, categoryId))) {
    return true;
    }
 
    activity = IPermission.CHANNEL_MANAGER_ACTIVITY;
  if (order <= ChannelLifecycleState.PUBLISHED.getOrder()
      && (doesPrincipalHavePermission(principal, owner, activity, all)
          || doesPrincipalHavePermission(principal, owner,
              activity, categoryId))) {
      return true;
    }
 
    activity = IPermission.CHANNEL_MANAGER_APPROVED_ACTIVITY;
  if (order <= ChannelLifecycleState.APPROVED.getOrder()
      && (doesPrincipalHavePermission(principal, owner, activity, all)
          || doesPrincipalHavePermission(principal, owner,
              activity, categoryId))) {
      return true;
    }
 
    activity = IPermission.CHANNEL_MANAGER_CREATED_ACTIVITY;
  if (order <= ChannelLifecycleState.CREATED.getOrder()
      && (doesPrincipalHavePermission(principal, owner, activity, all)
          || doesPrincipalHavePermission(principal, owner,
              activity, categoryId))) {
      return true;
    }
     
  return false;

}

/**
* Answers if the principal has permission to RENDER this Channel.  This
* implementation currently delegates to the SUBSCRIBE permission.
*
* @return boolean
* @param principal IAuthorizationPrincipal
* @param channelPublishId int
* @exception AuthorizationException indicates authorization information could not be retrieved.
*/
public boolean canPrincipalRender(IAuthorizationPrincipal principal, int channelPublishId)
throws AuthorizationException
{
  // This code simply assumes that anyone who can subscribe to a channel
  // should be able to render it.  In the future, we'd like to update this
  // implementation to use a separate permission for rendering.
    return canPrincipalSubscribe(principal, channelPublishId);
}

/**
* Answers if the principal has permission to SUBSCRIBE to this Channel.
* @return boolean
* @param principal IAuthorizationPrincipal
* @param channelPublishId int
* @exception AuthorizationException indicates authorization information could not be retrieved.
*/
public boolean canPrincipalSubscribe(IAuthorizationPrincipal principal, int channelPublishId)
{
    String owner = IPermission.PORTAL_FRAMEWORK;
    String target = IPermission.CHANNEL_PREFIX + channelPublishId;
   
    // retrieve the indicated channel from the channel registry store and
    // determine its current lifecycle state
  IChannelDefinition channel = this.channelRegistryStore
        .getChannelDefinition(channelPublishId);
    if (channel == null){
      return false;
    }   
    ChannelLifecycleState state = channel.getLifecycleState();
   
    /*
     * Each channel lifecycle state now has its own subscribe permission.  The
     * following logic checks the appropriate permission for the lifecycle.
     */
    String permission;
    if (state.equals(ChannelLifecycleState.PUBLISHED)) {
      permission = IPermission.CHANNEL_SUBSCRIBER_ACTIVITY;
    } else if (state.equals(ChannelLifecycleState.APPROVED)) {
      permission = IPermission.CHANNEL_SUBSCRIBER_APPROVED_ACTIVITY;
    } else if (state.equals(ChannelLifecycleState.CREATED)) {
      permission = IPermission.CHANNEL_SUBSCRIBER_CREATED_ACTIVITY;
    } else if (state.equals(ChannelLifecycleState.EXPIRED)) {
      permission = IPermission.CHANNEL_SUBSCRIBER_EXPIRED_ACTIVITY;
    } else {
      throw new AuthorizationException(
          "Unrecognized lifecycle state for channel "
              + channelPublishId);
    }

    // test the appropriate permission
    return (doesPrincipalHavePermission(principal, owner, permission, IPermission.ALL_CHANNELS_TARGET)
        || doesPrincipalHavePermission(principal, owner, permission, target));

}

/**
* Answers if the owner has given the principal (or any of its parents) permission
* to perform the activity on the target.  Params <code>owner</code> and
* <code>activity</code> must be non-null.  If <code>target</code> is null, then
* target is not checked.
*
* @return boolean
* @param principal IAuthorizationPrincipal
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not
* be retrieved.
*/
public boolean doesPrincipalHavePermission(
    IAuthorizationPrincipal principal,
    String owner,
    String activity,
    String target)
throws AuthorizationException
{
     return doesPrincipalHavePermission(principal, owner, activity, target, getDefaultPermissionPolicy());
}

/**
* Answers if the owner has given the principal permission to perform the activity on
* the target, as evaluated by the policy.  Params <code>policy</code>, <code>owner</code>
* and <code>activity</code> must be non-null.
*
* @return boolean
* @param principal IAuthorizationPrincipal
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not
* be retrieved.
*/
public boolean doesPrincipalHavePermission(
    IAuthorizationPrincipal principal,
    String owner,
    String activity,
    String target,
    IPermissionPolicy policy)
throws AuthorizationException
{
    return policy.doesPrincipalHavePermission(this, principal, owner, activity, target);
}

/**
* Returns the <code>IPermissions</code> owner has granted this <code>Principal</code> for
* the specified activity and target.  Null parameters will be ignored, that is, all
* <code>IPermissions</code> matching the non-null parameters are retrieved.  So,
* <code>getPermissions(principal,null, null, null)</code> should retrieve all <code>IPermissions</code>
* for a <code>Principal</code>.  Note that this includes <code>IPermissions</code> inherited
* from groups the <code>Principal</code> belongs to.
*
* @return org.jasig.portal.security.IPermission[]
* @param principal IAuthorizationPrincipal
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not
* be retrieved.
*/
public IPermission[] getAllPermissionsForPrincipal
    (IAuthorizationPrincipal principal,
    String owner,
    String activity,
    String target)
throws AuthorizationException
{
    IPermission[] perms = getPermissionsForPrincipal(principal, owner, activity, target);
    ArrayList<IPermission> al = new ArrayList<IPermission>(Arrays.asList(perms));
    Iterator i = getInheritedPrincipals(principal);
    while ( i.hasNext() )
    {
        IAuthorizationPrincipal p = (IAuthorizationPrincipal) i.next();
        perms = getPermissionsForPrincipal(p, owner, activity, target);
        al.addAll(Arrays.asList(perms));
    }
   
    if (log.isTraceEnabled()) {
      log.trace("query for all permissions for prcinipal=[" + principal + "], owner=[" + owner +
          "], activity=[" + activity + "], target=[" + target + "] returned permissions [" + al + "]");
    }
   
    return ((IPermission[])al.toArray(new IPermission[al.size()]));
}

/**
* Does this mean all channels the principal could conceivably subscribe
* to or all channels principal is specifically authorized to subscribe to,
* or what?
*
* @param principal IAuthorizationPrincipal
* @return Vector (of channels?)
* @exception AuthorizationException indicates authorization information could not
*/
public Vector getAuthorizedChannels(IAuthorizationPrincipal principal)
throws AuthorizationException
{
    return new Vector();
}

/**
* Returns <code>IAuthorizationPrincipals</code> that have <code>IPermissions</code> for
* the given owner, activity and target.
*
* @return IAuthorizationPrincipal[]
* @param owner
* @param activity
* @param target
*/
public IAuthorizationPrincipal[] getAuthorizedPrincipals(String owner, String activity, String target)
throws AuthorizationException
{
    IPermission[] permissions = getPermissionsForOwner(owner, activity, target);
    return getPrincipalsFromPermissions(permissions);
}

/**
* @return org.jasig.portal.security.IPermissionPolicy
*/
protected IPermissionPolicy getDefaultPermissionPolicy() {
    return this.defaultPermissionPolicy;
}

/**
* @return org.jasig.portal.groups.IGroupMember
* @param principal org.jasig.portal.security.IAuthorizationPrincipal
*/
public IGroupMember getGroupMember(IAuthorizationPrincipal principal)
throws GroupsException
{
    return getGroupMemberForPrincipal(principal);
}

/**
* @return org.jasig.portal.groups.IGroupMember
* @param principal org.jasig.portal.security.IAuthorizationPrincipal
*/
private IGroupMember getGroupMemberForPrincipal(IAuthorizationPrincipal principal)
throws GroupsException
{

    IGroupMember gm = GroupService.getGroupMember(principal.getKey(), principal.getType());

    if (log.isDebugEnabled()) {
        log.debug("AuthorizationImpl.getGroupMemberForPrincipal(): principal [" + principal + "] " +
                "got group member [" + gm + "]");
    }
       
    return gm;
}

/**
* Hook into the Groups system by converting the <code>IAuthorizationPrincipal</code> to
* an <code>IGroupMember</code>.  Returns ALL the groups the <code>IGroupMember</code>
* (recursively) belongs to.
* @param principal - org.jasig.portal.security.IAuthorizationPrincipal
* @return java.util.Iterator over Collection of IEntityGroups
*/
private Iterator getGroupsForPrincipal(IAuthorizationPrincipal principal)
throws GroupsException
{
    IGroupMember gm = getGroupMemberForPrincipal(principal);
    return gm.getAllContainingGroups();
}

/**
* Hook into the Groups system, find all containing groups, and convert the
* them to <code>IAuthorizationPrincipals</code>.
* @param principal - org.jasig.portal.security.IAuthorizationPrincipal
* @return java.util.Iterator over Collection of IEntityGroups
*/
private Iterator getInheritedPrincipals(IAuthorizationPrincipal principal)
throws AuthorizationException
{
    Iterator i = null;
    ArrayList<IAuthorizationPrincipal> al = new ArrayList<IAuthorizationPrincipal>(5);

    try
        { i = getGroupsForPrincipal(principal); }
    catch ( GroupsException ge )
        { throw new AuthorizationException("Could not retrieve Groups for " + principal,ge) ; }

    while ( i.hasNext() )
    {
        IEntityGroup group = (IEntityGroup) i.next();
        IAuthorizationPrincipal p = getPrincipalForGroup(group);
        al.add(p);
    }
    return al.iterator();
}

/**
* Returns the <code>IPermissions</code> owner has granted for the specified activity
* and target.  Null parameters will be ignored, that is, all <code>IPermissions</code>
* matching the non-null parameters are retrieved.
*
* @return org.jasig.portal.security.IPermission[]
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not
* be retrieved.
*/
public IPermission[] getPermissionsForOwner(String owner, String activity, String target)
throws AuthorizationException
{
    return primRetrievePermissions(owner, null, activity, target);
}

/**
* Returns the <code>IPermissions</code> owner has granted this <code>Principal</code> for
* the specified activity and target.  Null parameters will be ignored, that is, all
* <code>IPermissions</code> matching the non-null parameters are retrieved.  So,
* <code>getPermissions(principal,null, null, null)</code> should retrieve all <code>IPermissions</code>
* for a <code>Principal</code>.
*
* @return org.jasig.portal.security.IPermission[]
* @param principal IAuthorizationPrincipal
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not
* be retrieved.
*/
public IPermission[] getPermissionsForPrincipal
    (IAuthorizationPrincipal principal,
    String owner,
    String activity,
    String target)
throws AuthorizationException
{
    return primGetPermissionsForPrincipal(principal, owner, activity, target);
}

/**
* @return org.jasig.portal.security.IPermissionStore
*/
private IPermissionStore getPermissionStore()
{
    return this.permissionStore;
}

/**
* Returns <code>IAuthorizationPrincipal</code> associated with the <code>IPermission</code>.
*
* @return IAuthorizationPrincipal
* @param permission IPermission
*/
public IAuthorizationPrincipal getPrincipal(IPermission permission)
throws AuthorizationException
{
    String principalString = permission.getPrincipal();
    int idx = principalString.indexOf(PRINCIPAL_SEPARATOR);
    Integer typeId = new Integer(principalString.substring(0, idx));
    Class type = EntityTypes.getEntityType(typeId);
    String key = principalString.substring(idx + 1);
    return newPrincipal(key, type);
}

/**
* @param group
* @return user org.jasig.portal.security.IAuthorizationPrincipal
*/
private IAuthorizationPrincipal getPrincipalForGroup(IEntityGroup group)
{
    String key = group.getKey();
    Class type = EntityTypes.GROUP_ENTITY_TYPE;
    return newPrincipal(key, type);
}

/**
* Returns <code>IAuthorizationPrincipals</code> associated with the <code>IPermission[]</code>.
*
* @return IAuthorizationPrincipal[]
* @param permissions IPermission[]
*/
private IAuthorizationPrincipal[] getPrincipalsFromPermissions(IPermission[] permissions)
throws AuthorizationException
{
    Set principals = new HashSet();
    for ( int i=0; i<permissions.length; i++ )
    {
        IAuthorizationPrincipal principal = getPrincipal(permissions[i]);
        principals.add(principal);
    }
    return ((IAuthorizationPrincipal[])principals.toArray(new IAuthorizationPrincipal[principals.size()]));
}

/**
* Returns the String used by an <code>IPermission</code> to represent an
* <code>IAuthorizationPrincipal</code>.
* @param principal org.jasig.portal.security.IAuthorizationPrincipal
*/
public String getPrincipalString(IAuthorizationPrincipal principal)
{
    return getPrincipalString(principal.getType(), principal.getKey());
}
private String getPrincipalString(Class pType, String pKey) {
    Integer type = EntityTypes.getEntityTypeID(pType);
    return type + PRINCIPAL_SEPARATOR + pKey;
}

/**
* Returns the <code>IPermissions</code> owner has granted this <code>Principal</code> for
* the specified activity and target.  Null parameters will be ignored, that is, all
* <code>IPermissions</code> matching the non-null parameters are retrieved.  So,
* <code>getPermissions(principal,null, null, null)</code> should retrieve all <code>IPermissions</code>
* for a <code>Principal</code>.  Ignore any cached <code>IPermissions</code>.
*
* @return org.jasig.portal.security.IPermission[]
* @param principal IAuthorizationPrincipal
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not
* be retrieved.
*/
public IPermission[] getUncachedPermissionsForPrincipal
        (IAuthorizationPrincipal principal,
        String owner,
        String activity,
        String target)
throws AuthorizationException
{
    String pString = getPrincipalString(principal);
    return primRetrievePermissions(owner, pString, activity, target);
}

    private void initialize() throws IllegalArgumentException {
        final boolean DEFAULT_CACHE_PERMISSIONS = false;

         String factoryName = PropertiesManager.getProperty(
             "org.jasig.portal.security.IPermissionStore.implementation", null);
         String policyName = PropertiesManager
             .getProperty(
                 "org.jasig.portal.security.IPermissionPolicy.defaultImplementation",
                 null);
         this.cachePermissions = PropertiesManager.getPropertyAsBoolean(
             "org.jasig.portal.security.IAuthorizationService.cachePermissions",
             DEFAULT_CACHE_PERMISSIONS);

         if (factoryName == null) {
             final String eMsg = "AuthorizationImpl.initialize(): No entry for org.jasig.portal.security.IPermissionStore.implementation portal.properties.";
             log.error(eMsg);
             throw new IllegalArgumentException(eMsg);
         }

         if (policyName == null) {
             final String eMsg = "AuthorizationImpl.initialize(): No entry for org.jasig.portal.security.IPermissionPolicy.defaultImplementation portal.properties.";
             log.error(eMsg);
             throw new IllegalArgumentException(eMsg);
         }

         try {
             this.permissionStore = (IPermissionStore)Class.forName(factoryName)
                 .newInstance();
         }
         catch (Exception e) {
             final String eMsg = "AuthorizationImpl.initialize(): Problem creating permission store... ";
             log.error(eMsg, e);
             throw new IllegalArgumentException(eMsg);
         }

         try {
             this.defaultPermissionPolicy = (IPermissionPolicy)Class.forName(
                 policyName).newInstance();
         }
         catch (Exception e) {
             final String eMsg = "AuthorizationImpl.initialize(): Problem creating default permission policy... ";
             log.error(eMsg, e);
             throw new IllegalArgumentException(eMsg);
         }

         try {
             this.PERMISSION_SET_TYPE = Class
                 .forName("org.jasig.portal.security.IPermissionSet");
         }
         catch (ClassNotFoundException cnfe) {
             final String eMsg = "AuthorizationImpl.initialize(): Problem initializing service. ";
             log.error(eMsg, cnfe);
             throw new IllegalArgumentException(eMsg);
         }
     }


/**
* Factory method for an <code>IPermission</code>.
* @param owner String
* @return org.jasig.portal.security.Permission
*/
public IPermission newPermission(String owner)
{
    return newPermission(owner, null);
}

/**
* Factory method for an <code>IPermission</code>.
* @param owner String
* @param principal IAuthorizationPrincipal
* @return org.jasig.portal.security.IPermission
*/
public IPermission newPermission(String owner, IAuthorizationPrincipal principal)
{
    IPermission p = getPermissionStore().newInstance(owner);
    if ( principal != null )
    {
        String pString = getPrincipalString(principal);
        p.setPrincipal(pString);
    }
    return p;
}

/**
* Factory method for IPermissionManager.
* @return org.jasig.portal.security.IPermissionManager
* @param owner java.lang.String
*/
public IPermissionManager newPermissionManager(String owner)
{
    return new PermissionManagerImpl(owner, this);
}


/**
* Factory method for IAuthorizationPrincipal. First check the principal
* cache, and if not present, create the principal and cache it.
*
* @return org.jasig.portal.security.IAuthorizationPrincipal
* @param key java.lang.String
* @param type java.lang.Class
*/
public IAuthorizationPrincipal newPrincipal(String key, Class type) {
    final String principalKey = getPrincipalString(type, key);

    IAuthorizationPrincipal principal = null;

    synchronized (this.principalCache) {
        principal = this.principalCache.get(principalKey);
       
        if (principal == null) {
            principal = primNewPrincipal(key, type);
            this.principalCache.put(principalKey, principal);
        }
    }

    return principal;
}

/**
* Converts an <code>IGroupMember</code> into an <code>IAuthorizationPrincipal</code>.
* @return org.jasig.portal.security.IAuthorizationPrincipal
* @param groupMember org.jasig.portal.groups.IGroupMember
*/
public IAuthorizationPrincipal newPrincipal(IGroupMember groupMember)
throws GroupsException
{
    String key = groupMember.getKey();
    Class type = groupMember.getType();

    if (log.isDebugEnabled())
        log.debug("AuthorizationImpl.newPrincipal(): for " + type + "(" + key + ")");

    return newPrincipal(key, type);
}

private IAuthorizationPrincipal primNewPrincipal(String key, Class type) {
    return new AuthorizationPrincipalImpl(key, type, this);
}

/**
* Factory method for IUpdatingPermissionManager.
* @return org.jasig.portal.security.IUpdatingPermissionManager
* @param owner java.lang.String
*/
public IUpdatingPermissionManager newUpdatingPermissionManager(String owner)
{
    return new UpdatingPermissionManagerImpl(owner, this);
}

/**
* Returns permissions for a principal.  First check the entity caching
* service, and if the permissions have not been cached, retrieve and
* cache them.
* @return IPermission[]
* @param principal org.jasig.portal.security.IAuthorizationPrincipal
*/
private IPermission[] primGetPermissionsForPrincipal(IAuthorizationPrincipal principal)
throws AuthorizationException
{
    if ( ! this.cachePermissions )
        { return getUncachedPermissionsForPrincipal(principal, null, null, null);}

    IPermissionSet ps = null;
    // Check the caching service for the Permissions first.
    ps = cacheGet(principal);

    if ( ps == null )
    synchronized ( principal )
    {
        ps = cacheGet(principal);
        if ( ps == null )
        {
            IPermission[] permissions =
              getUncachedPermissionsForPrincipal(principal, null, null, null);
            ps = new PermissionSetImpl(permissions, principal);
            cacheAdd(ps);
        }
    }      // end synchronized
    return ps.getPermissions();
}

/**
* @return IPermission[]
* @param principal org.jasig.portal.security.IAuthorizationPrincipal
* @param owner String
* @param activity String
* @param target String
*/
private IPermission[] primGetPermissionsForPrincipal
    (IAuthorizationPrincipal principal,
    String owner,
    String activity,
    String target)
throws AuthorizationException
{

    /*
     * Get a list of all permissions for the specified principle, then iterate
     * through them to build a list of the permissions matching the specified
     * criteria.
     */

    IPermission[] perms = primGetPermissionsForPrincipal(principal);
    if ( owner == null && activity == null && target == null )
        { return perms; }

  Set<String> containingGroups;
 
  if (target != null) {
   
        containingGroups = (Set<String>) this.entityParentsCache.get(target);

        if (containingGroups == null) {

          containingGroups = new HashSet<String>();
          IGroupMember targetEntity = GroupService.findGroup(target);
        if (targetEntity == null) {
          if (target.startsWith(IPermission.CHANNEL_PREFIX)) {
            targetEntity = GroupService.getGroupMember(target.replace(IPermission.CHANNEL_PREFIX, ""), IChannelDefinition.class);
          } else {
            targetEntity = GroupService.getGroupMember(target, IPerson.class);
          }
        }
       
        if (targetEntity != null) {
          for (Iterator containing = targetEntity.getAllContainingGroups(); containing.hasNext();) {
            containingGroups.add(((IEntityGroup)containing.next()).getKey());
          }
        }
       
        this.entityParentsCache.put(target, containingGroups);
         
        }

   
  } else {
    containingGroups = new HashSet<String>();
  }

    List<IPermission> al = new ArrayList<IPermission>(perms.length);
   
    for ( int i=0; i<perms.length; i++ ) {
        String permissionTarget = perms[i].getTarget();
       
        if (
            // owner matches
            (owner == null || owner.equals(perms[i].getOwner())) &&
            // activity matches
                (activity == null || activity.equals(perms[i].getActivity())) &&
                // target matches or is a member of the current permission target
                (target == null || target.equals(permissionTarget)
                    || containingGroups.contains(permissionTarget))   
            ) {
         
            al.add(perms[i]);
        }
       
    }


   
    if (log.isTraceEnabled()) {
        log.trace(
                "AuthorizationImpl.primGetPermissionsForPrincipal(): " +
                "Principal: " + principal + " owner: " + owner +
                " activity: " + activity + " target: " + target + " : permissions retrieved: " + al);
    } else if (log.isDebugEnabled()) {
        log.debug(
                "AuthorizationImpl.primGetPermissionsForPrincipal(): " +
                "Principal: " + principal + " owner: " + owner +
                " activity: " + activity + " target: " + target + " : number of permissions retrieved: " + al.size());
    }


    return ((IPermission[])al.toArray(new IPermission[al.size()]));

}

/**
* @return IPermission[]
* @param owner String
* @param principal String
* @param activity String
* @param target String
*/
private IPermission[] primRetrievePermissions(String owner, String principal, String activity, String target)
throws AuthorizationException
{
    return getPermissionStore().select(owner, principal, activity, target, null);
}

/**
* Removes <code>IPermissions</code> for the <code>IAuthorizationPrincipals</code> from
* the cache.
* @param principals IAuthorizationPrincipal[]
*/
private void removeFromPermissionsCache(IAuthorizationPrincipal[] principals)
throws AuthorizationException
{
    for ( int i=0; i<principals.length; i++ )
        { cacheRemove(principals[i]); }
}

/**
* Removes <code>IPermissions</code> from the cache.
* @param permissions IPermission[]
*/
private void removeFromPermissionsCache(IPermission[] permissions)
throws AuthorizationException
{
    IAuthorizationPrincipal[] principals = getPrincipalsFromPermissions(permissions);
    removeFromPermissionsCache(principals);
}

/**
* Removes <code>IPermissions</code> from the back end store.
* @param permissions IPermission[]
* @exception AuthorizationException
*/
public void removePermissions(IPermission[] permissions)
throws AuthorizationException
{
    if (permissions.length > 0)
    {
        getPermissionStore().delete(permissions);
        if ( this.cachePermissions )
            { removeFromPermissionsCache(permissions); }
    }
}

/**
* @param newDefaultPermissionPolicy org.jasig.portal.security.IPermissionPolicy
*/
protected void setDefaultPermissionPolicy(IPermissionPolicy newDefaultPermissionPolicy) {
    this.defaultPermissionPolicy = newDefaultPermissionPolicy;
}

/**
* @return org.jasig.portal.security.provider.IAuthorizationService
*/
public static IAuthorizationService singleton()
{
    return singleton;
}

/**
* Updates <code>IPermissions</code> in the back end store.
* @param permissions IPermission[]
* @exception AuthorizationException
*/
public void updatePermissions(IPermission[] permissions)
throws AuthorizationException
{
    if (permissions.length > 0)
    {
        getPermissionStore().update(permissions);
        if ( this.cachePermissions )
            { removeFromPermissionsCache(permissions); }
    }
}
}
TOP

Related Classes of org.jasig.portal.security.provider.AuthorizationImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.