def show_cve(cve, path=None): data = get_cve_data(cve) if not data: return not_found() return render_template('cve.html', title=data['issue'].id, issue=data['issue'], groups=data['groups'], group_packages=data['group_packages'], advisories=data['advisories'], can_edit=user_can_edit_issue(data['advisories']), can_delete=user_can_delete_issue( data['advisories']))
def show_cve(cve, path=None): data = get_cve_data(cve) if not data: return not_found() packages = list(set(sorted([item for sublist in data['group_packages'].values() for item in sublist]))) title = '{} - {}'.format(data['issue'].id, ' '.join(packages)) \ if len(packages) else \ '{}'.format(data['issue'].id) return render_template('cve.html', title=title, issue=data['issue'], groups=data['groups'], group_packages=data['group_packages'], advisories=data['advisories'], can_edit=user_can_edit_issue(data['advisories']), can_delete=user_can_delete_issue(data['advisories']))
def edit_cve(cve): entries = (db.session.query( CVE, CVEGroup, Advisory).filter(CVE.id == cve).outerjoin(CVEGroupEntry).outerjoin( CVEGroup).outerjoin(CVEGroupPackage).outerjoin( Advisory, Advisory.group_package_id == CVEGroupPackage.id)).all() if not entries: return not_found() cve = entries[0][0] groups = set(group for (cve, group, advisory) in entries if group) advisories = set(advisory for (cve, group, advisory) in entries if advisory) if not user_can_edit_issue(advisories): return forbidden() form = CVEForm(edit=True) if not form.is_submitted(): form.cve.data = cve.id form.issue_type.data = cve.issue_type form.description.data = cve.description form.severity.data = cve.severity.name form.remote.data = cve.remote.name form.reference.data = cve.reference form.notes.data = cve.notes if not form.validate_on_submit(): if advisories: flash( 'WARNING: This is referenced by an already published advisory!', 'warning') return render_template('form/cve.html', title='Edit {}'.format(cve), form=form, CVE=CVE) severity = Severity.fromstring(form.severity.data) severity_changed = cve.severity != severity issue_type_changed = cve.issue_type != form.issue_type.data cve.issue_type = form.issue_type.data cve.description = form.description.data cve.severity = severity cve.remote = Remote.fromstring(form.remote.data) cve.reference = form.reference.data cve.notes = form.notes.data if severity_changed or issue_type_changed: # update cached group severity for all goups containing this issue group_ids = [group.id for group in groups] issues = (db.session.query(CVEGroup, CVE).join(CVEGroupEntry).join(CVE).group_by( CVEGroup.id).group_by(CVE.id)) if group_ids: issues = issues.filter(CVEGroup.id.in_(group_ids)) issues = (issues).all() if severity_changed: group_severity = defaultdict(list) for group, issue in issues: group_severity[group].append(issue.severity) for group, severities in group_severity.items(): group.severity = highest_severity(severities) # update scheduled advisories if the issue type changes if advisories and issue_type_changed: group_issue_type = defaultdict(set) for group, issue in issues: group_issue_type[group].add(issue.issue_type) for advisory in advisories: if Publication.published == advisory.publication: continue issue_types = group_issue_type[advisory.group_package.group] issue_type = 'multiple issues' if len( issue_types) > 1 else next(iter(issue_types)) advisory.advisory_type = issue_type db.session.commit() flash('Edited {}'.format(cve.id)) return redirect('/{}'.format(cve.id))
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())