View Javadoc

1   package org.apache.maven.continuum.xmlrpc.server;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.xmlrpc.XmlRpcException;
23  import org.apache.xmlrpc.XmlRpcRequest;
24  import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping;
25  import org.apache.xmlrpc.server.PropertyHandlerMapping;
26  import org.apache.xmlrpc.server.RequestProcessorFactoryFactory;
27  import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
28  import org.codehaus.plexus.DefaultPlexusContainer;
29  import org.codehaus.plexus.PlexusConstants;
30  import org.codehaus.plexus.PlexusContainer;
31  import org.codehaus.plexus.PlexusContainerException;
32  import org.codehaus.plexus.classworlds.ClassWorld;
33  import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
34  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
35  import org.codehaus.plexus.redback.authentication.AuthenticationException;
36  import org.codehaus.plexus.redback.authentication.PasswordBasedAuthenticationDataSource;
37  import org.codehaus.plexus.redback.policy.PolicyViolationException;
38  import org.codehaus.plexus.redback.system.DefaultSecuritySession;
39  import org.codehaus.plexus.redback.system.SecuritySystem;
40  import org.codehaus.plexus.redback.users.UserNotFoundException;
41  
42  import java.io.IOException;
43  import java.util.HashMap;
44  import java.util.Map;
45  import javax.servlet.ServletConfig;
46  import javax.servlet.ServletContext;
47  import javax.servlet.ServletException;
48  import javax.servlet.http.HttpServlet;
49  import javax.servlet.http.HttpServletRequest;
50  import javax.servlet.http.HttpServletResponse;
51  
52  /**
53   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
54   * @version $Id: ContinuumXmlRpcServlet.java 1372260 2012-08-13 04:29:09Z brett $
55   */
56  public class ContinuumXmlRpcServlet
57      extends HttpServlet
58  {
59      private ContinuumXmlRpcServletServer server;
60  
61      private SecuritySystem securitySystem;
62  
63      public String getServletInfo()
64      {
65          return "Continuum XMLRPC Servlet";
66      }
67  
68      public void destroy()
69      {
70          if ( server != null )
71          {
72              try
73              {
74                  getPlexusContainer().release( server );
75              }
76              catch ( ServletException e )
77              {
78                  log( "Unable to release XmlRpcServletServer.", e );
79              }
80              catch ( ComponentLifecycleException e )
81              {
82                  log( "Unable to release XmlRpcServletServer.", e );
83              }
84          }
85      }
86  
87      public void init( ServletConfig servletConfig )
88          throws ServletException
89      {
90          super.init( servletConfig );
91  
92          ensureContainerSet( servletConfig );
93  
94          initServer();
95      }
96  
97      public void initServer()
98          throws ServletException
99      {
100         server = new ContinuumXmlRpcServletServer();
101 
102         try
103         {
104             securitySystem = (SecuritySystem) getPlexusContainer().lookup( SecuritySystem.ROLE );
105         }
106         catch ( ComponentLookupException e )
107         {
108             throw new ServletException( "Can't init the xml rpc server, unable to obtain security system", e );
109         }
110 
111         try
112         {
113             XmlRpcServerConfigImpl cfg = (XmlRpcServerConfigImpl) server.getConfig();
114             cfg.setEnabledForExtensions( true );
115             PropertiesHandlerMapping mapping = (PropertiesHandlerMapping) lookup(
116                 PropertyHandlerMapping.class.getName() );
117             mapping.setRequestProcessorFactoryFactory( (RequestProcessorFactoryFactory) lookup(
118                 RequestProcessorFactoryFactory.class.getName() ) );
119             mapping.load();
120             mapping.setAuthenticationHandler( getAuthenticationHandler() );
121             server.setHandlerMapping( mapping );
122         }
123         catch ( XmlRpcException e )
124         {
125             throw new ServletException( "Can't init the xml rpc server", e );
126         }
127     }
128 
129     private AbstractReflectiveHandlerMapping.AuthenticationHandler getAuthenticationHandler()
130     {
131         return new AbstractReflectiveHandlerMapping.AuthenticationHandler()
132         {
133             public boolean isAuthorized( XmlRpcRequest pRequest )
134             {
135                 if ( pRequest.getConfig() instanceof ContinuumXmlRpcConfig )
136                 {
137                     ContinuumXmlRpcConfig config = (ContinuumXmlRpcConfig) pRequest.getConfig();
138 
139                     try
140                     {
141                         // if username is null, then treat this as a guest user with an empty security session
142                         if ( config.getBasicUserName() == null )
143                         {
144                             config.setSecuritySession( new DefaultSecuritySession() );
145 
146                             return true;
147                         }
148                         else
149                         {
150                             // otherwise treat this as an authn required session, and if the credentials are invalid
151                             // do not default to guest privileges
152                             PasswordBasedAuthenticationDataSource authdatasource =
153                                 new PasswordBasedAuthenticationDataSource();
154                             authdatasource.setPrincipal( config.getBasicUserName() );
155                             authdatasource.setPassword( config.getBasicPassword() );
156 
157                             config.setSecuritySession( securitySystem.authenticate( authdatasource ) );
158 
159                             return config.getSecuritySession().isAuthenticated();
160                         }
161                     }
162                     catch ( AuthenticationException e )
163                     {
164                         e.printStackTrace();
165                         return false;
166                     }
167                     catch ( PolicyViolationException e )
168                     {
169                         e.printStackTrace();
170                         return false;
171                     }
172                     catch ( UserNotFoundException e )
173                     {
174                         e.printStackTrace();
175                         return false;
176                     }
177                 }
178                 else
179                 {
180                     System.out.println( "unknown xml rpc configiration object found..." );
181                     return false;
182                 }
183             }
184         };
185     }
186 
187     public void doPost( HttpServletRequest pRequest, HttpServletResponse pResponse )
188         throws IOException, ServletException
189     {
190         server.execute( pRequest, pResponse );
191     }
192 
193     private void ensureContainerSet( ServletConfig sc )
194         throws ServletException
195     {
196         // TODO: unify this code with the lifecycle listener and application server
197 
198         ServletContext context = sc.getServletContext();
199 
200         // Container not found.
201 
202         if ( context.getAttribute( PlexusConstants.PLEXUS_KEY ) != null )
203         {
204             context.log( "Plexus container already in context." );
205 
206             return;
207         }
208 
209         // Create container.
210 
211         Map keys = new HashMap();
212 
213         PlexusContainer pc;
214         try
215         {
216             pc = new DefaultPlexusContainer( "default", keys, "META-INF/plexus/application.xml", new ClassWorld(
217                 "plexus.core", getClass().getClassLoader() ) );
218 
219             context.setAttribute( PlexusConstants.PLEXUS_KEY, pc );
220         }
221         catch ( PlexusContainerException e )
222         {
223             throw new ServletException( "Unable to initialize Plexus Container.", e );
224         }
225     }
226 
227     private PlexusContainer getPlexusContainer()
228         throws ServletException
229     {
230         PlexusContainer container = (PlexusContainer) getServletContext().getAttribute( PlexusConstants.PLEXUS_KEY );
231         if ( container == null )
232         {
233             throw new ServletException( "Unable to find plexus container." );
234         }
235         return container;
236     }
237 
238     public Object lookup( String role )
239         throws ServletException
240     {
241         try
242         {
243             return getPlexusContainer().lookup( role );
244         }
245         catch ( ComponentLookupException e )
246         {
247             throw new ServletException( "Unable to lookup role [" + role + "]", e );
248         }
249     }
250 
251     public Object lookup( String role, String hint )
252         throws ServletException
253     {
254         try
255         {
256             return getPlexusContainer().lookup( role, hint );
257         }
258         catch ( ComponentLookupException e )
259         {
260             throw new ServletException( "Unable to lookup role [" + role + "] hint [" + hint + "]", e );
261         }
262     }
263 }