Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 134   Methods: 2
NCLOC: 44   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ContextPropagatingRemoteInvocation.java 62.5% 78.6% 100% 75%
coverage coverage
 1    /* Copyright 2004, 2005 Acegi Technology Pty Limited
 2    *
 3    * Licensed under the Apache License, Version 2.0 (the "License");
 4    * you may not use this file except in compliance with the License.
 5    * You may obtain a copy of the License at
 6    *
 7    * http://www.apache.org/licenses/LICENSE-2.0
 8    *
 9    * Unless required by applicable law or agreed to in writing, software
 10    * distributed under the License is distributed on an "AS IS" BASIS,
 11    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    * See the License for the specific language governing permissions and
 13    * limitations under the License.
 14    */
 15   
 16    package org.acegisecurity.context.rmi;
 17   
 18    import org.acegisecurity.context.SecurityContext;
 19    import org.acegisecurity.context.SecurityContextHolder;
 20    import org.acegisecurity.context.SecurityContextImpl;
 21   
 22    import org.aopalliance.intercept.MethodInvocation;
 23   
 24    import org.apache.commons.logging.Log;
 25    import org.apache.commons.logging.LogFactory;
 26   
 27    import org.springframework.remoting.support.RemoteInvocation;
 28   
 29    import java.lang.reflect.InvocationTargetException;
 30   
 31   
 32    /**
 33    * The actual <code>RemoteInvocation</code> that is passed from the client to
 34    * the server, which contains the contents of {@link SecurityContextHolder},
 35    * being a {@link SecurityContext} object.
 36    *
 37    * <p>
 38    * When constructed on the client via {@link
 39    * org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory},
 40    * the contents of the <code>SecurityContext</code> are stored inside the
 41    * object. The object is then passed to the server that is processing the
 42    * remote invocation. Upon the server invoking the remote invocation, it will
 43    * retrieve the passed contents of the <code>SecurityContextHolder</code> and
 44    * set them to the server-side <code>SecurityContextHolder</code> whilst the
 45    * target object is invoked. When the target invocation has been completed,
 46    * the server-side <code>SecurityContextHolder</code> will be reset to a new
 47    * instance of <code>SecurityContextImpl</code>.
 48    * </p>
 49    *
 50    * @author James Monaghan
 51    * @author Ben Alex
 52    * @version $Id: ContextPropagatingRemoteInvocation.java,v 1.7 2005/11/23 16:09:44 luke_t Exp $
 53    */
 54    public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
 55    //~ Static fields/initializers =============================================
 56   
 57    private static final Log logger = LogFactory.getLog(ContextPropagatingRemoteInvocation.class);
 58   
 59    //~ Instance fields ========================================================
 60   
 61    private SecurityContext securityContext;
 62   
 63    //~ Constructors ===========================================================
 64   
 65    /**
 66    * Constructs the object, storing the value of the client-side
 67    * <code>SecurityContextHolder</code> inside the object.
 68    *
 69    * @param methodInvocation the method to invoke
 70    */
 71  3 public ContextPropagatingRemoteInvocation(MethodInvocation methodInvocation) {
 72  3 super(methodInvocation);
 73  3 securityContext = SecurityContextHolder.getContext();
 74   
 75  3 if (logger.isDebugEnabled()) {
 76  0 logger.debug("RemoteInvocation now has SecurityContext: "
 77    + securityContext);
 78    }
 79    }
 80   
 81    //~ Methods ================================================================
 82   
 83    /**
 84    * Invoked on the server-side as described in the class JavaDocs.
 85    *
 86    * <p>
 87    * Invocations will always have their {@link
 88    * org.acegisecurity.Authentication#setAuthenticated(boolean)} set to
 89    * <code>false</code>, which is guaranteed to always be accepted by
 90    * <code>Authentication</code> implementations. This ensures that even
 91    * remotely authenticated <code>Authentication</code>s will be untrusted
 92    * by the server-side, which is an appropriate security measure.
 93    * </p>
 94    *
 95    * @param targetObject the target object to apply the invocation to
 96    *
 97    * @return the invocation result
 98    *
 99    * @throws NoSuchMethodException if the method name could not be resolved
 100    * @throws IllegalAccessException if the method could not be accessed
 101    * @throws InvocationTargetException if the method invocation resulted in
 102    * an exception
 103    */
 104  3 public Object invoke(Object targetObject)
 105    throws NoSuchMethodException, IllegalAccessException,
 106    InvocationTargetException {
 107  3 SecurityContextHolder.setContext(securityContext);
 108   
 109  3 if ((SecurityContextHolder.getContext() != null)
 110    && (SecurityContextHolder.getContext().getAuthentication() != null)) {
 111  2 SecurityContextHolder.getContext().getAuthentication()
 112    .setAuthenticated(false);
 113    }
 114   
 115  3 if (logger.isDebugEnabled()) {
 116  0 logger.debug("Set SecurityContextHolder to contain: "
 117    + securityContext);
 118    }
 119   
 120  3 try {
 121   
 122  3 return super.invoke(targetObject);
 123   
 124    } finally {
 125   
 126  3 SecurityContextHolder.setContext(new SecurityContextImpl());
 127   
 128  3 if (logger.isDebugEnabled()) {
 129  0 logger.debug(
 130    "Set SecurityContext to new instance of SecurityContextImpl");
 131    }
 132    }
 133    }
 134    }