Skip to content

Commit

Permalink
Merge pull request #218 from ruromero/oss-auth-error
Browse files Browse the repository at this point in the history
fix: issue with invalid oss-index credentials
  • Loading branch information
ruromero authored Nov 30, 2023
2 parents 3278baa + 47c52e0 commit 3572e3c
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import com.redhat.exhort.model.CvssScoreComparable.DependencyScoreComparator;
import com.redhat.exhort.model.CvssScoreComparable.TransitiveScoreComparator;
import com.redhat.exhort.model.DependencyTree;
import com.redhat.exhort.model.ProviderResponse;
import com.redhat.exhort.monitoring.MonitoringProcessor;

import io.quarkus.runtime.annotations.RegisterForReflection;
Expand All @@ -66,7 +67,7 @@ public abstract class ProviderResponseHandler {

protected abstract String getProviderName();

public abstract Map<String, List<Issue>> responseToIssues(
public abstract ProviderResponse responseToIssues(
byte[] response, String privateProviders, DependencyTree tree) throws IOException;

protected ProviderStatus defaultOkStatus(String provider) {
Expand Down Expand Up @@ -111,9 +112,9 @@ public void processResponseError(Exchange exchange) {
.code(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
LOGGER.warn("Unable to process request to: {}", getProviderName(), cause);
}
ProviderReport report = new ProviderReport().status(status).sources(Collections.emptyMap());
ProviderResponse response = new ProviderResponse(null, status);
monitoringProcessor.processProviderError(exchange, exception, getProviderName());
exchange.getMessage().setBody(report);
exchange.getMessage().setBody(response);
}

public void processTokenFallBack(Exchange exchange) {
Expand Down Expand Up @@ -153,9 +154,9 @@ private static String prettifyHttpError(HttpOperationFailedException httpExcepti
};
}

public Map<String, List<Issue>> emptyResponse(
public ProviderResponse emptyResponse(
@ExchangeProperty(Constants.DEPENDENCY_TREE_PROPERTY) DependencyTree tree) {
return Collections.emptyMap();
return new ProviderResponse(Collections.emptyMap(), null);
}

private Map<String, Map<String, List<Issue>>> splitIssuesBySource(
Expand Down Expand Up @@ -188,11 +189,14 @@ private Map<String, Map<String, List<Issue>>> splitIssuesBySource(
}

public ProviderReport buildReport(
@Body Map<String, List<Issue>> issuesData,
@Body ProviderResponse response,
@ExchangeProperty(Constants.DEPENDENCY_TREE_PROPERTY) DependencyTree tree,
@ExchangeProperty(Constants.PROVIDER_PRIVATE_DATA_PROPERTY) String privateProviders)
throws IOException {
var sourcesIssues = splitIssuesBySource(issuesData);
if (response.status() != null) {
return new ProviderReport().status(response.status()).sources(Collections.emptyMap());
}
var sourcesIssues = splitIssuesBySource(response.issues());
Map<String, Source> reports = new HashMap<>();
sourcesIssues
.keySet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.apache.camel.Exchange;
import org.apache.camel.builder.AggregationStrategies;
import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
import org.apache.camel.http.base.HttpOperationFailedException;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import com.redhat.exhort.integration.Constants;
Expand Down Expand Up @@ -69,7 +68,6 @@ public void configure() {

from(direct("ossSplitReq"))
.routeId("ossSplitReq")
.doTry()
.split(body(), AggregationStrategies.beanAllowNull(OssIndexResponseHandler.class, "aggregateSplit"))
.parallelProcessing()
.transform().method(OssIndexRequestBuilder.class, "buildRequest")
Expand All @@ -81,10 +79,8 @@ public void configure() {
.end()
.to(vertxHttp("{{api.ossindex.host}}"))
.transform(method(OssIndexResponseHandler.class, "responseToIssues"))
.end()
.endDoTry()
.doCatch(HttpOperationFailedException.class)
.process(responseHandler::processResponseError);
.onFallback()
.process(responseHandler::processResponseError);

from(direct("ossValidateCredentials"))
.routeId("ossValidateCredentials")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.redhat.exhort.integration.providers.ProviderResponseHandler;
import com.redhat.exhort.model.CvssParser;
import com.redhat.exhort.model.DependencyTree;
import com.redhat.exhort.model.ProviderResponse;

import io.quarkus.runtime.annotations.RegisterForReflection;

Expand All @@ -54,34 +55,37 @@ public class OssIndexResponseHandler extends ProviderResponseHandler {

@Inject ObjectMapper mapper = ObjectMapperProducer.newInstance();

public Map<String, List<Issue>> aggregateSplit(
Map<String, List<Issue>> oldExchange, Map<String, List<Issue>> newExchange)
public ProviderResponse aggregateSplit(ProviderResponse oldExchange, ProviderResponse newExchange)
throws IOException {
if (oldExchange == null) {
return newExchange;
}
if (oldExchange.status() != null && !Boolean.TRUE.equals(oldExchange.status().getOk())) {
return oldExchange;
}
oldExchange
.issues()
.entrySet()
.forEach(
e -> {
var issues = newExchange.get(e.getKey());
var issues = newExchange.issues().get(e.getKey());
if (issues != null) {
e.getValue().addAll(issues);
}
});
newExchange.keySet().stream()
.filter(k -> !oldExchange.keySet().contains(k))
newExchange.issues().keySet().stream()
.filter(k -> !oldExchange.issues().keySet().contains(k))
.forEach(
k -> {
oldExchange.put(k, newExchange.get(k));
oldExchange.issues().put(k, newExchange.issues().get(k));
});
return oldExchange;
}

public Map<String, List<Issue>> responseToIssues(
public ProviderResponse responseToIssues(
@Body byte[] response, String privateProviders, DependencyTree tree) throws IOException {
var json = (ArrayNode) mapper.readTree(response);
return getIssues(json);
return new ProviderResponse(getIssues(json), null);
}

private Map<String, List<Issue>> getIssues(ArrayNode response) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ public void configure() {
.process(this::processDepGraphRequest)
.to(direct("snykRequest"))
.onFallback()
.process(responseHandler::processResponseError);
.process(responseHandler::processResponseError)
.end()
.transform().method(SnykResponseHandler.class, "buildReport");

from(direct("snykRequest"))
.routeId("snykRequest")
.to(vertxHttp("{{api.snyk.host}}"))
.transform().method(SnykResponseHandler.class, "responseToIssues")
.transform().method(SnykResponseHandler.class, "buildReport");
.transform().method(SnykResponseHandler.class, "responseToIssues");

from(direct("snykValidateToken"))
.routeId("snykValidateToken")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.redhat.exhort.integration.providers.ProviderResponseHandler;
import com.redhat.exhort.model.CvssParser;
import com.redhat.exhort.model.DependencyTree;
import com.redhat.exhort.model.ProviderResponse;

import io.quarkus.runtime.annotations.RegisterForReflection;

Expand All @@ -56,15 +57,15 @@ public class SnykResponseHandler extends ProviderResponseHandler {
"Sign up for a Snyk account to learn aboutn the vulnerabilities found";
@Inject ObjectMapper mapper = ObjectMapperProducer.newInstance();

public Map<String, List<Issue>> responseToIssues(
public ProviderResponse responseToIssues(
@Body byte[] providerResponse,
@ExchangeProperty(Constants.PROVIDER_PRIVATE_DATA_PROPERTY) String privateProviders,
@ExchangeProperty(Constants.DEPENDENCY_TREE_PROPERTY) DependencyTree tree)
throws IOException {
var filterUnique = privateProviders != null && privateProviders.contains(SNYK_PROVIDER);

var snykResponse = mapper.readTree((byte[]) providerResponse);
return getIssues(snykResponse, filterUnique, tree);
return new ProviderResponse(getIssues(snykResponse, filterUnique, tree), null);
}

private Map<String, List<Issue>> getIssues(
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/redhat/exhort/model/ProviderResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.redhat.exhort.model;

import java.util.List;
import java.util.Map;

import com.redhat.exhort.api.v4.Issue;
import com.redhat.exhort.api.v4.ProviderStatus;

public record ProviderResponse(Map<String, List<Issue>> issues, ProviderStatus status) {}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.redhat.exhort.integration.Constants;
import com.redhat.exhort.model.DependencyTree;
import com.redhat.exhort.model.DirectDependency;
import com.redhat.exhort.model.ProviderResponse;

import jakarta.ws.rs.core.Response;

Expand All @@ -59,7 +60,8 @@ public void testSummary(
throws IOException {

ProviderResponseHandler handler = new TestResponseHandler();
ProviderReport response = handler.buildReport(issuesData, tree, null);
ProviderReport response =
handler.buildReport(new ProviderResponse(issuesData, null), tree, null);
assertOkStatus(response);
SourceSummary summary = getValidSource(response).getSummary();

Expand Down Expand Up @@ -108,7 +110,7 @@ public void testFilterDepsWithoutIssues() throws IOException {
Map<String, List<Issue>> issues = Map.of("pkg:npm/aa@1", List.of(buildIssue(1, 5f)));
ProviderResponseHandler handler = new TestResponseHandler();
DependencyTree tree = buildTree();
ProviderReport response = handler.buildReport(issues, tree, null);
ProviderReport response = handler.buildReport(new ProviderResponse(issues, null), tree, null);
assertOkStatus(response);
assertEquals(1, response.getSources().size());
Source report = response.getSources().get(TEST_SOURCE);
Expand All @@ -127,7 +129,8 @@ public void testFilterTransitiveWithoutIssues() throws IOException {
"pkg:npm/aba@1", List.of(buildIssue(3, 8f)));
ProviderResponseHandler handler = new TestResponseHandler();

ProviderReport response = handler.buildReport(issues, buildTree(), null);
ProviderReport response =
handler.buildReport(new ProviderResponse(issues, null), buildTree(), null);

assertOkStatus(response);

Expand Down Expand Up @@ -178,7 +181,8 @@ public void testSorted() throws IOException {
"pkg:npm/abc@1", List.of(buildIssue(7, 6f)));
ProviderResponseHandler handler = new TestResponseHandler();

ProviderReport response = handler.buildReport(issues, buildTree(), null);
ProviderReport response =
handler.buildReport(new ProviderResponse(issues, null), buildTree(), null);

assertOkStatus(response);
DependencyReport reportHighest = getValidSource(response).getDependencies().get(0);
Expand Down Expand Up @@ -347,7 +351,7 @@ protected String getProviderName() {
}

@Override
public Map<String, List<Issue>> responseToIssues(
public ProviderResponse responseToIssues(
byte[] response, String privateProviders, DependencyTree tree) throws IOException {
throw new IllegalArgumentException("not implemented");
}
Expand Down

0 comments on commit 3572e3c

Please sign in to comment.