Skip to content

Commit d5ab2fe

Browse files
authored
Merge pull request #57 from haikoschol/import-cli
Provide CLI for data import
2 parents 42f4668 + ec81273 commit d5ab2fe

4 files changed

Lines changed: 135 additions & 18 deletions

File tree

README.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,7 @@ DJANGO_DEV=1 python manage.py test vulnerabilities/tests
6565
## Data import
6666

6767
```
68-
DJANGO_DEV=1 python manage.py shell
69-
```
70-
71-
```
72-
from vulnerabilities.scraper import archlinux, debian, ubuntu
73-
from vulnerabilities.data_dump import archlinux_dump, debian_dump, ubuntu_dump
74-
75-
# May be needed on macOS
76-
# import ssl; ssl._create_default_https_context = ssl._create_unverified_context
77-
78-
ubuntu_cves = ubuntu.scrape_cves()
79-
ubuntu_dump(ubuntu_cves)
80-
81-
debian_vulnerabilities = debian.scrape_vulnerabilities()
82-
debian_dump(debian_vulnerabilities)
83-
84-
archlinux_vulnerabilities = archlinux.scrape_vulnerabilities()
85-
archlinux_dump(archlinux_vulnerabilities)
68+
DJANGO_DEV=1 python manage.py import --all
8669
```
8770

8871
## API
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#
2+
# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
3+
# http://nexb.com and https://github.com/nexB/vulnerablecode/
4+
# The VulnerableCode software is licensed under the Apache License version 2.0.
5+
# Data generated with VulnerableCode require an acknowledgment.
6+
#
7+
# You may not use this software except in compliance with the License.
8+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software distributed
10+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
# specific language governing permissions and limitations under the License.
13+
#
14+
# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode
15+
# derivative work, you must accompany this data with the following acknowledgment:
16+
#
17+
# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
18+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
19+
# VulnerableCode should be considered or used as legal advice. Consult an Attorney
20+
# for any legal advice.
21+
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
22+
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
23+
24+
from django.core.management.base import BaseCommand, CommandError
25+
26+
from vulnerabilities import data_dump as dd
27+
from vulnerabilities.scraper import debian, ubuntu, archlinux
28+
29+
IMPORTERS = {
30+
'debian': lambda: dd.debian_dump(debian.scrape_vulnerabilities()),
31+
'ubuntu': lambda: dd.ubuntu_dump(ubuntu.scrape_cves()),
32+
'archlinux': lambda: dd.archlinux_dump(archlinux.scrape_vulnerabilities()),
33+
}
34+
35+
36+
class Command(BaseCommand):
37+
help = 'Import vulnerability data'
38+
39+
def add_arguments(self, parser):
40+
parser.add_argument('--list', action='store_true', help='List available data sources')
41+
42+
parser.add_argument('--all', action='store_true',
43+
help='Import data from all available sources')
44+
45+
parser.add_argument('sources', nargs='*',
46+
help='Data sources from which to import')
47+
48+
def handle(self, *args, **options):
49+
if options['list']:
50+
self.list_sources()
51+
return
52+
53+
if options['all']:
54+
self.import_data(IMPORTERS.keys())
55+
return
56+
57+
sources = options['sources']
58+
if not sources:
59+
raise CommandError(
60+
'Please provide at least one data source to import from or use "--all".')
61+
62+
self.validate_sources(sources)
63+
self.import_data(sources)
64+
65+
def validate_sources(self, sources):
66+
unknown = ', '.join([s for s in sources if s not in IMPORTERS.keys()])
67+
if unknown:
68+
raise CommandError(f'Unknown data sources: {unknown}')
69+
70+
def list_sources(self):
71+
self.stdout.write('Vulnerability data can be imported from the following sources:')
72+
self.stdout.write(', '.join(IMPORTERS.keys()))
73+
74+
def import_data(self, sources):
75+
for src in sources:
76+
self.stdout.write(f'Importing data from {src}')
77+
IMPORTERS[src]()
78+
self.stdout.write(self.style.SUCCESS(f'Successfully imported data from {src}'))

vulnerabilities/scraper/__init__.py

Whitespace-only changes.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#
2+
# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
3+
# http://nexb.com and https://github.com/nexB/vulnerablecode/
4+
# The VulnerableCode software is licensed under the Apache License version 2.0.
5+
# Data generated with VulnerableCode require an acknowledgment.
6+
#
7+
# You may not use this software except in compliance with the License.
8+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software distributed
10+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
# specific language governing permissions and limitations under the License.
13+
#
14+
# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode
15+
# derivative work, you must accompany this data with the following acknowledgment:
16+
#
17+
# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
18+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
19+
# VulnerableCode should be considered or used as legal advice. Consult an Attorney
20+
# for any legal advice.
21+
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
22+
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
23+
24+
from io import StringIO
25+
26+
from django.core.management import call_command
27+
from django.core.management.base import CommandError
28+
from django.test import TestCase
29+
30+
31+
class ImportCommandTest(TestCase):
32+
def test_list_sources(self):
33+
buf = StringIO()
34+
35+
call_command('import', '--list', stdout=buf)
36+
37+
out = buf.getvalue()
38+
self.assertIn('debian', out)
39+
self.assertIn('ubuntu', out)
40+
self.assertIn('archlinux', out)
41+
42+
def test_missing_sources(self):
43+
with self.assertRaises(CommandError) as cm:
44+
call_command('import', stdout=StringIO())
45+
46+
err = str(cm.exception)
47+
self.assertIn('Please provide at least one data source', err)
48+
49+
def test_unknown_sources(self):
50+
with self.assertRaises(CommandError) as cm:
51+
call_command('import', 'debian', 'foo', 'bar', stdout=StringIO())
52+
53+
err = str(cm.exception)
54+
self.assertIn('bar', err)
55+
self.assertIn('foo', err)
56+
self.assertNotIn('debian', err)

0 commit comments

Comments
 (0)