aboutsummaryrefslogtreecommitdiffstats
path: root/lib/srtgui/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/srtgui/views.py')
-rw-r--r--lib/srtgui/views.py790
1 files changed, 623 insertions, 167 deletions
diff --git a/lib/srtgui/views.py b/lib/srtgui/views.py
index 48556b3b..6e215f33 100644
--- a/lib/srtgui/views.py
+++ b/lib/srtgui/views.py
@@ -2,9 +2,9 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
-# BitBake Toaster Implementation
+# Security Response Tool Implementation
#
-# Copyright (C) 2013 Intel Corporation
+# Copyright (C) 2017-2018 Wind River Systems
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -25,18 +25,24 @@ import re
from django.db.models import F, Q, Sum
from django.db import IntegrityError
from django.shortcuts import render, redirect, get_object_or_404
-from orm.models import Cve, CveHistory
-from orm.models import Vulnerability, VulnerabilityHistory, CveToVulnerablility, VulnerabilityProduct
-from orm.models import Investigation, InvestigationHistory, InvestigationToDefect
+from orm.models import Cve, CveDetail, CveHistory
+from orm.models import Vulnerability, VulnerabilityHistory, CveToVulnerablility, VulnerabilityProduct, VulnerabilityNotification, VulnerabilityAccess, VulnerabilityComments, VulnerabilityUploads
+from orm.models import Investigation, InvestigationHistory, InvestigationToDefect, InvestigationComments, InvestigationNotification, InvestigationAccess, InvestigationUploads
from orm.models import SrtSetting, CweTable, Product
-from orm.models import Investigation, DataSource, User, Access
-from orm.models import Defect
+from orm.models import Investigation, DataSource, User, UserSafe, Access
+from orm.models import Defect, PublishPending
+
+from srtgui.reports import ReportManager
+from srtgui.api import readCveDetails
from django.core.urlresolvers import reverse, resolve
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
-from django.http import HttpResponse, HttpResponseNotFound, JsonResponse
+from django.core.files.uploadedfile import UploadedFile
+from django.http import HttpResponse, HttpResponseNotFound, JsonResponse, HttpResponseRedirect
from django.utils import timezone
+from django import forms
+
from datetime import timedelta, datetime
from srtgui.templatetags.projecttags import json as jsonfilter
from decimal import Decimal
@@ -44,16 +50,16 @@ import json
import os
from os.path import dirname
import mimetypes
-import datetime
+import subprocess
import logging
+SRT_BASE_DIR = os.environ['SRT_BASE_DIR']
+
logger = logging.getLogger("srt")
-def _log(msg):
- f1=open('/tmp/srt.log', 'a')
- f1.write("|" + msg + "|\n" )
- f1.close()
+# quick development/debugging support
+from srtgui.api import _log
class MimeTypeFinder(object):
# setting this to False enables additional non-standard mimetypes
@@ -72,25 +78,31 @@ class MimeTypeFinder(object):
# single point to add global values into the context before rendering
def toaster_render(request, page, context):
-# context['project_enable'] = project_enable
+ # Share session's user name
+ srt_user_id = int(request.session.get('srt_user_id', '0'))
+ if 0 == srt_user_id:
+ srt_user_id = User.USER_GUEST
+ request.session['srt_user_id'] = srt_user_id
+ request.session.modified = True
+ context['srt_user_id'] = srt_user_id ### REMOVE
+ # Set normal access rights unless pre-empted by page
+ if not 'access' in context:
+ context['access'] = Access(srt_user_id)
return render(request, page, context)
# a context processor which runs on every request; this provides the
# projects and non_cli_projects (i.e. projects created by the user)
# variables referred to in templates, which used to determine the
-# visibility of UI elements like the "New build" button
+# visibility of UI elements like the "Management" button
def managedcontextprocessor(request):
ret = {
# "non_cli_projects": projects.exclude(is_default=True),
# "DEBUG" : srtmain.settings.DEBUG,
# "TOASTER_BRANCH": srtmain.settings.TOASTER_BRANCH,
# "TOASTER_REVISION" : srtmain.settings.TOASTER_REVISION,
- 'access' : Access(),
}
return ret
-
-# all new sessions should come through the landing page;
# determine in which mode we are running in, and redirect appropriately
def landing(request):
@@ -99,9 +111,7 @@ def landing(request):
# user_projects = Project.objects.filter(is_default = False)
# has_user_project = user_projects.count() > 0
- context = {
- 'lvs_nos' : 0,
- }
+ context = {}
return toaster_render(request, 'landing.html', context)
@@ -447,19 +457,18 @@ def _add_daterange_context(queryset_all, request, daterange_list):
def management(request):
# does this user have permission to see this record?
- userAccess = Access()
- if not userAccess.is_admin():
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if not userAccess.is_creator():
return redirect(landing)
context = {
- 'lvs_nos' : 0,
'cve_total' : Cve.objects.all().count(),
'cve_new' : Cve.objects.filter(status=Cve.NEW).count(),
'cve_open' : Cve.objects.filter( Q(status=Cve.INVESTIGATE) & Q(status=Cve.VULNERABLE) ).count(),
'vulnerability_total' : Vulnerability.objects.all().count(),
-
+
'vulnerability_open' : Vulnerability.objects.filter(outcome=Vulnerability.OPEN).count(),
'vulnerability_high' : Vulnerability.objects.filter(severity=Vulnerability.HIGH).count(),
'vulnerability_medium' : Vulnerability.objects.filter(severity=Vulnerability.MEDIUM).count(),
@@ -479,13 +488,19 @@ def management(request):
import copy
def cve(request, cve_pk, active_tab="1"):
template = "cve.html"
- if Cve.objects.filter(pk=cve_pk).count() == 0 :
- return redirect(landing)
- cve_object = Cve.objects.get(pk=cve_pk)
+ # CVE name or pk
+ try:
+ if cve_pk[0].isdigit():
+ cve_object = Cve.objects.get(pk=cve_pk)
+ else:
+ cve_object = Cve.objects.get(name=cve_pk)
+ cve_pk = cve_object.id
+ except:
+ return redirect(landing)
# does this user have permission to see this record?
- userAccess = Access()
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
if (not cve_object.public) and (not userAccess.is_admin()):
return redirect(landing)
@@ -500,61 +515,214 @@ def cve(request, cve_pk, active_tab="1"):
else:
response_link = str(investigation_records[0].pk)
+ # fetch CVE's detail information
+ cve_object_detail = readCveDetails(cve_object)
+ _log("FOO:%s" % cve_object_detail)
+
cve_summary = copy.copy(cve_object)
+ cve_summary_detail = copy.copy(cve_object_detail)
cve_summary.source = 'Summary'
-
- cve_local = Cve
+
+ cve_local = Cve()
+ cve_local_detail = CveDetail()
cve_local.source = 'Local'
-
+
context = {
- 'object' : { "name" : "CVE-1234"} ,
- 'cve_list_table' : [
- (cve_summary,tab_states['1'],"Summary"),
- (cve_object,tab_states['2'],"NIST"),
- (cve_local,tab_states['3'],"Local"),
+ 'object' : { "name" : "CVE-1234",
+ "id" : cve_object.id,
+ },
+ 'cve_list_table' : [
+ (cve_summary,cve_summary_detail,tab_states['1'],"Summary"),
+ (cve_object,cve_object_detail,tab_states['2'],"NIST"),
+ (cve_local,cve_local_detail,tab_states['3'],"Local"),
],
'tab_states' : tab_states,
'response_link' : response_link,
'cve_prev' : str(max(1,int(cve_pk)-1)),
'cve_next' : str(min(int(cve_pk)+1,Cve.objects.count()-1)),
}
- return render(request, template, context)
+ return toaster_render(request, template, context)
def vulnerability(request, vulnerability_pk):
- template = "vulnerability.html"
- if Vulnerability.objects.filter(pk=vulnerability_pk).count() == 0 :
- return redirect(landing)
+ if request.method == "GET":
+ template = "vulnerability.html"
- vulnerability_object = Vulnerability.objects.get(pk=vulnerability_pk)
+ # Defect name or pk
+ try:
+ if vulnerability_pk[0].isdigit():
+ vulnerability_object = Vulnerability.objects.get(pk=vulnerability_pk)
+ else:
+ vulnerability_object = Vulnerability.objects.get(name=vulnerability_pk)
+ vulnerability_pk = vulnerability_object.id
+ except:
+ return redirect(landing)
+
+ products = Product.objects.all()
+
+ # does this user have permission to see this record?
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if (not vulnerability_object.public) and (not userAccess.is_admin()):
+ return redirect(landing)
+
+ context = {
+ 'object' : vulnerability_object,
+ 'users' : UserSafe.get_safe_userlist(True),
+ 'products': products,
+ }
+ return toaster_render(request, template, context)
+ elif request.method == "POST":
+ _log("EXPORT_POST:VULERNABILITY_POST: %s" % request)
+
+ if request.POST["action"] == "upload":
+ if vulnerability_pk[0].isdigit():
+ vulnerability_object = Vulnerability.objects.get(pk=vulnerability_pk)
+ else:
+ vulnerability_object = Vulnerability.objects.get(name=vulnerability_pk)
+ vulnerability_pk = vulnerability_object.id
+ path = os.path.join(SRT_BASE_DIR, "downloads/%s" % vulnerability_object.name)
+ # Catch the post against this page
+ try:
+ os.makedirs(path)
+ except:
+ pass
+
+ try:
+ file = request.FILES['fileUpload']
+ description = request.POST['fileDescription']
+ except Exception as e:
+ _log("EXPORT_POST:'fileupload' does not exist: %s" % e)
+
+ try:
+ with open(path + "/" + file.name, 'xb+') as destination:
+ for line in file:
+ destination.write(line)
+
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ VulnerabilityUploads.objects.get_or_create(vulnerability_id=vulnerability_object.id, description=description, path=path + "/" + file.name, size=file.size, date=datetime.today().strftime('%Y-%m-%d'), author=userAccess.current_user_name)
+ except Exception as e:
+ _log("EXPORT_POST:FILE ALREADY EXISTS: %s" % e)
+ return redirect(vulnerability,vulnerability_pk)
+ elif request.POST["action"] == "download":
+ record_id = request.POST['record_id']
+ upload = VulnerabilityUploads.objects.get(id=record_id)
+ file_path = upload.path
+ if file_path:
+ fsock = open(file_path, "rb")
+ content_type = MimeTypeFinder.get_mimetype(file_path)
+ response = HttpResponse(fsock, content_type = content_type)
+ disposition = 'attachment; filename="{}"'.format(file_path)
+ response['Content-Disposition'] = 'attachment; filename="{}"'.format(file_path)
+ _log("EXPORT_POST_Q{%s} %s || %s " % (response, response['Content-Disposition'], disposition))
+ return response
+ else:
+ return toaster_render(request, "unavailable_artifact.html")
- # does this user have permission to see this record?
- userAccess = Access()
- if (not vulnerability_object.public) and (not userAccess.is_admin()):
+def investigation(request, investigation_pk):
+ if request.method == "GET":
+ template = "investigation.html"
+
+ # Investigation name or pk
+ try:
+ if investigation_pk[0].isdigit():
+ investigation_object = Investigation.objects.get(pk=investigation_pk)
+ else:
+ investigation_object = Investigation.objects.get(name=investigation_pk)
+ investigation_pk = investigation_object.id
+ except:
+ return redirect(landing)
+
+ defects = Defect.objects.all()
+ investigation_to_defect = investigation_object.investigation_to_defect.all()
+ context = {
+ 'object' : investigation_object,
+ 'users' : UserSafe.get_safe_userlist(True),
+ 'defects' : defects,
+ 'investigation_to_defect' : investigation_to_defect,
+ 'defect_example' : SrtSetting.objects.get(name='SRTOOL_DEFECT_SAMPLENAME').value,
+ }
+ return toaster_render(request, template, context)
+ elif request.method == "POST":
+ _log("EXPORT_POST:INVESTIGATION_POST: %s" % request)
+
+ if request.POST["action"] == "upload":
+ if investigation_pk[0].isdigit():
+ investigation_object = Investigation.objects.get(pk=investigation_pk)
+ else:
+ investigation_object = Investigation.objects.get(name=investigation_pk)
+ investigation_pk = investigation_object.id
+ path = os.path.join(SRT_BASE_DIR, "downloads/%s" % investigation_object.name)
+ # Catch the post against this page
+ try:
+ os.makedirs(path)
+ except:
+ pass
+
+ try:
+ file = request.FILES['fileUpload']
+ description = request.POST['fileDescription']
+ except Exception as e:
+ _log("EXPORT_POST:'fileupload' does not exist: %s" % e)
+
+ try:
+ with open(path + "/" + file.name, 'xb+') as destination:
+ for line in file:
+ destination.write(line)
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ InvestigationUploads.objects.get_or_create(investigation_id=investigation_object.id, description=description, path=path + "/" + file.name, size=file.size, date=datetime.today().strftime('%Y-%m-%d'), author=userAccess.current_user_name)
+ except Exception as e:
+ _log("EXPORT_POST:FILE ALREADY EXISTS: %s" % e)
+ return redirect(investigation,investigation_pk)
+ elif request.POST["action"] == "download":
+ record_id = request.POST['record_id']
+ upload = InvestigationUploads.objects.get(id=record_id)
+ file_path = upload.path
+ if file_path:
+ fsock = open(file_path, "rb")
+ content_type = MimeTypeFinder.get_mimetype(file_path)
+ response = HttpResponse(fsock, content_type = content_type)
+ disposition = 'attachment; filename="{}"'.format(file_path)
+ response['Content-Disposition'] = 'attachment; filename="{}"'.format(file_path)
+ _log("EXPORT_POST_Q{%s} %s || %s " % (response, response['Content-Disposition'], disposition))
+ return response
+ else:
+ return toaster_render(request, "unavailable_artifact.html")
+
+
+def defect(request, defect_pk):
+ template = "defect.html"
+
+ # Defect name or pk
+ try:
+ if defect_pk[0].isdigit():
+ defect_object = Defect.objects.get(pk=defect_pk)
+ else:
+ defect_object = Defect.objects.get(name=defect_pk)
+ defect_pk = defect_object.id
+ except:
return redirect(landing)
context = {
- 'object' : vulnerability_object,
-# 'cwe_table' : CweTable.objects.all(),
+ 'object' : defect_object,
+ 'users' : users,
}
- return render(request, template, context)
+ return toaster_render(request, template, context)
-def investigation(request, investigation_pk):
- template = "investigation.html"
- if Investigation.objects.filter(pk=investigation_pk).count() == 0 :
+def product(request, product_pk):
+ template = "product.html"
+ if Product.objects.filter(pk=product_pk).count() == 0 :
return redirect(landing)
- investigation_object = Investigation.objects.get(pk=investigation_pk)
+ product_object = Product.objects.get(pk=product_pk)
context = {
- 'object' : investigation_object,
-# 'cwe_table' : CweTable.objects.all(),
+ 'object' : product_object,
}
- return render(request, template, context)
+ return toaster_render(request, template, context)
def sources(request):
# does this user have permission to see this record?
- userAccess = Access()
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
if not userAccess.is_admin():
return redirect(landing)
@@ -567,41 +735,46 @@ def sources(request):
context = {
'object' : object,
}
- return render(request, template, context)
+ return toaster_render(request, template, context)
def login(request):
- template = "login.html"
- context = {
- 'object' : object,
- }
- return render(request, template, context)
+ if request.method == "GET":
+ template = "login.html"
+ object = User.objects.all()
+ context = {
+ 'object' : object,
+ 'user_count' : len(object),
+ }
+ return toaster_render(request, template, context)
+ elif request.method == "POST":
+ user_name = request.POST.get('username', '_anonuser')
+ user_name = re.sub(r"\(.*","",user_name).strip()
+ password = request.POST.get('password', 'nopass')
+ _log("LOGIN_POST:%s,%s" % (user_name,password))
-def _log(msg):
- f1=open('/tmp/srt.log', 'a')
- f1.write("|" + msg + "|\n" )
- f1.close()
+ try:
+ ### USER CONTROL
+ user = User.objects.get(name=user_name)
+ request.session['srt_user_id'] = user.id
+ request.session.modified = True
+
+ except Exception as e:
+ _log("LOGIN_ERROR:%s,%s" % (user,e))
+ pass
+ return redirect(landing)
+ #return landing(request)
-# TEMP ACCESS TEST CODE
+ raise Exception("Invalid HTTP method for this page")
+
+# This is effectively the logout command
def login_guest(request):
- current_user = SrtSetting.objects.get_or_create(name='current_user')[0]
- current_user.value = 1
- current_user.save()
- current_user_access = SrtSetting.objects.get_or_create(name='current_user_access')[0]
- current_user_access.value = User.READER
- current_user_access.save()
- return redirect(landing)
-def login_admin(request):
- current_user = SrtSetting.objects.get_or_create(name='current_user')[0]
- current_user.value = 3
- current_user.save()
- current_user_access = SrtSetting.objects.get_or_create(name='current_user_access')[0]
- current_user_access.value = User.ADMIN
- current_user_access.save()
+ request.session['srt_user_id'] = User.USER_GUEST
+ request.session.modified = True
return redirect(landing)
def users(request):
# does this user have permission to see this record?
- userAccess = Access()
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
if not userAccess.is_admin():
return redirect(landing)
@@ -615,37 +788,55 @@ def users(request):
context = {
'object' : object,
}
- return render(request, template, context)
-
-def export(request,page_name):
- context = {
- 'lvs_nos' : 0,
- 'page' : '%s%s' % (page_name[0:1].upper(),page_name[1:])
- }
- return toaster_render(request, 'export.html', context)
+ return toaster_render(request, template, context)
+
+def report(request,page_name):
+ if request.method == "GET":
+ context = ReportManager.get_context_data(page_name,request=request)
+ record_list = request.GET.get('record_list', '')
+ _log("EXPORT_GET!:%s|%s|" % (request,record_list))
+ context['record_list'] = record_list
+ return toaster_render(request, 'report.html', context)
+ elif request.method == "POST":
+ _log("EXPORT_POST!:%s|%s" % (request,request.FILES))
+ parent_page = request.POST.get('parent_page', '')
+ file_name,response_file_name = ReportManager.exec_report(parent_page,request=request)
+
+ if file_name and response_file_name:
+ fsock = open(file_name, "rb")
+ content_type = MimeTypeFinder.get_mimetype(file_name)
+
+ response = HttpResponse(fsock, content_type = content_type)
+
+ disposition = "attachment; filename=" + response_file_name
+ response["Content-Disposition"] = disposition
+
+ _log("EXPORT_POST_Q{%s|" % (response))
+ return response
+ else:
+ return toaster_render(request, "unavailable_artifact.html", {})
-def export_null(request):
- return export(request,"NuLl")
+ return redirect(landing)
+ raise Exception("Invalid HTTP method for this page")
def triage_cves(request):
# does this user have permission to see this record?
- userAccess = Access()
- if not userAccess.is_admin():
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if not userAccess.is_creator():
return redirect(landing)
- context = {'lvs_nos' : 0}
+ context = {}
return toaster_render(request, 'triage_cves.html', context)
-
def keywords(request):
# does this user have permission to see this record?
- userAccess = Access()
- if not userAccess.is_admin():
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if not userAccess.is_creator():
return redirect(landing)
-
+
for_list = SrtSetting.objects.get(name='keywords_for').value.split('|')
against_list = SrtSetting.objects.get(name='keywords_against').value.split('|')
- context = {'lvs_nos' : 0,
+ context = {
'for_list' : for_list,
'for_list_count' : len(for_list),
'against_list' : against_list,
@@ -653,87 +844,36 @@ def keywords(request):
}
return toaster_render(request, 'keywords.html', context)
-
-def start_select_cves(request):
- # pre-calculate the recommend values
- queryset = \
- Cve.objects.filter(status = Cve.NEW,name__startswith = 'CVE-2018-')
-
- KeywordsFor = SrtSetting.objects.get(name='keywords_for').value.split('|')
- KeywordsAgainst = SrtSetting.objects.get(name='keywords_against').value.split('|')
-
- for cve in queryset:
- description = ' '+cve.description.lower()+' '
- total = 0
- list = ''
-
- for keypair in KeywordsFor:
- #print("keypair='%s'" % keypair)
- key,w = keypair.split(',')
- weight = 1
-# if w:
-# weight = int(w)
- #if ' '+key+' ' in description:
- if re.search(r'\b%s\b' % key, description):
- list += ",+%s" % key
- total += weight
-
- for keypair in KeywordsAgainst:
- #print("keypair='%s'" % keypair)
- key,w = keypair.split(',')
- weight = 1
-# if w:
-# weight = int(w)
- # re.search(r'\bis\b', your_string)
- #if ' '+key+' ' in description:
- #if re.search(re.escape(r'\b%s\b' % key), description):
- if re.search(r'\b%s\b' % key, description):
- list += ",-%s" % key
- total -= weight
-
- # set filter maximums
- if total < -3:
- total = -3
- if total > 3:
- total = 3
- cve.recommend = total
- cve.comments_private = list[1:]
- cve.save()
-
- #_log("%s[%d]=%s" % (cve.name,cve.recommend,cve.comments_private))
-
- return redirect("/srtgui/select-cves")
-
def create_vulnerability(request):
# does this user have permission to see this record?
- userAccess = Access()
- if not userAccess.is_admin():
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if not userAccess.is_creator():
return redirect(landing)
- context = {'lvs_nos' : 0}
+ context = {}
return toaster_render(request, 'create_vulnerability.html', context)
def publish(request):
# does this user have permission to see this record?
- userAccess = Access()
- if not userAccess.is_admin():
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if not userAccess.is_creator():
return redirect(landing)
- context = {'lvs_nos' : 0}
+ context = {}
return toaster_render(request, 'publish.html', context)
def manage_report(request):
# does this user have permission to see this record?
- userAccess = Access()
- if not userAccess.is_admin():
+ userAccess = Access(int(request.session.get('srt_user_id', '0')))
+ if not userAccess.is_creator():
return redirect(landing)
- return redirect(export,'management')
+ return redirect(report,'management')
def guided_tour(request):
- context = {'lvs_nos' : 0}
+ context = {}
return toaster_render(request, 'guided_tour.html', context)
-
+
def quicklink(request):
current_user = SrtSetting.objects.get_or_create(name='current_user')[0]
current_user.value = 16
@@ -741,7 +881,7 @@ def quicklink(request):
current_user_access = SrtSetting.objects.get_or_create(name='current_user_access')[0]
current_user_access.value = User.ADMIN
current_user_access.save()
- return redirect("/srtgui/start-select-cves")
+ return redirect("/srtgui/select-publish")
def xhr_triage_commit(request):
_log("xhr_triage_commit(%s)" % request.POST)
@@ -752,7 +892,7 @@ def xhr_triage_commit(request):
author_name = User.objects.get(pk=author_id).name
action = request.POST['action']
- today = datetime.datetime.today().strftime("%Y-%m-%d")
+ today = datetime.today().strftime("%Y-%m-%d")
if 'submit-notvulnerable' == action:
reason = request.POST['reason']
cves = request.POST['cves']
@@ -786,10 +926,11 @@ def xhr_triage_commit(request):
first_vulnerability = True
investigation_names = {}
for cve_name in cves[:-1].split(','):
-
+
# update CVE
cve = Cve.objects.get(name=cve_name)
cve.status = Cve.VULNERABLE
+ cve.priority = severity
if cve.comments:
cve.comments += ', ' + reason
else:
@@ -864,7 +1005,322 @@ def xhr_triage_commit(request):
_log("xhr_triage_commit:no(%s)" % e)
return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
+def xhr_cve_commit(request):
+ _log("xhr_cve_commit(%s)" % request.POST)
+ if not 'action' in request.POST:
+ return HttpResponse(json.dumps({"error":"missing action\n"}), content_type = "application/json")
+ try:
+ cve = Cve.objects.get(id=request.POST['cve_id'])
+ action = request.POST['action']
+ history_comment = ''
+ if 'submit-quickedit' == action:
+ note = request.POST['note']
+ priority = int(request.POST['priority'])
+ private_note = request.POST['private_note']
+ publish_state = request.POST['publish_state']
+ publish_date = request.POST['publish_date']
+ if (priority != cve.priority):
+ cve.priority = priority
+ history_comment += "Priority, "
+ if (note != cve.comments):
+ cve.comments = note
+ history_comment += "Note, "
+ if (private_note != cve.comments_private):
+ cve.comments_private = private_note
+ history_comment += "Private Note, "
+ if (publish_state != cve.publish_state):
+ cve.publish_state = publish_state
+ history_comment += "Publish State, "
+ if (publish_date != cve.publish_date):
+ cve.publish_date = publish_date
+ history_comment += "Publish Date, "
+ cve.save()
+ return_data = {
+ "error": "ok",
+ }
+
+ access = Access(int(request.session.get('srt_user_id', '0')))
+ if (history_comment != ''):
+ history_comment = history_comment[:-2]
+ history_comment += " edited"
+ CveHistory.objects.create(cve_id=cve.id, comment=history_comment, date=datetime.now().strftime('%Y-%m-%d'), author=access.current_user_name)
+ _log("xhr_cve_commit:SUCCESS")
+ return HttpResponse(json.dumps( return_data ), content_type = "application/json")
+
+ except Exception as e:
+ _log("xhr_cve_commit:no(%s)" % e)
+ return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
+
+def xhr_cve_publish_commit(request):
+ _log("xhr_cve_publish_commit(%s)" % request.POST)
+ cve_list = request.POST['cve_list']
+ publish_state = int(request.POST['publish_state'])
+ _log("xhr_cve_publish_commit2")
+ try:
+ for name in cve_list.split(','):
+ _log("xhr_cve_publish_commit3:%s" % name)
+ if name:
+ _log("xhr_cve_publish_commit4")
+ cve = Cve.objects.get(name=name)
+ cve.publish_state = publish_state
+ cve.save()
+ _log("xhr_cve_publish_commit5")
+ # Add to publish pending queue?
+ if Cve.PUBLISH_SUBMITTED == publish_state:
+ _log("xhr_cve_publish_commit5a")
+ pub_req,created = PublishPending.objects.get_or_create(cve=cve)
+ pub_req.date=datetime.today().strftime('%Y-%m-%d')
+ pub_req.save()
+ _log("xhr_cve_publish_commit5b")
+ # Remove from publish pending queue?
+ if Cve.PUBLISH_PUBLISHED == publish_state:
+ _log("xhr_cve_publish_commit5c")
+ try:
+ pub_req = PublishPending.objects.get(cve=cve)
+ pub_req.delete()
+ except:
+ pass
+ _log("xhr_cve_publish_commit5d")
+ _log("xhr_cve_publish_commit6")
+ return_data = {
+ "error": "ok",
+ }
+ return HttpResponse(json.dumps( return_data ), content_type = "application/json")
+ except Exception as e:
+ _log("xhr_cve_publish_commit:no(%s)" % e)
+ return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
+
+def xhr_vulnerability_commit(request):
+ _log("xhr_vulnerability_commit(%s)" % request.POST)
+ if not 'action' in request.POST:
+ return HttpResponse(json.dumps({"error":"missing action\n"}), content_type = "application/json")
+
+ action = request.POST['action']
+ v_id = request.POST['vulnerability_id']
+ access = Access(int(request.session.get('srt_user_id', '0')))
+ history_comment = ''
+ try:
+ if 'submit-quickedit' == action:
+ note = request.POST['note']
+ private_note = request.POST['private_note']
+ v = Vulnerability.objects.get(id=v_id)
+ if (v.comments != note):
+ v.comments = note
+ history_comment += "Note, "
+ if (v.comments_private != private_note):
+ v.comments_private = private_note
+ history_comment += "Private Note, "
+ if (v.status != request.POST['status']):
+ v.status = request.POST['status']
+ history_comment += "Status, "
+ if (v.outcome != request.POST['outcome']):
+ v.outcome = request.POST['outcome']
+ history_comment += "Outcome, "
+ if (v.severity != request.POST['severity']):
+ v.severity = request.POST['severity']
+ history_comment += "Severity, "
+ if (history_comment != ''):
+ history_comment = history_comment[:-2]
+ history_comment += " edited"
+ v.save()
+
+ if 'submit-addrelatedproduct' == action:
+ products = request.POST['products']
+ product_names = ''
+ for product_id in products[:-1].split(','):
+ tmp = Product.objects.get(pk=product_id)
+ product_names += tmp.name + ' ' + tmp.version + ', '
+ VulnerabilityProduct.objects.get_or_create(vulnerability_id=v_id, product_id=product_id, relation=1)
+ product_names = product_names[:-2]
+ history_comment = product_names + " added to related products"
+ if 'submit-trashrelated' == action:
+ record_id = request.POST['record_id']
+ record = VulnerabilityProduct.objects.get(id=record_id)
+ product = Product.objects.get(id=record.product_id)
+ history_comment = product.name + ' ' + product.version + " removed from related products"
+ record.delete()
+ if 'submit-addaffectedproduct' == action:
+ products = request.POST['products']
+ product_names = ''
+ for product_id in products[:-1].split(','):
+ tmp = Product.objects.get(pk=product_id)
+ product_names += tmp.name + ' ' + tmp.version + ', '
+ VulnerabilityProduct.objects.get_or_create(vulnerability_id=v_id, product_id=product_id, relation=0)
+ product_names = product_names[:-2]
+ history_comment = product_names + " added to affected products"
+ if 'submit-trashaffected' == action:
+ record_id = request.POST['record_id']
+ record = VulnerabilityProduct.objects.get(id=record_id)
+ product = Product.objects.get(id=record.product_id)
+ history_comment = product.name + ' ' + product.version + " removed from afftected products"
+ record.delete()
+ if 'submit-newcomment' == action:
+ comment = request.POST['comment']
+ VulnerabilityComments.objects.create(vulnerability_id=v_id, comment=comment, date=datetime.today().strftime('%Y-%m-%d'), author=access.current_user_name)
+ history_comment = "New comment submitted"
+ if 'submit-trashcomment' == action:
+ record_id = request.POST['record_id']
+ comment = VulnerabilityComments.objects.get(id=record_id)
+ history_comment = "Comment from " + comment.author + " deleted"
+ comment.delete()
+ if 'submit-trashattachment' == action:
+ record_id = request.POST['record_id']
+ upload = VulnerabilityUploads.objects.get(id=record_id)
+ history_comment = "Upload '" + upload.description + "' from " + upload.author + " deleted"
+ try:
+ os.remove(upload.path)
+ except OSError:
+ pass
+ upload.delete()
+ if 'submit-addusernotify' == action:
+ users = request.POST['users']
+ usernames = ''
+ for user_id in users[:-1].split(','):
+ usernames += User.objects.get(pk=user_id).name + ', '
+ VulnerabilityNotification.objects.get_or_create(vulnerability_id=v_id, user_id=user_id)
+ usernames = usernames[:-2]
+ history_comment = usernames + " added to notifications"
+ if 'submit-trashusernotification' == action:
+ record_id = request.POST['record_id']
+ notification_record = VulnerabilityNotification.objects.get(id=record_id)
+ removed_user = User.objects.get(pk=notification_record.user_id).name
+ history_comment = removed_user + " removed from notifications"
+ notification_record.delete()
+ if 'submit-adduseraccess' == action:
+ users = request.POST['users']
+ usernames = ''
+ for user_id in users[:-1].split(','):
+ usernames += User.objects.get(pk=user_id).name + ', '
+ VulnerabilityAccess.objects.get_or_create(vulnerability_id=v_id, user_id=user_id)
+ usernames = usernames[:-2]
+ history_comment = usernames + " granted access"
+ if 'submit-trashuseraccess' == action:
+ record_id = request.POST['record_id']
+ access_record = VulnerabilityAccess.objects.get(id=record_id)
+ removed_user = User.objects.get(pk=access_record.user_id).name
+ history_comment = removed_user + "'s access removed"
+ access_record.delete()
+ if (history_comment != ''):
+ VulnerabilityHistory.objects.create(vulnerability_id=v_id, comment=history_comment, date=datetime.now().strftime('%Y-%m-%d'), author=access.current_user_name)
+ return_data = {
+ "error": "ok",
+ }
+ return HttpResponse(json.dumps( return_data ), content_type = "application/json")
+ except Exception as e:
+ _log("xhr_vulnerability_commit:no(%s)" % e)
+ return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
+
+def xhr_investigation_commit(request):
+ _log("xhr_investigation_commit(%s)" % request.POST)
+ if not 'action' in request.POST:
+ return HttpResponse(json.dumps({"error":"missing action\n"}), content_type = "application/json")
+
+ action = request.POST['action']
+ invst_id = request.POST['investigation_id']
+ access = Access(int(request.session.get('srt_user_id', '0')))
+ history_comment = "Nothing happened."
+ try:
+ if 'submit-attachdefectlist' == action:
+ defects = request.POST['defects']
+ product_id = Investigation.objects.get(id=invst_id).product_id
+ defect_names = ""
+ for defect_id in defects[:-1].split(','):
+ defect_names += Defect.objects.get(pk=defect_id).name + ", "
+ InvestigationToDefect.objects.get_or_create(investigation_id=invst_id, defect_id=defect_id)
+ defect_names = defect_names[:-2]
+ history_comment = defect_names + " added to defects"
+ if 'submit-attachdefect' == action:
+ query = request.POST['query'].upper()
+ product_id = Investigation.objects.get(id=invst_id).product_id
+ #check if defect already in SRTool data
+ try:
+ defect = Defect.objects.get(name=query)
+ except Defect.DoesNotExist:
+ defect = None
+
+ #If defect not in SRTool, import data from Defect database and create record
+ if defect is None:
+ #try connecting to defect management tool
+ try:
+ cmd_list = SrtSetting.objects.get(name='SRTOOL_DEFECT_ADD').value.split(' ')
+ cmd_list.append(query)
+ result = subprocess.run(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if 0 == result.returncode:
+ defect = Defect.objects.get(name=query)
+ else:
+ defect = None
+ return HttpResponse(json.dumps({"error":str(e) + "\n"}), content_type = "application/json")
+ except Exception as e:
+ _log("xhr_investigation_commit:Error in defect attach query:(%s)\n" % e)
+ return HttpResponse(json.dumps({"error":str(e) + "\n"}), content_type = "application/json")
+ if defect:
+ InvestigationToDefect.objects.get_or_create(investigation_id=invst_id, defect_id=defect.id, product_id=product_id)
+ history_comment = "Attached " + defect.name
+ if 'submit-trashdefect' == action:
+ defects = request.POST['defects']
+ product_id = Investigation.objects.get(id=invst_id).product_id
+ defect_names = ""
+ for defect_id in defects[:-1].split(','):
+ defect_names += Defect.objects.get(pk=defect_id).name + ", "
+ InvestigationToDefect.objects.get(investigation_id=invst_id, defect_id=defect_id).delete()
+ defect_names = defect_names[:-2]
+ history_comment = defect_names + " deleted from defects"
+ if 'submit-newcomment' == action:
+ comment = request.POST['comment']
+ InvestigationComments.objects.create(investigation_id=invst_id, comment=comment, date=datetime.today().strftime('%Y-%m-%d'), author=access.current_user_name)
+ history_comment = "New comment submitted"
+ if 'submit-trashcomment' == action:
+ record_id = request.POST['record_id']
+ comment = InvestigationComments.objects.get(id=record_id)
+ history_comment = "Comment from " + comment.author + " deleted"
+ comment.delete()
+ if 'submit-trashattachment' == action:
+ record_id = request.POST['record_id']
+ upload = InvestigationUploads.objects.get(id=record_id)
+ history_comment = "Upload '" + upload.description + "' from " + upload.author + " deleted"
+ try:
+ os.remove(upload.path)
+ except OSError:
+ pass
+ upload.delete()
+ if 'submit-addusernotify' == action:
+ users = request.POST['users']
+ usernames = ""
+ for user_id in users[:-1].split(','):
+ usernames += User.objects.get(pk=user_id).name + ", "
+ InvestigationNotification.objects.get_or_create(investigation_id=invst_id, user_id=user_id)
+ usernames = usernames[:-2]
+ history_comment = usernames + " added to notifications"
+ if 'submit-trashusernotification' == action:
+ record_id = request.POST['record_id']
+ notification_record = InvestigationNotification.objects.get(id=record_id)
+ removed_user = User.objects.get(pk=notification_record.user_id).name
+ history_comment = removed_user + " removed from notifications"
+ notification_record.delete()
+ if 'submit-adduseraccess' == action:
+ users = request.POST['users']
+ usernames = ""
+ for user_id in users[:-1].split(','):
+ usernames += User.objects.get(pk=user_id).name + ", "
+ InvestigationAccess.objects.get_or_create(investigation_id=invst_id, user_id=user_id)
+ history_comment = usernames + " granted access"
+ if 'submit-trashuseraccess' == action:
+ record_id = request.POST['record_id']
+ access_record = InvestigationAccess.objects.get(id=record_id)
+ removed_user = User.objects.get(pk=access_record.user_id).name
+ history_comment = removed_user + "'s access removed"
+ access_record.delete()
+ InvestigationHistory.objects.create(investigation_id=invst_id, comment=history_comment, date=datetime.now().strftime('%Y-%m-%d'), author=access.current_user_name)
+ return_data = {
+ "error": "ok",
+ }
+
+ return HttpResponse(json.dumps( return_data ), content_type = "application/json")
+ except Exception as e:
+ _log("xhr_investigation_commit:no(%s)" % e)
+ return HttpResponse(json.dumps({"error":str(e) + "\n"}), content_type = "application/json")
+
+
def tbd(request):
- context = {'lvs_nos' : 0}
+ context = {}
return toaster_render(request, 'tbd.html', context)
-