Skip to content

Commit

Permalink
feat(project CreateBom): add info about clearing results
Browse files Browse the repository at this point in the history
  • Loading branch information
gernot-h committed Jul 18, 2023
1 parent 788aa7e commit b1a5689
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 8 deletions.
5 changes: 5 additions & 0 deletions capycli/common/capycli_bom_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,11 @@ class CaPyCliBom():
SOURCE_FILE_COMMENT = "source archive (local copy)"
BINARY_URL_COMMENT = "binary (download location)"
BINARY_FILE_COMMENT = "relativePath"
# machine-readable XML description of licensing situation of a component
# see https://github.com/sw360/clipython for more information
CLI_API_COMMENT = "component license information (api download location)"
# human-readable description of licensing situation and obligations
CRT_API_COMMENT = "clearing report (api download location)"

@classmethod
def read_sbom(cls, inputfile: str) -> Bom:
Expand Down
5 changes: 5 additions & 0 deletions capycli/common/script_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ def release_web_url(self, release_id) -> str:
return (self.sw360_url + "group/guest/components/-/component/release/detailRelease/"
+ release_id)

def attachment_api_url(self, release_id, attachment_id) -> str:
"""Returns the REST API URL for an attachment."""
return (self.sw360_url + "resource/api/releases/" + release_id
+ "/attachments/" + attachment_id)

def find_project(self, name: str, version: str, show_results: bool = False) -> str:
"""Find the project with the matching name and version on SW360"""
print_text(" Searching for project...")
Expand Down
34 changes: 26 additions & 8 deletions capycli/project/create_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
class CreateBom(capycli.common.script_base.ScriptBase):
"""Create a SBOM for a project on SW360."""

comments = {
"SOURCE": CaPyCliBom.SOURCE_FILE_COMMENT,
"SOURCE_SELF": CaPyCliBom.SOURCE_FILE_COMMENT,
"BINARY": CaPyCliBom.BINARY_FILE_COMMENT,
"BINARY_SELF": CaPyCliBom.BINARY_FILE_COMMENT,
"COMPONENT_LICENSE_INFO_XML": CaPyCliBom.CLI_API_COMMENT,
"CLEARING_REPORT": CaPyCliBom.CRT_API_COMMENT
}

def get_external_id(self, name: str, release_details: dict):
"""Returns the external id with the given name or None."""
if "externalIds" not in release_details:
Expand All @@ -51,6 +60,7 @@ def create_project_bom(self, project) -> list:
for release in releases:
print_text(" ", release["name"], release["version"])
href = release["_links"]["self"]["href"]
sw360_id = self.client.get_id_from_href(href)

try:
release_details = self.client.get_release_by_url(href)
Expand Down Expand Up @@ -85,13 +95,22 @@ def create_project_bom(self, project) -> list:
CycloneDxSupport.set_ext_ref(rel_item, ExternalReferenceType.VCS, comment=None,
value=release_details["repository"]["url"])

for at_type, comment in (("SOURCE", CaPyCliBom.SOURCE_FILE_COMMENT),
("BINARY", CaPyCliBom.BINARY_FILE_COMMENT)):
attachments = self.get_release_attachments(release_details, (at_type, at_type + "_SELF"))
for attachment in attachments:
CycloneDxSupport.set_ext_ref(rel_item, ExternalReferenceType.DISTRIBUTION,
comment, attachment["filename"],
HashAlgorithm.SHA_1, attachment.get("sha1"))
attachments = self.get_release_attachments(release_details)
for attachment in attachments:
at_type = attachment["attachmentType"]
if at_type not in self.comments:
continue
if at_type in ("SOURCE", "SOURCE_SELF", "BINARY", "BINARY_SELF"):
ext_ref_type = ExternalReferenceType.DISTRIBUTION
url = attachment["filename"]
else:
ext_ref_type = ExternalReferenceType.OTHER
url = self.attachment_api_url(
sw360_id,
self.client.get_id_from_href(attachment["_links"]["self"]["href"]))
CycloneDxSupport.set_ext_ref(rel_item, ext_ref_type,
self.comments[at_type], url,
HashAlgorithm.SHA_1, attachment.get("sha1"))

except sw360.SW360Error as swex:
print_red(" ERROR: unable to access project:" + repr(swex))
Expand All @@ -101,7 +120,6 @@ def create_project_bom(self, project) -> list:
if state:
CycloneDxSupport.set_property(rel_item, CycloneDxSupport.CDX_PROP_PROJ_STATE, state)

sw360_id = self.client.get_id_from_href(href)
CycloneDxSupport.set_property(rel_item, CycloneDxSupport.CDX_PROP_SW360ID, sw360_id)

CycloneDxSupport.set_property(
Expand Down
27 changes: 27 additions & 0 deletions tests/test_create_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,17 @@ def test_project_by_id(self):
}
}
})
release["_embedded"]["sw360:attachments"].append({
"filename": "clipython-1.3.0.docx",
"sha1": "f0d8f2ddd017bdeaecbaec72ff76a6c0a045ec66",
"attachmentType": "CLEARING_REPORT",
"_links": {
"self": {
"href": "https://my.server.com/resource/api/attachments/r002a003"
}
}
})

responses.add(
responses.GET,
url=self.MYURL + "resource/api/releases/r002",
Expand All @@ -194,6 +205,22 @@ def test_project_by_id(self):
self.assertEqual(ext_refs_src_file[0].hashes[0].alg, "SHA-1")
self.assertEqual(ext_refs_src_file[0].hashes[0].content, release["_embedded"]["sw360:attachments"][0]["sha1"])

ext_refs_src_file = [e for e in cx_comp.external_references if e.comment == CaPyCliBom.CLI_API_COMMENT]
self.assertEqual(len(ext_refs_src_file), 1)
self.assertEqual(ext_refs_src_file[0].url,
'https://my.server.com/resource/api/releases/r002/attachments/r002a002')
self.assertEqual(ext_refs_src_file[0].type, ExternalReferenceType.OTHER)
self.assertEqual(ext_refs_src_file[0].hashes[0].alg, "SHA-1")
self.assertEqual(ext_refs_src_file[0].hashes[0].content, release["_embedded"]["sw360:attachments"][1]["sha1"])

ext_refs_src_file = [e for e in cx_comp.external_references if e.comment == CaPyCliBom.CRT_API_COMMENT]
self.assertEqual(len(ext_refs_src_file), 1)
self.assertEqual(ext_refs_src_file[0].url,
'https://my.server.com/resource/api/releases/r002/attachments/r002a003')
self.assertEqual(ext_refs_src_file[0].type, ExternalReferenceType.OTHER)
self.assertEqual(ext_refs_src_file[0].hashes[0].alg, "SHA-1")
self.assertEqual(ext_refs_src_file[0].hashes[0].content, release["_embedded"]["sw360:attachments"][3]["sha1"])

ext_refs_vcs = [e for e in cx_comp.external_references if e.type == ExternalReferenceType.VCS]
self.assertEqual(len(ext_refs_vcs), 1)
self.assertEqual(ext_refs_vcs[0].url, release["repository"]["url"])
Expand Down

0 comments on commit b1a5689

Please sign in to comment.