Skip to content

Commit 6473fc4

Browse files
committed
feat(project CreateBom): ignore rejected attachments
This unfortunately requires retrieving attachment info for each attachment.
1 parent 7f272a5 commit 6473fc4

File tree

3 files changed

+103
-33
lines changed

3 files changed

+103
-33
lines changed

ChangeLog.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
If multiple purls are found, a warning is printed asking user to manually edit SBOM.
1515
* `project createbom` add SW360 attachment info as external references to SBOM
1616
(currently supported: source, binary, CLI, report).
17+
* `project createbom` will not add rejected attachments to SBOM
1718
* `project createbom` adds SW360 project name, version and description to SBOM.
1819
* new command `bom downloadattachments` to download CLI and report attachments
1920

capycli/project/create_bom.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,16 @@ def create_project_bom(self, project, create_controlfile) -> Tuple[list, list]:
101101
if at_type not in CaPyCliBom.FILE_COMMENTS:
102102
continue
103103
comment = CaPyCliBom.FILE_COMMENTS[at_type]
104+
at_data = self.client.get_attachment_by_url(attachment["_links"]["self"]["href"])
105+
if at_data.get("checkStatus") == "REJECTED":
106+
print_yellow(" WARNING: ignoring REJECTED attachment",
107+
attachment["filename"])
108+
continue
104109
if at_type in ("SOURCE", "SOURCE_SELF", "BINARY", "BINARY_SELF"):
105110
ext_ref_type = ExternalReferenceType.DISTRIBUTION
106111
else:
107112
ext_ref_type = ExternalReferenceType.OTHER
108113
if create_controlfile:
109-
at_data = self.client.get_attachment_by_url(attachment["_links"]["self"]["href"])
110-
111114
at_details = {
112115
"ComponentName": " ".join((release["name"], release["version"])),
113116
"Sw360Id": sw360_id,

tests/test_create_bom.py

+97-31
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def test_create_bom_multiple_purls(self, capsys):
149149
content_type="application/json",
150150
adding_headers={"Authorization": "Token " + self.MYTOKEN},
151151
)
152-
152+
self.add_project_attachment_responses()
153153
cdx_components, _ = sut.create_project_bom(self.get_project_for_test(),
154154
create_controlfile=False)
155155
captured = capsys.readouterr()
@@ -214,6 +214,86 @@ def add_project_releases_responses(self):
214214
)
215215
return release
216216

217+
def add_project_attachment_responses(self):
218+
responses.add(
219+
method=responses.GET,
220+
url=self.MYURL + "resource/api/attachments/r001a002",
221+
body="""
222+
{
223+
"filename": "wheel-0.38.4.zip",
224+
"attachmentType": "SOURCE"
225+
}""",
226+
status=200,
227+
content_type="application/json",
228+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
229+
)
230+
responses.add(
231+
method=responses.GET,
232+
url=self.MYURL + "resource/api/attachments/r001a001",
233+
body="""
234+
{
235+
"filename": "CLIXML_wheel-0.38.4.xml",
236+
"sha1": "ccd9f1ed2f59c46ff3f0139c05bfd76f83fd9851",
237+
"attachmentType": "COMPONENT_LICENSE_INFO_XML"
238+
}""",
239+
status=200,
240+
content_type="application/json",
241+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
242+
)
243+
244+
responses.add(
245+
method=responses.GET,
246+
url=self.MYURL + "resource/api/attachments/r002a001",
247+
body="""
248+
{
249+
"filename": "clipython-1.3.0.zip",
250+
"attachmentType": "SOURCE"
251+
}""",
252+
status=200,
253+
content_type="application/json",
254+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
255+
)
256+
responses.add(
257+
method=responses.GET,
258+
url=self.MYURL + "resource/api/attachments/r002a002",
259+
body="""
260+
{
261+
"filename": "CLIXML_clipython-1.3.0.xml",
262+
"sha1": "dd4c38387c6811dba67d837af7742d84e61e20de",
263+
"attachmentType": "COMPONENT_LICENSE_INFO_XML",
264+
"checkedBy": "[email protected]",
265+
"checkStatus": "ACCEPTED",
266+
"createdBy": "[email protected]"
267+
}""",
268+
status=200,
269+
content_type="application/json",
270+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
271+
)
272+
responses.add(
273+
method=responses.GET,
274+
url=self.MYURL + "resource/api/attachments/r002a003",
275+
body="""
276+
{
277+
"filename": "clipython-repacked-for-fun.zip",
278+
"attachmentType": "SOURCE_SELF"
279+
}""",
280+
status=200,
281+
content_type="application/json",
282+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
283+
)
284+
responses.add(
285+
method=responses.GET,
286+
url=self.MYURL + "resource/api/attachments/r002a004",
287+
body="""
288+
{
289+
"filename": "clipython-1.3.0.docx",
290+
"attachmentType": "CLEARING_REPORT"
291+
}""",
292+
status=200,
293+
content_type="application/json",
294+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
295+
)
296+
217297
@responses.activate
218298
def test_project_by_id(self):
219299
sut = CreateBom()
@@ -222,6 +302,7 @@ def test_project_by_id(self):
222302
sut.login(token=TestBasePytest.MYTOKEN, url=TestBasePytest.MYURL)
223303

