1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.data.nexus;
19
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.net.HttpURLConnection;
23 import java.net.URL;
24 import javax.xml.parsers.DocumentBuilder;
25 import javax.xml.parsers.DocumentBuilderFactory;
26 import javax.xml.xpath.XPath;
27 import javax.xml.xpath.XPathFactory;
28
29 import org.owasp.dependencycheck.utils.InvalidSettingException;
30 import org.owasp.dependencycheck.utils.Settings;
31 import org.owasp.dependencycheck.utils.URLConnectionFactory;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.w3c.dom.Document;
35
36
37
38
39
40
41 public class NexusSearch {
42
43
44
45
46 private final URL rootURL;
47
48
49
50
51 private final boolean useProxy;
52
53
54
55 private static final Logger LOGGER = LoggerFactory.getLogger(NexusSearch.class);
56
57
58
59
60
61
62
63
64
65 public NexusSearch(URL rootURL, boolean useProxy) {
66 this.rootURL = rootURL;
67 this.useProxy = useProxy;
68 LOGGER.debug("Using proxy: {}", useProxy);
69 }
70
71
72
73
74
75
76
77
78
79
80
81 public MavenArtifact searchSha1(String sha1) throws IOException {
82 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
83 throw new IllegalArgumentException("Invalid SHA1 format");
84 }
85
86 final URL url = new URL(rootURL, String.format("identify/sha1/%s",
87 sha1.toLowerCase()));
88
89 LOGGER.debug("Searching Nexus url {}", url);
90
91
92
93
94
95 HttpURLConnection conn;
96 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
97 conn.setDoOutput(true);
98
99
100
101 conn.addRequestProperty("Accept", "application/xml");
102 conn.connect();
103
104 switch (conn.getResponseCode()) {
105 case 200:
106 try {
107 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
108 factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
109 final DocumentBuilder builder = factory.newDocumentBuilder();
110 final Document doc = builder.parse(conn.getInputStream());
111 final XPath xpath = XPathFactory.newInstance().newXPath();
112 final String groupId = xpath
113 .evaluate(
114 "/org.sonatype.nexus.rest.model.NexusArtifact/groupId",
115 doc);
116 final String artifactId = xpath.evaluate(
117 "/org.sonatype.nexus.rest.model.NexusArtifact/artifactId",
118 doc);
119 final String version = xpath
120 .evaluate(
121 "/org.sonatype.nexus.rest.model.NexusArtifact/version",
122 doc);
123 final String link = xpath
124 .evaluate(
125 "/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink",
126 doc);
127 final String pomLink = xpath
128 .evaluate(
129 "/org.sonatype.nexus.rest.model.NexusArtifact/pomLink",
130 doc);
131 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
132 if (link != null && !link.isEmpty()) {
133 ma.setArtifactUrl(link);
134 }
135 if (pomLink != null && !pomLink.isEmpty()) {
136 ma.setPomUrl(pomLink);
137 }
138 return ma;
139 } catch (Throwable e) {
140
141
142 throw new IOException(e.getMessage(), e);
143 }
144 case 404:
145 throw new FileNotFoundException("Artifact not found in Nexus");
146 default:
147 LOGGER.debug("Could not connect to Nexus received response code: {} {}",
148 conn.getResponseCode(), conn.getResponseMessage());
149 throw new IOException("Could not connect to Nexus");
150 }
151 }
152
153
154
155
156
157
158
159 public boolean preflightRequest() {
160 HttpURLConnection conn;
161 try {
162 final URL url = new URL(rootURL, "status");
163 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
164 conn.addRequestProperty("Accept", "application/xml");
165 conn.connect();
166 if (conn.getResponseCode() != 200) {
167 LOGGER.warn("Expected 200 result from Nexus, got {}", conn.getResponseCode());
168 return false;
169 }
170 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
171 final Document doc = builder.parse(conn.getInputStream());
172 if (!"status".equals(doc.getDocumentElement().getNodeName())) {
173 LOGGER.warn("Expected root node name of status, got {}", doc.getDocumentElement().getNodeName());
174 return false;
175 }
176 } catch (Throwable e) {
177 return false;
178 }
179
180 return true;
181 }
182 }
183
184