Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,22 @@ public void inform(final Event e) {
SCANNER_OSSINDEX_API_TOKEN.getGroupName(),
SCANNER_OSSINDEX_API_TOKEN.getPropertyName()
);
if (apiUsernameProperty == null
|| apiUsernameProperty.getPropertyValue() == null
|| apiTokenProperty == null
|| apiTokenProperty.getPropertyValue() == null) {
LOGGER.warn("An API username or token has not been specified for use with OSS Index; Skipping");
if (apiTokenProperty == null || apiTokenProperty.getPropertyValue() == null) {
LOGGER.warn("An API token has not been specified for use with OSS Index; Skipping");
return;
} else {
try {
apiUsername = apiUsernameProperty.getPropertyValue();
apiToken = DebugDataEncryption.decryptAsString(apiTokenProperty.getPropertyValue());
} catch (Exception ex) {
// OSS Index will stop supporting unauthenticated requests
LOGGER.error("An error occurred decrypting the OSS Index API Token; Skipping", ex);
}
try {
apiToken = DebugDataEncryption.decryptAsString(apiTokenProperty.getPropertyValue());
} catch (Exception ex) {
LOGGER.error("An error occurred decrypting the OSS Index API Token; Skipping", ex);
return;
}
if (!isBearerToken(apiToken)) {
if (apiUsernameProperty == null || apiUsernameProperty.getPropertyValue() == null) {
LOGGER.warn("An API username has not been specified for use with OSS Index; Skipping");
return;
}
apiUsername = apiUsernameProperty.getPropertyValue();
}
aliasSyncEnabled = super.isEnabled(ConfigPropertyConstants.SCANNER_OSSINDEX_ALIAS_SYNC_ENABLED);
}
Expand Down Expand Up @@ -322,6 +323,10 @@ private static String minimizePurl(final PackageURL purl) {
return purl.getCoordinates().replaceFirst("@v", "@");
}

private static boolean isBearerToken(final String token) {
return token != null && token.startsWith("sonatype_pat_");
}

/**
* Submits the payload to the Sonatype OSS Index service
*/
Expand All @@ -331,7 +336,9 @@ private List<ComponentReport> submit(final JSONObject payload) throws Throwable
request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");
request.addHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent());
request.setEntity(new StringEntity(payload.toString()));
if (apiUsername != null && apiToken != null) {
if (isBearerToken(apiToken)) {
request.addHeader("Authorization", "Bearer " + apiToken);
} else if (apiUsername != null && apiToken != null) {
request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(apiUsername, apiToken));
}
try (final CloseableHttpResponse response = RETRY.executeCheckedSupplier(() -> HttpClientPool.getClient().execute(request))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,62 @@ void testAnalyzeWithoutApiToken() {
}

@Test
void testAnalyzeWithoutUser() {
configApiToken(null, API_TOKEN);
void testAnalyzeWithoutUser() throws Exception {
configApiToken(null, DataEncryption.encryptAsString(API_TOKEN));
stubPOSTRequest();

var project = configProject();

var component = getComponent(project);
qm.persist(component);

assertThatNoException().isThrownBy(() -> analysisTask.inform(new OssIndexAnalysisEvent(
List.of(component), VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS)));
assertThatNoException().isThrownBy(
() -> analysisTask.inform(
new OssIndexAnalysisEvent(
List.of(component),
VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS)));

verify(0, getRequestedPost());
verify(0, postRequestedFor(urlPathEqualTo("/api/v3/component-report")));
}

@Test
void testAnalyzeWithBearerToken() throws Exception {
final String bearerToken = "sonatype_pat_testtoken123";
configApiToken(null, DataEncryption.encryptAsString(bearerToken));
stubPOSTRequest();

var project = configProject();
var component = getComponent(project);
qm.persist(component);

assertThatNoException().isThrownBy(
() -> analysisTask.inform(
new OssIndexAnalysisEvent(
List.of(component),
VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS)));

verify(postRequestedFor(urlPathEqualTo("/api/v3/component-report"))
.withHeader("Authorization", equalTo("Bearer " + bearerToken)));
}

@Test
void testAnalyzeWithBearerTokenAndUsername() throws Exception {
final String bearerToken = "sonatype_pat_testtoken123";
configApiToken(API_USER, DataEncryption.encryptAsString(bearerToken));
stubPOSTRequest();

var project = configProject();
var component = getComponent(project);
qm.persist(component);

assertThatNoException().isThrownBy(
() -> analysisTask.inform(
new OssIndexAnalysisEvent(
List.of(component),
VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS)));

verify(postRequestedFor(urlPathEqualTo("/api/v3/component-report"))
.withHeader("Authorization", equalTo("Bearer " + bearerToken)));
}

private @NotNull Project configProject() {
Expand Down
Loading