Skip to content
Open
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 @@ -10,46 +10,27 @@

package org.eclipse.sw360.common.utils;

import java.io.IOException;
import java.net.*;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.sw360.datahandler.common.CommonUtils;
import org.eclipse.sw360.datahandler.common.SW360Constants;
import org.eclipse.sw360.datahandler.common.SW360Utils;

import static org.eclipse.sw360.datahandler.common.SW360ConfigKeys.VCS_HOSTS;
import static org.eclipse.sw360.datahandler.common.SW360ConfigKeys.VCS_REDIRECTION_LIMIT;
import static org.eclipse.sw360.datahandler.common.SW360ConfigKeys.VCS_REDIRECTION_TIMEOUT_LIMIT;

public class RepositoryURL {
private String url;
private static final Logger log = LogManager.getLogger(RepositoryURL.class);
private static final String SCHEMA_PATTERN = ".+://(\\w*(?:[\\-@.\\\\s,_:/][/(.\\-)A-Za-z0-9]+)*)";
private static final String VCS_HOSTS_STRING = SW360Utils.readConfig(VCS_HOSTS,"");
private static final Map<String, String> KNOWN_VCS_HOSTS = parseVCSHosts(VCS_HOSTS_STRING);
private Set<String> redirectedUrls = new HashSet<>();
private static int redirectionTimeout = Integer.parseInt(SW360Utils.readConfig(VCS_REDIRECTION_TIMEOUT_LIMIT, SW360Constants.VCS_REDIRECTION_TIMEOUT_LIMIT));
private static int redirectionLimit = Integer.parseInt(SW360Utils.readConfig(VCS_REDIRECTION_LIMIT, SW360Constants.VCS_REDIRECTION_LIMIT));

public RepositoryURL(){}

public RepositoryURL(String url) {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("URL cannot be null or empty");
}
this.url = processURL(url);
}

public String processURL(String url) {
String sanitized = sanitizeVCS(url);
return handleURLRedirection(sanitized);
return sanitizeVCS(url);
}


