From eb404c5caf9578aa4025641e1b854fa986d4b4db Mon Sep 17 00:00:00 2001 From: Gernot Hillier Date: Tue, 22 Aug 2023 18:57:19 +0200 Subject: [PATCH] feat(project CreateBom): ignore rejected attachments This unfortunately requires retrieving attachment info for each attachment. --- ChangeLog.md | 1 + capycli/project/create_bom.py | 7 +- tests/test_create_bom.py | 128 ++++++++++++++++++++++++++-------- 3 files changed, 103 insertions(+), 33 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 24cbe0a..47117b6 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -10,6 +10,7 @@ * make `findsources` more resilient against SW360 issues. * `project createbom` now stores multiple purls in the property "purl_list" instead of trying to encode them in a strange way in the "purl" field. +* `project createbom` will not add rejected attachments to SBOM * `project createbom` adds CLI and report information to SBOM * new command `bom downloadattachments` to download CLI and report attachments diff --git a/capycli/project/create_bom.py b/capycli/project/create_bom.py index 2bf9f16..a86ca93 100644 --- a/capycli/project/create_bom.py +++ b/capycli/project/create_bom.py @@ -108,13 +108,16 @@ def create_project_bom(self, project: Dict[str, Any], create_controlfile: bool) if at_type not in CaPyCliBom.FILE_COMMENTS: continue comment = CaPyCliBom.FILE_COMMENTS[at_type] + at_data = self.client.get_attachment_by_url(attachment["_links"]["self"]["href"]) + if at_data.get("checkStatus") == "REJECTED": + print_yellow(" WARNING: ignoring REJECTED attachment", + attachment["filename"]) + continue if at_type in ("SOURCE", "SOURCE_SELF", "BINARY", "BINARY_SELF"): ext_ref_type = ExternalReferenceType.DISTRIBUTION else: ext_ref_type = ExternalReferenceType.OTHER if create_controlfile: - at_data = self.client.get_attachment_by_url(attachment["_links"]["self"]["href"]) - at_details = { "ComponentName": " ".join((release["name"], release["version"])), "Sw360Id": sw360_id, diff --git a/tests/test_create_bom.py b/tests/test_create_bom.py index 26a400d..e082086 100644 --- a/tests/test_create_bom.py +++ b/tests/test_create_bom.py @@ -150,7 +150,7 @@ def test_create_bom_multiple_purls(self, capsys: Any) -> None: content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) - + self.add_project_attachment_responses() cdx_components, _ = sut.create_project_bom(self.get_project_for_test(), create_controlfile=False) captured = capsys.readouterr() @@ -217,6 +217,86 @@ def add_project_releases_responses(self): ) return release + def add_project_attachment_responses(self): + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r001a002", + body=""" + { + "filename": "wheel-0.38.4.zip", + "attachmentType": "SOURCE" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r001a001", + body=""" + { + "filename": "CLIXML_wheel-0.38.4.xml", + "sha1": "ccd9f1ed2f59c46ff3f0139c05bfd76f83fd9851", + "attachmentType": "COMPONENT_LICENSE_INFO_XML" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) + + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r002a001", + body=""" + { + "filename": "clipython-1.3.0.zip", + "attachmentType": "SOURCE" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r002a002", + body=""" + { + "filename": "CLIXML_clipython-1.3.0.xml", + "sha1": "dd4c38387c6811dba67d837af7742d84e61e20de", + "attachmentType": "COMPONENT_LICENSE_INFO_XML", + "checkedBy": "user2@siemens.com", + "checkStatus": "ACCEPTED", + "createdBy": "user1@siemens.com" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r002a003", + body=""" + { + "filename": "clipython-repacked-for-fun.zip", + "attachmentType": "SOURCE_SELF" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r002a004", + body=""" + { + "filename": "clipython-1.3.0.docx", + "attachmentType": "CLEARING_REPORT" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) + @responses.activate def test_project_by_id(self) -> None: sut = CreateBom() @@ -225,6 +305,7 @@ def test_project_by_id(self) -> None: sut.login(token=TestBasePytest.MYTOKEN, url=TestBasePytest.MYURL) release = self.add_project_releases_responses() + self.add_project_attachment_responses() project = self.get_project_for_test() cdx_bom, _ = sut.create_project_cdx_bom("p001", create_controlfile=False) @@ -278,37 +359,8 @@ def test_project_by_id_controlfile(self): sut.login(token=TestBasePytest.MYTOKEN, url=TestBasePytest.MYURL) self.add_project_releases_responses() + self.add_project_attachment_responses() - # attachment info - responses.add( - method=responses.GET, - url=self.MYURL + "resource/api/attachments/r001a001", - body=""" - { - "filename": "CLIXML_wheel-0.38.4.xml", - "sha1": "ccd9f1ed2f59c46ff3f0139c05bfd76f83fd9851", - "attachmentType": "COMPONENT_LICENSE_INFO_XML" - }""", - status=200, - content_type="application/json", - adding_headers={"Authorization": "Token " + self.MYTOKEN}, - ) - responses.add( - method=responses.GET, - url=self.MYURL + "resource/api/attachments/r002a002", - body=""" - { - "filename": "CLIXML_clipython-1.3.0.xml", - "sha1": "dd4c38387c6811dba67d837af7742d84e61e20de", - "attachmentType": "COMPONENT_LICENSE_INFO_XML", - "checkedBy": "user2@siemens.com", - "checkStatus": "ACCEPTED", - "createdBy": "user1@siemens.com" - }""", - status=200, - content_type="application/json", - adding_headers={"Authorization": "Token " + self.MYTOKEN}, - ) responses.add( method=responses.GET, url=self.MYURL + "resource/api/attachments/r002a004", @@ -418,6 +470,7 @@ def test_project_show_by_name(self) -> None: content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) + self.add_project_attachment_responses() self.delete_file(self.OUTPUTFILE) out = self.capture_stdout(sut.run, args) @@ -457,6 +510,7 @@ def test_create_project_bom_release_error(self): content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) + self.add_project_attachment_responses() with pytest.raises(SystemExit): bom, _ = sut.create_project_bom(self.get_project_for_test(), create_controlfile=False) @@ -483,6 +537,18 @@ def test_create_project_bom_controlfile_attachment_error(self): content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) + responses.add( + method=responses.GET, + url=self.MYURL + "resource/api/attachments/r002a001", + body=""" + { + "filename": "clipython-1.3.0.zip", + "attachmentType": "COMPONENT_LICENSE_INFO_XML" + }""", + status=200, + content_type="application/json", + adding_headers={"Authorization": "Token " + self.MYTOKEN}, + ) responses.add( method=responses.GET, url=self.MYURL + "resource/api/attachments/r002a002",