Skip to content

Commit

Permalink
pylint
Browse files Browse the repository at this point in the history
  • Loading branch information
nilp0inter committed Sep 26, 2018
1 parent 82e9882 commit e3b6292
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 30 deletions.
8 changes: 5 additions & 3 deletions deeptracy/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,22 @@ class Artifact(BaseModel):
last_checked = peewee.DateTimeField(
null=True,
default=None,
help_text='Timestamp of the latest analysis performed for this artifact.')
help_text=('Timestamp of the latest analysis performed for '
'this artifact.'))

def analysis_needed(self):
if self.last_checked is None:
return True
else:
return self.last_checked < (datetime.datetime.utcnow()
+ Config.MAX_ANALYSIS_INTERVAL)

class Meta:
indexes = (
(('source', 'version', 'name'), True), # Unique Index
)



class Vulnerability(BaseModel):
artifact = peewee.ForeignKeyField(
Artifact,
Expand All @@ -125,7 +126,8 @@ class Vulnerability(BaseModel):
help_text='Extra information provided about the vulnerability.')
last_seen = peewee.DateTimeField(
default=datetime.datetime.utcnow,
help_text='Timestamp of the latest analysis detecting this vulnerability.')
help_text=('Timestamp of the latest analysis detecting '
'this vulnerability.'))

class Meta:
indexes = (
Expand Down
92 changes: 65 additions & 27 deletions deeptracy/providers.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
"""
This module contains the vulnerability providers.
"""
# pylint: disable=no-member,no-else-return
import collections
import datetime
import fnmatch
import functools
import json
import requests
import time

from playhouse.shortcuts import model_to_dict
import celery

from deeptracy import Config
from deeptracy import model
from deeptracy.model import Analysis
from deeptracy.model import Artifact
from deeptracy.model import Vulnerability
from deeptracy.tasks import app

Expand All @@ -34,24 +33,8 @@ def analyze_artifacts(artifacts):
Given a list of `Artifact` objects return a Celery group to analyze them.
"""
def group_by_provider(acc, entry):
artifact, providers = entry
for provider in providers:
acc[provider].add(artifact)
return acc

# [(artifact1, (provider1, provider2)),
# (artifact2, (provider2)),
# (artifact3, (provider1, provider3))]
providers_by_artifact = get_providers_for_artifacts(artifacts)

# {provider1: {artifact1, artifact3},
# provider2: {artifact1, artifact2},
# provider3: {artifact3}}
grouped_providers = functools.reduce(
group_by_provider,
providers_by_artifact,
collections.defaultdict(set))
grouped_providers = group_artifacts_by_provider(providers_by_artifact)

# group(provider1.s([artifact1{asdict}, artifact3{asdict}]),
# provider2.s([artifact1{asdict}, artifact2{asdict}]),
Expand All @@ -63,20 +46,72 @@ def group_by_provider(acc, entry):


def get_providers_for_artifacts(artifacts):
"""
Return a set of providers for each given artifact.
Given::
[artifact1, artifact2, artifact3]
Returns::
[(artifact1, (provider1, provider2)),
(artifact2, (provider2)),
(artifact3, (provider1, provider3))]
"""
for artifact in artifacts:
yield (artifact, providers_for_source(artifact.source))


def provider(pattern, enabled=True, **kwargs):
def _provider(f):
task = app.task(f)
def group_artifacts_by_provider(artifacts_with_providers):
"""
Return a dictionary with providers as keys and the set of artifact to check
for each one.
Given::
[(artifact1, (provider1, provider2)),
(artifact2, (provider2)),
(artifact3, (provider1, provider3))]
Returns::
{provider1: {artifact1, artifact3},
provider2: {artifact1, artifact2},
provider3: {artifact3}}
"""
def _group_by_provider(acc, entry):
artifact, providers = entry
for cprov in providers:
acc[cprov].add(artifact)
return acc

return functools.reduce(
_group_by_provider,
artifacts_with_providers,
collections.defaultdict(set))


def provider(pattern, enabled=True):
"""
Decorator to register new providers by pattern.
"""
def _provider(func):
task = app.task(func)
if enabled:
PROVIDERS[pattern].add(task)
return task
return _provider


def providers_for_source(source):
"""
Return the set of provider matching the given source.
"""
providers = set()
for pattern, fns in PROVIDERS.items():
if fnmatch.fnmatch(source, pattern):
Expand All @@ -90,7 +125,7 @@ def patton(method, dependencies):
response = requests.post(
(f"http://{Config.PATTON_HOST}/api/v1/"
f"check-dependencies?cpeDetailed=1"),
json={"method": "python",
json={"method": method,
"libraries": [{"library": dependency['name'],
"version": dependency['version']}
for dependency in dependencies]},
Expand All @@ -115,16 +150,19 @@ def patton(method, dependencies):

@provider("pypi")
def patton_python_provider(dependencies):
"""Pypi source is scanned with patton method `python`."""
patton("python", dependencies)


@provider("npm")
def patton_npm_provider(dependencies):
"""NPM source is scanned with patton method `simple_parser`."""
patton("simple_parser", dependencies)


@provider("pypi", enabled=WITH_SAFETY_LIB)
def safety_provider(dependencies):
"""Pypi source is scanned with `safety`."""
for dependency in dependencies:
packages = [safetyutil.Package(key=dependency['name'],
version=dependency['version'])]
Expand Down

0 comments on commit e3b6292

Please sign in to comment.