diff options
author | Magnus Hagander | 2018-01-25 20:59:13 +0000 |
---|---|---|
committer | Magnus Hagander | 2018-01-25 20:59:13 +0000 |
commit | 0cb56d93554926d087dfb696f608f9b51bfc7cfc (patch) | |
tree | 208b180b049bee4ad4b263faa8ebb677d1a4d9be /pgweb/security/admin.py | |
parent | d0aa8ac11910e7352d83dfe281afebb57cfde554 (diff) |
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.
Diffstat (limited to 'pgweb/security/admin.py')
-rw-r--r-- | pgweb/security/admin.py | 69 |
1 files changed, 69 insertions, 0 deletions
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 '<a href="https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector={0}">{0}</a>'.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) |