Esempio n. 1
0
def show_group(avg):
    data = get_group_data(avg)
    if not data:
        return not_found()

    group = data['group']
    advisories = data['advisories']
    issues = data['issues']
    packages = data['packages']
    issue_types = data['issue_types']
    versions = data['versions']
    issue_type = 'multiple issues' if len(issue_types) > 1 else issue_types[0]

    form = AdvisoryForm()
    form.advisory_type.data = issue_type

    return render_template('group.html',
                           title='{}'.format(group),
                           form=form,
                           group=group,
                           packages=packages,
                           issues=issues,
                           advisories=advisories,
                           versions=versions,
                           Status=Status,
                           issue_type=issue_type,
                           bug_data=get_bug_data(issues, packages, versions,
                                                 group),
                           advisory_pending=data['advisory_pending'],
                           can_edit=user_can_edit_group(advisories),
                           can_delete=user_can_delete_group(advisories),
                           can_handle_advisory=user_can_handle_advisory())
def edit_group(avg):
    group_id = avg.replace('AVG-', '')
    group_data = (db.session.query(
        CVEGroup, CVE, func.group_concat(CVEGroupPackage.pkgname, ' '),
        Advisory).filter(CVEGroup.id == group_id).join(CVEGroupEntry).join(
            CVE).join(CVEGroupPackage).outerjoin(
                Advisory,
                Advisory.group_package_id == CVEGroupPackage.id).group_by(
                    CVEGroup.id).group_by(CVE.id).order_by(CVE.id)).all()
    if not group_data:
        return not_found()

    group = group_data[0][0]
    issues = [cve for (group, cve, pkg, advisory) in group_data]
    issue_ids = [cve.id for cve in issues]
    pkgnames = set(
        chain.from_iterable(
            [pkg.split(' ') for (group, cve, pkg, advisory) in group_data]))
    advisories = set(advisory for (group, cve, pkg, advisory) in group_data
                     if advisory)

    if not user_can_edit_group(advisories):
        return forbidden()

    form = GroupForm(pkgnames)
    if not form.is_submitted():
        form.affected.data = group.affected
        form.fixed.data = group.fixed
        form.pkgnames.data = "\n".join(sorted(pkgnames))
        form.status.data = status_to_affected(group.status).name
        form.reference.data = group.reference
        form.notes.data = group.notes
        form.bug_ticket.data = group.bug_ticket
        form.advisory_qualified.data = group.advisory_qualified and group.status is not Status.not_affected

        form.cve.data = "\n".join(issue_ids)
    if not form.validate_on_submit():
        if advisories:
            flash(
                'WARNING: This is referenced by an already published advisory!',
                'warning')
        return render_template('form/group.html',
                               title='Edit {}'.format(avg),
                               form=form,
                               CVEGroup=CVEGroup)

    pkgnames_edited = multiline_to_list(form.pkgnames.data)
    group.affected = form.affected.data
    group.fixed = form.fixed.data
    group.status = affected_to_status(Affected.fromstring(form.status.data),
                                      pkgnames_edited[0], group.fixed)
    group.bug_ticket = form.bug_ticket.data
    group.reference = form.reference.data
    group.notes = form.notes.data
    group.advisory_qualified = form.advisory_qualified.data and group.status is not Status.not_affected

    cve_ids = multiline_to_list(form.cve.data)
    cve_ids = set(filter(lambda s: s.startswith('CVE-'), cve_ids))
    issues_removed = set(filter(lambda issue: issue not in cve_ids, issue_ids))
    issues_added = set(filter(lambda issue: issue not in issue_ids, cve_ids))
    issues_final = set(
        filter(lambda issue: issue.id not in issues_removed, issues))

    if issues_removed:
        (db.session.query(CVEGroupEntry).filter(
            CVEGroupEntry.group_id == group.id).filter(
                CVEGroupEntry.cve_id.in_(issues_removed)).delete(
                    synchronize_session=False))
        for removed in issues_removed:
            flash('Removed {}'.format(removed))

    severities = [
        issue.severity for issue in list(
            filter(lambda issue: issue.id not in issues_removed, issues))
    ]
    for cve_id in issues_added:
        cve = db.get_or_create(CVE, id=cve_id)
        db.get_or_create(CVEGroupEntry, group=group, cve=cve)
        severities.append(cve.severity)
        issues_final.add(cve)
        flash('Added {}'.format(cve.id))
    group.severity = highest_severity(severities)

    pkgnames_removed = set(
        filter(lambda pkgname: pkgname not in pkgnames_edited, pkgnames))
    pkgnames_added = set(
        filter(lambda pkgname: pkgname not in pkgnames, pkgnames_edited))

    if pkgnames_removed:
        (db.session.query(CVEGroupPackage).filter(
            CVEGroupPackage.group_id == group.id).filter(
                CVEGroupPackage.pkgname.in_(pkgnames_removed)).delete(
                    synchronize_session=False))
        for removed in pkgnames_removed:
            flash('Removed {}'.format(removed))

    for pkgname in pkgnames_added:
        db.get_or_create(CVEGroupPackage, pkgname=pkgname, group=group)
        flash('Added {}'.format(pkgname))

    # update scheduled advisories
    for advisory in advisories:
        if Publication.published == advisory.publication:
            continue
        issue_type = 'multiple issues' if len(
            set([issue.issue_type for issue in issues_final])) > 1 else next(
                iter(issues_final)).issue_type
        advisory.advisory_type = issue_type

    db.session.commit()
    flash('Edited {}'.format(group.name))
    return redirect('/{}'.format(group.name))
