Skip to content

Commit 0d34d20

Browse files
committed
fix: derive CSAF relationship and product-tree ids consistently
(cherry picked from commit 29a9991)
1 parent 3b5ce4b commit 0d34d20

10 files changed

Lines changed: 82 additions & 77 deletions

backend/application/vex/services/csaf_generator_component.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from application.core.models import Observation
66
from application.vex.services.csaf_generator_helpers import (
7+
get_component_id,
78
get_product_id,
89
get_relationship_name,
910
)
@@ -18,14 +19,6 @@
1819
)
1920

2021

21-
def get_component_id(component_name_version: str, purl: Optional[str], cpe: Optional[str]) -> str:
22-
if purl:
23-
return purl
24-
if cpe:
25-
return cpe
26-
return component_name_version
27-
28-
2922
def append_component_to_product_tree(
3023
product_tree: CSAFProductTree,
3124
observation: Observation,

backend/application/vex/services/csaf_generator_helpers.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,22 @@ def get_product_id(product: Product, branch: Optional[Branch]) -> str:
6060
return product.name
6161

6262

63+
def get_component_id(component_name_version: str, purl: Optional[str], cpe: Optional[str]) -> str:
64+
if purl:
65+
return purl
66+
if cpe:
67+
return cpe
68+
return component_name_version
69+
70+
6371
def get_relationship_name(observation: Observation) -> str:
64-
relationship_name = f"{observation.origin_component_name_version}@"
65-
relationship_name += (
66-
f"{observation.product.name}:{observation.branch.name}" if observation.branch else observation.product.name
72+
component_id = get_component_id(
73+
observation.origin_component_name_version,
74+
observation.origin_component_purl,
75+
observation.origin_component_cpe,
6776
)
68-
return relationship_name
77+
product_id = get_product_id(observation.product, observation.branch)
78+
return f"{component_id}@{product_id}"
6979

7080

7181
def get_product_or_relationship_id(observation: Observation) -> str:

backend/application/vex/services/csaf_generator_product.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ def append_product_to_product_tree(
3030
)
3131
product_tree.branches.append(product_family_branch)
3232

33+
product_id = get_product_id(product, branch)
34+
3335
if not branch:
3436
if product_family_branch.branches is None:
3537
raise ValueError("Product family branches should not be None")
3638
for product_name_branch in product_family_branch.branches:
37-
if product_name_branch.name == product.name:
39+
if product_name_branch.product and product_name_branch.product.product_id == product_id:
3840
return
3941

4042
new_product_full_name = _create_product(product, branch)
@@ -48,7 +50,7 @@ def append_product_to_product_tree(
4850
if product_family_branch.branches is None:
4951
raise ValueError("Product family branches should not be None")
5052
for version_branch in product_family_branch.branches:
51-
if version_branch.name == f"{product.name}:{branch.name}":
53+
if version_branch.product and version_branch.product.product_id == product_id:
5254
return
5355

5456
new_product_full_name = _create_product(product, branch)

backend/unittests/vex/api/files/csaf_given_vulnerability.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,26 +120,26 @@
120120
{
121121
"category": "default_component_of",
122122
"full_product_name": {
123-
"name": "vex_comp_2:2.0.0@vex_product_1",
124-
"product_id": "vex_comp_2:2.0.0@vex_product_1"
123+
"name": "pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1",
124+
"product_id": "pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1"
125125
},
126126
"product_reference": "pkg:so/vendor2/vex_comp_2@2.0.0",
127127
"relates_to_product_reference": "vex_product_1"
128128
},
129129
{
130130
"category": "default_component_of",
131131
"full_product_name": {
132-
"name": "vex_comp_2:2.0.0@vex_product_2:dev",
133-
"product_id": "vex_comp_2:2.0.0@vex_product_2:dev"
132+
"name": "pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev",
133+
"product_id": "pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
134134
},
135135
"product_reference": "pkg:so/vendor2/vex_comp_2@2.0.0",
136136
"relates_to_product_reference": "pkg:so/vex_product_2@dev"
137137
},
138138
{
139139
"category": "default_component_of",
140140
"full_product_name": {
141-
"name": "vex_comp_4:4.0.0@vex_product_2:dev",
142-
"product_id": "vex_comp_4:4.0.0@vex_product_2:dev"
141+
"name": "pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev",
142+
"product_id": "pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev"
143143
},
144144
"product_reference": "pkg:so/vex_comp_4@4.0.0",
145145
"relates_to_product_reference": "pkg:so/vex_product_2@dev"
@@ -157,10 +157,10 @@
157157
],
158158
"product_status": {
159159
"known_affected": [
160-
"vex_comp_2:2.0.0@vex_product_2:dev"
160+
"pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
161161
],
162162
"under_investigation": [
163-
"vex_comp_2:2.0.0@vex_product_1"
163+
"pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1"
164164
]
165165
},
166166
"references": [
@@ -175,7 +175,7 @@
175175
"category": "mitigation",
176176
"details": "Upgrade to release 2.1.0",
177177
"product_ids": [
178-
"vex_comp_2:2.0.0@vex_product_2:dev"
178+
"pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
179179
]
180180
}
181181
]

backend/unittests/vex/api/files/csaf_given_vulnerability_update.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,26 @@
125125
{
126126
"category": "default_component_of",
127127
"full_product_name": {
128-
"name": "vex_comp_2:2.0.0@vex_product_1",
129-
"product_id": "vex_comp_2:2.0.0@vex_product_1"
128+
"name": "pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1",
129+
"product_id": "pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1"
130130
},
131131
"product_reference": "pkg:so/vendor2/vex_comp_2@2.0.0",
132132
"relates_to_product_reference": "vex_product_1"
133133
},
134134
{
135135
"category": "default_component_of",
136136
"full_product_name": {
137-
"name": "vex_comp_2:2.0.0@vex_product_2:dev",
138-
"product_id": "vex_comp_2:2.0.0@vex_product_2:dev"
137+
"name": "pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev",
138+
"product_id": "pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
139139
},
140140
"product_reference": "pkg:so/vendor2/vex_comp_2@2.0.0",
141141
"relates_to_product_reference": "pkg:so/vex_product_2@dev"
142142
},
143143
{
144144
"category": "default_component_of",
145145
"full_product_name": {
146-
"name": "vex_comp_4:4.0.0@vex_product_2:dev",
147-
"product_id": "vex_comp_4:4.0.0@vex_product_2:dev"
146+
"name": "pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev",
147+
"product_id": "pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev"
148148
},
149149
"product_reference": "pkg:so/vex_comp_4@4.0.0",
150150
"relates_to_product_reference": "pkg:so/vex_product_2@dev"
@@ -162,8 +162,8 @@
162162
],
163163
"product_status": {
164164
"known_affected": [
165-
"vex_comp_2:2.0.0@vex_product_1",
166-
"vex_comp_2:2.0.0@vex_product_2:dev"
165+
"pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1",
166+
"pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
167167
]
168168
},
169169
"references": [
@@ -178,8 +178,8 @@
178178
"category": "mitigation",
179179
"details": "Upgrade to release 2.1.0",
180180
"product_ids": [
181-
"vex_comp_2:2.0.0@vex_product_1",
182-
"vex_comp_2:2.0.0@vex_product_2:dev"
181+
"pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1",
182+
"pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
183183
]
184184
}
185185
]

backend/unittests/vex/api/files/csaf_product_branches.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -131,26 +131,26 @@
131131
{
132132
"category": "default_component_of",
133133
"full_product_name": {
134-
"name": "vex_comp_2:2.0.0@vex_product_2:dev",
135-
"product_id": "vex_comp_2:2.0.0@vex_product_2:dev"
134+
"name": "pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev",
135+
"product_id": "pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
136136
},
137137
"product_reference": "pkg:so/vendor2/vex_comp_2@2.0.0",
138138
"relates_to_product_reference": "pkg:so/vex_product_2@dev"
139139
},
140140
{
141141
"category": "default_component_of",
142142
"full_product_name": {
143-
"name": "vex_comp_4:4.0.0@vex_product_2:dev",
144-
"product_id": "vex_comp_4:4.0.0@vex_product_2:dev"
143+
"name": "pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev",
144+
"product_id": "pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev"
145145
},
146146
"product_reference": "pkg:so/vex_comp_4@4.0.0",
147147
"relates_to_product_reference": "pkg:so/vex_product_2@dev"
148148
},
149149
{
150150
"category": "default_component_of",
151151
"full_product_name": {
152-
"name": "vex_comp_5:5.0.0@vex_product_2:main",
153-
"product_id": "vex_comp_5:5.0.0@vex_product_2:main"
152+
"name": "vex_comp_5:5.0.0@pkg:so/vex_product_2@main",
153+
"product_id": "vex_comp_5:5.0.0@pkg:so/vex_product_2@main"
154154
},
155155
"product_reference": "vex_comp_5:5.0.0",
156156
"relates_to_product_reference": "pkg:so/vex_product_2@main"
@@ -168,7 +168,7 @@
168168
],
169169
"product_status": {
170170
"known_affected": [
171-
"vex_comp_2:2.0.0@vex_product_2:dev"
171+
"pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
172172
]
173173
},
174174
"references": [
@@ -183,7 +183,7 @@
183183
"category": "mitigation",
184184
"details": "Upgrade to release 2.1.0",
185185
"product_ids": [
186-
"vex_comp_2:2.0.0@vex_product_2:dev"
186+
"pkg:so/vendor2/vex_comp_2@2.0.0@pkg:so/vex_product_2@dev"
187187
]
188188
}
189189
]
@@ -203,7 +203,7 @@
203203
],
204204
"product_status": {
205205
"fixed": [
206-
"vex_comp_4:4.0.0@vex_product_2:dev"
206+
"pkg:so/vex_comp_4@4.0.0@pkg:so/vex_product_2@dev"
207207
]
208208
}
209209
},
@@ -222,15 +222,15 @@
222222
],
223223
"product_status": {
224224
"known_not_affected": [
225-
"vex_comp_5:5.0.0@vex_product_2:main"
225+
"vex_comp_5:5.0.0@pkg:so/vex_product_2@main"
226226
]
227227
},
228228
"threats": [
229229
{
230230
"category": "impact",
231231
"details": "Should be no problem",
232232
"product_ids": [
233-
"vex_comp_5:5.0.0@vex_product_2:main"
233+
"vex_comp_5:5.0.0@pkg:so/vex_product_2@main"
234234
]
235235
}
236236
]

