Skip to content

Commit

Permalink
fix: revive root component in generated sbom for python pip
Browse files Browse the repository at this point in the history
Signed-off-by: Jude Niroshan <jude.niroshan11@gmail.com>
  • Loading branch information
JudeNiroshan committed Apr 29, 2024
1 parent 62e4445 commit b421f0a
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 21 deletions.
22 changes: 4 additions & 18 deletions src/main/java/com/redhat/exhort/providers/PythonPipProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
public final class PythonPipProvider extends Provider {

private Logger log = LoggersFactory.getLogger(this.getClass().getName());
private static final String DEFAULT_PIP_ROOT_COMPONENT_NAME = "default-pip-root";
private static final String DEFAULT_PIP_ROOT_COMPONENT_VERSION = "0.0.0";

public void setPythonController(PythonControllerBase pythonController) {
this.pythonController = pythonController;
Expand Down Expand Up @@ -76,22 +78,14 @@ public Content provideStack(Path manifestPath) throws IOException {
pythonController.getDependencies(manifestPath.toString(), true);
printDependenciesTree(dependencies);
Sbom sbom = SbomFactory.newInstance(Sbom.BelongingCondition.PURL, "sensitive");
try {
sbom.addRoot(new PackageURL(Ecosystem.Type.PYTHON.getType(), "root"));
} catch (MalformedPackageURLException e) {
throw new RuntimeException(e);
}
sbom.addRoot(toPurl(DEFAULT_PIP_ROOT_COMPONENT_NAME, DEFAULT_PIP_ROOT_COMPONENT_VERSION));
dependencies.stream()
.forEach(
(component) -> {
addAllDependencies(sbom.getRoot(), component, sbom);
});
byte[] requirementsFile = Files.readAllBytes(manifestPath);
handleIgnoredDependencies(new String(requirementsFile), sbom);
// In python' pip requirements.txt, there is no real root element, then need to remove dummy
// root element that
// was created for creating the sbom.
sbom.removeRootComponent();
return new Content(
sbom.getAsJsonString().getBytes(StandardCharsets.UTF_8), Api.CYCLONEDX_MEDIA_TYPE);
}
Expand Down Expand Up @@ -132,11 +126,7 @@ public Content provideComponent(byte[] manifestContent) throws IOException {
pythonController.getDependencies(manifestPath.toString(), false);
printDependenciesTree(dependencies);
Sbom sbom = SbomFactory.newInstance();
try {
sbom.addRoot(new PackageURL(Ecosystem.Type.PYTHON.getType(), "root"));
} catch (MalformedPackageURLException e) {
throw new RuntimeException(e);
}
sbom.addRoot(toPurl(DEFAULT_PIP_ROOT_COMPONENT_NAME, DEFAULT_PIP_ROOT_COMPONENT_VERSION));
dependencies.stream()
.forEach(
(component) -> {
Expand All @@ -147,10 +137,6 @@ public Content provideComponent(byte[] manifestContent) throws IOException {
Files.delete(manifestPath);
Files.delete(tempRepository);
handleIgnoredDependencies(new String(manifestContent), sbom);
// In python' pip requirements.txt, there is no real root element, then need to remove dummy
// root element that
// was created for creating the sbom.
sbom.removeRootComponent();
return new Content(
sbom.getAsJsonString().getBytes(StandardCharsets.UTF_8), Api.CYCLONEDX_MEDIA_TYPE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2023-09-28T12:40:41Z"
"timestamp" : "2024-04-29T09:14:16Z",
"component" : {
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
}
},
"components" : [
{
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -183,6 +197,36 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/default-pip-root@0.0.0",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [ ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2023-09-28T12:40:47Z"
"timestamp" : "2024-04-29T08:54:46Z",
"component" : {
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
}
},
"components" : [
{
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -183,6 +197,36 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/default-pip-root@0.0.0",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,23 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2024-04-29T09:13:11Z",
"component" : {
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
}
},
"components" : [
{
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -196,6 +211,38 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/default-pip-root@0.0.0",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/click@8.0.4",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/pydantic@1.9.2",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [ ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2023-09-28T12:40:44Z"
"timestamp" : "2024-04-29T09:00:11Z",
"component" : {
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
}
},
"components" : [
{
"name" : "default-pip-root",
"version" : "0.0.0",
"purl" : "pkg:pypi/default-pip-root@0.0.0",
"type" : "application",
"bom-ref" : "pkg:pypi/default-pip-root@0.0.0"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -197,6 +211,38 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/default-pip-root@0.0.0",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/click@8.0.4",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/pydantic@1.9.2",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [
Expand Down

0 comments on commit b421f0a

Please sign in to comment.