Esempio n. 3
0
def todo():
    incomplete_advisories = (db.session.query(Advisory, CVEGroupPackage, CVEGroup)
                             .join(CVEGroupPackage).join(CVEGroup)
                             .filter(and_(
                                 Advisory.publication == Publication.published,
                                 or_(Advisory.content == '', Advisory.content.is_(None),
                                     Advisory.reference == '', Advisory.reference.is_(None))))
                             .group_by(CVEGroupPackage.id)
                             .order_by(Advisory.created.desc())).all()

    scheduled_advisories = (db.session.query(Advisory, CVEGroupPackage, CVEGroup)
                            .join(CVEGroupPackage).join(CVEGroup)
                            .filter(Advisory.publication == Publication.scheduled)
                            .group_by(CVEGroupPackage.id)
                            .order_by(Advisory.created.desc())).all()

    unhandled_advisories = (db.session.query(CVEGroup, func.group_concat(CVEGroupPackage.pkgname, ' '))
                            .join(CVEGroupPackage)
                            .outerjoin(Advisory)
                            .filter(CVEGroup.advisory_qualified)
                            .filter(CVEGroup.status == Status.fixed)
                            .group_by(CVEGroup.id)
                            .having(func.count(Advisory.id) == 0)
                            .order_by(CVEGroup.id)).all()
    for index, item in enumerate(unhandled_advisories):
        unhandled_advisories[index] = (item[0], item[1].split(' '))
    unhandled_advisories = sorted(unhandled_advisories, key=lambda item: item[0].id)
    unhandled_advisories = sorted(unhandled_advisories, key=lambda item: item[0].severity)

    unknown_issues = (db.session.query(CVE)
                      .filter(or_(CVE.remote == Remote.unknown,
                                  CVE.severity == Severity.unknown,
                                  CVE.description.is_(None),
                                  CVE.description == '',
                                  CVE.issue_type.is_(None),
                                  CVE.issue_type == 'unknown'))
                      .order_by(CVE.id.desc())).all()

    unknown_groups = CVEGroup.query.filter(CVEGroup.status == Status.unknown).all()
    unknown_groups = (db.session.query(CVEGroup, Package)
                        .join(CVEGroupPackage).join(Package, Package.name == CVEGroupPackage.pkgname)
                        .filter(CVEGroup.status == Status.unknown)
                        .group_by(CVEGroupPackage.id)
                        .order_by(CVEGroup.created.desc())).all()

    unknown_groups_data = defaultdict(list)
    for group, package in unknown_groups:
        unknown_groups_data[group].append(package)
    unknown_groups = []
    for group, packages in unknown_groups_data.items():
        unknown_groups.append((group, packages))
    unknown_groups = sorted(unknown_groups, key=lambda item: item[0].id)

    vulnerable_groups = (db.session.query(CVEGroup, Package)
                         .join(CVEGroupPackage).join(Package, Package.name == CVEGroupPackage.pkgname)
                         .filter(CVEGroup.status == Status.vulnerable)
                         .filter(or_(CVEGroup.fixed is None, CVEGroup.fixed == ''))
                         .group_by(CVEGroup.id).group_by(Package.name, Package.version)
                         .order_by(CVEGroup.created.desc())).all()

    vulnerable_group_data = defaultdict(list)
    for group, package in vulnerable_groups:
        vulnerable_group_data[group].append(package)

    bumped_groups = []
    for group, packages in vulnerable_group_data.items():
        packages = sorted(packages, key=cmp_to_key(vercmp, attrgetter('version')), reverse=True)
        if 0 == vercmp(group.affected, packages[0].version):
            continue
        versions = filter_duplicate_packages(packages, filter_arch=True)
        pkgnames = set([pkg.name for pkg in packages])
        bumped_groups.append((group, pkgnames, versions))
    bumped_groups = sorted(bumped_groups, key=lambda item: item[0].id, reverse=True)
    bumped_groups = sorted(bumped_groups, key=lambda item: item[0].severity)

    orphan_issues = (db.session.query(CVE)
                       .outerjoin(CVEGroupEntry)
                       .group_by(CVE.id)
                       .having(func.count(CVEGroupEntry.id) == 0)
                       .order_by(CVE.id)).all()

    entries = {
        'scheduled_advisories': scheduled_advisories,
        'incomplete_advisories': incomplete_advisories,
        'unhandled_advisories': unhandled_advisories,
        'unknown_issues': unknown_issues,
        'unknown_groups': unknown_groups,
        'bumped_groups': bumped_groups,
        'orphan_issues': orphan_issues
    }
    return render_template('todo.html',
                           title='Todo リスト',
                           entries=entries,
                           smiley=smileys_happy[randint(0, len(smileys_happy) - 1)],
                           can_handle_advisory=user_can_handle_advisory(),
                           can_edit_group=user_can_edit_group(),
                           can_edit_issue=user_can_edit_issue())