]> source.dussan.org Git - archiva.git/blob
d1fed7a0ba2370ee4438ca0189266e8a7f7aa6dd
[archiva.git] /
1 package org.apache.archiva.upload;
2 /*
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  */
20
21 import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
22 import org.apache.archiva.admin.model.beans.RemoteRepository;
23 import org.apache.archiva.redback.rest.api.services.RoleManagementService;
24 import org.apache.archiva.redback.rest.services.AbstractRestServicesTest;
25 import org.apache.archiva.remotedownload.AbstractDownloadTest;
26 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
27 import org.apache.archiva.security.common.ArchivaRoleConstants;
28 import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
29 import org.apache.archiva.web.api.FileUploadService;
30 import org.apache.archiva.web.api.RuntimeInfoService;
31 import org.apache.archiva.web.model.ApplicationRuntimeInfo;
32 import org.apache.commons.io.FileUtils;
33 import org.apache.commons.lang.StringUtils;
34 import org.apache.commons.lang.SystemUtils;
35 import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
36 import org.apache.cxf.jaxrs.client.WebClient;
37 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
38 import org.apache.cxf.jaxrs.ext.multipart.AttachmentBuilder;
39 import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
40 import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
41 import org.apache.maven.wagon.providers.http.HttpWagon;
42 import org.apache.maven.wagon.repository.Repository;
43 import org.eclipse.jetty.server.Server;
44 import org.eclipse.jetty.servlet.ServletContextHandler;
45 import org.eclipse.jetty.servlet.ServletHolder;
46 import org.junit.After;
47 import org.junit.AfterClass;
48 import org.junit.Before;
49 import org.junit.BeforeClass;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import javax.servlet.ServletException;
56 import javax.servlet.http.HttpServlet;
57 import javax.servlet.http.HttpServletRequest;
58 import javax.servlet.http.HttpServletResponse;
59 import java.io.File;
60 import java.io.IOException;
61 import java.net.URLEncoder;
62 import java.nio.file.Files;
63 import java.nio.file.Path;
64 import java.nio.file.Paths;
65 import java.nio.file.StandardCopyOption;
66 import java.util.Collections;
67 import java.util.List;
68 import java.util.zip.ZipEntry;
69 import java.util.zip.ZipFile;
70
71 /**
72  * @author Olivier Lamy
73  */
74 @RunWith( ArchivaBlockJUnit4ClassRunner.class )
75 public class UploadArtifactsTest
76     extends AbstractRestServicesTest
77 {
78     @Override
79     @Before
80     public void startServer()
81         throws Exception
82     {
83         File appServerBase = new File( System.getProperty( "appserver.base" ) );
84         File confDir = new File(appServerBase, "conf");
85         if (!confDir.exists()) {
86             confDir.mkdir();
87         }
88         Path log4jCfg = Paths.get("src/test/resources/log4j2-test.xml");
89         Path log4jCfgDst = confDir.toPath().resolve(log4jCfg.getFileName());
90         Files.copy( log4jCfg, log4jCfgDst, StandardCopyOption.REPLACE_EXISTING );
91
92         File jcrDirectory = new File( appServerBase, "jcr" );
93
94         if ( jcrDirectory.exists() )
95         {
96             FileUtils.deleteDirectory( jcrDirectory );
97         }
98         // We have to activate this to verify the bad path traversal protection. We cannot rely on
99         // the application server only.
100         System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH","true");
101
102         super.startServer();
103     }
104
105     @After
106     public void stop() {
107         System.clearProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH" );
108     }
109
110     @Override
111     protected String getSpringConfigLocation()
112     {
113         return "classpath*:META-INF/spring-context.xml,classpath:/spring-context-with-jcr.xml";
114     }
115
116     @Override
117     protected String getRestServicesPath()
118     {
119         return "restServices";
120     }
121
122     protected String getBaseUrl()
123     {
124         String baseUrlSysProps = System.getProperty( "archiva.baseRestUrl" );
125         return StringUtils.isBlank( baseUrlSysProps ) ? "http://localhost:" + port : baseUrlSysProps;
126     }
127
128     private FileUploadService getUploadService()
129     {
130         FileUploadService service =
131             JAXRSClientFactory.create( getBaseUrl( ) + "/" + getRestServicesPath( ) + "/archivaUiServices/",
132                 FileUploadService.class,
133                 Collections.singletonList( new JacksonJaxbJsonProvider( ) ) );
134
135         WebClient.client( service ).header( "Authorization", authorizationHeader );
136         WebClient.client( service ).header( "Referer", "http://localhost:" + port );
137
138         WebClient.client( service ).header( "Referer", "http://localhost" );
139         return service;
140     }
141
142     @Test
143     public void clearUploadedFiles()
144         throws Exception
145     {
146         FileUploadService service = getUploadService( );
147         service.clearUploadedFiles();
148     }
149
150     @Test
151     public void uploadFile() throws IOException, ArchivaRestServiceException
152     {
153         FileUploadService service = getUploadService( );
154         try
155         {
156             Path file = Paths.get( "src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar" );
157             final Attachment fileAttachment = new AttachmentBuilder( ).object( Files.newInputStream( file ) ).contentDisposition( new ContentDisposition( "form-data; filename=\"" + file.getFileName( ).toString( ) + "\"; name=\"files[]\"" ) ).build( );
158             MultipartBody body = new MultipartBody( fileAttachment );
159             service.post( body );
160         } finally
161         {
162             service.clearUploadedFiles( );
163         }
164     }
165
166     @Test
167     public void uploadAndDeleteFile() throws IOException, ArchivaRestServiceException
168     {
169         FileUploadService service = getUploadService( );
170         try
171         {
172             Path file = Paths.get( "src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar" );
173             final Attachment fileAttachment = new AttachmentBuilder( ).object( Files.newInputStream( file ) ).contentDisposition( new ContentDisposition( "form-data; filename=\"" + file.getFileName( ).toString( ) + "\"; name=\"files[]\"" ) ).build( );
174             MultipartBody body = new MultipartBody( fileAttachment );
175             service.post( body );
176             service.deleteFile( file.getFileName( ).toString( ) );
177         } finally
178         {
179             service.clearUploadedFiles();
180         }
181     }
182
183     @Test
184     public void uploadAndDeleteWrongFile() throws IOException, ArchivaRestServiceException
185     {
186         FileUploadService service = getUploadService( );
187         try
188         {
189             Path file = Paths.get( "src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar" );
190             final Attachment fileAttachment = new AttachmentBuilder( ).object( Files.newInputStream( file ) ).contentDisposition( new ContentDisposition( "form-data; filename=\"" + file.getFileName( ).toString( ) + "\"; name=\"files[]\"" ) ).build( );
191             MultipartBody body = new MultipartBody( fileAttachment );
192             service.post( body );
193             assertFalse( service.deleteFile( "file123" + file.getFileName( ).toString( ) ) );
194         } finally {
195             service.clearUploadedFiles();
196         }
197     }
198
199     @Test
200     public void uploadAndDeleteFileInOtherDir() throws IOException, ArchivaRestServiceException
201     {
202         Path testFile = null;
203         try
204         {
205             FileUploadService service = getUploadService( );
206             Path file = Paths.get( "src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar" );
207             Path targetDir = Paths.get( "target/testDelete" ).toAbsolutePath( );
208             if ( !Files.exists( targetDir ) ) Files.createDirectory( targetDir );
209             Path tempDir = SystemUtils.getJavaIoTmpDir( ).toPath( );
210             testFile = Files.createTempFile( targetDir, "TestFile", ".txt" );
211             log.debug( "Test file {}", testFile.toAbsolutePath( ) );
212             log.debug( "Tmp dir {}", tempDir.toAbsolutePath( ) );
213             assertTrue( Files.exists( testFile ) );
214             Path relativePath = tempDir.relativize( testFile.toAbsolutePath( ) );
215             final Attachment fileAttachment = new AttachmentBuilder( ).object( Files.newInputStream( file ) ).contentDisposition( new ContentDisposition( "form-data; filename=\"" + file.getFileName( ).toString( ) + "\"; name=\"files[]\"" ) ).build( );
216             MultipartBody body = new MultipartBody( fileAttachment );
217             service.post( body );
218             String relativePathEncoded = URLEncoder.encode( "../target/" + relativePath.toString( ), "UTF-8" );
219             log.debug( "Trying to delete with path traversal: {}, {}", relativePath, relativePathEncoded );
220             try
221             {
222                 service.deleteFile( relativePathEncoded );
223             }
224             catch ( ArchivaRestServiceException ex )
225             {
226                 // Expected exception
227             }
228             assertTrue( "File in another directory may not be deleted", Files.exists( testFile ) );
229         } finally
230         {
231             if (testFile!=null) {
232                 Files.deleteIfExists( testFile );
233             }
234         }
235     }
236 }