]> source.dussan.org Git - archiva.git/blob
089bb59973240f18937f9aa6c0c0384de06bdcfc
[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      * This method has been overridden and copy/pasted to allow better exception handling
86      * and to support different realms
87      *
88      * @param request
89      * @param response
90      * @throws ServletException
91      * @throws java.io.IOException
92      */
93     @Override
94     protected void service(HttpServletRequest request, HttpServletResponse response)
95             throws ServletException, IOException
96     {
97         WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
98         // DeltaV requires 'Cache-Control' header for all methods except 'VERSION-CONTROL' and 'REPORT'.
99         int methodCode = DavMethods.getMethodCode(request.getMethod());
100         boolean noCache = DavMethods.isDeltaVMethod(webdavRequest) && !(DavMethods.DAV_VERSION_CONTROL == methodCode || DavMethods.DAV_REPORT == methodCode);
101         WebdavResponse webdavResponse = new WebdavResponseImpl(response, noCache);
102         try {
103             // make sure there is a authenticated user
104             if (!getDavSessionProvider().attachSession(webdavRequest)) {
105                 return;
106             }
107
108             // check matching if=header for lock-token relevant operations
109             DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
110             if (!isPreconditionValid(webdavRequest, resource)) {
111                 webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
112                 return;
113             }
114             if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
115                 super.service(request, response);
116             }
117
118         }
119         catch (UnauthorizedDavException e)
120         {
121             webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
122             webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
123         }
124         catch (DavException e) {
125             if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
126                 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
127                 log.error(msg);
128                 webdavResponse.sendError(e.getErrorCode(), msg);
129             } else if ( e.getCause() != null ) {
130                 webdavResponse.sendError(e.getErrorCode(), e.getCause().getMessage());
131             } else {
132                 webdavResponse.sendError(e.getErrorCode(), e.getMessage());
133             }
134         } finally {
135             getDavSessionProvider().releaseSession(webdavRequest);
136         }
137     }
138
139     public synchronized void initServers( ServletConfig servletConfig )
140     {
141         WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
142
143         securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
144         httpAuth =
145             (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
146
147         configuration = (ArchivaConfiguration) wac.getBean(
148             PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
149         configuration.addListener( this );
150
151         repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
152
153         for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
154         {
155             File repoDir = new File( repo.getLocation() );
156
157             if ( !repoDir.exists() )
158             {
159                 if ( !repoDir.mkdirs() )
160                 {
161                     // Skip invalid directories.
162                     log( "Unable to create missing directory for " + repo.getLocation() );
163                     continue;
164                 }
165             }
166         }
167
168         resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
169         locatorFactory = new ArchivaDavLocatorFactory();
170         sessionProvider = new ArchivaDavSessionProvider(wac);
171     }
172     
173     public void configurationEvent( ConfigurationEvent event )
174     {
175         if( event.getType() == ConfigurationEvent.SAVED )
176         {
177             initRepositories();
178         }
179     }
180
181     private void initRepositories()
182     {
183         synchronized ( repositoryMap )
184         {
185             repositoryMap.clear();
186             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
187         }
188
189         synchronized ( reloadLock )
190         {
191             initServers( getServletConfig() );
192         }
193     }
194
195     public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
196     {
197         if ( repositoryMap.isEmpty() )
198         {
199             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
200         }
201         return repositoryMap.get( prefix );
202     }
203
204     ArchivaConfiguration getConfiguration()
205     {
206         return configuration;
207     }
208
209     protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
210     {
211         return true;
212     }
213
214     public DavSessionProvider getDavSessionProvider()
215     {
216         return sessionProvider;
217     }
218
219     public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
220     {
221         this.sessionProvider = davSessionProvider;
222     }
223
224     public DavLocatorFactory getLocatorFactory()
225     {
226         return locatorFactory;
227     }
228
229     public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
230     {
231         locatorFactory = davLocatorFactory;
232     }
233
234     public DavResourceFactory getResourceFactory()
235     {
236         return resourceFactory;
237     }
238
239     public void setResourceFactory(final DavResourceFactory davResourceFactory)
240     {
241         resourceFactory = davResourceFactory;
242     }
243
244     public String getAuthenticateHeaderValue()
245     {
246         throw new UnsupportedOperationException();
247     }
248
249     public String getAuthenticateHeaderValue(String repository)
250     {
251         return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";
252     }
253 }