You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UploadArtifactsTest.java 15KB

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