| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| NexusSearch |
|
| 5.0;5 |
| 1 | /* | |
| 2 | * This file is part of dependency-check-core. | |
| 3 | * | |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | * you may not use this file except in compliance with the License. | |
| 6 | * You may obtain a copy of the License at | |
| 7 | * | |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | * | |
| 10 | * Unless required by applicable law or agreed to in writing, software | |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | * See the License for the specific language governing permissions and | |
| 14 | * limitations under the License. | |
| 15 | * | |
| 16 | * Copyright (c) 2014 Jeremy Long. All Rights Reserved. | |
| 17 | */ | |
| 18 | package org.owasp.dependencycheck.data.nexus; | |
| 19 | ||
| 20 | import java.io.FileNotFoundException; | |
| 21 | import java.io.IOException; | |
| 22 | import java.net.URL; | |
| 23 | import java.net.URLConnection; | |
| 24 | import java.util.logging.Logger; | |
| 25 | import javax.xml.parsers.DocumentBuilder; | |
| 26 | import javax.xml.parsers.DocumentBuilderFactory; | |
| 27 | import javax.xml.xpath.XPath; | |
| 28 | import javax.xml.xpath.XPathFactory; | |
| 29 | import org.w3c.dom.Document; | |
| 30 | ||
| 31 | /** | |
| 32 | * Class of methods to search Nexus repositories. | |
| 33 | * | |
| 34 | * @author colezlaw | |
| 35 | */ | |
| 36 | public class NexusSearch { | |
| 37 | ||
| 38 | /** | |
| 39 | * The root URL for the Nexus repository service | |
| 40 | */ | |
| 41 | private final URL rootURL; | |
| 42 | ||
| 43 | /** | |
| 44 | * Used for logging. | |
| 45 | */ | |
| 46 | 1 | private static final Logger LOGGER = Logger.getLogger(NexusSearch.class.getName()); |
| 47 | ||
| 48 | /** | |
| 49 | * Creates a NexusSearch for the given repository URL. | |
| 50 | * | |
| 51 | * @param rootURL the root URL of the repository on which searches should execute. full URL's are calculated | |
| 52 | * relative to this URL, so it should end with a / | |
| 53 | */ | |
| 54 | 2 | public NexusSearch(URL rootURL) { |
| 55 | 2 | this.rootURL = rootURL; |
| 56 | 2 | } |
| 57 | ||
| 58 | /** | |
| 59 | * Searches the configured Nexus repository for the given sha1 hash. If the artifact is found, a | |
| 60 | * <code>MavenArtifact</code> is populated with the coordinate information. | |
| 61 | * | |
| 62 | * @param sha1 The SHA-1 hash string for which to search | |
| 63 | * @return the populated Maven coordinates | |
| 64 | * @throws IOException if it's unable to connect to the specified repositor or if the specified artifact is not | |
| 65 | * found. | |
| 66 | */ | |
| 67 | public MavenArtifact searchSha1(String sha1) throws IOException { | |
| 68 | 2 | if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) { |
| 69 | 2 | throw new IllegalArgumentException("Invalid SHA1 format"); |
| 70 | } | |
| 71 | ||
| 72 | 0 | final URL url = new URL(rootURL, String.format("identify/sha1/%s", sha1.toLowerCase())); |
| 73 | ||
| 74 | 0 | LOGGER.fine(String.format("Searching Nexus url %s", url.toString())); |
| 75 | ||
| 76 | 0 | final URLConnection conn = url.openConnection(); |
| 77 | 0 | conn.setDoOutput(true); |
| 78 | ||
| 79 | // JSON would be more elegant, but there's not currently a dependency | |
| 80 | // on JSON, so don't want to add one just for this | |
| 81 | 0 | conn.addRequestProperty("Accept", "application/xml"); |
| 82 | 0 | conn.connect(); |
| 83 | ||
| 84 | try { | |
| 85 | 0 | final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); |
| 86 | 0 | final Document doc = builder.parse(conn.getInputStream()); |
| 87 | 0 | final XPath xpath = XPathFactory.newInstance().newXPath(); |
| 88 | 0 | final String groupId = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/groupId", doc); |
| 89 | 0 | final String artifactId = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/artifactId", doc); |
| 90 | 0 | final String version = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/version", doc); |
| 91 | 0 | final String link = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink", doc); |
| 92 | 0 | return new MavenArtifact(groupId, artifactId, version, link); |
| 93 | 0 | } catch (FileNotFoundException fnfe) { |
| 94 | // This is what we get when the SHA1 they sent doesn't exist in Nexus. This | |
| 95 | // is useful upstream for recovery, so we just re-throw it | |
| 96 | 0 | throw fnfe; |
| 97 | 0 | } catch (Exception e) { |
| 98 | // Anything else is jacked-up XML stuff that we really can't recover from well | |
| 99 | 0 | throw new IOException(e.getMessage(), e); |
| 100 | } | |
| 101 | } | |
| 102 | } | |
| 103 | ||
| 104 | // vim: cc=120:sw=4:ts=4:sts=4 |