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 @@ -15,6 +15,7 @@
import com.devonfw.tools.ide.tool.ToolCommandlet;
import com.devonfw.tools.ide.url.model.file.UrlDownloadFileMetadata;
import com.devonfw.tools.ide.url.model.file.json.ToolDependency;
import com.devonfw.tools.ide.url.model.file.json.ToolSecurity;
import com.devonfw.tools.ide.version.GenericVersionRange;
import com.devonfw.tools.ide.version.VersionIdentifier;

Expand Down Expand Up @@ -149,6 +150,11 @@ public Collection<ToolDependency> findDependencies(String tool, String edition,
return Collections.emptyList();
}

@Override
public ToolSecurity findSecurity(String tool, String edition) {
return ToolSecurity.getEmpty();
}

@Override
public List<String> getSortedEditions(String tool) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.devonfw.tools.ide.url.model.file.UrlDownloadFileMetadata;
import com.devonfw.tools.ide.url.model.file.json.ToolDependencies;
import com.devonfw.tools.ide.url.model.file.json.ToolDependency;
import com.devonfw.tools.ide.url.model.file.json.ToolSecurity;
import com.devonfw.tools.ide.url.model.folder.UrlEdition;
import com.devonfw.tools.ide.url.model.folder.UrlTool;
import com.devonfw.tools.ide.url.model.folder.UrlVersion;
Expand Down Expand Up @@ -60,6 +61,20 @@ public Collection<ToolDependency> findDependencies(String tool, String edition,
return dependencies.findDependencies(version, this.context);
}

@Override
public ToolSecurity findSecurity(String tool, String edition) {
UrlEdition urlEdition = this.context.getUrls().getEdition(tool, edition);
ToolSecurity security = urlEdition.getSecurityFile().getSecurity();
if (security == ToolSecurity.getEmpty()) {
UrlTool urlTool = urlEdition.getParent();
security = urlTool.getSecurityFile().getSecurity();
}
if (security != ToolSecurity.getEmpty()) {
this.context.trace("Found dependencies in {}", security);
}
return security;
}

@Override
public List<String> getSortedEditions(String tool) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.devonfw.tools.ide.url.model.file.UrlGenericChecksum;
import com.devonfw.tools.ide.url.model.file.UrlGenericChecksumType;
import com.devonfw.tools.ide.url.model.file.json.ToolDependency;
import com.devonfw.tools.ide.url.model.file.json.ToolSecurity;
import com.devonfw.tools.ide.variable.IdeVariables;
import com.devonfw.tools.ide.version.GenericVersionRange;
import com.devonfw.tools.ide.version.VersionIdentifier;
Expand Down Expand Up @@ -263,6 +264,11 @@ public Collection<ToolDependency> findDependencies(String groupId, String artifa
return Collections.emptyList();
}

@Override
public ToolSecurity findSecurity(String tool, String edition) {
return ToolSecurity.getEmpty();
}

@Override
public Path download(UrlDownloadFileMetadata metadata) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

import com.devonfw.tools.ide.tool.ToolCommandlet;
import com.devonfw.tools.ide.url.model.AbstractUrlMetadata;
import com.devonfw.tools.ide.url.model.file.json.CVE;
import com.devonfw.tools.ide.url.model.file.json.ToolDependency;
import com.devonfw.tools.ide.url.model.file.json.ToolSecurity;
import com.devonfw.tools.ide.version.GenericVersionRange;
import com.devonfw.tools.ide.version.VersionIdentifier;

Expand Down Expand Up @@ -61,4 +63,10 @@ public interface ToolRepository extends AbstractUrlMetadata {
*/
Collection<ToolDependency> findDependencies(String tool, String edition, VersionIdentifier version);

/**
* @param tool the name of the tool.
* @param edition the edition of the tool.
* @return the {@link Collection} of {@link CVE cve security}.
*/
ToolSecurity findSecurity(String tool, String edition);
}
Original file line number Diff line number Diff line change
@@ -1,129 +1,47 @@
package com.devonfw.tools.ide.url.model.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Set;
import java.util.TreeSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.devonfw.tools.ide.url.model.file.json.ToolSecurity;
import com.devonfw.tools.ide.url.model.folder.AbstractUrlToolOrEdition;
import com.devonfw.tools.ide.url.model.folder.UrlEdition;
import com.devonfw.tools.ide.version.VersionIdentifier;
import com.devonfw.tools.ide.version.VersionRange;

