]> source.dussan.org Git - archiva.git/blob
fb4d2e3c44292c9266d230da776370d3743f9e69
[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                 log.error("Should throw UnauthorizedDavException");
125             } else {
126                 webdavResponse.sendError(e);
127             }
128         } finally {
129             getDavSessionProvider().releaseSession(webdavRequest);
130         }
131     }
132
133     public synchronized void initServers( ServletConfig servletConfig )
134     {
135         WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
136
137         securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
138         httpAuth =
139             (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
140
141         configuration = (ArchivaConfiguration) wac.getBean(
142             PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
143         configuration.addListener( this );
144
145         repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
146
147         for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
148         {
149             File repoDir = new File( repo.getLocation() );
150
151             if ( !repoDir.exists() )
152             {
153                 if ( !repoDir.mkdirs() )
154                 {
155                     // Skip invalid directories.
156                     log( "Unable to create missing directory for " + repo.getLocation() );
157                     continue;
158                 }
159             }
160         }
161
162         resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
163         locatorFactory = new ArchivaDavLocatorFactory();
164         sessionProvider = new ArchivaDavSessionProvider(wac);
165     }
166     
167     public void configurationEvent( ConfigurationEvent event )
168     {
169         if( event.getType() == ConfigurationEvent.SAVED )
170         {
171             initRepositories();
172         }
173     }
174
175     private void initRepositories()
176     {
177         synchronized ( repositoryMap )
178         {
179             repositoryMap.clear();
180             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
181         }
182
183         synchronized ( reloadLock )
184         {
185             initServers( getServletConfig() );
186         }
187     }
188
189     public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
190     {
191         if ( repositoryMap.isEmpty() )
192         {
193             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
194         }
195         return repositoryMap.get( prefix );
196     }
197
198     ArchivaConfiguration getConfiguration()
199     {
200         return configuration;
201     }
202
203     protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
204     {
205         return true;
206     }
207
208     public DavSessionProvider getDavSessionProvider()
209     {
210         return sessionProvider;
211     }
212
213     public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
214     {
215         this.sessionProvider = davSessionProvider;
216     }
217
218     public DavLocatorFactory getLocatorFactory()
219     {
220         return locatorFactory;
221     }
222
223     public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
224     {
225         locatorFactory = davLocatorFactory;
226     }
227
228     public DavResourceFactory getResourceFactory()
229     {
230         return resourceFactory;
231     }
232
233     public void setResourceFactory(final DavResourceFactory davResourceFactory)
234     {
235         resourceFactory = davResourceFactory;
236     }
237
238     public String getAuthenticateHeaderValue()
239     {
240         throw new UnsupportedOperationException("");
241     }
242
243     public String getAuthenticateHeaderValue(String repository)
244     {
245         return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";
246     }
247 }