224304
release = self.add_project_releases_responses()
305+
self.add_project_attachment_responses()
225306
project = self.get_project_for_test()
226307

227308
cdx_bom, _ = sut.create_project_cdx_bom("p001", create_controlfile=False)
@@ -273,37 +354,8 @@ def test_project_by_id_controlfile(self):
273354
sut.login(token=TestBasePytest.MYTOKEN, url=TestBasePytest.MYURL)
274355

275356
self.add_project_releases_responses()
357+
self.add_project_attachment_responses()
276358

277-
# attachment info
278-
responses.add(
279-
method=responses.GET,
280-
url=self.MYURL + "resource/api/attachments/r001a001",
281-
body="""
282-
{
283-
"filename": "CLIXML_wheel-0.38.4.xml",
284-
"sha1": "ccd9f1ed2f59c46ff3f0139c05bfd76f83fd9851",
285-
"attachmentType": "COMPONENT_LICENSE_INFO_XML"
286-
}""",
287-
status=200,
288-
content_type="application/json",
289-
adding_headers={"Authorization": "Token " + self.MYTOKEN},
290-
)
291-
responses.add(
292-
method=responses.GET,
293-
url=self.MYURL + "resource/api/attachments/r002a002",
294-
body="""
295-
{
296-
"filename": "CLIXML_clipython-1.3.0.xml",
297-
"sha1": "dd4c38387c6811dba67d837af7742d84e61e20de",
298-
"attachmentType": "COMPONENT_LICENSE_INFO_XML",
299-
"checkedBy": "[email protected]",
300-
"checkStatus": "ACCEPTED",
301-
"createdBy": "[email protected]"
302-
}""",
303-
status=200,
304-
content_type="application/json",
305-
adding_headers={"Authorization": "Token " + self.MYTOKEN},
306-
)
307359
responses.add(
308360
method=responses.GET,
309361
url=self.MYURL + "resource/api/attachments/r002a004",
@@ -413,6 +465,7 @@ def test_project_show_by_name(self):
413465
content_type="application/json",
414466
adding_headers={"Authorization": "Token " + self.MYTOKEN},
415467
)
468+
self.add_project_attachment_responses()
416469

417470
self.delete_file(self.OUTPUTFILE)
418471
out = self.capture_stdout(sut.run, args)
@@ -452,6 +505,7 @@ def test_create_project_bom_release_error(self):
452505
content_type="application/json",
453506
adding_headers={"Authorization": "Token " + self.MYTOKEN},
454507
)
508+
self.add_project_attachment_responses()
455509
with pytest.raises(SystemExit):
456510
bom, _ = sut.create_project_bom(self.get_project_for_test(), create_controlfile=False)
457511

@@ -478,6 +532,18 @@ def test_create_project_bom_controlfile_attachment_error(self):
478532
content_type="application/json",
479533
adding_headers={"Authorization": "Token " + self.MYTOKEN},
480534
)
535+
responses.add(
536+
method=responses.GET,
537+
url=self.MYURL + "resource/api/attachments/r002a001",
538+
body="""
539+
{
540+
"filename": "clipython-1.3.0.zip",
541+
"attachmentType": "COMPONENT_LICENSE_INFO_XML"
542+
}""",
543+
status=200,
544+
content_type="application/json",
545+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
546+
)
481547
responses.add(
482548
method=responses.GET,
483549
url=self.MYURL + "resource/api/attachments/r002a002",

0 commit comments

Comments
 (0)