Package org.jboss.seam.security

Source Code of org.jboss.seam.security.SecurityInterceptor$Restriction

package org.jboss.seam.security;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.annotations.intercept.InterceptorType;
import org.jboss.seam.annotations.security.PermissionCheck;
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.annotations.security.RoleCheck;
import org.jboss.seam.async.AsynchronousInterceptor;
import org.jboss.seam.intercept.AbstractInterceptor;
import org.jboss.seam.intercept.InvocationContext;
import org.jboss.seam.util.Strings;

/**
* Provides authorization services for component invocations.
*
* @author Shane Bryzak
*/
@Interceptor(type=InterceptorType.CLIENT,
         around=AsynchronousInterceptor.class)
public class SecurityInterceptor extends AbstractInterceptor implements Serializable
{
   private static final long serialVersionUID = -6567750187000766925L;
  
   /**
    * You may encounter a JVM bug where the field initializer is not evaluated for a transient field after deserialization.
    * @see "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6252102"
    */
   private transient volatile Map<Method,Restriction> restrictions = new HashMap<Method,Restriction>();
  
   private class Restriction
   {
      private String expression;
     
      private String permissionTarget;
      private String permissionAction;
     
      private Map<String, Object> methodRestrictions;
      private Map<Integer,Set<String>> paramRestrictions;
      private Set<String> roleRestrictions;
           
      public void setExpression(String expression)
      {
         this.expression = expression;
      }
     
      public void setPermissionTarget(String target)
      {
         this.permissionTarget = target;
      }
     
      public void setPermissionAction(String action)
      {
         this.permissionAction = action;
      }
     
      public void addMethodRestriction(Object target, String action)
      {
         if (methodRestrictions == null)
         {
            methodRestrictions = new HashMap<String, Object>();
         }
        
         methodRestrictions.put(action, target);
      }
     
      public void addRoleRestriction(String role)
      {
         if (roleRestrictions == null)
         {
            roleRestrictions = new HashSet<String>();
         }
        
         roleRestrictions.add(role);
      }
     
      public void addParameterRestriction(int index, String action)
      {
         Set<String> actions = null;
        
         if (paramRestrictions == null)
         {
            paramRestrictions = new HashMap<Integer,Set<String>>();
         }
        
         if (!paramRestrictions.containsKey(index))
         {
            actions = new HashSet<String>();
            paramRestrictions.put(index, actions);
         }
         else
         {
            actions = paramRestrictions.get(index);
         }
        
         actions.add(action);
      }
     
      public void check(Object[] parameters)
      {
         if (Identity.isSecurityEnabled())
         {
            if (expression != null)
            {
               Identity.instance().checkRestriction(expression);
            }
           
            if (methodRestrictions != null)
            {
               for (String action : methodRestrictions.keySet())
               {
                  Identity.instance().checkPermission(methodRestrictions.get(action), action);
               }
            }
           
            if (paramRestrictions != null)
            {
               for (Integer idx : paramRestrictions.keySet())
               {
                  Set<String> actions = paramRestrictions.get(idx);
                  for (String action : actions)
                  {
                     Identity.instance().checkPermission(parameters[idx], action);
                  }
               }
            }
           
            if (roleRestrictions != null)
            {
               for (String role : roleRestrictions)
               {
                  Identity.instance().checkRole(role);
               }
            }
           
            if (permissionTarget != null && permissionAction != null)
            {
               Identity.instance().checkPermission(permissionTarget, permissionAction);
            }
         }
      }
   }

   @AroundInvoke
   public Object aroundInvoke(InvocationContext invocation) throws Exception
   {
      Method interfaceMethod = invocation.getMethod();
     
      if (!"hashCode".equals(interfaceMethod.getName()))
      {
         Restriction restriction = getRestriction(interfaceMethod);     
         if ( restriction != null ) restriction.check(invocation.getParameters());
      }

      return invocation.proceed();
   }

   private Restriction getRestriction(Method interfaceMethod) throws Exception
   {
      // see field declaration as to why this is done
      if (restrictions == null)
      {
         synchronized(this)
         {
            restrictions = new HashMap<Method, Restriction>();
         }
      }
     
      if (!restrictions.containsKey(interfaceMethod))
      {
         synchronized(restrictions)
         {
            // FIXME this logic should be abstracted rather than sitting in the middle of this interceptor
            if (!restrictions.containsKey(interfaceMethod))
            { 
               Restriction restriction = null;
              
               Method method = getComponent().getBeanClass().getMethod(
                     interfaceMethod.getName(), interfaceMethod.getParameterTypes() );     
              
               Restrict restrict = null;
              
               if ( method.isAnnotationPresent(Restrict.class) )
               {
                  restrict = method.getAnnotation(Restrict.class);
               }
               else if ( getComponent().getBeanClass().isAnnotationPresent(Restrict.class) )
               {
                  if ( !getComponent().isLifecycleMethod(method) )
                  {
                     restrict = getComponent().getBeanClass().getAnnotation(Restrict.class);
                  }
               }
              
               if (restrict != null)
               {
                  if (restriction == null) restriction = new Restriction();
                 
                  if ( Strings.isEmpty(restrict.value()) )
                  {
                     restriction.setPermissionTarget(getComponent().getName());
                     restriction.setPermissionAction(method.getName());
                  }
                  else
                  {
                     restriction.setExpression(restrict.value());
                  }
               }
              
               for (Annotation annotation : method.getDeclaringClass().getAnnotations())
               {
                  if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
                  {
                     if (restriction == null) restriction = new Restriction();
                     restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
                  }
               }
              
               for (Annotation annotation : method.getAnnotations())
               {
                  if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
                  {
                     PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
                           PermissionCheck.class);
                    
                     Method valueMethod = null;
                     for (Method m : annotation.annotationType().getDeclaredMethods())
                     {
                        valueMethod = m;
                        break;
                     }
                    
                     if (valueMethod != null)
                     {                       
                        if (restriction == null) restriction = new Restriction();
                        Object target = valueMethod.invoke(annotation);
                        if (!target.equals(void.class))
                        {
                           if (restriction == null) restriction = new Restriction();
                           restriction.addMethodRestriction(target,
                                 getPermissionAction(permissionCheck, annotation));
                        }
                     }
                  }
                  if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
                  {
                     if (restriction == null) restriction = new Restriction();
                     restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
                  }
               }              
              
               for (int i = 0; i < method.getParameterAnnotations().length; i++)
               {
                  Annotation[] annotations = method.getParameterAnnotations()[i];
                  for (Annotation annotation : annotations)
                  {
                     if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
                     {                       
                        PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
                              PermissionCheck.class);
                        if (restriction == null) restriction = new Restriction();
                        restriction.addParameterRestriction(i,
                              getPermissionAction(permissionCheck, annotation));                       
                     }
                  }
               }                            
              
               restrictions.put(interfaceMethod, restriction);
               return restriction;
            }
         }
      }
      return restrictions.get(interfaceMethod);     
   }
  
   private String getPermissionAction(PermissionCheck check, Annotation annotation)
   {
      if (!"".equals(check.value()))
      {
         return check.value();
      }
      else
      {
         return annotation.annotationType().getSimpleName().toLowerCase();
      }
   }
  
   public boolean isInterceptorEnabled()
   {
      return getComponent().isSecure() && !getComponent().beanClassHasAnnotation("javax.jws.WebService");
   }
}
TOP

Related Classes of org.jboss.seam.security.SecurityInterceptor$Restriction

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.