Exemple #1
0
def create_notice():
    """
    POST method to create a new notice
    """

    notice_schema = NoticeSchema()
    notice_schema.context["release_codenames"] = [
        rel.codename for rel in db_session.query(Release).all()
    ]

    try:
        notice_data = notice_schema.load(flask.request.json)
    except ValidationError as error:
        return (
            flask.jsonify({
                "message": "Invalid payload",
                "errors": error.messages
            }),
            400,
        )

    db_session.add(
        _update_notice_object(Notice(id=notice_data["id"]), notice_data))

    try:
        db_session.commit()
    except IntegrityError:
        return (
            flask.jsonify(
                {"message": f"Notice {notice_data['id']} already exists"}),
            400,
        )

    return flask.jsonify({"message": "Notice created"}), 201
Exemple #2
0
def update_notice(notice_id):
    """
    PUT method to update a single notice
    """
    notice = db_session.query(Notice).get(notice_id)

    if not notice:
        return (
            flask.jsonify({"message": f"Notice {notice_id} doesn't exist"}),
            404,
        )

    notice_schema = NoticeSchema()
    notice_schema.context["release_codenames"] = [
        rel.codename for rel in db_session.query(Release).all()
    ]

    try:
        notice_data = notice_schema.load(flask.request.json, unknown=EXCLUDE)
    except ValidationError as error:
        return (
            flask.jsonify({
                "message": "Invalid payload",
                "errors": error.messages
            }),
            400,
        )

    notice = _update_notice_object(notice, notice_data)

    db_session.add(notice)
    db_session.commit()

    return flask.jsonify({"message": "Notice updated"}), 200
Exemple #3
0
def update_statuses(cve, data, packages):
    statuses = cve.packages

    statuses_query = db_session.query(Status).filter(Status.cve_id == cve.id)
    statuses_to_delete = {
        f"{v.package_name}||{v.release_codename}": v
        for v in statuses_query.all()
    }

    for package_data in data.get("packages", []):
        name = package_data["name"]

        if packages.get(name) is None:
            package = Package(name=name)
            package.source = package_data["source"]
            package.ubuntu = package_data["ubuntu"]
            package.debian = package_data["debian"]
            packages[name] = package

            db_session.add(package)

        for status_data in package_data["statuses"]:
            update_status = False
            codename = status_data["release_codename"]

            status = statuses[name].get(codename)
            if status is None:
                update_status = True
                status = Status(
                    cve_id=cve.id, package_name=name, release_codename=codename
                )
            elif f"{name}||{codename}" in statuses_to_delete:
                del statuses_to_delete[f"{name}||{codename}"]

            if status.status != status_data["status"]:
                update_status = True
                status.status = status_data["status"]

            if status.description != status_data["description"]:
                update_status = True
                status.description = status_data["description"]

            if status.component != status_data.get("component"):
                update_status = True
                status.component = status_data.get("component")

            if status.pocket != status_data.get("pocket"):
                update_status = True
                status.pocket = status_data.get("pocket")

            if update_status:
                statuses[name][codename] = status
                db_session.add(status)

    for key in statuses_to_delete:
        db_session.delete(statuses_to_delete[key])
Exemple #4
0
def create_release():
    """
    POST method to create a new release
    """

    release_schema = ReleaseSchema()

    try:
        release_data = release_schema.load(flask.request.json)
    except ValidationError as error:
        return (
            flask.jsonify(
                {"message": "Invalid payload", "errors": error.messages}
            ),
            400,
        )

    release = Release(
        codename=release_data["codename"],
        version=release_data["version"],
        name=release_data["name"],
        development=release_data["development"],
        lts=release_data["lts"],
        release_date=release_data["release_date"],
        esm_expires=release_data["esm_expires"],
        support_expires=release_data["support_expires"],
    )

    db_session.add(release)

    try:
        db_session.commit()
    except IntegrityError:
        return (
            flask.jsonify(
                {
                    "message": (
                        f"Release with [codename:'{release_data['codename']}']"
                        f" or [version:'{release_data['version']}'] or "
                        f"[name:'{release_data['name']}'] already exists"
                    )
                }
            ),
            400,
        )

    return flask.jsonify({"message": "Release created"}), 200
