Package org.jboss.seam.security.permission

Source Code of org.jboss.seam.security.permission.RuleBasedPermissionResolver

package org.jboss.seam.security.permission;

import static org.jboss.seam.ScopeType.SESSION;
import static org.jboss.seam.annotations.Install.BUILT_IN;

import java.io.Serializable;
import java.security.Principal;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.drools.FactHandle;
import org.drools.RuleBase;
import org.drools.StatefulSession;
import org.drools.base.ClassObjectFilter;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.Seam;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.Role;
import org.jboss.seam.security.management.JpaIdentityStore;

/**
* A permission resolver that uses a Drools rule base to perform permission checks
* @author Shane Bryzak
*/
@Name("org.jboss.seam.security.ruleBasedPermissionResolver")
@Scope(SESSION)
@BypassInterceptors
@Install(precedence=BUILT_IN, classDependencies="org.drools.WorkingMemory")
@Startup
public class RuleBasedPermissionResolver implements PermissionResolver, Serializable
{     
   public static final String RULES_COMPONENT_NAME = "securityRules";  
  
   private static final LogProvider log = Logging.getLogProvider(RuleBasedPermissionResolver.class);
  
   private StatefulSession securityContext;
  
   private RuleBase securityRules; 
  
   @Create
   public boolean create()
   {
      initSecurityContext();
      return getSecurityContext() != null;
   }
  
   protected void initSecurityContext()
   {
      if (getSecurityRules() == null)
      {
         setSecurityRules((RuleBase) Component.getInstance(RULES_COMPONENT_NAME, true));
      }
     
      if (getSecurityRules() != null)
      {
         setSecurityContext(getSecurityRules().newStatefulSession(false));
      }
     
      if (getSecurityContext() == null)
      {
         log.debug("no security rule base available - please install a RuleBase with the name '" +
                  RULES_COMPONENT_NAME + "' if permission checks are required.");
      }
   }
  
   /**
    * Performs a permission check for the specified name and action
    *
    * @param target Object The target of the permission check
    * @param action String The action to be performed on the target
    * @return boolean True if the user has the specified permission
    */
   public boolean hasPermission(Object target, String action)
   {          
      StatefulSession securityContext = getSecurityContext();
     
      if (securityContext == null) return false;     
     
      List<FactHandle> handles = new ArrayList<FactHandle>()

      PermissionCheck check;
     
      synchronized( securityContext )
      {
         if (!(target instanceof String) && !(target instanceof Class))
         {
            handles.add( securityContext.insert(target) );
         }
         else if (target instanceof Class)
         {
            String componentName = Seam.getComponentName((Class) target);
            target = componentName != null ? componentName : ((Class) target).getName();
         }
        
         check = new PermissionCheck(target, action);        
        
         try
         {
            synchronizeContext();
           
            handles.add( securityContext.insert(check) );
  
            securityContext.fireAllRules();
         }
         finally
         {
            for (FactHandle handle : handles)
            {
               securityContext.retract(handle);
            }
         }
      }
     
      return check.isGranted();
   }
  
   public void filterSetByAction(Set<Object> targets, String action)
   {
      Iterator iter = targets.iterator();
      while (iter.hasNext())
      {
         Object target = iter.next();
         if (hasPermission(target, action)) iter.remove();
      }
   }
  
   public boolean checkConditionalRole(String roleName, Object target, String action)
   {     
      StatefulSession securityContext = getSecurityContext();
      if (securityContext == null) return false;
     
      RoleCheck roleCheck = new RoleCheck(roleName);
     
      List<FactHandle> handles = new ArrayList<FactHandle>();
      PermissionCheck check = new PermissionCheck(target, action);
     
      synchronized( securityContext )
      {
         if (!(target instanceof String) && !(target instanceof Class))
         {
            handles.add( securityContext.insert(target) );
         }
         else if (target instanceof Class)
         {
            String componentName = Seam.getComponentName((Class) target);
            target = componentName != null ? componentName : ((Class) target).getName();
         }
        
         try
         {
            synchronizeContext();

            handles.add( securityContext.insert(roleCheck));
            handles.add( securityContext.insert(check));
           
            securityContext.fireAllRules();
         }
         finally
         {
            for (FactHandle handle : handles)
            {
               securityContext.retract(handle);
            }
         }
      }
     
      return roleCheck.isGranted();
   }
  
   @SuppressWarnings("unchecked"
   @Observer(Identity.EVENT_LOGGED_OUT)
   public void unAuthenticate()
   {
      if (getSecurityContext() != null)
      {
         getSecurityContext().dispose();     
         setSecurityContext(null);
      }
      initSecurityContext();
   }
  
   /**
    *  Synchronises the state of the security context with that of the subject
    */
   private void synchronizeContext()
   {
      Identity identity = Identity.instance();
     
      if (getSecurityContext() != null)
      {
         getSecurityContext().insert(identity.getPrincipal());
        
         for ( Group sg : identity.getSubject().getPrincipals(Group.class) )     
         {
            if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
            {
               Enumeration e = sg.members();
               while (e.hasMoreElements())
               {
                  Principal role = (Principal) e.nextElement();
  
                  boolean found = false;
                  Iterator<Role> iter = getSecurityContext().iterateObjects(new ClassObjectFilter(Role.class));
                  while (iter.hasNext())
                  {
                     Role r = iter.next();
                     if (r.getName().equals(role.getName()))
                     {
                        found = true;
                        break;
                     }
                  }
                 
                  if (!found)
                  {
                     getSecurityContext().insert(new Role(role.getName()));
                  }
                 
               }
            }
         }   
        
         Iterator<Role> iter = getSecurityContext().iterateObjects(new ClassObjectFilter(Role.class));
         while (iter.hasNext())
         {
            Role r = iter.next();
            if (!identity.hasRole(r.getName()))
            {
               FactHandle fh = getSecurityContext().getFactHandle(r);
               getSecurityContext().retract(fh);
            }
         }
      }
   }
  
  
   public StatefulSession getSecurityContext()
   {
      return securityContext;
   }
  
   public void setSecurityContext(StatefulSession securityContext)
   {
      this.securityContext = securityContext;
   }
  

   public RuleBase getSecurityRules()
   {
      return securityRules;
   }

   public void setSecurityRules(RuleBase securityRules)
   {
      this.securityRules = securityRules;
   }      
  
   public static RuleBasedPermissionResolver instance()
   {
      if ( !Contexts.isSessionContextActive() )
      {
         throw new IllegalStateException("No active session context");
      }

      RuleBasedPermissionResolver instance = (RuleBasedPermissionResolver) Component.getInstance(
            RuleBasedPermissionResolver.class, ScopeType.SESSION);

      if (instance == null)
      {
         throw new IllegalStateException("No RuleBasedPermissionResolver could be created");
      }

      return instance;
   }
  
   /**
    * Post-authentication event observer
    */
   @Observer(Identity.EVENT_POST_AUTHENTICATE)
   public void setUserAccountInSecurityContext()
   {
      if (getSecurityContext() != null)
      {        
         getSecurityContext().insert(Identity.instance().getPrincipal());

         // If we were authenticated with the JpaIdentityStore, then insert the authenticated
         // UserAccount into the security context.        
         if (Contexts.isEventContextActive() && Contexts.isSessionContextActive() &&
               Contexts.getEventContext().isSet(JpaIdentityStore.AUTHENTICATED_USER))
         {
            getSecurityContext().insert(Contexts.getEventContext().get(JpaIdentityStore.AUTHENTICATED_USER));
         }
      }
   }
}
TOP

Related Classes of org.jboss.seam.security.permission.RuleBasedPermissionResolver

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.