backend/unittests/vex/api/files/csaf_product_given_branch.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@
7878
{
7979
"category": "default_component_of",
8080
"full_product_name": {
81-
"name": "vex_comp_5:5.0.0@vex_product_2:main",
82-
"product_id": "vex_comp_5:5.0.0@vex_product_2:main"
81+
"name": "vex_comp_5:5.0.0@pkg:so/vex_product_2@main",
82+
"product_id": "vex_comp_5:5.0.0@pkg:so/vex_product_2@main"
8383
},
8484
"product_reference": "vex_comp_5:5.0.0",
8585
"relates_to_product_reference": "pkg:so/vex_product_2@main"
@@ -102,15 +102,15 @@
102102
],
103103
"product_status": {
104104
"known_not_affected": [
105-
"vex_comp_5:5.0.0@vex_product_2:main"
105+
"vex_comp_5:5.0.0@pkg:so/vex_product_2@main"
106106
]
107107
},
108108
"threats": [
109109
{
110110
"category": "impact",
111111
"details": "Should be no problem",
112112
"product_ids": [
113-
"vex_comp_5:5.0.0@vex_product_2:main"
113+
"vex_comp_5:5.0.0@pkg:so/vex_product_2@main"
114114
]
115115
}
116116
]

backend/unittests/vex/api/files/csaf_product_no_branch.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,26 +127,26 @@
127127
{
128128
"category": "default_component_of",
129129
"full_product_name": {
130-
"name": "vex_comp_1:1.0.0@vex_product_1",
131-
"product_id": "vex_comp_1:1.0.0@vex_product_1"
130+
"name": "pkg:so/vex_comp_1@1.0.0@vex_product_1",
131+
"product_id": "pkg:so/vex_comp_1@1.0.0@vex_product_1"
132132
},
133133
"product_reference": "pkg:so/vex_comp_1@1.0.0",
134134
"relates_to_product_reference": "vex_product_1"
135135
},
136136
{
137137
"category": "default_component_of",
138138
"full_product_name": {
139-
"name": "vex_comp_2:2.0.0@vex_product_1",
140-
"product_id": "vex_comp_2:2.0.0@vex_product_1"
139+
"name": "pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1",
140+
"product_id": "pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1"
141141
},
142142
"product_reference": "pkg:so/vendor2/vex_comp_2@2.0.0",
143143
"relates_to_product_reference": "vex_product_1"
144144
},
145145
{
146146
"category": "default_component_of",
147147
"full_product_name": {
148-
"name": "vex_comp_3:3.0.0@vex_product_1",
149-
"product_id": "vex_comp_3:3.0.0@vex_product_1"
148+
"name": "pkg:so/vendor_3/vex_comp_3@3.0.0@vex_product_1",
149+
"product_id": "pkg:so/vendor_3/vex_comp_3@3.0.0@vex_product_1"
150150
},
151151
"product_reference": "pkg:so/vendor_3/vex_comp_3@3.0.0",
152152
"relates_to_product_reference": "vex_product_1"
@@ -169,7 +169,7 @@
169169
],
170170
"product_status": {
171171
"known_affected": [
172-
"vex_comp_1:1.0.0@vex_product_1"
172+
"pkg:so/vex_comp_1@1.0.0@vex_product_1"
173173
]
174174
},
175175
"references": [
@@ -184,7 +184,7 @@
184184
"category": "mitigation",
185185
"details": "Upgrade to release 1.1.0",
186186
"product_ids": [
187-
"vex_comp_1:1.0.0@vex_product_1"
187+
"pkg:so/vex_comp_1@1.0.0@vex_product_1"
188188
]
189189
}
190190
]
@@ -199,7 +199,7 @@
199199
],
200200
"product_status": {
201201
"under_investigation": [
202-
"vex_comp_2:2.0.0@vex_product_1"
202+
"pkg:so/vendor2/vex_comp_2@2.0.0@vex_product_1"
203203
]
204204
},
205205
"references": [
@@ -215,7 +215,7 @@
215215
{
216216
"label": "vulnerable_code_not_in_execute_path",
217217
"product_ids": [
218-
"vex_comp_3:3.0.0@vex_product_1"
218+
"pkg:so/vendor_3/vex_comp_3@3.0.0@vex_product_1"
219219
]
220220
}
221221
],
@@ -233,7 +233,7 @@
233233
],
234234
"product_status": {
235235
"known_not_affected": [
236-
"vex_comp_3:3.0.0@vex_product_1"
236+
"pkg:so/vendor_3/vex_comp_3@3.0.0@vex_product_1"
237237
]
238238
}
239239
}

0 commit comments

Comments
 (0)