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