Exemple #5
0
def bulk_upsert_cve():
    """
    Receives a PUT request from load_cve.py
    Parses the object and bulk inserts or updates
    @returns 3 lists of CVEs, created CVEs, updated CVEs and failed CVEs
    """

    cves_schema = CVESchema(many=True)
    cves_schema.context["release_codenames"] = [
        rel.codename for rel in db_session.query(Release).all()
    ]

    try:
        cves_data = cves_schema.load(flask.request.json)
    except ValidationError as error:
        return (
            flask.jsonify({
                "message": "Invalid payload",
                "errors": error.messages
            }),
            400,
        )

    if len(cves_data) > 50:
        return (
            flask.jsonify({
                "message": ("Please only submit up to 50 CVEs at a time. "
                            f"({len(cves_data)} submitted)")
            }),
            413,
        )

    packages = {}
    for package in db_session.query(Package).all():
        packages[package.name] = package

    for data in cves_data:
        cve = db_session.query(CVE).get(data["id"]) or CVE(id=data["id"])

        cve.status = data.get("status")
        cve.published = data.get("published")
        cve.priority = data.get("priority")
        cve.cvss3 = data.get("cvss3")
        cve.description = data.get("description")
        cve.ubuntu_description = data.get("ubuntu_description")
        cve.notes = data.get("notes")
        cve.references = data.get("references")
        cve.bugs = data.get("bugs")

        statuses = update_statuses(cve,
                                   data,
                                   packages,
                                   releases=db_session.query(Release))

        db_session.add(cve)
        db_session.add_all(statuses)

    created = defaultdict(lambda: 0)
    updated = defaultdict(lambda: 0)

    for item in db_session.new:
        created[type(item).__name__] += 1

    for item in db_session.dirty:
        updated[type(item).__name__] += 1

    try:
        db_session.commit()
    except DataError as error:
        return (
            flask.jsonify({
                "message": "Failed bulk upserting session",
                "error": error.orig.args[0],
            }),
            400,
        )

    return (flask.jsonify({"created": created, "updated": updated}), 200)
