def show_group(avg): data = get_group_data(avg) if not data: return not_found() group = data['group'] advisories = data['advisories'] if not current_user.role.is_reporter: advisories = list(filter(lambda advisory: advisory.publication == Publication.published, 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] pkgnames = list(set(sorted([pkg.pkgname for pkg in packages]))) form = AdvisoryForm() form.advisory_type.data = issue_type return render_template('group.html', title='{} - {}'.format(group, ' '.join(pkgnames)), 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), advisories_pending=data['advisories_pending'], can_edit=user_can_edit_group(advisories), can_delete=user_can_delete_group(advisories), can_handle_advisory=user_can_handle_advisory())
def todo(): entries = get_todo_data() return render_template('todo.html', title='Todo Lists', 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())
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, CVEGroup.issues) .join(CVE, CVEGroupEntry.cve) .join(CVEGroupPackage, CVEGroup.packages) .outerjoin(Advisory, Advisory.group_package_id == CVEGroupPackage.id) .group_by(CVEGroup.id).group_by(CVE.id).group_by(CVEGroupPackage.pkgname) .order_by(CVE.id)).all() if not group_data: return not_found() group = group_data[0][0] issues = set([cve for (group, cve, pkg, advisory) in group_data]) issue_ids = set([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 issue_ids = sorted(issue_ids, key=issue_to_numeric) 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)) issues_changed = any(issues_added) or any(issues_removed) # remove old issues for issue in filter(lambda issue: issue.cve_id in issues_removed, list(group.issues)): group.issues.remove(issue) flash('Removed {}'.format(issue.cve_id)) # add new issues severities = [issue.severity for issue in list(filter(lambda issue: issue.id not in issues_removed, issues))] for cve_id in issues_added: # TODO check if we can avoid this by the latter append call cve = db.get(CVE, id=cve_id) if not cve: cve = CVE.new(id=cve_id) db.get_or_create(CVEGroupEntry, group=group, cve=cve) flash('Added {}'.format(cve.id)) severities.append(cve.severity) issues_final.add(cve) 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)) pkgnames_changed = any(pkgnames_removed) or any(pkgnames_added) # remove old packages for pkg in filter(lambda pkg: pkg.pkgname in pkgnames_removed, list(group.packages)): group.packages.remove(pkg) flash('Removed {}'.format(pkg.pkgname)) # add new packages 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 # update changed date on modification if pkgnames_changed or issues_changed or db.session.is_modified(group): group.changed = datetime.utcnow() flash('Edited {}'.format(group.name)) db.session.commit() return redirect('/{}'.format(group.name))
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 Lists', 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())