]> source.dussan.org Git - archiva.git/blob
0487368db12031353f7011f0788494341479e513
[archiva.git] /
1 package org.apache.archiva.web.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  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19
20 import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
21 import org.apache.archiva.configuration.ArchivaConfiguration;
22 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
23 import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
24 import org.apache.archiva.web.AbstractRestServicesTest;
25 import org.apache.archiva.web.api.FileUploadService;
26 import org.apache.archiva.web.model.FileMetadata;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.lang3.SystemUtils;
29 import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
30 import org.apache.cxf.jaxrs.client.WebClient;
31 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
32 import org.apache.cxf.jaxrs.ext.multipart.AttachmentBuilder;
33 import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
34 import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
35 import org.apache.cxf.message.Message;
36 import org.junit.AfterClass;
37 import org.junit.BeforeClass;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40
41 import javax.ws.rs.ClientErrorException;
42 import java.io.IOException;
43 import java.net.URLEncoder;
44 import java.nio.file.Files;
45 import java.nio.file.Path;
46 import java.nio.file.Paths;
47 import java.util.Collections;
48 import java.util.concurrent.atomic.AtomicReference;
49
50 /**
51  * @author Olivier Lamy
52  */
53 @RunWith(ArchivaBlockJUnit4ClassRunner.class)
54 public class UploadArtifactsTest
55         extends AbstractRestServicesTest
56 {
57
58     private static String PREVIOUS_ARCHIVA_PATH;
59     private AtomicReference<Path> projectDir = new AtomicReference<>( );
60
61     @BeforeClass
62     public static void initConfigurationPath()
63             throws Exception
64     {
65         PREVIOUS_ARCHIVA_PATH = System.getProperty(ArchivaConfiguration.USER_CONFIG_PROPERTY);
66         if (System.getProperties().containsKey( "test.resources.path" ))
67         {
68             System.setProperty( ArchivaConfiguration.USER_CONFIG_PROPERTY,
69                 System.getProperty( "test.resources.path" ) + "/archiva.xml" );
70         } else {
71             Path path = Paths.get( "src/test/resources/archiva.xml" ).toAbsolutePath();
72             System.setProperty( ArchivaConfiguration.USER_CONFIG_PROPERTY,
73                 path.toString() );
74
75         }
76         System.err.println( "USER_CONFIG_DIR " + System.getProperty( ArchivaConfiguration.USER_CONFIG_PROPERTY ) );
77     }
78
79
80     @AfterClass
81     public static void restoreConfigurationPath()
82             throws Exception
83     {
84         System.setProperty( ArchivaConfiguration.USER_CONFIG_PROPERTY, PREVIOUS_ARCHIVA_PATH );
85     }
86     @Override
87     protected String getSpringConfigLocation() {
88         return "classpath*:META-INF/spring-context.xml,classpath:/spring-context-test-upload.xml";
89     }
90
91     protected Path getProjectDirectory() {
92         if ( projectDir.get()==null) {
93             String propVal = System.getProperty("mvn.project.base.dir");
94             Path newVal;
95             if (StringUtils.isEmpty(propVal)) {
96                 newVal = Paths.get("").toAbsolutePath();
97             } else {
98                 newVal = Paths.get(propVal).toAbsolutePath();
99             }
100             projectDir.compareAndSet(null, newVal);
101         }
102         System.err.println( "project dir: " + projectDir.get( ).toString( ) );
103         return projectDir.get();
104     }
105
106     @Override
107     protected String getRestServicesPath() {
108         return "restServices";
109     }
110
111     protected String getBaseUrl() {
112         String baseUrlSysProps = System.getProperty("archiva.baseRestUrl");
113         return StringUtils.isBlank(baseUrlSysProps) ? "http://localhost:" + getServerPort() : baseUrlSysProps;
114     }
115
116     private FileUploadService getUploadService() {
117         FileUploadService service =
118                 JAXRSClientFactory.create(getBaseUrl() + "/" + getRestServicesPath() + "/archivaUiServices/",
119                         FileUploadService.class,
120                         Collections.singletonList(new JacksonJaxbJsonProvider()));
121         log.debug("Service class {}", service.getClass().getName());
122         WebClient.client(service).header("Authorization", authorizationHeader);
123         WebClient.client(service).header("Referer", "http://localhost:" + getServerPort());
124
125         WebClient.client(service).header("Referer", "http://localhost");
126         WebClient.getConfig(service).getRequestContext().put(Message.MAINTAIN_SESSION, true);
127         WebClient.getConfig(service).getRequestContext().put(Message.EXCEPTION_MESSAGE_CAUSE_ENABLED, true);
128         WebClient.getConfig(service).getRequestContext().put(Message.FAULT_STACKTRACE_ENABLED, true);
129         WebClient.getConfig(service).getRequestContext().put(Message.PROPOGATE_EXCEPTION, true);
130         WebClient.getConfig(service).getRequestContext().put("org.apache.cxf.transport.no_io_exceptions", true);
131
132         // WebClient.client( service ).
133         return service;
134     }
135
136     @Test
137     public void clearUploadedFiles()
138             throws Exception {
139         FileUploadService service = getUploadService();
140         service.clearUploadedFiles();
141     }
142
143     @Test
144     public void uploadFile() throws IOException, ArchivaRestServiceException {
145         FileUploadService service = getUploadService();
146         try {
147             Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
148             final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"" + file.getFileName().toString() + "\"; name=\"files[]\"")).build();
149             MultipartBody body = new MultipartBody(fileAttachment);
150             service.post(body);
151         } finally {
152             service.clearUploadedFiles();
153         }
154     }
155
156     @Test
157     public void failUploadFileWithBadFileName() throws IOException, ArchivaRestServiceException {
158         FileUploadService service = getUploadService();
159         try {
160             Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
161             final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"/../TestFile.testext\"; name=\"files[]\"")).build();
162             MultipartBody body = new MultipartBody(fileAttachment);
163             try {
164                 service.post(body);
165                 fail("FileNames with path contents should not be allowed.");
166             } catch (ClientErrorException e) {
167                 assertEquals(422, e.getResponse().getStatus());
168             }
169         } finally {
170             service.clearUploadedFiles();
171         }
172     }
173
174     @Test
175     public void uploadAndDeleteFile() throws IOException, ArchivaRestServiceException {
176         FileUploadService service = getUploadService();
177         try {
178             Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
179             final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"" + file.getFileName().toString() + "\"; name=\"files[]\"")).build();
180             MultipartBody body = new MultipartBody(fileAttachment);
181             service.post(body);
182             service.deleteFile(file.getFileName().toString());
183         } finally {
184             service.clearUploadedFiles();
185         }
186     }
187
188     @Test
189     public void failUploadAndDeleteWrongFile() throws IOException, ArchivaRestServiceException {
190         FileUploadService service = getUploadService();
191         try {
192             Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
193             final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"" + file.getFileName().toString() + "\"; name=\"files[]\"")).build();
194             MultipartBody body = new MultipartBody(fileAttachment);
195             service.post(body);
196             assertFalse(service.deleteFile("file123" + file.getFileName().toString()));
197         } finally {
198             service.clearUploadedFiles();
199         }
200     }
201
202     @Test
203     public void failUploadAndDeleteFileInOtherDir() throws IOException, ArchivaRestServiceException {
204         Path testFile = null;
205         try {
206             FileUploadService service = getUploadService();
207             Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
208             Path targetDir = getProjectDirectory().resolve("target/testDelete").toAbsolutePath();
209             if (!Files.exists(targetDir)) Files.createDirectories(targetDir);
210             Path tempDir = SystemUtils.getJavaIoTmpDir().toPath();
211             testFile = Files.createTempFile(targetDir, "TestFile", ".txt");
212             log.debug("Test file {}", testFile.toAbsolutePath());
213             log.debug("Tmp dir {}", tempDir.toAbsolutePath());
214             assertTrue(Files.exists(testFile));
215             Path relativePath = tempDir.relativize(testFile.toAbsolutePath());
216             final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"" + file.getFileName().toString() + "\"; name=\"files[]\"")).build();
217             MultipartBody body = new MultipartBody(fileAttachment);
218             service.post(body);
219             String relativePathEncoded = URLEncoder.encode("../target/" + relativePath.toString(), "UTF-8");
220             log.debug("Trying to delete with path traversal: {}, {}", relativePath, relativePathEncoded);
221             try {
222                 service.deleteFile(relativePathEncoded);
223             } catch (ArchivaRestServiceException ex) {
224                 // Expected exception
225             }
226             assertTrue("File in another directory may not be deleted", Files.exists(testFile));
227         } finally {
228             if (testFile != null) {
229                 Files.deleteIfExists(testFile);
230             }
231         }
232     }
233
234     @Test
235     public void failSaveFileWithBadParams() throws IOException, ArchivaRestServiceException {
236         Path path = getProjectDirectory().resolve("target/appserver-base/repositories/internal/org/apache/archiva/archiva-model/1.2/archiva-model-1.2.jar");
237         Files.deleteIfExists(path);
238         FileUploadService service = getUploadService();
239         Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
240
241         Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"archiva-model.jar\"; name=\"files[]\"")).build();
242         MultipartBody body = new MultipartBody(fileAttachment);
243         service.post(body);
244         assertTrue(service.save("internal", "org.apache.archiva", "archiva-model", "1.2", "jar", true));
245
246         fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"TestFile.FileExt\"; name=\"files[]\"")).build();
247         body = new MultipartBody(fileAttachment);
248         FileMetadata meta = service.post(body);
249         log.debug("Metadata {}", meta.toString());
250         try {
251             service.save("internal", "org", URLEncoder.encode("../../../test", "UTF-8"), URLEncoder.encode("testSave", "UTF-8"), "4", true);
252             fail("Error expected, if the content contains bad characters.");
253         } catch (ClientErrorException e) {
254             assertEquals(422, e.getResponse().getStatus());
255         }
256         assertFalse(Files.exists(getProjectDirectory().resolve("target/test-testSave.4")));
257     }
258
259     @Test
260     public void saveFile() throws IOException, ArchivaRestServiceException {
261         log.debug("Starting saveFile()");
262
263         Path path = getProjectDirectory().resolve("target/appserver-base/repositories/internal/org/apache/archiva/archiva-model/1.2/archiva-model-1.2.jar");
264         log.debug("Jar exists: {}",Files.exists(path));
265         Files.deleteIfExists(path);
266         path = getProjectDirectory().resolve("target/appserver-base/repositories/internal/org/apache/archiva/archiva-model/1.2/archiva-model-1.2.pom");
267         Files.deleteIfExists(path);
268         FileUploadService service = getUploadService();
269         service.clearUploadedFiles();
270         Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
271         log.debug("Upload file exists: {}", Files.exists(file));
272         final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"archiva-model.jar\"; name=\"files[]\"")).build();
273         MultipartBody body = new MultipartBody(fileAttachment);
274         service.post(body);
275         service.save("internal", "org.apache.archiva", "archiva-model", "1.2", "jar", true);
276     }
277
278     @Test
279     public void saveFileWithOtherExtension() throws IOException, ArchivaRestServiceException {
280         log.debug("Starting saveFileWithOtherExtension()");
281
282         Path path = getProjectDirectory().resolve("target/appserver-base/repositories/internal/org/apache/archiva/archiva-model/1.2/archiva-model-1.2.bin");
283         log.debug("Jar exists: {}",Files.exists(path));
284         Files.deleteIfExists(path);
285         Path pomPath = getProjectDirectory().resolve("target/appserver-base/repositories/internal/org/apache/archiva/archiva-model/1.2/archiva-model-1.2.pom");
286         Files.deleteIfExists(pomPath);
287         FileUploadService service = getUploadService();
288         service.clearUploadedFiles();
289         Path file = getProjectDirectory().resolve("src/test/repositories/snapshot-repo/org/apache/archiva/archiva-model/1.4-M4-SNAPSHOT/archiva-model-1.4-M4-20130425.081822-1.jar");
290         log.debug("Upload file exists: {}", Files.exists(file));
291         final Attachment fileAttachment = new AttachmentBuilder().object(Files.newInputStream(file)).contentDisposition(new ContentDisposition("form-data; filename=\"archiva-model.bin\"; name=\"files[]\"")).build();
292         MultipartBody body = new MultipartBody(fileAttachment);
293         service.post(body);
294         assertTrue(service.save("internal", "org.apache.archiva", "archiva-model", "1.2", "bin", false));
295         assertTrue(Files.exists(path));
296     }
297
298
299 }