servicemix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r1087697 - in /servicemix/smx4/nmr/trunk/nmr: api/src/main/java/org/apache/servicemix/nmr/api/ core/src/main/java/org/apache/servicemix/nmr/core/ core/src/test/java/org/apache/servicemix/nmr/core/
Date Fri, 01 Apr 2011 13:19:43 GMT
Author: gertv
Date: Fri Apr  1 13:19:42 2011
New Revision: 1087697

URL: http://svn.apache.org/viewvc?rev=1087697&view=rev
Log:
SMX4NMR-265: Allow invoking an endpoint as the Subject passed along in the Message

Added:
    servicemix/smx4/nmr/trunk/nmr/core/src/test/java/org/apache/servicemix/nmr/core/ExchangeWithSecuritySubjectTest.java
Modified:
    servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/Endpoint.java
    servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/ChannelImpl.java
    servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/EndpointRegistryImpl.java

Modified: servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/Endpoint.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/Endpoint.java?rev=1087697&r1=1087696&r2=1087697&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/Endpoint.java
(original)
+++ servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/Endpoint.java
Fri Apr  1 13:19:42 2011
@@ -72,6 +72,13 @@ public interface Endpoint {
     String CHANNEL_SYNC_DELIVERY = "CHANNEL_SYNC_DELIVERY";
 
     /**
+     * If this property is set to <code>true</code>, the endpoint code
+     * will be run as the <code>Subject</code> passed along with the message
+     * being sent to it.
+     */
+    String RUN_AS_SUBJECT = "RUN_AS_SUBJECT";
+
+    /**
      * Set the channel so that the endpoint can send exchanges back
      * when they are processed or act as a consumer itself.
      * This method will be called by the NMR while the endpoint is registered.

Modified: servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/ChannelImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/ChannelImpl.java?rev=1087697&r1=1087696&r2=1087697&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/ChannelImpl.java
(original)
+++ servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/ChannelImpl.java
Fri Apr  1 13:19:42 2011
@@ -26,6 +26,9 @@ import org.apache.servicemix.nmr.api.int
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.security.auth.Subject;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Map;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.Semaphore;
@@ -51,6 +54,7 @@ public class ChannelImpl implements Inte
     private String name;
     private AtomicBoolean closed = new AtomicBoolean();
     private boolean shouldRunSynchronously;
+    private boolean runAsSubject;
 
     public ChannelImpl(InternalEndpoint endpoint, Executor executor, NMR nmr) {
         this.endpoint = endpoint;
@@ -74,6 +78,23 @@ public class ChannelImpl implements Inte
     }
 
     /**
+     * Will the endpoint code be invoked on behalf of the 'in' message subject?
+     */
+    public boolean isRunAsSubject() {
+        return runAsSubject;
+    }
+
+    /**
+     * Configure whether or not the endpoint will be invoked on behalf of the subject
+     * found on the in message or not.  Defaults to <code>false</code>.
+     *
+     * @param runAsSubject
+     */
+    public void setRunAsSubject(boolean runAsSubject) {
+        this.runAsSubject = runAsSubject;
+    }
+
+    /**
      * Access to the bus
      *
      * @return the NMR
@@ -243,11 +264,16 @@ public class ChannelImpl implements Inte
             // rather than delivering the exchange
             // TODO:
             // Process exchange
-            endpoint.process(exchange);
+            Subject subject = exchange.getIn().getSecuritySubject();
+            if (isRunAsSubject() && subject != null) {
+                process(endpoint, exchange, subject);
+            } else {
+                endpoint.process(exchange);
+            }
         } catch (RuntimeException e) {
             handleFailure(exchange, e, false);
         }
-    }                             
+    }
 
     /**
      * Dispatch the exchange to the NMR
@@ -319,4 +345,24 @@ public class ChannelImpl implements Inte
     protected final Executor getExecutor() {
         return executor;
     }
+
+    /**
+     * Make the endpoint process the exchange on behalf of the provided security Subject.
+     *
+     * @param endpoint the target endpoint
+     * @param exchange the exchange to be processed
+     * @param subject the subject that the endpoint is to be invoked by
+     */
+    private void process(final InternalEndpoint endpoint, final InternalExchange exchange,
final Subject subject) {
+        try {
+            Subject.doAs(subject, new PrivilegedExceptionAction<Object>() {
+                public Object run() throws Exception {
+                    endpoint.process(exchange);
+                    return null;
+                }
+            });
+        } catch (PrivilegedActionException e) {
+            throw new NmrRuntimeException("Unable to invoke endpoint on behalf of " + subject,
e);
+        }
+    }
 }

Modified: servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/EndpointRegistryImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/EndpointRegistryImpl.java?rev=1087697&r1=1087696&r2=1087697&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/EndpointRegistryImpl.java
(original)
+++ servicemix/smx4/nmr/trunk/nmr/core/src/main/java/org/apache/servicemix/nmr/core/EndpointRegistryImpl.java
Fri Apr  1 13:19:42 2011
@@ -125,6 +125,7 @@ public class EndpointRegistryImpl implem
             // Create channel
             ChannelImpl channel = new ChannelImpl(wrapper, executor, nmr);
             channel.setShouldRunSynchronously(isChannelSyncDelivery(properties));