/**
* {@link UrlFile} with the security information for an {@link UrlEdition}.
*/
public class UrlSecurityFile extends AbstractUrlFile<UrlEdition> {
public class UrlSecurityFile extends AbstractUrlFile<AbstractUrlToolOrEdition<?, ?>> {

/** {@link #getName() Name} of security file. */
public static final String FILENAME_SECURITY = "security";
public static final String SECURITY_JSON = "security.json";

private static final Logger LOG = LoggerFactory.getLogger(UrlSecurityFile.class);

private final Set<VersionRange> versionRanges;
private ToolSecurity security;

/**
* The constructor.
*
* @param parent the {@link #getParent() parent folder}.
*/
public UrlSecurityFile(UrlEdition parent) {
public UrlSecurityFile(AbstractUrlToolOrEdition<?, ?> parent) {

super(parent, FILENAME_SECURITY);
this.versionRanges = new TreeSet<>();
super(parent, SECURITY_JSON);
}

/**
* @return the number of #getUrl
* @return the content of the CVE map of the security.json file
*/
public int getVersionRangeCount() {
public ToolSecurity getSecurity() {

return this.versionRanges.size();
}

/**
* @param versionRange the {@link VersionRange} add.
*/
public void addVersionRange(VersionRange versionRange) {

boolean added = this.versionRanges.add(versionRange);
if (added) {
this.modified = true;
if (this.security == null) {
return ToolSecurity.getEmpty();
}
}

/**
* @param versionRange the {@link VersionRange} to remove.
*/
public void removeVersionRange(VersionRange versionRange) {

boolean removed = this.versionRanges.remove(versionRange);
if (removed) {
this.modified = true;
}
}

/**
* @param version the {@link VersionIdentifier} to check.
* @return {@code true} if the given {@link VersionIdentifier} is contained in this {@link UrlSecurityFile}, {@code false} otherwise.
*/
public boolean contains(VersionIdentifier version) {

for (VersionRange range : this.versionRanges) {
if (range.contains(version)) {
return true;
}
}
return false;
return this.security;
}

@Override
protected void doLoad() {

this.versionRanges.clear();
Path path = getPath();
if (!Files.exists(path)) {
return;
}
try (BufferedReader br = Files.newBufferedReader(path)) {
String line;
do {
line = br.readLine();
if (line != null) {
line = line.trim();
VersionRange range = VersionRange.of(line);
if (range == null) {
LOG.warn("Invalid line in file " + path + ": " + line);
} else {
this.versionRanges.add(range);
}
}
} while (line != null);
} catch (IOException e) {
throw new IllegalStateException("Failed to load file " + path, e);
}
this.security = ToolSecurity.of(getPath());
}

@Override
protected void doSave() {

Path path = getPath();
if (this.versionRanges.isEmpty() && !Files.exists(path)) {
return;
}
try (BufferedWriter bw = Files.newBufferedWriter(path, StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
for (VersionRange range : this.versionRanges) {
bw.write(range + "\n");
}
} catch (IOException e) {
throw new IllegalStateException("Failed to save file " + path, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.devonfw.tools.ide.url.model.file.json;

import java.util.List;

import com.devonfw.tools.ide.version.VersionRange;

/**
* Model to represent a CVE of a tool (inside a "security.json" file).
*/
public record CVE(String id, double severity, List<VersionRange> versions) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.devonfw.tools.ide.url.model.file.json;

import java.io.BufferedReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.devonfw.tools.ide.json.JsonMapping;
import com.devonfw.tools.ide.version.VersionIdentifier;
import com.devonfw.tools.ide.version.VersionRange;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
* Container representing data from the "security.json".
*
* @see com.devonfw.tools.ide.url.model.file.UrlSecurityFile
*/
public class ToolSecurity {

private static final ObjectMapper MAPPER = JsonMapping.create();

private static final ToolSecurity EMPTY = new ToolSecurity(Collections.emptyList());
private List<CVE> issues;


private ToolSecurity() {
super();
}

private ToolSecurity(List<CVE> issues) {

super();
this.issues = issues;
}

/**
* @param version the {@link VersionIdentifier} of the tool to install.
* @return The {@link List} of {@link CVE}s for the given tool version.
*/
public List<CVE> findCVEs(VersionIdentifier version) {
List<CVE> cves = new ArrayList<>();
for (CVE cve : issues) {
for (VersionRange versionRange : cve.versions()) {
if (versionRange.contains(version)) {
cves.add(cve);
}
}
}
return cves;
}

/**
* @param file the {@link Path} to the JSON file to load.
* @return the loaded {@link ToolSecurity} or the {@link #getEmpty() empty instance} if given {@link Path} does not exist.
*/
public static ToolSecurity of(Path file) {

if (Files.exists(file)) {
try (BufferedReader reader = Files.newBufferedReader(file)) {
return MAPPER.readValue(reader, ToolSecurity.class);
} catch (Exception e) {
throw new IllegalStateException("Failed to load " + file, e);
}
} else {
return EMPTY;
}
}

/**
* @return the empty instance of {@link ToolSecurity}.
*/
public static ToolSecurity getEmpty() {

return EMPTY;
}

/**
* @return the list of CVEs
*/
public List<CVE> getIssues() {
return issues;
}

/**
* @param issues the list of CVEs
*/
public void setIssues(List<CVE> issues) {
this.issues = issues;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import com.devonfw.tools.ide.url.model.AbstractUrlFolderWithParent;
import com.devonfw.tools.ide.url.model.UrlArtifactWithParent;
import com.devonfw.tools.ide.url.model.file.UrlDependencyFile;
import com.devonfw.tools.ide.url.model.file.UrlSecurityFile;

public abstract class AbstractUrlToolOrEdition<P extends AbstractUrlFolder<?>, C extends UrlArtifactWithParent<?>> extends AbstractUrlFolderWithParent<P, C> {

private UrlDependencyFile dependencyFile;
private UrlSecurityFile securityFile;

/**
* The constructor.
Expand All @@ -32,4 +34,17 @@ public UrlDependencyFile getDependencyFile() {
}
return dependencyFile;
}

/**
* @return the {@link UrlSecurityFile} of this {@link UrlEdition}. Will be lazily initialized on the first call of this method. If the file exists, it will be
* loaded, otherwise it will be empty and only created on save if data was added.
*/
public UrlSecurityFile getSecurityFile() {

if (this.securityFile == null) {
this.securityFile = new UrlSecurityFile(this);
this.securityFile.load(false);
}
return securityFile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,6 @@ protected UrlVersion newChild(String name) {
return new UrlVersion(this, name);
}

/**
* @return the {@link UrlSecurityFile} of this {@link UrlEdition}. Will be lazily initialized on the first call of this method. If the file exists, it will be
* loaded, otherwise it will be empty and only created on save if data was added.
*/
public UrlSecurityFile getSecurityFile() {

if (this.securityFile == null) {
this.securityFile = new UrlSecurityFile(this);
this.securityFile.load(false);
}
return this.securityFile;
}

@Override
public void save() {

Expand Down
Loading