Author: rmannibucau
Date: Thu Aug 23 19:40:04 2012
New Revision: 1376662

URL: http://svn.apache.org/viewvc?rev=1376662&view=rev
Log:
TOMEE-404 lazy realm can be low typed

Added:
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LowTypedRealm.java
Modified:
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LazyRealm.java

Modified: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LazyRealm.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LazyRealm.java?rev=1376662&r1=1376661&r2=1376662&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LazyRealm.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LazyRealm.java
 Thu Aug 23 19:40:04 2012
@@ -70,10 +70,11 @@ public class LazyRealm implements Realm 
         if (delegate == null) {
             synchronized (this) {
                 if (delegate == null) {
-                    final Class<Realm> clazz;
+                    final Object instance;
+
+                    final Class<?> clazz;
                     try {
-                        clazz = (Class<Realm>) 
Thread.currentThread().getContextClassLoader()
-                                .loadClass(realmClass);
+                        clazz = 
Thread.currentThread().getContextClassLoader().loadClass(realmClass);
                     } catch (ClassNotFoundException e) {
                         throw new TomEERuntimeException(e);
                     }
@@ -90,7 +91,7 @@ public class LazyRealm implements Realm 
                                         
.unmarshal(properties.trim().replaceAll("\\p{Space}*(\\p{Alnum}*)=", "\n$1="));
                                 recipe.setAllProperties(props);
                             }
-                            delegate = (Realm) recipe.create();
+                            instance = recipe.create();
                         } catch (Exception e) {
                             throw new TomEERuntimeException(e);
                         }
@@ -99,13 +100,19 @@ public class LazyRealm implements Realm 
                         final Set<Bean<?>> beans = bm.getBeans(clazz);
                         final Bean<?> bean = bm.resolve(beans);
                         creationalContext = bm.createCreationalContext(null);
-                        delegate = (Realm) bm.getReference(bean, clazz, 
creationalContext);
-                        if (delegate == null) {
-                            throw new TomEERuntimeException("realm can't be 
retrieved from cdi");
-                        }
+                        instance = bm.getReference(bean, clazz, 
creationalContext);
+                    }
+
+                    if (instance == null) {
+                        throw new TomEERuntimeException("realm can't be 
retrieved from cdi");
+                    }
+                    if (instance instanceof Realm) {
+                        delegate = (Realm) instance;
+                    } else {
+                        delegate = new LowTypedRealm(instance);
                     }
+                    delegate.setContainer(container);
                 }
-                delegate.setContainer(container);
             }
         }
         return delegate;

Added: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LowTypedRealm.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LowTypedRealm.java?rev=1376662&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LowTypedRealm.java
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LowTypedRealm.java
 Thu Aug 23 19:40:04 2012
