Example #1
0
def test_analyze_vulnerability_release_not_found(db_request, metrics):
    project = ProjectFactory.create()
    ReleaseFactory.create(project=project, version="1.0")

    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    with pytest.raises(HTTPBadRequest):
        utils.analyze_vulnerability(
            request=db_request,
            vulnerability_report={
                "project": project.name,
                "versions": ["1", "2"],
                "id": "vuln_id",
                "link": "vulns.com/vuln_id",
                "aliases": ["vuln_alias"],
            },
            origin="test_report_source",
            metrics=metrics,
        )

    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
        (
            "warehouse.vulnerabilities.error.release_not_found",
            ("origin:test_report_source",),
        ): 2,
    }
Example #2
0
def test_analyze_vulnerability_no_versions(db_request, metrics):
    project = ProjectFactory.create()

    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    utils.analyze_vulnerability(
        request=db_request,
        vulnerability_report={
            "project": project.name,
            "versions": [],
            "id": "vuln_id",
            "link": "vulns.com/vuln_id",
            "aliases": ["vuln_alias"],
        },
        origin="test_report_source",
        metrics=metrics,
    )

    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1,
    }
Example #3
0
def test_analyze_vulnerability_project_not_found(db_request, metrics):
    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    with pytest.raises(NoResultFound):
        utils.analyze_vulnerability(
            request=db_request,
            vulnerability_report={
                "project": faker.Faker().text(max_nb_chars=8),
                "versions": ["1", "2"],
                "id": "vuln_id",
                "link": "vulns.com/vuln_id",
                "aliases": ["vuln_alias"],
            },
            origin="test_report_source",
            metrics=metrics,
        )

    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
        (
            "warehouse.vulnerabilities.error.project_not_found",
            ("origin:test_report_source",),
        ): 1,
    }
Example #4
0
def test_analyze_vulnerability_invalid_request(db_request, metrics):
    project = ProjectFactory.create()

    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    with pytest.raises(vulnerabilities.InvalidVulnerabilityReportError) as exc:
        utils.analyze_vulnerability(
            request=db_request,
            vulnerability_report={
                "project": project.name,
                "versions": ["1", "2"],
                # "id": "vuln_id",
                "link": "vulns.com/vuln_id",
                "aliases": ["vuln_alias"],
            },
            origin="test_report_source",
            metrics=metrics,
        )

    assert str(exc.value) == "Record is missing attribute(s): id"
    assert exc.value.reason == "format"
    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.error.format", ("origin:test_report_source",)): 1,
    }
Example #5
0
def analyze_vulnerability_task(request, vulnerability_report, origin):
    metrics = request.find_service(IMetricsService, context=None)
    utils.analyze_vulnerability(
        request=request,
        vulnerability_report=vulnerability_report,
        origin=origin,
        metrics=metrics,
    )
Example #6
0
def test_analyze_vulnerability_add_release(db_request, metrics):
    project = ProjectFactory.create()
    release1 = ReleaseFactory.create(project=project, version="1.0")
    release2 = ReleaseFactory.create(project=project, version="2.0")

    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    utils.analyze_vulnerability(
        request=db_request,
        vulnerability_report={
            "project": project.name,
            "versions": ["1.0"],
            "id": "vuln_id",
            "link": "vulns.com/vuln_id",
            "aliases": ["vuln_alias"],
        },
        origin="test_report_source",
        metrics=metrics,
    )

    assert len(release1.vulnerabilities) == 1
    assert len(release2.vulnerabilities) == 0
    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
    }

    metrics_counter.clear()

    utils.analyze_vulnerability(
        request=db_request,
        vulnerability_report={
            "project": project.name,
            "versions": ["1.0", "2.0"],  # Add 2.0
            "id": "vuln_id",
            "link": "vulns.com/vuln_id",
            "aliases": ["vuln_alias"],
        },
        origin="test_report_source",
        metrics=metrics,
    )

    assert len(release1.vulnerabilities) == 1
    assert len(release2.vulnerabilities) == 1
    assert release1.vulnerabilities[0] == release2.vulnerabilities[0]

    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
    }
Example #7
0
def test_analyze_vulnerability_unknown_error(db_request, monkeypatch, metrics):
    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    class UnknownError(Exception):
        pass

    def raise_unknown_err():
        raise UnknownError()

    vuln_report_from_api_request = pretend.call_recorder(
        lambda **k: raise_unknown_err())
    vuln_report_cls = pretend.stub(
        from_api_request=vuln_report_from_api_request)
    monkeypatch.setattr(vulnerabilities, "VulnerabilityReportRequest",
                        vuln_report_cls)

    with pytest.raises(UnknownError):
        utils.analyze_vulnerability(
            request=db_request,
            vulnerability_report={
                "project": "whatever",
                "versions": [],
                "id": "vuln_id",
                "link": "vulns.com/vuln_id",
                "aliases": ["vuln_alias"],
            },
            origin="test_report_source",
            metrics=metrics,
        )

    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source", )):
        1,
        ("warehouse.vulnerabilities.error.unknown", ("origin:test_report_source", )):
        1,
    }
Example #8
0
def test_analyze_vulnerability_delete_releases(db_request, metrics):
    project = ProjectFactory.create()
    release1 = ReleaseFactory.create(project=project, version="1.0")
    release2 = ReleaseFactory.create(project=project, version="2.0")

    metrics_counter = collections.Counter()

    def metrics_increment(key, tags):
        metrics_counter.update([(key, tuple(tags))])

    metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed)

    utils.analyze_vulnerability(
        request=db_request,
        vulnerability_report={
            "project": project.name,
            "versions": ["1.0", "2.0"],
            "id": "vuln_id",
            "link": "vulns.com/vuln_id",
            "aliases": ["vuln_alias"],
        },
        origin="test_report_source",
        metrics=metrics,
    )

    assert len(release1.vulnerabilities) == 1
    assert len(release2.vulnerabilities) == 1
    assert release1.vulnerabilities[0] == release2.vulnerabilities[0]

    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
    }

    metrics_counter.clear()

    utils.analyze_vulnerability(
        request=db_request,
        vulnerability_report={
            "project": project.name,
            "versions": ["1.0"],  # Remove v2 as vulnerable
            "id": "vuln_id",
            "link": "vulns.com/vuln_id",
            "aliases": ["vuln_alias"],
        },
        origin="test_report_source",
        metrics=metrics,
    )

    assert len(release1.vulnerabilities) == 1
    assert len(release2.vulnerabilities) == 0
    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
    }

    metrics_counter.clear()

    utils.analyze_vulnerability(
        request=db_request,
        vulnerability_report={
            "project": project.name,
            "versions": [],  # Remove all releases
            "id": "vuln_id",
            "link": "vulns.com/vuln_id",
            "aliases": ["vuln_alias"],
        },
        origin="test_report_source",
        metrics=metrics,
    )

    # Weird behavior, see:
    # https://docs.sqlalchemy.org/en/14/orm/cascades.html#notes-on-delete-deleting-objects-referenced-from-collections-and-scalar-relationships
    # assert len(release1.vulnerabilities) == 0
    assert len(release2.vulnerabilities) == 0
    assert metrics_counter == {
        ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1,
        ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1,
    }