[seam-commits] Seam SVN: r7419 - in trunk/src/main/org/jboss/seam: security and 1 other directory.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Wed Feb 13 09:46:43 EST 2008


Author: shane.bryzak at jboss.com
Date: 2008-02-13 09:46:43 -0500 (Wed, 13 Feb 2008)
New Revision: 7419

Added:
   trunk/src/main/org/jboss/seam/annotations/security/PermissionAction.java
Modified:
   trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java
Log:
support for annotated permission checks in security interceptor

Added: trunk/src/main/org/jboss/seam/annotations/security/PermissionAction.java
===================================================================
--- trunk/src/main/org/jboss/seam/annotations/security/PermissionAction.java	                        (rev 0)
+++ trunk/src/main/org/jboss/seam/annotations/security/PermissionAction.java	2008-02-13 14:46:43 UTC (rev 7419)
@@ -0,0 +1,24 @@
+package org.jboss.seam.annotations.security;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Meta-annotation that designates an annotation as being a permission action, 
+ * requiring a security check prior to invoking the annotated method or class
+ *
+ * @author Shane Bryzak
+ */
+ at Target({TYPE})
+ at Documented
+ at Retention(RUNTIME)
+ at Inherited
+public @interface PermissionAction 
+{
+   String value() default "";
+}

Modified: trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java	2008-02-13 04:21:03 UTC (rev 7418)
+++ trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java	2008-02-13 14:46:43 UTC (rev 7419)
@@ -1,10 +1,14 @@
 package org.jboss.seam.security;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
 
 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.PermissionAction;
 import org.jboss.seam.annotations.security.Restrict;
 import org.jboss.seam.async.AsynchronousInterceptor;
 import org.jboss.seam.intercept.AbstractInterceptor;
@@ -16,44 +20,137 @@
  * 
  * @author Shane Bryzak
  */
- at Interceptor(stateless = true, type=InterceptorType.CLIENT, 
+ at Interceptor(type=InterceptorType.CLIENT, 
          around=AsynchronousInterceptor.class)
 public class SecurityInterceptor extends AbstractInterceptor
 {
    private static final long serialVersionUID = -6567750187000766925L;
+   
+   private Map<Method,Restriction> restrictions = new HashMap<Method,Restriction>();
+   
+   private class Restriction
+   {
+      private String expression;
+      
+      private Object target;
+      private String action;
+            
+      public void setExpression(String expression)
+      {
+         this.expression = expression;
+      }
+      
+      public void setTarget(Object target)
+      {
+         this.target = target;
+      }
+      
+      public void setAction(String action)
+      {
+         this.action = action;
+      }
+      
+      public void check()
+      {
+         if (Identity.isSecurityEnabled())
+         {
+            if (expression != null)
+            {
+               Identity.instance().checkRestriction(expression);
+            }
+            else if (target != null && action != null)
+            {
+               // TODO implement the security check
+            }
+         }
+      }
+   }
 
    @AroundInvoke
    public Object aroundInvoke(InvocationContext invocation) throws Exception
    {
       Method interfaceMethod = invocation.getMethod();
-      //TODO: optimize this:
-      Method method = getComponent().getBeanClass()
-               .getMethod( interfaceMethod.getName(), interfaceMethod.getParameterTypes() );
-      Restrict restrict = getRestriction(method);
       
-      if ( restrict!=null && Identity.isSecurityEnabled() )
-      {
-         String expr = !Strings.isEmpty( restrict.value() ) ? 
-                  restrict.value() : createDefaultExpr(method);
-         Identity.instance().checkRestriction(expr);
-      }
+      Restriction restriction = getRestriction(interfaceMethod);
+      
+      if ( restriction != null ) restriction.check();
+
       return invocation.proceed();
    }
 
-   private Restrict getRestriction(Method method)
+   private Restriction getRestriction(Method interfaceMethod) throws Exception
    {
-      if ( method.isAnnotationPresent(Restrict.class) )
+      if (!restrictions.containsKey(interfaceMethod))
       {
-         return method.getAnnotation(Restrict.class);
-      }
-      else if ( getComponent().getBeanClass().isAnnotationPresent(Restrict.class) )
-      {
-         if ( !getComponent().isLifecycleMethod(method) )
+         synchronized(restrictions)
          {
-            return getComponent().getBeanClass().getAnnotation(Restrict.class);
+            if (!restrictions.containsKey(interfaceMethod))
+            {               
+               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)
+               {
+                  Restriction restriction = new Restriction();
+                  restriction.setExpression(!Strings.isEmpty( restrict.value() ) ? 
+                        restrict.value() : createDefaultExpr(method));
+                  restrictions.put(interfaceMethod, restriction);
+                  return restriction;
+               }
+               
+               for (Annotation annotation : method.getAnnotations())
+               {
+                  if (annotation.annotationType().isAnnotationPresent(PermissionAction.class))
+                  {
+                     PermissionAction permissionAction = annotation.annotationType().getAnnotation(PermissionAction.class);
+                     
+                     Method valueMethod = null;
+                     for (Method m : annotation.annotationType().getDeclaredMethods())
+                     {
+                        valueMethod = m;
+                        break;
+                     }
+                     
+                     if (valueMethod != null)
+                     {
+                        Restriction restriction = new Restriction();
+                        restriction.setTarget(valueMethod.invoke(annotation));
+                        
+                        if (!"".equals(permissionAction.value()))
+                        {
+                           restriction.setAction(permissionAction.value());
+                        }
+                        else
+                        {
+                           // If the PermissionAction.value isn't set, just use the lower-case version of the annotation name
+                           restriction.setAction(annotation.annotationType().getSimpleName().toLowerCase());
+                        }
+                        restrictions.put(interfaceMethod, restriction);
+                        return restriction;
+                     }
+                  }
+               }
+               
+               restrictions.put(interfaceMethod, null);
+               return null;
+            }
          }
       }
-      return null;
+      return restrictions.get(interfaceMethod);      
    }
    
    /**
@@ -65,6 +162,7 @@
     */
    private String createDefaultExpr(Method method)
    {
-      return String.format( "#{s:hasPermission('%s','%s', null)}", getComponent().getName(), method.getName() );
+      return String.format( "#{s:hasPermission('%s','%s', null)}", 
+            getComponent().getName(), method.getName() );
    }
 }




More information about the seam-commits mailing list