@@ -0,0 +1,195 @@
+package org.apache.tomee.catalina.realm;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Realm;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.tomee.catalina.TomEERuntimeException;
+import org.ietf.jgss.GSSContext;
+
+import javax.servlet.ServletSecurityElement;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class LowTypedRealm implements Realm {
+    private static final Class<?>[] SIMPLE_AUTHENTICATE_ARGS = new Class<?>[] 
{ String.class, String.class };
+    private static final Class<?>[] AUTHENTICATE_ARGS = new Class<?>[] { 
String.class, String.class, String.class, String.class, String.class, 
String.class, String.class, String.class };
+    private static final Class<?>[] GSCONTEXT_AUTHENTICATE = new Class<?>[] { 
GSSContext.class, Boolean.class };
+    private static final Class<?>[] X509CERT_AUTHENTICATE = new Class<?>[] { 
X509Certificate[].class };
+    private static final Class<?>[] FIND_SECURITY_CONSTRAINTS_CONSTRAINT = new 
Class<?>[] { HttpServletRequest.class, String.class };
+    private static final Class<?>[] HAS_RESOURCE_PERMISSION_CONSTRAINT = new 
Class<?>[] { HttpServletRequest.class, HttpServletResponse.class, 
Object[].class, String.class };
+    private static final Class<?>[] HAS_ROLE_CONSTRAINT = new Class<?>[] { 
Principal.class, String.class };
+    private static final Class<?>[] HAS_USER_DATA_PERMISSION_CONSTRAINT = new 
Class<?>[] { HttpServletRequest.class, HttpServletResponse.class, 
Object[].class };
+
+    private final Object delegate;
+    private final String info;
+
+    private final Method simpleAuthenticateMethod;
+    private final Method authenticateMethod;
+    private final Method gsMethod;
+    private final Method findSecurityConstraintsMethod;
+    private final Method x509Method;
+    private final Method hasResourcePermissionMethod;
+    private final Method hasRoleConstraintMethod;
+    private final Method hasUserDataMethod;
+
+    private Container container;
+
+    public LowTypedRealm(final Object delegate) {
+        this.delegate = delegate;
+        info = delegate.getClass() + "/1.0";
+
+        final Class<?> clazz = delegate.getClass();
+
+        simpleAuthenticateMethod = findMethod(clazz, SIMPLE_AUTHENTICATE_ARGS);
+        authenticateMethod = findMethod(clazz, AUTHENTICATE_ARGS);
+        gsMethod = findMethod(clazz, GSCONTEXT_AUTHENTICATE);
+        findSecurityConstraintsMethod = findMethod(clazz, 
FIND_SECURITY_CONSTRAINTS_CONSTRAINT);
+        x509Method = findMethod(clazz, X509CERT_AUTHENTICATE);
+        hasResourcePermissionMethod = findMethod(clazz, 
HAS_RESOURCE_PERMISSION_CONSTRAINT);
+        hasRoleConstraintMethod = findMethod(clazz, HAS_ROLE_CONSTRAINT);
+        hasUserDataMethod = findMethod(clazz, 
HAS_USER_DATA_PERMISSION_CONSTRAINT);
+    }
+
+    private Method findMethod(final Class<?> clazz, final Class<?>[] argTypes) 
{
+        for (Method mtd : clazz.getMethods()) {
+            if (!Modifier.isAbstract(mtd.getModifiers())) {
+                continue;
+            }
+
+            boolean match = true;
+            for (int i = 0; i < argTypes.length; i++) {
+                final Class<?>[] params = mtd.getParameterTypes();
+                if (params.length != argTypes.length) {
+                    match = false;
+                    break;
+                }
+
+                if (!argTypes[i].isAssignableFrom(params[i])) {
+                    match = false;
+                    break;
+                }
+            }
+
+            if (match) {
+                return mtd;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public Container getContainer() {
+        return container;
+    }
+
+    @Override
+    public void setContainer(final Container container) {
+        this.container = container;
+    }
+
+    @Override
+    public String getInfo() {
+        return info;
+    }
+
+    @Override
+    public void addPropertyChangeListener(final PropertyChangeListener 
listener) {
+        // no-op
+    }
+
+    @Override
+    public void removePropertyChangeListener(final PropertyChangeListener 
listener) {
+        // no-op
+    }
+
+    @Override
+    public Principal authenticate(final String username, final String 
credentials) {
+        return (Principal) invoke(simpleAuthenticateMethod, username, 
credentials);
+    }
+
+    @Override
+    public Principal authenticate(final String username, final String digest, 
final String nonce,
+                                  final String nc, final String cnonce, final 
String qop,
+                                  final String realm, final String md5a2) {
+        return (Principal) invoke(authenticateMethod, username, digest, nonce, 
nc, cnonce, qop, realm, md5a2);
+    }
+
+    @Override
+    public Principal authenticate(final GSSContext gssContext, final boolean 
storeCreds) {
+        return (Principal) invoke(gsMethod, gssContext, storeCreds);
+    }
+
+    @Override
+    public Principal authenticate(final X509Certificate[] certs) {
+        return (Principal) invoke(x509Method, certs);
+    }
+
+    @Override
+    public boolean hasRole(final Wrapper wrapper, final Principal principal, 
final String role) {
+        return (Boolean) invoke(hasRoleConstraintMethod, principal, role);
+    }
+
+    @Override
+    public void backgroundProcess() {
+        // no-op
+    }
+
+    //
+    // next patterns can be fully reworked
+    //
+
+    @Override
+    public SecurityConstraint[] findSecurityConstraints(final Request request, 
final Context context) {
+        final Map<String, ServletSecurityElement> map = (Map<String, 
ServletSecurityElement>) invoke(findSecurityConstraintsMethod, 
request.getRequest(), context.getPath());
+        final List<SecurityConstraint> constraints = new 
ArrayList<SecurityConstraint>();
+        for (Map.Entry<String, ServletSecurityElement> entry : map.entrySet()) 
{
+            
constraints.addAll(Arrays.asList(SecurityConstraint.createConstraints(entry.getValue(),
 entry.getKey())));
+        }
+        return constraints.toArray(new SecurityConstraint[constraints.size()]);
+    }
+
+    @Override
+    public boolean hasResourcePermission(final Request request, final Response 
response,
+                                         final SecurityConstraint[] 
constraint, final Context context) throws IOException {
+        return (Boolean) invoke(hasResourcePermissionMethod, 
request.getRequest(), response.getResponse(), constraint, context.getPath());
+    }
+
+    @Override
+    public boolean hasUserDataPermission(final Request request, final Response 
response, final SecurityConstraint[] constraint) throws IOException {
+        return (Boolean) invoke(hasUserDataMethod, request.getRequest(), 
response.getResponse(), constraint);
+    }
+
+    private Object invoke(final Method method, final Object... args) {
+        if (method == null) {
+            return null;
+        }
+
+        try {
+            return method.invoke(delegate, args);
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof RuntimeException) {
+                throw (RuntimeException) e.getCause();
+            }
+            throw new TomEERuntimeException(e.getCause());
+        } catch (IllegalAccessException e) {
+            throw new TomEERuntimeException(e);
+        }
+    }
+
+}


Reply via email to