Exemple #6
0
def load_releases():
    releases = [
        Release(
            codename="warty",
            version="4.10",
            name="Warty Warthog",
            development=False,
            lts=False,
            release_date=datetime.strptime("2004-10-20", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2004-10-20", "%Y-%m-%d"),
            support_expires=datetime.strptime("2004-10-20", "%Y-%m-%d"),
        ),
        Release(
            codename="hoary",
            version="5.04",
            name="Hoary Hedgehog",
            development=False,
            lts=False,
            release_date=datetime.strptime("2005-04-08", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2005-04-08", "%Y-%m-%d"),
            support_expires=datetime.strptime("2005-04-08", "%Y-%m-%d"),
        ),
        Release(
            codename="breezy",
            version="5.10",
            name="Breezy Badger",
            development=False,
            lts=False,
            release_date=datetime.strptime("2005-10-13", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2005-10-13", "%Y-%m-%d"),
            support_expires=datetime.strptime("2005-10-13", "%Y-%m-%d"),
        ),
        Release(
            codename="dapper",
            version="6.06",
            name="Dapper Drake",
            development=False,
            lts=True,
            release_date=datetime.strptime("2006-06-01", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2006-06-01", "%Y-%m-%d"),
            support_expires=datetime.strptime("2006-06-01", "%Y-%m-%d"),
        ),
        Release(
            codename="edgy",
            version="6.10",
            name="Edgy Eft",
            development=False,
            lts=False,
            release_date=datetime.strptime("2006-10-26", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2006-10-26", "%Y-%m-%d"),
            support_expires=datetime.strptime("2006-10-26", "%Y-%m-%d"),
        ),
        Release(
            codename="feisty",
            version="7.04",
            name="Feisty Fawn",
            development=False,
            lts=False,
            release_date=datetime.strptime("2007-04-19", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2007-04-19", "%Y-%m-%d"),
            support_expires=datetime.strptime("2007-04-19", "%Y-%m-%d"),
        ),
        Release(
            codename="gutsy",
            version="7.10",
            name="Gutsy Gibbon",
            development=False,
            lts=False,
            release_date=datetime.strptime("2007-10-18", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2007-10-18", "%Y-%m-%d"),
            support_expires=datetime.strptime("2007-10-18", "%Y-%m-%d"),
        ),
        Release(
            codename="hardy",
            version="8.04",
            name="Hardy Heron",
            development=False,
            lts=True,
            release_date=datetime.strptime("2008-04-24", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2008-04-24", "%Y-%m-%d"),
            support_expires=datetime.strptime("2008-04-24", "%Y-%m-%d"),
        ),
        Release(
            codename="intrepid",
            version="8.10",
            name="Intrepid Ibex",
            development=False,
            lts=False,
            release_date=datetime.strptime("2008-10-30", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2008-10-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2008-10-30", "%Y-%m-%d"),
        ),
        Release(
            codename="jaunty",
            version="9.04",
            name="Jaunty Jackalope",
            development=False,
            lts=False,
            release_date=datetime.strptime("2009-04-23", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2008-10-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2008-10-30", "%Y-%m-%d"),
        ),
        Release(
            codename="karmic",
            version="9.10",
            name="Karmic Koala",
            development=False,
            lts=False,
            release_date=datetime.strptime("2009-10-29", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2009-10-29", "%Y-%m-%d"),
            support_expires=datetime.strptime("2009-10-29", "%Y-%m-%d"),
        ),
        Release(
            codename="lucid",
            version="10.04",
            name="Lucid Lynx",
            development=False,
            lts=True,
            release_date=datetime.strptime("2010-04-29", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2010-04-29", "%Y-%m-%d"),
            support_expires=datetime.strptime("2010-04-29", "%Y-%m-%d"),
        ),
        Release(
            codename="maverick",
            version="10.10",
            name="Maverick Meerkat",
            development=False,
            lts=False,
            release_date=datetime.strptime("2010-10-10", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2010-10-10", "%Y-%m-%d"),
            support_expires=datetime.strptime("2010-10-10", "%Y-%m-%d"),
        ),
        Release(
            codename="natty",
            version="11.04",
            name="Natty Narwhal",
            development=False,
            lts=False,
            release_date=datetime.strptime("2011-04-28", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2011-04-28", "%Y-%m-%d"),
            support_expires=datetime.strptime("2011-04-28", "%Y-%m-%d"),
        ),
        Release(
            codename="oneiric",
            version="11.10",
            name="Oneiric Ocelot",
            development=False,
            lts=False,
            release_date=datetime.strptime("2011-10-13", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2011-10-13", "%Y-%m-%d"),
            support_expires=datetime.strptime("2011-10-13", "%Y-%m-%d"),
        ),
        Release(
            codename="precise",
            version="12.04",
            name="Precise Pangolin",
            development=False,
            lts=True,
            release_date=datetime.strptime("2012-04-26", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2021-04-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2012-04-26", "%Y-%m-%d"),
        ),
        Release(
            codename="quantal",
            version="12.10",
            name="Quantal Quetzal",
            development=False,
            lts=False,
            release_date=datetime.strptime("2012-10-18", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2012-10-18", "%Y-%m-%d"),
            support_expires=datetime.strptime("2012-10-18", "%Y-%m-%d"),
        ),
        Release(
            codename="raring",
            version="13.04",
            name="Raring Ringtail",
            development=False,
            lts=False,
            release_date=datetime.strptime("2013-04-25", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2013-04-25", "%Y-%m-%d"),
            support_expires=datetime.strptime("2013-04-25", "%Y-%m-%d"),
        ),
        Release(
            codename="saucy",
            version="13.10",
            name="Saucy Salamander",
            development=False,
            lts=False,
            release_date=datetime.strptime("2013-10-17", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2013-10-17", "%Y-%m-%d"),
            support_expires=datetime.strptime("2013-10-17", "%Y-%m-%d"),
        ),
        Release(
            codename="trusty",
            version="14.04",
            name="Trusty Tahr",
            development=False,
            lts=True,
            release_date=datetime.strptime("2014-04-17", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2022-04-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2019-04-30", "%Y-%m-%d"),
        ),
        Release(
            codename="utopic",
            version="14.10",
            name="Utopic Unicorn",
            development=False,
            lts=False,
            release_date=datetime.strptime("2014-10-23", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2014-10-23", "%Y-%m-%d"),
            support_expires=datetime.strptime("2014-10-23", "%Y-%m-%d"),
        ),
        Release(
            codename="vivid",
            version="15.04",
            name="Vivid Vervet",
            development=False,
            lts=False,
            release_date=datetime.strptime("2015-04-23", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2015-04-23", "%Y-%m-%d"),
            support_expires=datetime.strptime("2015-04-23", "%Y-%m-%d"),
        ),
        Release(
            codename="wily",
            version="15.10",
            name="Wily Werewolf",
            development=False,
            lts=False,
            release_date=datetime.strptime("2015-10-22", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2015-10-22", "%Y-%m-%d"),
            support_expires=datetime.strptime("2015-10-22", "%Y-%m-%d"),
        ),
        Release(
            codename="xenial",
            version="16.04",
            name="Xenial Xerus",
            development=False,
            lts=True,
            release_date=datetime.strptime("2016-04-21", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2024-04-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2021-04-30", "%Y-%m-%d"),
        ),
        Release(
            codename="yakkety",
            version="16.10",
            name="Yakkety Yak",
            development=False,
            lts=False,
            release_date=datetime.strptime("2016-10-13", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2016-10-13", "%Y-%m-%d"),
            support_expires=datetime.strptime("2016-10-13", "%Y-%m-%d"),
        ),
        Release(
            codename="zesty",
            version="17.04",
            name="Zesty Zapus",
            development=False,
            lts=False,
            release_date=datetime.strptime("2017-04-13", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2017-04-13", "%Y-%m-%d"),
            support_expires=datetime.strptime("2017-04-13", "%Y-%m-%d"),
        ),
        Release(
            codename="artful",
            version="17.10",
            name="Artful Aardvark",
            development=False,
            lts=False,
            release_date=datetime.strptime("2017-10-19", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2017-10-19", "%Y-%m-%d"),
            support_expires=datetime.strptime("2017-10-19", "%Y-%m-%d"),
        ),
        Release(
            codename="bionic",
            version="18.04",
            name="Bionic Beaver",
            development=False,
            lts=True,
            release_date=datetime.strptime("2018-04-26", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2028-04-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2023-04-30", "%Y-%m-%d"),
        ),
        Release(
            codename="cosmic",
            version="18.10",
            name="Cosmic Cuttlefish",
            development=False,
            lts=False,
            release_date=datetime.strptime("2018-10-18", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2018-10-18", "%Y-%m-%d"),
            support_expires=datetime.strptime("2018-10-18", "%Y-%m-%d"),
        ),
        Release(
            codename="disco",
            version="19.04",
            name="Disco Dingo",
            development=False,
            lts=False,
            release_date=datetime.strptime("2019-04-18", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2019-04-18", "%Y-%m-%d"),
            support_expires=datetime.strptime("2019-04-18", "%Y-%m-%d"),
        ),
        Release(
            codename="eoan",
            version="19.10",
            name="Eoan Ermine",
            development=False,
            lts=False,
            release_date=datetime.strptime("2019-10-17", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2020-07-31", "%Y-%m-%d"),
            support_expires=datetime.strptime("2019-10-17", "%Y-%m-%d"),
        ),
        Release(
            codename="focal",
            version="20.04",
            name="Focal Fossa",
            development=False,
            lts=True,
            release_date=datetime.strptime("2020-04-23", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2030-04-30", "%Y-%m-%d"),
            support_expires=datetime.strptime("2025-04-30", "%Y-%m-%d"),
        ),
        Release(
            codename="groovy",
            version="20.10",
            name="Groovy Gorilla",
            development=True,
            lts=False,
            release_date=datetime.strptime("2020-10-20", "%Y-%m-%d"),
            esm_expires=datetime.strptime("2021-07-31", "%Y-%m-%d"),
            support_expires=datetime.strptime("2021-07-31", "%Y-%m-%d"),
        ),
        Release(codename="upstream", name="Upstream"),
    ]

    for release in releases:
        exists = db_session.query(Release).get(release.codename)

        if not exists:
            db_session.add(release)

    db_session.commit()
Exemple #7
0
def update_notice():
    if not flask.request.json:
        return (flask.jsonify({"message": "No payload received"}), 400)

    notice_schema = NoticeSchema()
    try:
        data = notice_schema.load(flask.request.json, unknown=EXCLUDE)
    except ValidationError as error:
        return (
            flask.jsonify(
                {"message": "Invalid payload", "errors": error.messages}
            ),
            400,
        )

    notice = db_session.query(Notice).get(data["notice_id"])
    if not notice:
        return (
            flask.jsonify(
                {"message": f"Notice {data['notice_id']} doesn't exist"}
            ),
            404,
        )

    notice.title = data["title"]
    notice.summary = data["summary"]
    notice.details = data["description"]
    notice.packages = data["releases"]
    notice.published = datetime.fromtimestamp(data["timestamp"])

    if "action" in data:
        notice.instructions = data["action"]

    if "isummary" in data:
        notice.isummary = data["isummary"]

    # Clear m2m relations to re-add
    notice.cves.clear()
    notice.releases.clear()
    notice.references.clear()

    # Link releases
    for release_codename in data["releases"].keys():
        try:
            notice.releases.append(
                db_session.query(Release)
                .filter(Release.codename == release_codename)
                .one()
            )
        except NoResultFound:
            message = f"No release with codename: {release_codename}."
            return (flask.jsonify({"message": message}), 400)

    # Link CVEs, creating them if they don't exist
    refs = set(data.get("references", []))
    for ref in refs:
        if ref.startswith("CVE-"):
            cve_id = ref[4:]
            cve = db_session.query(CVE).get(cve_id)
            if not cve:
                cve = CVE(id=cve_id)
            notice.cves.append(cve)
        else:
            reference = (
                db_session.query(Reference)
                .filter(Reference.uri == ref)
                .first()
            )
            if not reference:
                reference = Reference(uri=ref)
            notice.references.append(reference)

    db_session.add(notice)
    db_session.commit()

    return flask.jsonify({"message": "Notice updated"}), 200
Exemple #8
0
def api_create_notice():
    if not flask.request.json:
        return (flask.jsonify({"message": f"No payload received"}), 400)

    # Because we get a dict with ID as a key and the payload as a value
    notice_id, payload = flask.request.json.popitem()

    notice = db_session.query(Notice).filter(Notice.id == notice_id).first()
    if notice:
        return (
            flask.jsonify({"message": f"Notice '{notice.id}' already exists"}),
            400,
        )

    notice_schema = NoticeSchema()

    try:
        data = notice_schema.load(payload, unknown=EXCLUDE)
    except ValidationError as error:
        return (
            flask.jsonify({
                "message": "Invalid payload",
                "errors": error.messages
            }),
            400,
        )

    notice = Notice(
        id=data["notice_id"],
        title=data["title"],
        summary=data["summary"],
        details=data["description"],
        packages=data["releases"],
        published=datetime.fromtimestamp(data["timestamp"]),
    )

    if "action" in data:
        notice.instructions = data["action"]

    if "isummary" in data:
        notice.isummary = data["isummary"]

    # Link releases
    for release_codename in data["releases"].keys():
        try:
            notice.releases.append(
                db_session.query(Release).filter(
                    Release.codename == release_codename).one())
        except NoResultFound:
            message = f"No release with codename: {release_codename}."
            return (flask.jsonify({"message": message}), 400)

    # Link CVEs, creating them if they don't exist
    refs = set(data.get("references", []))
    for ref in refs:
        if ref.startswith("CVE-"):
            cve_id = ref[4:]
            cve = db_session.query(CVE).filter(CVE.id == cve_id).first()
            if not cve:
                cve = CVE(id=cve_id)
            notice.cves.append(cve)
        else:
            reference = (db_session.query(Reference).filter(
                Reference.uri == ref).first())
            if not reference:
                reference = Reference(uri=ref)
            notice.references.append(reference)

    db_session.add(notice)
    db_session.commit()

    return flask.jsonify({"message": "Notice created"}), 201