From 0cb56d93554926d087dfb696f608f9b51bfc7cfc Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Thu, 25 Jan 2018 21:59:13 +0100 Subject: Database:ify the list of security patches This finally moves the patches into the db, which makes it a lot easier to filter patches in the views. It also adds the new way of categorising patches, which is assigning them a CVSSv3 score. For now, there are no public views to this, and the old static pages remain. This is so we can backfill all existing security patches before we make it public. --- pgweb/security/admin.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 pgweb/security/admin.py (limited to 'pgweb/security/admin.py') diff --git a/pgweb/security/admin.py b/pgweb/security/admin.py new file mode 100644 index 00000000..7abe19c7 --- /dev/null +++ b/pgweb/security/admin.py @@ -0,0 +1,69 @@ +from django.contrib import admin +from django import forms +from django.db import models +from django.core.validators import ValidationError +from django.conf import settings + +from pgweb.core.models import Version +from pgweb.news.models import NewsArticle +from models import SecurityPatch, SecurityPatchVersion + +class VersionChoiceField(forms.ModelChoiceField): + def label_from_instance(self, obj): + return obj.numtree + +class SecurityPatchVersionAdminForm(forms.ModelForm): + model = SecurityPatchVersion + version = VersionChoiceField(queryset=Version.objects.filter(tree__gt=0), required=True) + +class SecurityPatchVersionAdmin(admin.TabularInline): + model = SecurityPatchVersion + extra = 2 + form = SecurityPatchVersionAdminForm + +class SecurityPatchForm(forms.ModelForm): + model = SecurityPatch + newspost = forms.ModelChoiceField(queryset=NewsArticle.objects.filter(org=settings.PGDG_ORG_ID), required=False) + + def clean(self): + d = super(SecurityPatchForm, self).clean() + vecs = [v for k,v in d.items() if k.startswith('vector_') and k != 'vector_other'] + empty = [v for v in vecs if v == ''] + if len(empty) != len(vecs) and len(empty) != 0: + for k in d.keys(): + if k.startswith('vector_') and k != 'vector_other': + self.add_error(k, 'Either specify all vector values or none') + if d['vector_other'] and len(empty) > 0: + self.add_error('vector_other', 'Cannot specify other vectors without base vectors') + return d + +class SecurityPatchAdmin(admin.ModelAdmin): + form = SecurityPatchForm + exclude = ['cvenumber', ] + inlines = (SecurityPatchVersionAdmin, ) + list_display = ('cve', 'public', 'cvssscore', 'legacyscore', 'cvssvector', 'description') + actions = ['make_public', 'make_unpublic'] + + def cvssvector(self, obj): + if not obj.cvssvector: + return '' + return '{0}'.format( + obj.cvssvector) + cvssvector.allow_tags = True + cvssvector.short_description = "CVSS vector link" + + def cvssscore(self, obj): + return obj.cvssscore + cvssscore.short_description = "CVSS score" + + def make_public(self, request, queryset): + self.do_public(queryset, True) + def make_unpublic(self, request, queryset): + self.do_public(queryset, False) + def do_public(self, queryset, val): + # Intentionally loop and do manually, so we generate change notices + for p in queryset.all(): + p.public=val + p.save() + +admin.site.register(SecurityPatch, SecurityPatchAdmin) -- cgit v1.2.3