]> source.dussan.org Git - archiva.git/blob
48ba64ba1b714fb151850124162fe1c1a7708a8b
[archiva.git] /
1 package org.apache.maven.archiva.web.repository;
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.maven.archiva.configuration.ArchivaConfiguration;
23 import org.apache.maven.archiva.configuration.ConfigurationEvent;
24 import org.apache.maven.archiva.configuration.ConfigurationListener;
25 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
26 import org.apache.maven.archiva.webdav.ArchivaDavLocatorFactory;
27 import org.apache.maven.archiva.webdav.ArchivaDavResourceFactory;
28 import org.apache.maven.archiva.webdav.ArchivaDavSessionProvider;
29 import org.apache.maven.archiva.webdav.UnauthorizedDavException;
30 import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
31 import org.apache.jackrabbit.webdav.*;
32 import org.codehaus.plexus.redback.system.SecuritySystem;
33 import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
34 import org.codehaus.plexus.spring.PlexusToSpringUtils;
35 import org.springframework.web.context.WebApplicationContext;
36 import org.springframework.web.context.support.WebApplicationContextUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import javax.servlet.ServletConfig;
41 import javax.servlet.ServletException;
42 import javax.servlet.http.HttpServletResponse;
43 import javax.servlet.http.HttpServletRequest;
44 import java.io.File;
45 import java.io.IOException;
46 import java.util.Map;
47
48 /**
49  * RepositoryServlet
50  *
51  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
52  * @version $Id$
53  */
54 public class RepositoryServlet
55     extends AbstractWebdavServlet
56     implements ConfigurationListener
57 {
58     private Logger log = LoggerFactory.getLogger(RepositoryServlet.class);
59
60     private SecuritySystem securitySystem;
61
62     private HttpAuthenticator httpAuth;
63
64     private ArchivaConfiguration configuration;
65
66     private Map<String, ManagedRepositoryConfiguration> repositoryMap;
67
68     private DavLocatorFactory locatorFactory;
69
70     private DavResourceFactory resourceFactory;
71
72     private DavSessionProvider sessionProvider;
73
74     private final Object reloadLock = new Object();
75
76     public void init(javax.servlet.ServletConfig servletConfig)
77         throws ServletException
78     {
79         super.init(servletConfig);
80         initServers(servletConfig);
81     }
82
83     /**
84      * Service the given request.
85      *
86      * @param request
87      * @param response
88      * @throws ServletException
89      * @throws java.io.IOException
90      */
91     @Override
92     protected void service(HttpServletRequest request, HttpServletResponse response)
93             throws ServletException, IOException
94     {
95         WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
96         // DeltaV requires 'Cache-Control' header for all methods except 'VERSION-CONTROL' and 'REPORT'.
97         int methodCode = DavMethods.getMethodCode(request.getMethod());
98         boolean noCache = DavMethods.isDeltaVMethod(webdavRequest) && !(DavMethods.DAV_VERSION_CONTROL == methodCode || DavMethods.DAV_REPORT == methodCode);
99         WebdavResponse webdavResponse = new WebdavResponseImpl(response, noCache);
100         try {
101             // make sure there is a authenticated user
102             if (!getDavSessionProvider().attachSession(webdavRequest)) {
103                 return;
104             }
105
106             // check matching if=header for lock-token relevant operations
107             DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
108             if (!isPreconditionValid(webdavRequest, resource)) {
109                 webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
110                 return;
111             }
112             if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
113                 super.service(request, response);
114             }
115
116         }
117         catch (UnauthorizedDavException e)
118         {
119             webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
120             webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
121         }
122         catch (DavException e) {
123             if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
124                 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
125                 log.error(msg);
126                 webdavResponse.sendError(e.getErrorCode(), msg);
127             } else {
128                 webdavResponse.sendError(e);
129             }
130         } finally {
131             getDavSessionProvider().releaseSession(webdavRequest);
132         }
133     }
134
135     public synchronized void initServers( ServletConfig servletConfig )
136     {
137         WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
138
139         securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
140         httpAuth =
141             (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
142
143         configuration = (ArchivaConfiguration) wac.getBean(
144             PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
145         configuration.addListener( this );
146
147         repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
148
149         for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
150         {
151             File repoDir = new File( repo.getLocation() );
152
153             if ( !repoDir.exists() )
154             {
155                 if ( !repoDir.mkdirs() )
156                 {
157                     // Skip invalid directories.
158                     log( "Unable to create missing directory for " + repo.getLocation() );
159                     continue;
160                 }
161             }
162         }
163
164         resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
165         locatorFactory = new ArchivaDavLocatorFactory();
166         sessionProvider = new ArchivaDavSessionProvider(wac);
167     }
168     
169     public void configurationEvent( ConfigurationEvent event )
170     {
171         if( event.getType() == ConfigurationEvent.SAVED )
172         {
173             initRepositories();
174         }
175     }
176
177     private void initRepositories()
178     {
179         synchronized ( repositoryMap )
180         {
181             repositoryMap.clear();
182             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
183         }
184
185         synchronized ( reloadLock )
186         {
187             initServers( getServletConfig() );
188         }
189     }
190
191     public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
192     {
193         if ( repositoryMap.isEmpty() )
194         {
195             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
196         }
197         return repositoryMap.get( prefix );
198     }
199
200     ArchivaConfiguration getConfiguration()
201     {
202         return configuration;
203     }
204
205     protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
206     {
207         return true;
208     }
209
210     public DavSessionProvider getDavSessionProvider()
211     {
212         return sessionProvider;
213     }
214
215     public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
216     {
217         this.sessionProvider = davSessionProvider;
218     }
219
220     public DavLocatorFactory getLocatorFactory()
221     {
222         return locatorFactory;
223     }
224
225     public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
226     {
227         locatorFactory = davLocatorFactory;
228     }
229
230     public DavResourceFactory getResourceFactory()
231     {
232         return resourceFactory;
233     }
234
235     public void setResourceFactory(final DavResourceFactory davResourceFactory)
236     {
237         resourceFactory = davResourceFactory;
238     }
239
240     public String getAuthenticateHeaderValue()
241     {
242         throw new UnsupportedOperationException("");
243     }
244
245     public String getAuthenticateHeaderValue(String repository)
246     {
247         return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";
248     }
249 }