Conversation
* updated views * updated urls.py Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
| class VulnerabilitySerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = Vulnerability | ||
| exclude = ('id', 'cvss') |
There was a problem hiding this comment.
Avoid using exclude, use fields instead, see https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#selecting-the-fields-to-use
It is strongly recommended that you explicitly set all fields that should be edited in the form using the fields attribute. Failure to do so can easily lead to security problems when a form unexpectedly allows a user to set certain fields, especially when new fields are added to a model.
| class VulnerabilityReferenceSerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = VulnerabilityReference | ||
| exclude = ('id', 'source', 'url', 'vulnerability') |
There was a problem hiding this comment.
Similar comment, use fields.
* use natural impactpackage link * add impact package link in data_dump Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
pombredanne
left a comment
There was a problem hiding this comment.
Looking good! Only a few comments to address and of course some tests
|
|
||
| from vulncode_app.models import Vulnerability | ||
| from vulncode_app.models import VulnerabilityReference | ||
| from vulncode_app.models import ImpactedPackage |
|
|
||
| from rest_framework import serializers | ||
|
|
||
| from vulncode_app.models import Vulnerability |
| from django.conf.urls import url | ||
|
|
||
| from . import views | ||
| from rest_framework.urlpatterns import format_suffix_patterns |
There was a problem hiding this comment.
Empty line needed after this
| urlpatterns = [ | ||
| url(r'(?P<name>[a-z]+)/(?P<version>[0-9]+)', views.package_version, name='package_version'), | ||
| url(r'^(?P<name>[a-z]+)', views.package, name='package'), | ||
| url(r'^cve-search/(?P<name>[a-z]+)/(?P<version>[0-9]+)', |
There was a problem hiding this comment.
Why do you call this cve-search?
There was a problem hiding this comment.
@pombredanne because it is getting its's data from CVE-SEARCH API, that we worked out in the beginning.
|
|
||
| pk = Package.objects.filter(name=package_name) | ||
|
|
||
| for i, v in enumerate(pk): |
There was a problem hiding this comment.
This is the wrong approach and should be handled by the proper serializers.
There was a problem hiding this comment.
@kartiksibal rather than for i, v in enumerate(pk): just iterate on the packages:
packages = Package.objects.filter(name=package_name)
for package in packages:
....
* use dict instead of sets in data output Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
|
|
||
| pk = Package.objects.filter(name=package_name) | ||
|
|
||
| for i, v in enumerate(pk): |
There was a problem hiding this comment.
you are still enumerating pk. Instead loop on packages:
for package in Package.objects.filter(name=package_name): ....
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
| """ | ||
| vulnerability = models.ForeignKey('Vulnerability') | ||
| package = models.ForeignKey('Package') | ||
| package_fk = models.ForeignKey('Package') |
There was a problem hiding this comment.
You should not rename this. This is a package object, not only a package_fk..
There was a problem hiding this comment.
Also since you updated the models, you need to run makemigrations to generate the new migrations alright.
There was a problem hiding this comment.
@pombredanne It was necessary to rename this since the reverse query name for Package.impacted_package clashes with ImpactedPackage.package
There was a problem hiding this comment.
What do you mean by clash? can you be more specific? at the db level? in code? where? provide an example with some stack/error trace.
In any case, package_fk is not a good name.
If a name change is really need to avoid some collision, then this would be the ManyToMany field name in Package that would need to be changed instead.
Or maybe what you are really returning in you API as a primary model is not a Package... but an ImpactedPackage instead which would be actually more natural, what do you think?
There was a problem hiding this comment.
And I'll take another look into it, before lodging a ticket.
There was a problem hiding this comment.
You also likely need a unique together on these two fields to avoid dupe entries
| class VulnerabilityReferenceSerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = VulnerabilityReference | ||
| fields = ('reference_id',) |
There was a problem hiding this comment.
You want to add the other reference fields too there.
|
|
||
|
|
||
| class PackageSerializer(serializers.ModelSerializer): | ||
| vulnerability = ImpactedPackageSerializer(source='impactedpackage_set', many=True) |
There was a problem hiding this comment.
This should be vulnerabilities, plural IMHO
* sort imports Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
|
|
||
| from vulncode_app.models import Vulnerability | ||
| from vulncode_app.models import VulnerabilityReference | ||
| from vulncode_app.models import ImpactedPackage |
pombredanne
left a comment
There was a problem hiding this comment.
I have added some comments.
Please check all import sort order...
Also the name collision that you experience is because the lack of plural.
| ) | ||
| impacted_package = ImpactedPackage.objects.create( | ||
| vulnerability=vulnerability, | ||
| package_fk=package |
There was a problem hiding this comment.
Do not call this package_fk in the model, but package.
| vulnerability=vulnerability, | ||
| package_fk=package | ||
| ) | ||
| package.impacted_package.add( |
There was a problem hiding this comment.
Why do you add this? You created it alright in line 46?
| ) | ||
| ImpactedPackage.objects.create( | ||
| vulnerability=vulnerability, | ||
| package_fk=package |
There was a problem hiding this comment.
Same as above: use package, not package_fk as an attribute name in the model
| @@ -50,13 +50,16 @@ class VulnerabilityReference(models.Model): | |||
| class Meta: | |||
| unique_together = ('vulnerability', 'source', 'reference_id') | |||
There was a problem hiding this comment.
Would not the URL also be part of the unique together? just a question, not sure. We can quite likely have multiple URLs for a source that refer to the same reference_id.
There was a problem hiding this comment.
I think more than one URL can point at a particular reference_id
There was a problem hiding this comment.
ok, then you need to update the unique together then?
There was a problem hiding this comment.
And you may want to check other models that may need updated unique together too
| """ | ||
| vulnerability = models.ForeignKey('Vulnerability') | ||
| package = models.ForeignKey('Package') | ||
| package_fk = models.ForeignKey('Package') |
There was a problem hiding this comment.
What do you mean by clash? can you be more specific? at the db level? in code? where? provide an example with some stack/error trace.
In any case, package_fk is not a good name.
If a name change is really need to avoid some collision, then this would be the ManyToMany field name in Package that would need to be changed instead.
Or maybe what you are really returning in you API as a primary model is not a Package... but an ImpactedPackage instead which would be actually more natural, what do you think?
| from rest_framework.response import Response | ||
| from rest_framework import status | ||
|
|
||
| from vulncode_app.serializers import PackageSerializer |
| def get(self, request, package_name): | ||
| pk = Package.objects.filter(name=package_name) | ||
| response = PackageSerializer(pk, many=True).data | ||
|
|
| response = PackageSerializer(pk, many=True).data | ||
|
|
||
| return Response(response) | ||
|
|
There was a problem hiding this comment.
Only one line between class methods
There was a problem hiding this comment.
Not a class method.
| from vulncode_app.models import Package | ||
| from vulncode_app.models import PackageReference | ||
| from vulncode_app.models import VulnerabilityReference | ||
| from vulncode_app.models import Vulnerability |
There was a problem hiding this comment.
Sort your imports, this comes before VulnerabilityReference
| impacted_package = models.ManyToManyField('ImpactedPackage') | ||
| platform = models.CharField(max_length=50, help_text='Package platform eg:maven', blank=True) | ||
| name = models.CharField(max_length=50, help_text='Package name', blank=True) | ||
| version = models.CharField(max_length=50, help_text='Package version', blank=True) |
There was a problem hiding this comment.
in the line below
def __str__(self):
return self.name
we likely need more than just name ... , but this is minor
|
|
||
| from django.test import TestCase | ||
| from rest_framework.response import Response | ||
| from collections import OrderedDict |
There was a problem hiding this comment.
e.g. this is stdlib and should not be in this block
|
Also you likely need to run makemigrations and commit the migrations for the model updates |
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
* remove M2M on package * rename package_fk to package Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
| @@ -50,13 +50,16 @@ class VulnerabilityReference(models.Model): | |||
| class Meta: | |||
| unique_together = ('vulnerability', 'source', 'reference_id') | |||
There was a problem hiding this comment.
ok, then you need to update the unique together then?
| @@ -50,13 +50,16 @@ class VulnerabilityReference(models.Model): | |||
| class Meta: | |||
| unique_together = ('vulnerability', 'source', 'reference_id') | |||
There was a problem hiding this comment.
And you may want to check other models that may need updated unique together too
* test blank response Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
* add url in vulnerability reference unique together Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
pombredanne
left a comment
There was a problem hiding this comment.
So I guess you removed the manytomany. Can you elaborate on this?
Also Would not the root of your seralizers be the impacted package in earnest? (that's not a big deal as the serialization would end up the same)
Finally I think you are missing the all important Resolved packages in your output
If you do not mind, to not force push future commits... it will be easier for review!
Thanks
| Package.objects.create( | ||
| package = Package.objects.create( | ||
| name=data.get('package_name', ''), | ||
| version=data.get('fixed_version', ''), |
There was a problem hiding this comment.
Based on our chat, does it ever make sense to create package without name and version or both empty values?
Also what about the platform field? Same for Ubuntu
| class PackageReferenceSerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = PackageReference | ||
| fields = ('name', 'version', 'repository', 'platform', ) |
There was a problem hiding this comment.
Can you keep the field order from the model?
| class VulnerabilityReferenceSerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = VulnerabilityReference | ||
| fields = ('reference_id', 'source', 'url') |
There was a problem hiding this comment.
Here and elsewhere, please keep the model fields order
| # Visit https://github.com/nexB/vulnerablecode/ for support and download. | ||
|
|
||
| import json | ||
|
|
There was a problem hiding this comment.
no empty lines between a block of imports from the same kind (here stdlib)
| 'summary', | ||
| 'Multiple stack-based buffer overflows in mimetex.cgi in mimeTeX' | ||
| ), | ||
| ('reference', |
There was a problem hiding this comment.
Should not this be plural "references"?
There was a problem hiding this comment.
atm, every reference contains a single reference id. So, I think not.
There was a problem hiding this comment.
My point is that there are multiple references, hence the list should be plural
Signed-off-by: Thomas Druez <tdruez@nexb.com>
|
@kartiksibal The API code is in much better shape now, thanks to using proper Serializers ;) I've made some cleanup in 8158a84 Some refinements are still needed from you before the merge:
Avoid using @pombredanne could you review the shape of the returned package data structure? |
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
pombredanne
left a comment
There was a problem hiding this comment.
Thanks! I added a few comments on the overall structure of the returned data
| debian_dump(extract_data) | ||
| response = self.client.get('/vulncode_app/api/mimetex', format='json') | ||
|
|
||
| expected = [{ |
There was a problem hiding this comment.
I would expect the returned payload to have some "header" data (e.g. some tool version, what was the query made, number of results returned, ... And to have the list of packages returned under the packages: element
| response = self.client.get('/vulncode_app/api/mimetex', format='json') | ||
|
|
||
| expected = [{ | ||
| "name": "mimetex", |
There was a problem hiding this comment.
May be we are missing other Package fields at the same level as this such as the "platform" ?
| "vulnerabilities": [{ | ||
| "vulnerability": { | ||
| "summary": "Multiple stack-based buffer overflows in mimetex.cgi in mimeTeX", | ||
| "reference": [{ |
There was a problem hiding this comment.
Should this be references (plural) and not reference, since this is also a list of mappings?
| "name": "mimetex", | ||
| "version": "1.50-1.1", | ||
| "vulnerabilities": [{ | ||
| "vulnerability": { |
There was a problem hiding this comment.
IMHO we do not need vulnerabilities/vulnerability
Only vulnerabilities as a list of mappings, each being a vulnerability since we only list these there. No need for an extra level of nesting and a "vulnerability" nested mapping?
- Following Django best-practices - Simplify the layout - Use proper naming convention Signed-off-by: Thomas Druez <tdruez@nexb.com>
Signed-off-by: Thomas Druez <tdruez@nexb.com>
Signed-off-by: Thomas Druez <tdruez@nexb.com>
| url(r'^cve-search/(?P<name>[a-z]+)', | ||
| views.package, | ||
| name='package'), | ||
| url(r'^api/(?P<package_name>[a-z]+)', |
There was a problem hiding this comment.
This pattern [a-z]+ is not good enough to catch real package names, for example: ruby1.9.1 and gcc-4.6. Use (?P<package_name>.+) instead.
Signed-off-by: Kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Signed-off-by: kartik sibal <kartiksibal@gmail.com>
Set the new 2m field on the PackageSerializer Signed-off-by: Thomas Druez <tdruez@nexb.com>
Create junction from Scripts to bin

Signed-off-by: Kartik sibal kartiksibal@gmail.com