]> source.dussan.org Git - archiva.git/blob
61919910d913052b57f973494f9315a61f2db3ed
[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.security.ArchivaRoleConstants;
27 import org.codehaus.plexus.redback.authentication.AuthenticationException;
28 import org.codehaus.plexus.redback.authentication.AuthenticationResult;
29 import org.codehaus.plexus.redback.authorization.AuthorizationException;
30 import org.codehaus.plexus.redback.authorization.AuthorizationResult;
31 import org.codehaus.plexus.redback.policy.AccountLockedException;
32 import org.codehaus.plexus.redback.policy.MustChangePasswordException;
33 import org.codehaus.plexus.redback.system.SecuritySession;
34 import org.codehaus.plexus.redback.system.SecuritySystem;
35 import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
36 import org.codehaus.plexus.webdav.DavServerComponent;
37 import org.codehaus.plexus.webdav.DavServerException;
38 import org.codehaus.plexus.webdav.DavServerManager;
39 import org.codehaus.plexus.webdav.servlet.DavServerRequest;
40 import org.codehaus.plexus.webdav.servlet.multiplexed.MultiplexedWebDavServlet;
41 import org.codehaus.plexus.webdav.util.WebdavMethodUtil;
42
43 import java.io.File;
44 import java.io.IOException;
45 import java.util.Map;
46
47 import javax.servlet.ServletConfig;
48 import javax.servlet.ServletException;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51
52 /**
53  * RepositoryServlet
54  *
55  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
56  * @version $Id$
57  */
58 public class RepositoryServlet
59     extends MultiplexedWebDavServlet
60     implements ConfigurationListener
61 {
62     private SecuritySystem securitySystem;
63
64     private HttpAuthenticator httpAuth;
65
66     private AuditLog audit;
67
68     private ArchivaConfiguration configuration;
69
70     private Map<String, ManagedRepositoryConfiguration> repositoryMap;
71     
72     private ArchivaMimeTypeLoader mimeTypeLoader;
73
74     public synchronized void initComponents()
75         throws ServletException
76     {
77         super.initComponents();
78         
79         mimeTypeLoader = (ArchivaMimeTypeLoader) lookup( ArchivaMimeTypeLoader.class.getName() );
80         
81         securitySystem = (SecuritySystem) lookup( SecuritySystem.ROLE );
82         httpAuth = (HttpAuthenticator) lookup( HttpAuthenticator.ROLE, "basic" );
83         audit = (AuditLog) lookup( AuditLog.ROLE );
84
85         configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class.getName() );
86         configuration.addListener( this );
87
88         repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
89     }
90
91     public synchronized void initServers( ServletConfig servletConfig )
92         throws DavServerException
93     {
94         for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
95         {
96             File repoDir = new File( repo.getLocation() );
97
98             if ( !repoDir.exists() )
99             {
100                 if ( !repoDir.mkdirs() )
101                 {
102                     // Skip invalid directories.
103                     log( "Unable to create missing directory for " + repo.getLocation() );
104                     continue;
105                 }
106             }
107
108             DavServerComponent server = createServer( repo.getId(), repoDir, servletConfig );
109
110             server.setUseIndexHtml( true );
111             server.addListener( audit );
112         }
113     }
114     
115     @Override
116     public void destroy()
117     {
118         try
119         {
120             release( securitySystem );
121         }
122         catch ( ServletException e )
123         {
124             log( "Unable to release SecuritySystem : " + e.getMessage(), e );
125         }
126         try
127         {
128             release( httpAuth );
129         }
130         catch ( ServletException e )
131         {
132             log( "Unable to release HttpAuth : " + e.getMessage(), e );
133         }
134         try
135         {
136             release( audit );
137         }
138         catch ( ServletException e )
139         {
140             log( "Unable to release AuditLog : " + e.getMessage(), e );
141         }
142         try
143         {
144             release( configuration );
145         }
146         catch ( ServletException e )
147         {
148             log( "Unable to release ArchivaConfiguration : " + e.getMessage(), e );
149         }
150         try
151         {
152             release( mimeTypeLoader );
153         }
154         catch ( ServletException e )
155         {
156             log( "Unable to release ArchivaMimeTypeLoader : " + e.getMessage(), e );
157         }
158
159         super.destroy();
160     }
161     
162     @Override
163     protected void service( HttpServletRequest httpRequest, HttpServletResponse httpResponse )
164         throws ServletException, IOException
165     {
166         // Wrap the incoming request to adjust paths and whatnot.
167         super.service( new PolicingServletRequest( httpRequest ), httpResponse );
168     }
169
170     public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
171     {
172         if ( repositoryMap.isEmpty() )
173         {
174             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
175         }
176         return repositoryMap.get( prefix );
177     }
178
179     private String getRepositoryName( DavServerRequest request )
180     {
181         ManagedRepositoryConfiguration repoConfig = getRepository( request.getPrefix() );
182         if ( repoConfig == null )
183         {
184             return "Unknown";
185         }
186
187         return repoConfig.getName();
188     }
189
190     public boolean isAuthenticated( DavServerRequest davRequest, HttpServletResponse response )
191         throws ServletException, IOException
192     {
193         HttpServletRequest request = davRequest.getRequest();
194
195         // Authentication Tests.
196         try
197         {
198             AuthenticationResult result = httpAuth.getAuthenticationResult( request, response );
199
200             if ( result != null && !result.isAuthenticated() )
201             {
202                 // Must Authenticate.
203                 httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
204                                     new AuthenticationException( "User Credentials Invalid" ) );
205                 return false;
206             }
207         }
208         catch ( AuthenticationException e )
209         {
210             log( "Fatal Http Authentication Error.", e );
211             throw new ServletException( "Fatal Http Authentication Error.", e );
212         }
213         catch ( AccountLockedException e )
214         {
215             httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
216                                 new AuthenticationException( "User account is locked" ) );
217         }
218         catch ( MustChangePasswordException e )
219         {
220             httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
221                                 new AuthenticationException( "You must change your password." ) );
222         }
223
224         return true;
225     }
226
227     public boolean isAuthorized( DavServerRequest davRequest, HttpServletResponse response )
228         throws ServletException, IOException
229     {
230         // Authorization Tests.
231         HttpServletRequest request = davRequest.getRequest();
232
233         boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() );
234
235         SecuritySession securitySession = httpAuth.getSecuritySession();
236         try
237         {
238             String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
239
240             if ( isWriteRequest )
241             {
242                 permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
243             }
244
245             AuthorizationResult authzResult =
246                 securitySystem.authorize( securitySession, permission, davRequest.getPrefix() );
247
248             if ( !authzResult.isAuthorized() )
249             {
250                 if ( authzResult.getException() != null )
251                 {
252                     log( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest +
253                         ",permission=" + permission + ",repo=" + davRequest.getPrefix() + "] : " +
254                         authzResult.getException().getMessage() );
255                 }
256
257                 // Issue HTTP Challenge.
258                 httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
259                                     new AuthenticationException( "Authorization Denied." ) );
260                 return false;
261             }
262         }
263         catch ( AuthorizationException e )
264         {
265             throw new ServletException( "Fatal Authorization Subsystem Error." );
266         }
267
268         return true;
269     }
270     
271     public void configurationEvent( ConfigurationEvent event )
272     {
273         if( event.getType() == ConfigurationEvent.SAVED )
274         {
275             initRepositories();
276         }
277     }
278
279     private void initRepositories()
280     {
281         synchronized ( repositoryMap )
282         {
283             repositoryMap.clear();
284             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
285         }
286         
287         DavServerManager davManager = getDavManager();
288         
289         synchronized ( davManager )
290         {
291             // Clear out the old servers.
292             davManager.removeAllServers();
293             
294             // Create new servers.
295             try
296             {
297                 initServers( getServletConfig() );
298             }
299             catch ( DavServerException e )
300             {
301                 log( "Unable to init servers: " + e.getMessage(), e );
302             }
303         }
304     }
305 }