Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bfa5bc7
Add serializers based on models #8
kartiksibal Aug 14, 2017
89f2bb1
Add DRF to requirements.txt
kartiksibal Aug 14, 2017
c75ae67
Remove un-used imports #8
kartiksibal Aug 14, 2017
4d1c6c1
Merge branch 'json_api' of https://github.com/nexB/vulnerablecode int…
kartiksibal Aug 14, 2017
585327a
Change data output format #8
kartiksibal Aug 20, 2017
37d16b2
Change API data format to as discussed #8
kartiksibal Aug 21, 2017
96d6bfd
Add test cases and change data output format #8
kartiksibal Aug 22, 2017
0705c24
Updated serialization logic
kartiksibal Aug 23, 2017
f08d614
Add many to many field on Package #8
kartiksibal Aug 23, 2017
692d72d
Remove un-used imports #8
kartiksibal Aug 23, 2017
fcadb17
Add test cases #8
kartiksibal Aug 24, 2017
d41215d
New migrations #8
kartiksibal Aug 24, 2017
9015a68
Update models #8
kartiksibal Aug 24, 2017
bdcb807
Minor formatting changes #8
kartiksibal Aug 24, 2017
42c7be2
Add test cases #8
kartiksibal Aug 25, 2017
d1821c4
Update unique together #8
kartiksibal Aug 25, 2017
8158a84
Add missing migration file along some code cleanup #8
tdruez Sep 7, 2017
0317f8a
Move tests to vulncode_app/tests #8
kartiksibal Sep 12, 2017
d533162
Re-order serializers according to models #8
kartiksibal Sep 12, 2017
5469f99
change API url to api/ from data/ #8
kartiksibal Sep 12, 2017
0bf6354
Update travis according to new dir structure
kartiksibal Sep 12, 2017
9b277d6
Update tests according to changed api url #8
kartiksibal Sep 12, 2017
5d5f089
Merge branch 'json_api' of https://github.com/nexB/vulnerablecode int…
kartiksibal Sep 12, 2017
16ea31a
Update readme for API instructions #8
kartiksibal Sep 12, 2017
86c359a
Refactor the codebase structure
tdruez Sep 20, 2017
b016877
Fix failing tests following codebase structure changes
tdruez Sep 21, 2017
23fc544
Add back Gitter webhooks removed by mistake
tdruez Sep 21, 2017
a860bef
Update URL regex #8
kartiksibal Sep 22, 2017
c42a775
Included platform in package serializer #8
kartiksibal Sep 22, 2017
2d6d5eb
Update tests according to changes #8
kartiksibal Sep 22, 2017
2c5f78d
Add a `vulnerabilities` m2m field on the Package model
tdruez Sep 22, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ python: 3.6

install:
- pip install -r requirements.txt
- pip install pycodestyle

before_script:
- pycodestyle --exclude=migrations,settings.py,lib,tests --max-line-length=100 .
- cd app/
- python3 manage.py migrate
- ./manage.py migrate

script:
- python3.6 -m pytest -v tests/
- python3.6 manage.py test
- python3.6 -m pytest -v vulnerabilities/tests/test_scrapers.py vulnerabilities/tests/test_api_data.py
- ./manage.py test vulnerabilities/tests

notifications:
email: false
Expand Down
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,52 @@ Activate a virtualenv, install dependencies, and run the database migrations:
python3.6 -m venv .
source bin/activate
pip install -r requirements.txt
app/manage.py migrate
./manage.py migrate
```

Tests
-----

```
pycodestyle --exclude=migrations,settings.py,lib,tests --max-line-length=100 .
cd app/
python3.6 -m pytest -v tests/
python3.6 -m pytest -v vulnerabilities/tests/test_scrapers.py vulnerabilities/tests/test_api_data.py
```

For Django based tests
```
cd app/
./manage.py test
./manage.py test vulnerabilities/tests
```

Scrape and save to the database
-------------------------------

```
cd app/
./manage.py shell
```

```
from scraper import debian, ubuntu
from vulncode_app.data_dump import debian_dump, ubuntu_dump
from vulnerabilities.scraper import debian, ubuntu
from vulnerabilities.data_dump import debian_dump, ubuntu_dump

