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
88 changes: 52 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ encrypted-token-will-appear-here

```xml
<servers>
...
<!-- ... other servers -->
<server>
<id>github</id>
<username>github-userid-goes-here</username>
<password>encrypted-token-goes-here-including-curly-brackets</password>
</server>
...
<!-- ... other servers -->
</servers>
```
</li>
Expand All @@ -66,12 +66,12 @@ encrypted-token-will-appear-here

```xml
<repositories>
...
<!-- ... other repositories -->
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/guacsec/trustify-da-java-client</url>
</repository>
...
<!-- ... other repositories -->
</repositories>
```
</li>
Expand All @@ -81,15 +81,15 @@ encrypted-token-will-appear-here

```groovy
repositories {
...
// ... other repositories
maven {
url 'https://maven.pkg.github.com/guacsec/trustify-da-java-client'
credentials {
username System.getenv("GITHUB_USERNAME")
password System.getenv("GITHUB_TOKEN")
}
}
...
// ... other repositories
}
```
</li>
Expand Down Expand Up @@ -177,14 +177,25 @@ public class TrustifyExample {

<h3>Excluding Packages</h3>
<p>
Excluding a package from any analysis can be achieved by marking the package for exclusion.
Excluding a package from any analysis can be achieved by marking the package for exclusion using either the <code>trustify-da-ignore</code> syntax.

Although both `trustify-da-ignore` and `exhortignore` patterns work identically and can be used interchangeably. The `trustify-da-ignore` syntax is recommended for new projects, while `exhortignore` continues to be supported for backwards compatibility. You can gradually migrate your projects or use both patterns in the same manifest.

</p>

<ul>
<li>
<em>Java Maven</em> users can add a comment in <em>pom.xml</em>

```xml
<!-- Using trustify-da-ignore syntax -->
<dependency> <!--trustify-da-ignore-->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>0.0.9-SNAPSHOT</version>
</dependency>

<!-- Using legacy exhortignore syntax -->
<dependency> <!--exhortignore-->
<groupId>...</groupId>
<artifactId>...</artifactId>
Expand All @@ -193,10 +204,8 @@ Excluding a package from any analysis can be achieved by marking the package for
```
</li>

</ul>
<ul>
<li>
<em>Javascript NPM </em> users can add a root (key, value) pair with value of list of names (strings) to be ignored (without versions), and key called <b>exhortignore</b> in <em>package.json</em>, example:
<em>Javascript NPM</em> users can add ignore arrays in <em>package.json</em>:

```json
{
Expand All @@ -213,45 +222,49 @@ Excluding a package from any analysis can be achieved by marking the package for
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.9.18"
},
"exhortignore": [
"trustify-da-ignore": [
"jsonwebtoken"
]
}

```
</li>

<li>
<em>Golang</em> users can add in go.mod a comment with //trustify-da-ignore next to the package to be ignored, or to "piggyback" on existing comment ( e.g - //indirect) , for example:

<em>Golang</em> users can add in go.mod a comment with //exhortignore next to the package to be ignored, or to "piggyback" on existing comment ( e.g - //indirect) , for example:
```go
```mod
module github.com/RHEcosystemAppEng/SaaSi/deployer

go 1.19

require (
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.1.2
github.com/jessevdk/go-flags v1.5.0 //exhortignore
github.com/jessevdk/go-flags v1.5.0 //trustify-da-ignore
github.com/kr/pretty v0.3.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/apimachinery v0.26.1
k8s.io/client-go v0.26.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect exhortignore
github.com/davecgh/go-spew v1.1.1 // indirect trustify-da-ignore
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect //exhortignore

github.com/go-logr/logr v1.2.3 // indirect trustify-da-ignore
)
```
</li>

<li>
<em>Python pip</em> users can add in requirement text a comment with #trustify-da-ignore(or # trustify-da-ignore) to the right of the same artifact to be ignored, for example:

<em>Python pip</em> users can add in requirement text a comment with #exhortignore(or # exhortignore) to the right of the same artifact to be ignored, for example:
```properties
anyio==3.6.2
asgiref==3.4.1
beautifulsoup4==4.12.2
certifi==2023.7.22
chardet==4.0.0
click==8.0.4 #exhortignore
click==8.0.4 #trustify-da-ignore
contextlib2==21.6.0
fastapi==0.75.1
Flask==2.0.3
Expand All @@ -262,9 +275,9 @@ importlib-metadata==4.8.3
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
pydantic==1.9.2 # exhortignore
pydantic==1.9.2 # trustify-da-ignore
requests==2.25.1
six==1.16.0
six==1.16.0
sniffio==1.2.0
soupsieve==2.3.2.post1
starlette==0.17.1
Expand All @@ -273,12 +286,16 @@ urllib3==1.26.16
uvicorn==0.17.0
Werkzeug==2.0.3
zipp==3.6.0

```
<em>Gradle</em> users can add in build.gradle a comment with //exhortignore next to the package to be ignored:
</li>

<li>
<em>Gradle</em> users can add in build.gradle a comment with //trustify-da-ignore next to the package to be ignored:
```build.gradle

```groovy
plugins {
id 'java'
id 'java'
}

group = 'groupName'
Expand All @@ -289,32 +306,31 @@ repositories {
}

dependencies {
implementation "groupId:artifactId:version" // exhortignore
implementation "groupId:artifactId:version" // trustify-da-ignore
}

test {
useJUnitPlatform()
}
```
</li>

</ul>
All of the 5 above examples are valid for marking a package to be ignored

#### Ignore Strategies - experimental
You can specify the method to ignore dependencies in manifest (globally), by setting the environment variable `TRUSTIFY_DA_IGNORE_METHOD` to one of the following values: \
**_Possible values:_**
- `insensitive` - ignoring the dependency and all of its subtree(all transitives) - default.
- `sensitive` - ignoring the dependency but let its transitives remain if they are also transitive of another dependency in the tree or if they're direct dependency of root in the dependency tree.


</li>
You can specify the method to ignore dependencies in manifest (globally), by setting the environment variable `TRUSTIFY_DA_IGNORE_METHOD` to one of the following values:

</ul>
**Possible values:**
- `insensitive` - ignoring the dependency and all of its subtree(all transitives) - default.
- `sensitive` - ignoring the dependency but let its transitives remain if they are also transitive of another dependency in the tree or if they're direct dependency of root in the dependency tree.

<h3>Customization</h3>
<p>
There are 2 approaches for customizing <em>Trustify DA Java Client</em>. Using <em>Environment Variables</em> or
<em>Java Properties</em>:

```java
```text
System.setProperty("TRUSTIFY_DA_MVN_PATH", "/path/to/custom/mvn");
System.setProperty("TRUSTIFY_DA_NPM_PATH", "/path/to/custom/npm");
System.setProperty("TRUSTIFY_DA_PNPM_PATH", "/path/to/custom/pnpm");
Expand Down Expand Up @@ -473,7 +489,7 @@ export TRUSTIFY_DA_MVN_LOCAL_REPO=/home/user/custom-maven-repo
```

Using Java properties:
```java
```text
System.setProperty("TRUSTIFY_DA_MVN_USER_SETTINGS", "/home/user/.m2/custom-settings.xml");
System.setProperty("TRUSTIFY_DA_MVN_LOCAL_REPO", "/home/user/custom-maven-repo");
```
Expand Down
2 changes: 1 addition & 1 deletion catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
annotations:
backstage.io/kuberqnetes-id: trustify-da-java-client
backstage.io/kubernetes-id: trustify-da-java-client
github.com/project-slug: guacsec/trustify-da-java-client
github.com/project-readme-path: README.md
backstage.io/view-url: https://github.com/guacsec/trustify-da-java-client/blob/main/catalog-info.yaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.github.guacsec.trustifyda.tools.Ecosystem.Type;
import io.github.guacsec.trustifyda.tools.Operations;
import io.github.guacsec.trustifyda.utils.Environment;
import io.github.guacsec.trustifyda.utils.IgnorePatternDetector;
import io.github.guacsec.trustifyda.vcs.GitVersionControlSystemImpl;
import io.github.guacsec.trustifyda.vcs.TagInfo;
import io.github.guacsec.trustifyda.vcs.VersionControlSystem;
Expand Down Expand Up @@ -459,15 +460,16 @@ private String extractPackageName(String line) {

public boolean IgnoredLine(String line) {
boolean result = false;
if (line.contains("exhortignore")) {
// if exhortignore is alone in a comment or is in a comment together with indirect or as a
if (IgnorePatternDetector.containsIgnorePattern(line)) {
// if exhortignore or trustify-da-ignore is alone in a comment or is in a comment together
// with indirect or as a
// comment inside a
// comment ( e.g // indirect //exhort)
// then this line is to be checked if it's a comment after a package name.
if (Pattern.matches(".+//\\s*exhortignore", line)
|| Pattern.matches(".+//\\sindirect (//)?\\s*exhortignore", line)) {
if (Pattern.matches(".+//\\s*(exhortignore|trustify-da-ignore)", line)
|| Pattern.matches(".+//\\sindirect (//)?\\s*(exhortignore|trustify-da-ignore)", line)) {
String trimmedRow = line.trim();
// filter out lines where exhortignore has no meaning
// filter out lines where exhortignore or trustify-da-ignore has no meaning
if (!trimmedRow.startsWith("module ")
&& !trimmedRow.startsWith("go ")
&& !trimmedRow.startsWith("require (")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.github.guacsec.trustifyda.sbom.SbomFactory;
import io.github.guacsec.trustifyda.tools.Ecosystem.Type;
import io.github.guacsec.trustifyda.tools.Operations;
import io.github.guacsec.trustifyda.utils.IgnorePatternDetector;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -202,7 +203,7 @@ private boolean depHasLibsNotation(String depToBeIgnored) {
}

private boolean isIgnoredLine(String line) {
return line.contains("exhortignore");
return IgnorePatternDetector.containsIgnorePattern(line);
}

private String extractPackageName(String line) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.github.guacsec.trustifyda.tools.Ecosystem.Type;
import io.github.guacsec.trustifyda.tools.Operations;
import io.github.guacsec.trustifyda.utils.Environment;
import io.github.guacsec.trustifyda.utils.IgnorePatternDetector;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -277,7 +278,7 @@ private List<DependencyAggregator> getDependencies(final Path manifestPath) thro
if (!Objects.isNull(dependencyAggregator)) {
// if we hit an ignore comment, mark aggregator to be ignored
if (reader.getEventType() == XMLStreamConstants.COMMENT
&& "exhortignore".equals(reader.getText().strip())) {
&& isIgnoreComment(reader.getText())) {
dependencyAggregator.ignored = true;
continue;
}
Expand Down Expand Up @@ -491,4 +492,17 @@ public static String normalizePath(String thePath) {
}
return result;
}

/**
* Checks if a comment text exactly matches an ignore pattern. Used for XML comment detection in
* pom.xml files.
*
* @param commentText the comment text to check (will be stripped of whitespace)
* @return true if the comment exactly matches an ignore pattern
*/
private boolean isIgnoreComment(String commentText) {
String stripped = commentText.strip();
return IgnorePatternDetector.IGNORE_PATTERN.equals(stripped)
|| IgnorePatternDetector.LEGACY_IGNORE_PATTERN.equals(stripped);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
Expand Down Expand Up @@ -240,18 +238,6 @@ protected String parseDepTreeOutput(String output) {
return output;
}

protected List<String> getIgnoredDeps(JsonNode manifest) {
var ignored = new ArrayList<String>();
var ignoredNode = manifest.withArray("exhortignore");
if (ignoredNode == null) {
return ignored;
}
for (JsonNode n : ignoredNode) {
ignored.add(n.asText());
}
return ignored;
}

protected Map<String, String> getExecEnv() {
String pathEnv = Environment.get(pathEnv());
if (pathEnv != null && !pathEnv.isBlank()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.github.guacsec.trustifyda.tools.Ecosystem;
import io.github.guacsec.trustifyda.tools.Operations;
import io.github.guacsec.trustifyda.utils.Environment;
import io.github.guacsec.trustifyda.utils.IgnorePatternDetector;
import io.github.guacsec.trustifyda.utils.PythonControllerBase;
import io.github.guacsec.trustifyda.utils.PythonControllerRealEnv;
import io.github.guacsec.trustifyda.utils.PythonControllerVirtualEnv;
Expand Down Expand Up @@ -168,12 +169,26 @@ private void handleIgnoredDependencies(String manifestContent, Sbom sbom) {
}
}

/**
* Checks if a text line contains a Python pip ignore pattern. Handles both '#exhortignore' and
* '#trustify-da-ignore' with optional spacing.
*
* @param line the line to check
* @return true if the line contains a Python pip ignore pattern
*/
private boolean containsPythonIgnorePattern(String line) {
return line.contains("#" + IgnorePatternDetector.IGNORE_PATTERN)
|| line.contains("# " + IgnorePatternDetector.IGNORE_PATTERN)
|| line.contains("#" + IgnorePatternDetector.LEGACY_IGNORE_PATTERN)
|| line.contains("# " + IgnorePatternDetector.LEGACY_IGNORE_PATTERN);
}

private Set<PackageURL> getIgnoredDependencies(String requirementsDeps) {

String[] requirementsLines = requirementsDeps.split(System.lineSeparator());
Set<PackageURL> collected =
Arrays.stream(requirementsLines)
.filter(line -> line.contains("#exhortignore") || line.contains("# exhortignore"))
.filter(this::containsPythonIgnorePattern)
.map(PythonPipProvider::extractDepFull)
.map(this::splitToNameVersion)
.map(dep -> toPurl(dep[0], dep[1]))
Expand Down
Loading
Loading