diff options
Diffstat (limited to 'lib/srtgui/views.py')
-rw-r--r-- | lib/srtgui/views.py | 790 |
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) - |