+            channel.setRunAsSubject(isRunAsSubject(properties));
             wrapper.setChannel(channel);
             
             wrappers.put(wrapper, endpoint);
@@ -147,6 +148,13 @@ public class EndpointRegistryImpl implem
         return getBoolean(properties.get(Endpoint.CHANNEL_SYNC_DELIVERY));
     }
 
+    /*
+     * Should the Channel invoke the endpoint on behalf of the Subject in the mesage?
+     */
+    private boolean isRunAsSubject(Map<String, ?> properties) {
+        return getBoolean(properties.get(Endpoint.RUN_AS_SUBJECT));
+    }
+
     /**
      * Unregister a previously register enpoint.
      * In an OSGi world, this would be performed automatically by a ServiceTracker.

Added: servicemix/smx4/nmr/trunk/nmr/core/src/test/java/org/apache/servicemix/nmr/core/ExchangeWithSecuritySubjectTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/core/src/test/java/org/apache/servicemix/nmr/core/ExchangeWithSecuritySubjectTest.java?rev=1087697&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/core/src/test/java/org/apache/servicemix/nmr/core/ExchangeWithSecuritySubjectTest.java
(added)
+++ servicemix/smx4/nmr/trunk/nmr/core/src/test/java/org/apache/servicemix/nmr/core/ExchangeWithSecuritySubjectTest.java
Fri Apr  1 13:19:42 2011
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.nmr.core;
+
+import junit.framework.TestCase;
+import org.apache.servicemix.nmr.api.*;
+import org.apache.servicemix.nmr.api.event.ExchangeListener;
+import org.apache.servicemix.nmr.api.security.UserPrincipal;
+import org.apache.servicemix.nmr.api.service.ServiceHelper;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+import javax.security.auth.Subject;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.security.AccessController;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import static org.easymock.EasyMock.*;
+
+/**
+ * Test class to ensure the NMR handles Exchange with a security subject set on them correctly
+ */
+public class ExchangeWithSecuritySubjectTest extends TestCase {
+
+    private NMR nmr;
+
+    public void setUp() {
+        ServiceMix smx = new ServiceMix();
+        smx.init();
+        nmr = smx;
+    }
+
+    /**
+     * Ensure that endpoint code can be run as the passed in subject
+     */
+    public void testRunAsSubject() {
+        // let's register the endpoint first, asking for the code to invoked on behalf of
the subject
+        SubjectCapturingEndpoint endpoint = new SubjectCapturingEndpoint();
+        nmr.getEndpointRegistry().register(endpoint,
+                                           ServiceHelper.createMap(Endpoint.NAME, "runas",
+                                                                   Endpoint.RUN_AS_SUBJECT,
"true"));
+
+
+        Subject subject = new Subject();
+        subject.getPrincipals().add(new UserPrincipal("VIP User"));
+
+        Channel channel = nmr.createChannel();
+        Exchange exchange = channel.createExchange(Pattern.InOnly);
+        exchange.setTarget(
+                nmr.getEndpointRegistry().lookup(ServiceHelper.createMap(Endpoint.NAME, "runas")));
+        exchange.getIn().setSecuritySubject(subject);
+
+        channel.sendSync(exchange);
+
+        assertTrue("Endpoint should have been invoked 'as' the Subject",
+                   endpoint.captures.contains(subject));
+    }
+
+    /**
+     * Ensure that endpoint code is not invoked on behalf of the Subject if the option has
not been
+     * explicitly enabled first.
+     */
+    public void testDoNotRunAsSubject() {
+        // let's register the endpoint first without asking for any special Subject handling
+        SubjectCapturingEndpoint endpoint = new SubjectCapturingEndpoint();
+        nmr.getEndpointRegistry().register(endpoint,
+                                           ServiceHelper.createMap(Endpoint.NAME, "do_not_runas"));
+
+        Subject subject = new Subject();
+        subject.getPrincipals().add(new UserPrincipal("VIP User"));
+
+        Channel channel = nmr.createChannel();
+        Exchange exchange = channel.createExchange(Pattern.InOnly);
+        exchange.setTarget(
+                nmr.getEndpointRegistry().lookup(ServiceHelper.createMap(Endpoint.NAME, "do_not_runas")));
+        exchange.getIn().setSecuritySubject(subject);
+
+        channel.sendSync(exchange);
+
+        assertTrue("Endpoint should not have been invoked 'as' the Subject",
+                   endpoint.captures.isEmpty());
+    }
+
+    /*
+     * Endpoint that captures the Subject it is being invoked as.
+     */
+    private static class SubjectCapturingEndpoint implements Endpoint {
+
+        private Set<Subject> captures = new HashSet<Subject>();
+        private Channel channel;
+
+        public void process(Exchange exchange) {
+            Subject subject = Subject.getSubject(AccessController.getContext());
+            if (subject != null) {
+                captures.add(subject);
+            }
+
+            exchange.setStatus(Status.Done);
+            channel.send(exchange);
+        }
+
+        public void setChannel(Channel channel) {
+            this.channel = channel;
+        }            
+    }
+}



Mime
View raw message