# May be needed on macOS
# import ssl; ssl._create_default_https_context = ssl._create_unverified_context

debian_vulnerabilities = debian.scrape_vulnerabilities()
ubuntu_cves = ubuntu.scrape_cves()
ubuntu_dump(ubuntu_cves)

debian_vulnerabilities = debian.scrape_vulnerabilities()
debian_dump(debian_vulnerabilities)
ubuntu_dump(ubuntu_cves)
```

API
----
Start the webserver

```
./manage.py runserver
```

In your browser access:
```
http://127.0.0.1:8000/vulnerabilities/api/<package_name>
```
2 changes: 1 addition & 1 deletion app/manage.py → manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "vulnerablecode.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
Expand Down
10 changes: 7 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
setuptools==36.5.0

beautifulsoup4==4.6.0
lxml==3.8.0
django==1.11.4
lxml==4.0.0
django==1.11.5
djangorestframework==3.6.4

# Tests
pytest==3.1.3
pytest==3.2.2
pycodestyle==2.3.1
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions app/vulncode_app/apps.py → vulnerabilities/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
from django.apps import AppConfig


class VulncodeAppConfig(AppConfig):
name = 'vulncode_app'
class VulnerabilitiesAppConfig(AppConfig):
name = 'vulnerabilities'
19 changes: 14 additions & 5 deletions app/vulncode_app/data_dump.py → vulnerabilities/data_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
# Visit https://github.com/nexB/vulnerablecode/ for support and download.

from vulncode_app.models import Vulnerability
from vulncode_app.models import VulnerabilityReference
from vulncode_app.models import Package
from vulnerabilities.models import ImpactedPackage
from vulnerabilities.models import Package
from vulnerabilities.models import Vulnerability
from vulnerabilities.models import VulnerabilityReference


def debian_dump(extract_data):
Expand All @@ -38,10 +39,14 @@ def debian_dump(extract_data):
vulnerability=vulnerability,
reference_id=data.get('vulnerability_id', ''),
)
Package.objects.create(
package = Package.objects.create(
name=data.get('package_name', ''),
version=data.get('fixed_version', ''),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refer: #29

)
ImpactedPackage.objects.create(
vulnerability=vulnerability,
package=package
)


def ubuntu_dump(html):
Expand All @@ -56,6 +61,10 @@ def ubuntu_dump(html):
vulnerability=vulnerability,
reference_id=data.get('cve_id'),
)
Package.objects.create(
package = Package.objects.create(
name=data.get('package_name'),
)
ImpactedPackage.objects.create(
vulnerability=vulnerability,
package=package
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-08 09:11
# Generated by Django 1.11.4 on 2017-09-20 22:34
from __future__ import unicode_literals

from django.db import migrations, models
Expand Down Expand Up @@ -37,14 +37,14 @@ class Migration(migrations.Migration):
('platform', models.CharField(blank=True, help_text='Platform eg:maven', max_length=50)),
('name', models.CharField(blank=True, help_text='Package reference name eg:org.apache.commons.io', max_length=50)),
('version', models.CharField(blank=True, help_text='Reference version', max_length=50)),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulncode_app.Package')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.Package')),
],
),
migrations.CreateModel(
name='ResolvedPackage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulncode_app.Package')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.Package')),
],
),
migrations.CreateModel(
Expand All @@ -59,29 +59,33 @@ class Migration(migrations.Migration):
name='VulnerabilityReference',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('source', models.CharField(blank=True, help_text="Source's name eg:NVD", max_length=50)),
('source', models.CharField(blank=True, help_text='Source(s) name eg:NVD', max_length=50)),
('reference_id', models.CharField(blank=True, help_text='Reference ID, eg:CVE-ID', max_length=50)),
('url', models.URLField(blank=True, help_text='URL of Vulnerability data', max_length=1024)),
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulncode_app.Vulnerability')),
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.Vulnerability')),
],
),
migrations.AddField(
model_name='resolvedpackage',
name='vulnerability',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulncode_app.Vulnerability'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.Vulnerability'),
),
migrations.AddField(
model_name='impactedpackage',
name='package',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulncode_app.Package'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.Package'),
),
migrations.AddField(
model_name='impactedpackage',
name='vulnerability',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulncode_app.Vulnerability'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.Vulnerability'),
),
migrations.AlterUniqueTogether(
name='vulnerabilityreference',
unique_together=set([('vulnerability', 'source', 'reference_id')]),
unique_together=set([('vulnerability', 'source', 'reference_id', 'url')]),
),
migrations.AlterUniqueTogether(
name='impactedpackage',
unique_together=set([('vulnerability', 'package')]),
),
]
20 changes: 20 additions & 0 deletions vulnerabilities/migrations/0002_package_vulnerabilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-22 19:18
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('vulnerabilities', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='package',
name='vulnerabilities',
field=models.ManyToManyField(through='vulnerabilities.ImpactedPackage', to='vulnerabilities.Vulnerability'),
),
]
File renamed without changes.
9 changes: 8 additions & 1 deletion app/vulncode_app/models.py → vulnerabilities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ class VulnerabilityReference(models.Model):
url = models.URLField(max_length=1024, help_text='URL of Vulnerability data', blank=True)

class Meta:
unique_together = ('vulnerability', 'source', 'reference_id')
unique_together = ('vulnerability', 'source', 'reference_id', 'url')

def __str__(self):
return self.source


class ImpactedPackage(models.Model):
Expand All @@ -58,6 +61,9 @@ class ImpactedPackage(models.Model):
vulnerability = models.ForeignKey('Vulnerability')
package = models.ForeignKey('Package')

class Meta:
unique_together = ('vulnerability', 'package')


class ResolvedPackage(models.Model):
"""
Expand All @@ -76,6 +82,7 @@ class Package(models.Model):
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)
vulnerabilities = models.ManyToManyField(to='Vulnerability', through='ImpactedPackage')

def __str__(self):
return self.name
Expand Down
File renamed without changes.
File renamed without changes.
57 changes: 57 additions & 0 deletions vulnerabilities/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#
# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
# http://nexb.com and https://github.com/nexB/vulnerablecode/
# The VulnerableCode software is licensed under the Apache License version 2.0.
# Data generated with VulnerableCode require an acknowledgment.
#
# You may not use this software except in compliance with the License.
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode
# derivative work, you must accompany this data with the following acknowledgment:
#
# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
# VulnerableCode should be considered or used as legal advice. Consult an Attorney
# for any legal advice.
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
# Visit https://github.com/nexB/vulnerablecode/ for support and download.

from rest_framework import serializers

from vulnerabilities.models import Package
from vulnerabilities.models import PackageReference
from vulnerabilities.models import Vulnerability
from vulnerabilities.models import VulnerabilityReference


class PackageReferenceSerializer(serializers.ModelSerializer):
class Meta:
model = PackageReference
fields = ('repository', 'platform', 'name', 'version')


class VulnerabilityReferenceSerializer(serializers.ModelSerializer):
class Meta:
model = VulnerabilityReference
fields = ('source', 'reference_id', 'url')


class VulnerabilitySerializer(serializers.ModelSerializer):
references = VulnerabilityReferenceSerializer(source='vulnerabilityreference_set', many=True)

class Meta:
model = Vulnerability
fields = ('summary', 'references')


class PackageSerializer(serializers.ModelSerializer):
vulnerabilities = VulnerabilitySerializer(many=True)

class Meta:
model = Package
fields = ('name', 'version', 'platform', 'vulnerabilities')
Loading