private static String formatVCSUrl(String host, String[] urlParts) {
String formatString = KNOWN_VCS_HOSTS.get(host);

Expand Down Expand Up @@ -111,74 +92,6 @@ public static String getComponentNameFromVCS(String vcsUrl, boolean isGetVendora
return isGetVendorandName ? String.join("/", pathParts) : pathParts[pathParts.length - 1];
}

public String handleURLRedirection(String urlString) {
URL url;
HttpURLConnection connection = null;
try {
url = new URI(urlString).toURL();
} catch (MalformedURLException | URISyntaxException | IllegalArgumentException e) {
log.error("Invalid URL format: {}", e.getMessage());
return urlString;
}

int redirectCount = 0;

while (redirectCount < redirectionLimit) {
try {
connection = openConnection(url);
int status = connection.getResponseCode();

if (status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_MOVED_TEMP || status == 308) {
String newUrl = connection.getHeaderField("Location");
connection.disconnect();

// Resolve relative URLs
url = url.toURI().resolve(newUrl).toURL();

if (!"https".equalsIgnoreCase(url.getProtocol())) {
log.error("Insecure redirection to non-HTTPS URL: {}", url);
return urlString;
}

redirectCount++;
redirectedUrls.add(urlString);
} else {
connection.disconnect();
break;
}
} catch (IOException | URISyntaxException | IllegalArgumentException e) {
log.error("Error during redirection handling: {}", e.getMessage());
return urlString;
}
finally {
if (connection != null) {
connection.disconnect();
}
}

}

if (redirectCount == 0 || redirectCount >= redirectionLimit) {
if (redirectCount >= redirectionLimit) {
log.error("Exceeded maximum redirect limit. Returning original URL.");
}
return urlString;
}
return sanitizeVCS(url.toString());
}

private static HttpURLConnection openConnection(URL url) throws IOException{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(false);
connection.setConnectTimeout(redirectionTimeout);
connection.setReadTimeout(redirectionTimeout);
return connection;
}

public Set<String> getRedirectedUrls(){
return redirectedUrls;
}

private static Map<String, String> parseVCSHosts(String propertyValue) {
if (propertyValue == null || propertyValue.isEmpty()) {
log.error("VCS_HOSTS property is empty");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ public class CycloneDxBOMImporter {
private static final String INVALID_PACKAGE = "invalidPkg";
private static final String PROJECT_ID = "projectId";
private static final String PROJECT_NAME = "projectName";
private static final String REDIRECTED_VCS = "redirectedVCS";
public static final String INVALID_VCS_COMPONENT = "invalidVcsComponent";
private static final Predicate<ExternalReference.Type> typeFilter = Type.VCS::equals;

Expand Down Expand Up @@ -299,8 +298,6 @@ public RequestSummary importFromBOM(InputStream inputStream, AttachmentContent a
// all components does not have VCS, so return & show appropriate error in UI
messageMap.put(INVALID_COMPONENT, String.join(JOINER, componentsWithoutVcs));
messageMap.put(INVALID_PACKAGE, String.join(JOINER, invalidPackages));
messageMap.put(REDIRECTED_VCS, String.join(JOINER, repositoryURL.getRedirectedUrls()));
messageMap.put(DUPLICATE_PACKAGE, String.join(JOINER, duplicatePackages));
messageMap.put(SW360Constants.MESSAGE,
String.format("VCS information is missing for <b>%s</b> / <b>%s</b> Components!",
componentsCount - vcsCount, componentsCount));
Expand Down Expand Up @@ -811,7 +808,6 @@ private Map<String, String> importAllComponentsAsPackages(Map<String, List<org.c
messageMap.put(DUPLICATE_RELEASE, String.join(JOINER, duplicateReleases));
messageMap.put(DUPLICATE_PACKAGE, String.join(JOINER, duplicatePackages));
messageMap.put(INVALID_RELEASE, String.join(JOINER, invalidReleases));
messageMap.put(REDIRECTED_VCS, String.join(JOINER, repositoryURL.getRedirectedUrls()));
messageMap.put(NON_PKG_MANAGED_COMP_WITHOUT_VCS, String.join(JOINER, nonPkgManagedCompWithoutVCS));
messageMap.put(INVALID_PACKAGE, String.join(JOINER, invalidPackages));
messageMap.put(INVALID_VCS_COMPONENT, String.join(JOINER, invalidVcsComponents));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ private void loadToConfigsInMemForSw360(ConfigContainer configContainer) {
.put(RELEASE_FRIENDLY_URL, getOrDefault(configContainer, RELEASE_FRIENDLY_URL, "http://localhost:3000/components/releases/detail/releaseId"))
.put(COMBINED_CLI_PARSER_EXTERNAL_ID_CORRELATION_KEY, getOrDefault(configContainer, COMBINED_CLI_PARSER_EXTERNAL_ID_CORRELATION_KEY, ""))
.put(VCS_HOSTS, getOrDefault(configContainer, VCS_HOSTS, ""))
.put(VCS_REDIRECTION_LIMIT, getOrDefault(configContainer, VCS_REDIRECTION_LIMIT, String.valueOf(SW360Constants.VCS_REDIRECTION_LIMIT)))
.put(VCS_REDIRECTION_TIMEOUT_LIMIT, getOrDefault(configContainer, VCS_REDIRECTION_TIMEOUT_LIMIT, String.valueOf(SW360Constants.VCS_REDIRECTION_TIMEOUT_LIMIT)))
.put(NON_PKG_MANAGED_COMPS_PROP, getOrDefault(configContainer, NON_PKG_MANAGED_COMPS_PROP, ""))
.build();
putInMemory(ConfigFor.SW360_CONFIGURATION, configMap);
Expand Down Expand Up @@ -208,9 +206,7 @@ private boolean isConfigValid(String configKey, String configValue) {
-> configValue != null;

// validate int value
case ATTACHMENT_DELETE_NO_OF_DAYS,
VCS_REDIRECTION_LIMIT,
VCS_REDIRECTION_TIMEOUT_LIMIT
case ATTACHMENT_DELETE_NO_OF_DAYS
-> isIntegerValue(configValue);

// validate string in enum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ public class SW360ConfigKeys {

//Properties used by the RepositoryURL class to handle VCS from SBOM
public static final String VCS_HOSTS = "vcs.hosts";
public static final String VCS_REDIRECTION_LIMIT = "vcs.redirection.limit";
public static final String VCS_REDIRECTION_TIMEOUT_LIMIT = "vcs.redirection.timeout.limit";
public static final String NON_PKG_MANAGED_COMPS_PROP = "non.pkg.managed.comps.prop";

// Properties purely used by UI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ public class SW360Constants {
public static final String SRC_ATTACHMENT_DOWNLOAD_LOCATION;
public static final String PREFERRED_CLEARING_DATE_LIMIT;

public static final String VCS_REDIRECTION_LIMIT = "5";
public static final String VCS_REDIRECTION_TIMEOUT_LIMIT = "5000";

public static final String COMPONENTS = "components";
public static final String PROJECTS = "projects";
public static final String LICENSES = "licenses";
Expand Down