@@ -57,11 +57,15 @@ class VulnSerializerRefsAndSummary(serializers.HyperlinkedModelSerializer):
5757 Used for nesting inside package focused APIs.
5858 """
5959
60+ fixed_packages = MinimalPackageSerializer (
61+ many = True , source = "filtered_fixed_packages" , read_only = True
62+ )
63+
6064 references = VulnerabilityReferenceSerializer (many = True , source = "vulnerabilityreference_set" )
6165
6266 class Meta :
6367 model = Vulnerability
64- fields = ["url" , "vulnerability_id" , "summary" , "references" ]
68+ fields = ["url" , "vulnerability_id" , "summary" , "references" , "fixed_packages" ]
6569
6670
6771class MinimalVulnerabilitySerializer (serializers .HyperlinkedModelSerializer ):
@@ -74,21 +78,6 @@ class Meta:
7478 fields = ["url" , "vulnerability_id" ]
7579
7680
77- class PackageSerializerFixedVulns (serializers .HyperlinkedModelSerializer ):
78- """
79- Used for nesting inside vulnerability focused APIs.
80- """
81-
82- purl = serializers .CharField (source = "package_url" )
83- fixing_vulnerabilities = MinimalVulnerabilitySerializer (
84- many = True , source = "resolved_to" , read_only = True
85- )
86-
87- class Meta :
88- model = Package
89- fields = ["url" , "purl" , "fixing_vulnerabilities" ]
90-
91-
9281class AliasSerializer (serializers .HyperlinkedModelSerializer ):
9382 """
9483 Used for nesting inside package focused APIs.
@@ -129,13 +118,52 @@ def to_representation(self, instance):
129118 return data
130119
131120 purl = serializers .CharField (source = "package_url" )
132- affected_by_vulnerabilities = VulnSerializerRefsAndSummary (
133- many = True , source = "vulnerable_to" , read_only = True
134- )
135- fixing_vulnerabilities = VulnSerializerRefsAndSummary (
136- many = True , source = "resolved_to" , read_only = True
137- )
138- fixed_packages = PackageSerializerFixedVulns (many = True , read_only = True )
121+
122+ affected_by_vulnerabilities = serializers .SerializerMethodField ("get_affected_vulnerabilities" )
123+
124+ fixing_vulnerabilities = serializers .SerializerMethodField ("get_fixed_vulnerabilities" )
125+
126+ def get_fixed_packages (self , package ):
127+ return Package .objects .filter (
128+ name = package .name ,
129+ namespace = package .namespace ,
130+ type = package .type ,
131+ qualifiers = package .qualifiers ,
132+ subpath = package .subpath ,
133+ packagerelatedvulnerability__fix = True ,
134+ ).distinct ()
135+
136+ def get_affected_vulnerabilities (self , package ):
137+ fixed_packages = self .get_fixed_packages (package = package )
138+ qs = package .vulnerabilities .filter (packagerelatedvulnerability__fix = False )
139+ qs = qs .prefetch_related (
140+ Prefetch (
141+ "packages" ,
142+ queryset = fixed_packages ,
143+ to_attr = "filtered_fixed_packages" ,
144+ )
145+ )
146+ return VulnSerializerRefsAndSummary (
147+ instance = qs ,
148+ many = True ,
149+ context = {"request" : self .context ["request" ]},
150+ ).data
151+
152+ def get_fixed_vulnerabilities (self , package ):
153+ fixed_packages = self .get_fixed_packages (package = package )
154+ qs = package .vulnerabilities .filter (packagerelatedvulnerability__fix = True )
155+ qs = qs .prefetch_related (
156+ Prefetch (
157+ "packages" ,
158+ queryset = fixed_packages ,
159+ to_attr = "filtered_fixed_packages" ,
160+ )
161+ )
162+ return VulnSerializerRefsAndSummary (
163+ instance = qs ,
164+ many = True ,
165+ context = {"request" : self .context ["request" ]},
166+ ).data
139167
140168 class Meta :
141169 model = Package
@@ -149,7 +177,6 @@ class Meta:
149177 "qualifiers" ,
150178 "subpath" ,
151179 "affected_by_vulnerabilities" ,
152- "fixed_packages" ,
153180 "fixing_vulnerabilities" ,
154181 ]
155182
0 commit comments