def all_endpoints(request): endpoints = Endpoint.objects.all() show_uri = get_system_setting('display_endpoint_uri') # are they authorized if request.user.is_staff: pass else: products = Product.objects.filter(authorized_users__in=[request.user]) if products.exists(): endpoints = endpoints.filter(product__in=products.all()) else: raise PermissionDenied product = None if 'product' in request.GET: p = request.GET.getlist('product', []) if len(p) == 1: product = get_object_or_404(Product, id=p[0]) ids = get_endpoint_ids(EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs) if show_uri: paged_endpoints = get_page_items(request, endpoints, 25) else: endpoints = EndpointFilter(request.GET, queryset=endpoints.filter(id__in=ids), user=request.user) paged_endpoints = get_page_items(request, endpoints.qs, 25) add_breadcrumb(title="All Endpoints", top_level=not len(request.GET), request=request) return render(request, 'dojo/endpoints.html', {"endpoints": paged_endpoints, "filtered": endpoints, "name": "All Endpoints", "show_uri": show_uri })
def view_test(request, tid): test = Test.objects.get(id=tid) prod = test.engagement.product auth = request.user.is_staff or request.user in prod.authorized_users.all() if not auth: # will render 403 raise PermissionDenied notes = test.notes.all() person = request.user.username findings = Finding.objects.filter(test=test).order_by('numerical_severity') stub_findings = Stub_Finding.objects.filter(test=test) cred_test = Cred_Mapping.objects.filter(test=test).select_related('cred_id').order_by('cred_id') creds = Cred_Mapping.objects.filter(engagement=test.engagement).select_related('cred_id').order_by('cred_id') if request.method == 'POST' and request.user.is_staff: form = NoteForm(request.POST) if form.is_valid(): new_note = form.save(commit=False) new_note.author = request.user new_note.date = timezone.now() new_note.save() test.notes.add(new_note) form = NoteForm() url = request.build_absolute_uri(reverse("view_test", args=(test.id,))) title = "Test: %s on %s" % (test.test_type.name, test.engagement.product.name) process_notifications(request, new_note, url, title) messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') else: form = NoteForm() fpage = get_page_items(request, findings, 25) sfpage = get_page_items(request, stub_findings, 25) show_re_upload = any(test.test_type.name in code for code in ImportScanForm.SCAN_TYPE_CHOICES) product_tab = Product_Tab(prod.id, title="Test", tab="engagements") product_tab.setEngagement(test.engagement) return render(request, 'dojo/view_test.html', {'test': test, 'product_tab': product_tab, 'findings': fpage, 'findings_count': findings.count(), 'stub_findings': sfpage, 'form': form, 'notes': notes, 'person': person, 'request': request, 'show_re_upload': show_re_upload, 'creds': creds, 'cred_test': cred_test })
def accepted_findings(request): user = request.user fids = [finding.id for ra in Risk_Acceptance.objects.all() for finding in ra.accepted_findings.all()] findings = Finding.objects.filter(id__in=fids) findings = AcceptedFingingSuperFilter(request.GET, queryset=findings) title_words = [word for ra in Risk_Acceptance.objects.all() for finding in ra.accepted_findings.order_by( 'title').values('title').distinct() for word in finding['title'].split() if len(word) > 2] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings, 25) add_breadcrumb(title="Accepted findings", top_level=not len(request.GET), request=request) return render(request, 'dojo/accepted_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, })
def open_findings(request): findings = Finding.objects.filter(mitigated__isnull=True, verified=True, false_p=False, duplicate=False, out_of_scope=False) if request.user.is_staff: findings = OpenFingingSuperFilter(request.GET, queryset=findings, user=request.user) else: findings = findings.filter(product__authorized_users__in=[request.user]) findings = OpenFindingFilter(request.GET, queryset=findings, user=request.user) title_words = [word for finding in findings for word in finding.title.split() if len(word) > 2] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings, 25) product_type = None if 'product__prod_type' in request.GET: p = request.GET.getlist('product__prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) add_breadcrumb(title="Open findings", top_level=not len(request.GET), request=request) return render(request, 'dojo/open_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, })
def report_findings(request): findings = Finding.objects.filter() findings = ReportAuthedFindingFilter(request.GET, queryset=findings, user=request.user) title_words = [word for finding in findings for word in finding.title.split() if len(word) > 2] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings, 25) product_type = None if 'test__engagement__product__prod_type' in request.GET: p = request.GET.getlist('test__engagement__product__prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) return render(request, 'dojo/report_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, "title": "finding-list", })
def all_findings(request): findings = Finding.objects.filter() if request.user.is_staff: findings = AllFindingSuperFilter(request.GET, queryset=findings, user=request.user) else: findings = findings.filter(test__engagement__product__authorized_users__in=[request.user]) findings = AllFindingFilter(request.GET, queryset=findings, user=request.user) title_words = [word for finding in findings.qs for word in finding.title.split() if len(word) > 2] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings.qs, 25) product_type = None if 'test__engagement__product__prod_type' in request.GET: p = request.GET.getlist('test__engagement__product__prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) add_breadcrumb(title="All findings", top_level=not len(request.GET), request=request) return render(request, 'dojo/all_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, })
def __init__(self, *args, **kwargs): if 'request' in kwargs: self.request = kwargs.get('request') if 'endpoints' in kwargs: self.endpoints = kwargs.get('endpoints') else: raise Exception("Need to instantiate with endpoint queryset.") if 'finding_notes' in kwargs: self.finding_notes = kwargs.get('finding_notes') else: self.finding_notes = False super(EndpointList, self).__init__(*args, **kwargs) self.title = 'Endpoint List' self.form = self.endpoints.form self.multiple = 'false' if self.request is not None: self.paged_endpoints = get_page_items(self.request, self.endpoints, 25) else: self.paged_endpoints = self.endpoints self.multiple = 'true' self.extra_help = "You can use this form to filter endpoints and select only the ones to be included in the " \ "report."
def product(request): if request.user.is_staff: initial_queryset = Product.objects.all() name_words = [product.name for product in Product.objects.all()] else: initial_queryset = Product.objects.filter( authorized_users__in=[request.user]) name_words = [word for product in Product.objects.filter( authorized_users__in=[request.user]) for word in product.name.split() if len(word) > 2] product_type = None if 'prod_type' in request.GET: p = request.GET.getlist('prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) """ if 'tags' in request.GET: tags = request.GET.getlist('tags', []) initial_queryset = TaggedItem.objects.get_by_model(initial_queryset, Tag.objects.filter(name__in=tags)) """ prods = ProductFilter(request.GET, queryset=initial_queryset, user=request.user) prod_list = get_page_items(request, prods.qs, 25) add_breadcrumb(title="Product List", top_level=not len(request.GET), request=request) return render(request, 'dojo/product.html', {'prod_list': prod_list, 'prods': prods, 'name_words': sorted(set(name_words)), 'user': request.user})
def __init__(self, *args, **kwargs): if 'request' in kwargs: self.request = kwargs.get('request') if 'findings' in kwargs: self.findings = kwargs.get('findings') else: raise Exception("Need to instantiate with finding queryset.") if 'finding_notes' in kwargs: self.finding_notes = kwargs.get('finding_notes') else: self.finding_notes = False super(FindingList, self).__init__(*args, **kwargs) self.title = 'Finding List' if 'form' in self.findings: self.form = self.findings.form else: self.form = None self.multiple = 'true' self.extra_help = "You can use this form to filter findings and select only the ones to be included in the " \ "report." title_words = [word for finding in self.findings for word in finding.title.split() if len(word) > 2] self.title_words = sorted(set(title_words)) if self.request is not None: self.paged_findings = get_page_items(self.request, self.findings, 25) else: self.paged_findings = self.findings
def engagement(request): filtered = EngagementFilter( request.GET, queryset=Product.objects.filter( ~Q(engagement=None), engagement__active=True, ).distinct()) prods = get_page_items(request, filtered.qs, 25) name_words = [ product.name for product in Product.objects.filter( ~Q(engagement=None), engagement__active=True, ).distinct() ] eng_words = [ engagement.name for product in Product.objects.filter( ~Q(engagement=None), engagement__active=True, ).distinct() for engagement in product.engagement_set.all() ] add_breadcrumb( title="Active Engagements", top_level=not len(request.GET), request=request) return render( request, 'dojo/engagement.html', { 'products': prods, 'filtered': filtered, 'name_words': sorted(set(name_words)), 'eng_words': sorted(set(eng_words)), })
def alerts(request): alerts = get_alerts(request.user) paged_alerts = get_page_items(request, alerts, 25) add_breadcrumb(title="Alerts for " + request.user.get_full_name(), top_level=True, request=request) return render(request, 'dojo/alerts.html', {'alerts': paged_alerts})
def vulnerable_endpoints(request): endpoints = Endpoint.objects.filter(finding__active=True, finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False).distinct() # are they authorized if request.user.is_staff: pass else: products = Product.objects.filter(authorized_users__in=[request.user]) if products.exists(): endpoints = endpoints.filter(product__in=products.all()) else: raise PermissionDenied product = None if 'product' in request.GET: p = request.GET.getlist('product', []) if len(p) == 1: product = get_object_or_404(Product, id=p[0]) ids = get_endpoint_ids(EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs) endpoints = EndpointFilter(request.GET, queryset=endpoints.filter(id__in=ids), user=request.user) paged_endpoints = get_page_items(request, endpoints.qs, 25) add_breadcrumb(title="Vulnerable Endpoints", top_level=not len(request.GET), request=request) return render(request, 'dojo/endpoints.html', {"endpoints": paged_endpoints, "filtered": endpoints, "name": "Vulnerable Endpoints", })
def view_engagements(request, pid, engagement_type="Interactive"): prod = get_object_or_404(Product, id=pid) auth = request.user.is_staff or request.user in prod.authorized_users.all() if not auth: raise PermissionDenied default_page_num = 10 # In Progress Engagements result_engs = EngagementFilter( request.GET, queryset=Engagement.objects.filter(product=prod, active=True, status="In Progress", engagement_type=engagement_type).order_by('-updated')) engs = get_page_items(request, result_engs.qs, default_page_num, param_name="engs") # Engagements that are queued because they haven't started or paused queued_engs = EngagementFilter( request.GET, queryset=Engagement.objects.filter(~Q(status="In Progress"), product=prod, active=True, engagement_type=engagement_type).order_by('-updated')) result_queued_engs = get_page_items(request, queued_engs.qs, default_page_num, param_name="queued_engs") # Cancelled or Completed Engagements result = EngagementFilter( request.GET, queryset=Engagement.objects.filter(product=prod, active=False, engagement_type=engagement_type).order_by('-target_end')) i_engs_page = get_page_items(request, result.qs, default_page_num, param_name="i_engs") title = "All Engagements" if engagement_type == "CI/CD": title = "CI/CD Engagements" product_tab = Product_Tab(pid, title=title, tab="engagements") return render(request, 'dojo/view_engagements.html', {'prod': prod, 'product_tab': product_tab, 'engagement_type': engagement_type, 'engs': engs, 'engs_count': result_engs.qs.count(), 'queued_engs': result_queued_engs, 'queued_engs_count': queued_engs.qs.count(), 'i_engs': i_engs_page, 'i_engs_count': result.qs.count(), 'user': request.user, 'authorized': auth})
def action_history(request, cid, oid): try: ct = ContentType.objects.get_for_id(cid) obj = ct.get_object_for_this_type(pk=oid) except KeyError: raise Http404() product_id = None active_tab = None finding = None test = False object_value = None if str(ct) == "product": product_id = obj.id active_tab = "overview" object_value = Product.objects.get(id=obj.id) elif str(ct) == "engagement": object_value = Engagement.objects.get(id=obj.id) product_id = object_value.product.id active_tab = "engagements" elif str(ct) == "test": object_value = Test.objects.get(id=obj.id) product_id = object_value.engagement.product.id active_tab = "engagements" test = True elif str(ct) == "finding": object_value = Finding.objects.get(id=obj.id) product_id = object_value.test.engagement.product.id active_tab = "findings" finding = object_value elif str(ct) == "endpoint": object_value = Endpoint.objects.get(id=obj.id) product_id = object_value.product.id active_tab = "endpoints" product_tab = None if product_id: product_tab = Product_Tab(product_id, title="History", tab=active_tab) if active_tab == "engagements": if str(ct) == "engagement": product_tab.setEngagement(object_value) else: product_tab.setEngagement(object_value.engagement) history = LogEntry.objects.filter(content_type=ct, object_pk=obj.id).order_by('-timestamp') history = LogEntryFilter(request.GET, queryset=history) paged_history = get_page_items(request, history.qs, 25) return render(request, 'dojo/action_history.html', {"history": paged_history, 'product_tab': product_tab, "filtered": history, "obj": obj, "test": test, "object_value": object_value, "finding": finding })
def view_test(request, tid): test = Test.objects.get(id=tid) notes = test.notes.all() person = request.user.username findings = Finding.objects.filter(test=test) stub_findings = Stub_Finding.objects.filter(test=test) cred_test = Cred_Mapping.objects.filter(test=test).select_related('cred_id').order_by('cred_id') creds = Cred_Mapping.objects.filter(engagement=test.engagement).select_related('cred_id').order_by('cred_id') if request.method == 'POST': form = NoteForm(request.POST) if form.is_valid(): new_note = form.save(commit=False) new_note.author = request.user new_note.date = timezone.now() new_note.save() test.notes.add(new_note) form = NoteForm() url = request.build_absolute_uri(reverse("view_test", args=(test.id,))) title="Test: %s on %s" % (test.test_type.name, test.engagement.product.name) process_notifications(request, new_note, url, title) messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') else: form = NoteForm() fpage = get_page_items(request, findings, 25) sfpage = get_page_items(request, stub_findings, 25) show_re_upload = any(test.test_type.name in code for code in ImportScanForm.SCAN_TYPE_CHOICES) add_breadcrumb(parent=test, top_level=False, request=request) return render(request, 'dojo/view_test.html', {'test': test, 'findings': fpage, 'stub_findings': sfpage, 'form': form, 'notes': notes, 'person': person, 'request': request, 'show_re_upload': show_re_upload, 'creds': creds, 'cred_test': cred_test })
def view_endpoint(request, eid): endpoint = get_object_or_404(Endpoint, id=eid) host = endpoint.host_no_port endpoints = Endpoint.objects.filter(host__regex="^" + host + ":?", product=endpoint.product).distinct() if (request.user in endpoint.product.authorized_users.all()) or request.user.is_staff: pass else: raise PermissionDenied ct = ContentType.objects.get_for_model(endpoint) endpoint_cf = CustomField.objects.filter(content_type=ct) endpoint_metadata = {} for cf in endpoint_cf: cfv = CustomFieldValue.objects.filter(field=cf, object_id=endpoint.id) if len(cfv): endpoint_metadata[cf] = cfv[0] all_findings = Finding.objects.filter(endpoints__in=endpoints).distinct() active_findings = Finding.objects.filter(endpoints__in=endpoints, active=True, verified=True).distinct() closed_findings = Finding.objects.filter(endpoints__in=endpoints, mitigated__isnull=False).distinct() if all_findings: start_date = timezone.make_aware(datetime.combine(all_findings.last().date, datetime.min.time())) else: start_date = timezone.now() end_date = timezone.now() r = relativedelta(end_date, start_date) months_between = (r.years * 12) + r.months # include current month months_between += 1 monthly_counts = get_period_counts(active_findings, all_findings, closed_findings, None, months_between, start_date, relative_delta='months') paged_findings = get_page_items(request, active_findings, 25) add_breadcrumb(parent=endpoint, top_level=False, request=request) return render(request, "dojo/view_endpoint.html", {"endpoint": endpoint, "endpoints": endpoints, "findings": paged_findings, 'all_findings': all_findings, 'opened_per_month': monthly_counts['opened_per_period'], 'endpoint_metadata': endpoint_metadata, })
def user(request): users = Dojo_User.objects.all().order_by('username', 'last_name', 'first_name') users = UserFilter(request.GET, queryset=users) paged_users = get_page_items(request, users.qs, 25) add_breadcrumb(title="All Users", top_level=True, request=request) return render(request, 'dojo/users.html', {"users": paged_users, "filtered": users, "name": "All Users", })
def survey(request): user = request.user surveys = Engagement_Survey.objects.all() surveys = SurveyFilter(request.GET, queryset=surveys) paged_surveys = get_page_items(request, surveys, 25) add_breadcrumb(title="All Surveys", top_level=True, request=request) return render(request, 'defectDojo-engagement-survey/list_surveys.html', {"surveys": paged_surveys, "filtered": surveys, "name": "All Surveys", })
def view_endpoint(request, eid): endpoint = get_object_or_404(Endpoint, id=eid) host = endpoint.host_no_port endpoints = Endpoint.objects.filter(host__regex="^" + host + ":?", product=endpoint.product).distinct() if (request.user in endpoint.product.authorized_users.all()) or request.user.is_staff: pass else: raise PermissionDenied endpoint_metadata = dict(endpoint.endpoint_meta.values_list('name', 'value')) all_findings = Finding.objects.filter(endpoints__in=endpoints).distinct() active_findings = Finding.objects.filter(endpoints__in=endpoints, active=True, verified=True).distinct() closed_findings = Finding.objects.filter(endpoints__in=endpoints, mitigated__isnull=False).distinct() if all_findings: start_date = timezone.make_aware(datetime.combine(all_findings.last().date, datetime.min.time())) else: start_date = timezone.now() end_date = timezone.now() r = relativedelta(end_date, start_date) months_between = (r.years * 12) + r.months # include current month months_between += 1 monthly_counts = get_period_counts(active_findings, all_findings, closed_findings, None, months_between, start_date, relative_delta='months') paged_findings = get_page_items(request, active_findings, 25) vulnerable = False if active_findings.count() != 0: vulnerable = True product_tab = Product_Tab(endpoint.product.id, "Endpoint", tab="endpoints") return render(request, "dojo/view_endpoint.html", {"endpoint": endpoint, 'product_tab': product_tab, "endpoints": endpoints, "findings": paged_findings, 'all_findings': all_findings, 'opened_per_month': monthly_counts['opened_per_period'], 'endpoint_metadata': endpoint_metadata, 'vulnerable': vulnerable, })
def questions(request): user = request.user questions = Question.objects.all() questions = QuestionFilter(request.GET, queryset=questions) paged_questions = get_page_items(request, questions, 25) add_breadcrumb(title="All Questions", top_level=False, request=request) return render(request, 'defectDojo-engagement-survey/list_questions.html', {"questions": paged_questions, "filtered": questions, "name": "All Questions", })
def view_test(request, tid): test = Test.objects.get(id=tid) notes = test.notes.all() person = request.user.username findings = Finding.objects.filter(test=test) stub_findings = Stub_Finding.objects.filter(test=test) if request.method == 'POST': form = NoteForm(request.POST) if form.is_valid(): new_note = form.save(commit=False) new_note.author = request.user new_note.date = datetime.now(tz=localtz) new_note.save() test.notes.add(new_note) form = NoteForm() messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') else: form = NoteForm() fpage = get_page_items(request, findings, 25) sfpage = get_page_items(request, stub_findings, 25) show_re_upload = any(test.test_type.name in code for code in ImportScanForm.SCAN_TYPE_CHOICES) ajax_url = reverse('api_dispatch_list', kwargs={'resource_name': 'stub_findings', 'api_name': 'v1_a'}) add_breadcrumb(parent=test, top_level=False, request=request) return render(request, 'dojo/view_test.html', {'test': test, 'findings': fpage, 'stub_findings': sfpage, 'form': form, 'notes': notes, 'person': person, 'request': request, 'show_re_upload': show_re_upload, 'ajax_url': ajax_url, })
def alerts(request): alerts = Alerts.objects.filter(user_id=request.user) if request.method == 'POST': removed_alerts = request.POST.getlist('alert_select') alerts.filter(id__in=removed_alerts).delete() alerts = alerts.filter(~Q(id__in=removed_alerts)) paged_alerts = get_page_items(request, alerts, 25) add_breadcrumb(title="Alerts for " + request.user.get_full_name(), top_level=True, request=request) return render(request, 'dojo/alerts.html', {'alerts': paged_alerts})
def test_type(request): initial_queryset = Test_Type.objects.all().order_by('name') name_words = [tt.name for tt in initial_queryset] test_types = TestTypeFilter(request.GET, queryset=initial_queryset) tts = get_page_items(request, test_types, 25) add_breadcrumb(title="Test Type List", top_level=True, request=request) return render(request, 'dojo/test_type.html', { 'name': 'Test Type List', 'metric': False, 'user': request.user, 'tts': tts, 'test_types': test_types, 'name_words': name_words})
def dev_env(request): initial_queryset = Development_Environment.objects.all().order_by('name') name_words = [de.name for de in initial_queryset] devs = DevelopmentEnvironmentFilter(request.GET, queryset=initial_queryset) dev_page = get_page_items(request, devs.qs, 25) add_breadcrumb(title="Development Environment List", top_level=True, request=request) return render(request, 'dojo/dev_env.html', { 'name': 'Development Environment List', 'metric': False, 'user': request.user, 'devs': dev_page, 'dts': devs, 'name_words': name_words})
def templates(request): templates = Finding_Template.objects.all() templates = TemplateFindingFilter(request.GET, queryset=templates) paged_templates = get_page_items(request, templates, 25) title_words = [word for finding in templates for word in finding.title.split() if len(word) > 2] title_words = sorted(set(title_words)) add_breadcrumb(title="Template Listing", top_level=True, request=request) return render(request, 'dojo/templates.html', {'templates': paged_templates, 'filtered': templates, 'title_words': title_words, })
def product_type(request): initial_queryset = Product_Type.objects.all().order_by('name') name_words = [product.name for product in initial_queryset] ptl = ProductTypeFilter(request.GET, queryset=initial_queryset) pts = get_page_items(request, ptl, 25) add_breadcrumb(title="Product Type List", top_level=True, request=request) return render(request, 'dojo/product_type.html', { 'name': 'Product Type List', 'metric': False, 'user': request.user, 'pts': pts, 'ptl': ptl, 'name_words': name_words})
def engineer_metrics(request): # checking if user is super_user if request.user.is_superuser: users = Dojo_User.objects.filter(is_staff=True).order_by('username') else: return HttpResponseRedirect(reverse('view_engineer', args=(request.user.id,))) users = EngineerFilter(request.GET, queryset=users) paged_users = get_page_items(request, users.qs, 15) add_breadcrumb(title="Engineer Metrics", top_level=True, request=request) return render(request, 'dojo/engineer_metrics.html', {'users': paged_users})
def reports(request): if request.user.is_staff: reports = Report.objects.all() else: reports = Report.objects.filter(requester=request.user) reports = ReportFilter(request.GET, queryset=reports) paged_reports = get_page_items(request, reports, 25) add_breadcrumb(title="Report List", top_level=True, request=request) return render(request, 'dojo/reports.html', {'report_list': reports, 'reports': paged_reports})
def closed_findings(request): findings = Finding.objects.filter(mitigated__isnull=False) findings = ClosedFingingSuperFilter(request.GET, queryset=findings) title_words = [word for finding in findings for word in finding.title.split() if len(word) > 2] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings, 25) add_breadcrumb(title="Closed findings", top_level=not len(request.GET), request=request) return render(request, 'dojo/closed_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, })
def view_engagement(request, eid): eng = Engagement.objects.get(id=eid) tests = Test.objects.filter(engagement=eng) risks_accepted = eng.risk_acceptance.all() exclude_findings = [finding.id for ra in eng.risk_acceptance.all() for finding in ra.accepted_findings.all()] eng_findings = Finding.objects.filter(test__in=eng.test_set.all()) \ .exclude(id__in=exclude_findings).order_by('title') try: check = Check_List.objects.get(engagement=eng) except: check = None pass form = DoneForm() if request.method == 'POST': eng.progress = 'check_list' eng.save() add_breadcrumb(parent=eng, top_level=False, request=request) if hasattr(settings, 'ENABLE_DEDUPLICATION'): if settings.ENABLE_DEDUPLICATION: enabled = True findings = Finding.objects.filter(test__engagement=eng, duplicate=False) else: enabled = False findings = None else: enabled = False findings = None if findings is not None: fpage = get_page_items(request, findings, 15) else: fpage = None return render(request, 'dojo/view_eng.html', {'eng': eng, 'tests': tests, 'findings': fpage, 'enabled': enabled, 'check': check, 'threat': eng.tmodel_path, 'risk': eng.risk_path, 'form': form, 'risks_accepted': risks_accepted, 'can_add_risk': len(eng_findings), })
def __init__(self, *args, **kwargs): if 'request' in kwargs: self.request = kwargs.get('request') if 'user_id' in kwargs: self.user_id = kwargs.get('user_id') if 'host' in kwargs: self.host = kwargs.get('host') if 'findings' in kwargs: self.findings = kwargs.get('findings') else: raise Exception("Need to instantiate with finding queryset.") if 'finding_notes' in kwargs: self.finding_notes = kwargs.get('finding_notes') else: self.finding_notes = False if 'finding_images' in kwargs: self.finding_images = kwargs.get('finding_images') else: self.finding_images = False super(FindingList, self).__init__(*args, **kwargs) self.title = 'Finding List' if hasattr(self.findings, 'form'): self.form = self.findings.form else: self.form = None self.multiple = 'true' self.extra_help = "You can use this form to filter findings and select only the ones to be included in the " \ "report." self.title_words = get_words_for_field(Finding, 'title') self.component_words = get_words_for_field(Finding, 'component_name') if self.request is not None: self.paged_findings = get_page_items(self.request, self.findings.qs, 25) else: self.paged_findings = self.findings
def open_findings(request): findings = Finding.objects.filter(mitigated__isnull=True, verified=True, false_p=False, duplicate=False, out_of_scope=False) if request.user.is_staff: findings = OpenFingingSuperFilter(request.GET, queryset=findings, user=request.user) else: findings = findings.filter( test__engagement__product__authorized_users__in=[request.user]) findings = OpenFindingFilter(request.GET, queryset=findings, user=request.user) title_words = [ word for finding in findings for word in finding.title.split() if len(word) > 2 ] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings, 25) product_type = None if 'test__engagement__product__prod_type' in request.GET: p = request.GET.getlist('test__engagement__product__prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) add_breadcrumb(title="Open findings", top_level=not len(request.GET), request=request) return render( request, 'dojo/open_findings.html', { "findings": paged_findings, "filtered": findings, "title_words": title_words, })
def components(request): add_breadcrumb(title='Components', top_level=True, request=request) component_query = Finding.objects.filter().values("component_name", "component_version") component_query = component_query.order_by('component_name', 'component_version') component_query = component_query.annotate(total=Count('id')).order_by( 'component_name', 'component_version') component_query = component_query.annotate( active=Count('id', filter=Q(active=True))) component_query = component_query.annotate( duplicate=(Count('id', filter=Q(duplicate=True)))) comp_filter = ComponentFilter(request.GET, queryset=component_query) result = get_page_items(request, comp_filter.qs, 25) return render(request, 'dojo/components.html', { 'filter': comp_filter, 'result': result })
def search(request, tid): test = get_object_or_404(Test, id=tid) templates = Finding_Template.objects.all() templates = TemplateFindingFilter(request.GET, queryset=templates) paged_templates = get_page_items(request, templates.qs, 25) title_words = get_words_for_field(Finding_Template, 'title') add_breadcrumb(parent=test, title="Add From Template", top_level=False, request=request) return render( request, 'dojo/templates.html', { 'templates': paged_templates, 'filtered': templates, 'title_words': title_words, 'tid': tid, 'add_from_template': True, })
def action_history(request, cid, oid): try: ct = ContentType.objects.get_for_id(cid) obj = ct.get_object_for_this_type(pk=oid) except KeyError: raise Http404() history = LogEntry.objects.filter(content_type=ct, object_pk=obj.id).order_by('-timestamp') history = LogEntryFilter(request.GET, queryset=history) paged_history = get_page_items(request, history.qs, 25) add_breadcrumb(parent=obj, title="Action History", top_level=False, request=request) return render(request, 'dojo/action_history.html', { "history": paged_history, "filtered": history, "obj": obj, })
def components(request): add_breadcrumb(title='Components', top_level=True, request=request) separator = ', ' # Get components ordered by component_name and concat component versions to the same row component_query = get_authorized_findings(Permissions.Finding_View) if connection.vendor == 'postgresql': component_query = component_query.values("component_name").order_by( 'component_name').annotate(component_version=StringAgg( 'component_version', delimiter=separator, distinct=True)) else: component_query = component_query.values("component_name").order_by( 'component_name') component_query = component_query.annotate( component_version=Sql_GroupConcat( 'component_version', separator=separator, distinct=True)) # Append counts component_query = component_query.annotate( total=Count('id')).order_by('component_name') component_query = component_query.annotate( active=Count('id', filter=Q(active=True))) component_query = component_query.annotate( duplicate=(Count('id', filter=Q(duplicate=True)))) component_query = component_query.order_by( '-total') # Default sort by total descending comp_filter = ComponentFilter(request.GET, queryset=component_query) result = get_page_items(request, comp_filter.qs, 25) # Filter out None values for auto-complete component_words = component_query.exclude( component_name__isnull=True).values_list('component_name', flat=True) return render( request, 'dojo/components.html', { 'filter': comp_filter, 'result': result, 'component_words': sorted(set(component_words)) })
def report_endpoints(request): endpoints = Endpoint.objects.filter( finding__active=True, finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False, ).distinct() endpoints = EndpointFilter(request.GET, queryset=endpoints, user=request.user) paged_endpoints = get_page_items(request, endpoints.qs, 25) return render( request, 'dojo/report_endpoints.html', { "endpoints": paged_endpoints, "filtered": endpoints, "title": "endpoint-list", })
def product_type(request): # query for names outside of query with prefetch to avoid the complex prefetch query from executing twice name_words = Product_Type.objects.all().values_list('name', flat=True) prod_types = Product_Type.objects.all() ptl = ProductTypeFilter(request.GET, queryset=prod_types) pts = get_page_items(request, ptl.qs, 25) pts.object_list = prefetch_for_product_type(pts.object_list) add_breadcrumb(title="Product Type List", top_level=True, request=request) return render( request, 'dojo/product_type.html', { 'name': 'Product Type List', 'metric': False, 'user': request.user, 'pts': pts, 'ptl': ptl, 'name_words': name_words })
def all_product_findings(request, pid): p = get_object_or_404(Product, id=pid) auth = request.user.is_staff or request.user in p.authorized_users.all() if not auth: # will render 403 raise PermissionDenied result = ProductFindingFilter(request.GET, queryset=Finding.objects.filter( test__engagement__product=p, active=True, verified=True)) page = get_page_items(request, result.qs, 25) add_breadcrumb(title="Open findings", top_level=False, request=request) return render(request, "dojo/all_product_findings.html", { "findings": page, "product": p, "filtered": result, "user": request.user, })
def vulnerable_endpoints(request): endpoints = Endpoint.objects.filter(finding__active=True, finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False, mitigated=False).distinct() # are they authorized if request.user.is_staff: pass else: endpoints = Endpoint.objects.filter( Q(product__authorized_users__in=[request.user]) | Q(product__prod_type__authorized_users__in=[request.user]) ) if not endpoints: raise PermissionDenied product = None if 'product' in request.GET: p = request.GET.getlist('product', []) if len(p) == 1: product = get_object_or_404(Product, id=p[0]) ids = get_endpoint_ids(EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs) endpoints = EndpointFilter(request.GET, queryset=endpoints.filter(id__in=ids), user=request.user) endpoints_query = endpoints.qs.order_by('host') paged_endpoints = get_page_items(request, endpoints_query, 25) add_breadcrumb(title="Vulnerable Endpoints", top_level=not len(request.GET), request=request) system_settings = System_Settings.objects.get() product_tab = None view_name = "All Endpoints" if product: product_tab = Product_Tab(product.id, "Vulnerable Endpoints", tab="endpoints") return render( request, 'dojo/endpoints.html', { 'product_tab': product_tab, "endpoints": paged_endpoints, "filtered": endpoints, "name": "Vulnerable Endpoints", })
def vulnerable_endpoints(request): endpoints = Endpoint.objects.filter( finding__active=True, finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False).distinct() # are they authorized if request.user.is_staff: pass else: products = Product.objects.filter(authorized_users__in=[request.user]) if products.exists(): endpoints = endpoints.filter(product__in=products.all()) else: raise PermissionDenied product = None if 'product' in request.GET: p = request.GET.getlist('product', []) if len(p) == 1: product = get_object_or_404(Product, id=p[0]) ids = get_endpoint_ids( EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs) endpoints = EndpointFilter(request.GET, queryset=endpoints.filter(id__in=ids), user=request.user) paged_endpoints = get_page_items(request, endpoints.qs, 25) add_breadcrumb(title="Vulnerable Endpoints", top_level=not len(request.GET), request=request) return render( request, 'dojo/endpoints.html', { "endpoints": paged_endpoints, "filtered": endpoints, "name": "Vulnerable Endpoints", })
def accepted_findings(request): user = request.user findings = Finding.objects.filter(risk_acceptance__isnull=False) findings = AcceptedFingingSuperFilter(request.GET, queryset=findings) title_words = [word for ra in Risk_Acceptance.objects.all() for finding in ra.accepted_findings.order_by( 'title').values('title').distinct() for word in finding['title'].split() if len(word) > 2] title_words = sorted(set(title_words)) paged_findings = get_page_items(request, findings, 25) add_breadcrumb(title="Accepted findings", top_level=not len(request.GET), request=request) return render(request, 'dojo/accepted_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, })
def product(request): if request.user.is_staff: initial_queryset = Product.objects.all() name_words = [product.name for product in Product.objects.all()] else: initial_queryset = Product.objects.filter( authorized_users__in=[request.user]) name_words = [ word for product in Product.objects.filter( authorized_users__in=[request.user]) for word in product.name.split() if len(word) > 2 ] product_type = None if 'prod_type' in request.GET: p = request.GET.getlist('prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) """ if 'tags' in request.GET: tags = request.GET.getlist('tags', []) initial_queryset = TaggedItem.objects.get_by_model(initial_queryset, Tag.objects.filter(name__in=tags)) """ prods = ProductFilter(request.GET, queryset=initial_queryset, user=request.user) prod_list = get_page_items(request, prods.qs, 25) add_breadcrumb(title="Product List", top_level=not len(request.GET), request=request) return render( request, 'dojo/product.html', { 'prod_list': prod_list, 'prods': prods, 'name_words': sorted(set(name_words)), 'user': request.user })
def report_endpoints(request): user = Dojo_User.objects.get(id=request.user.id) endpoints = Endpoint.objects.filter( finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False, ).distinct() ids = get_endpoint_ids(endpoints) endpoints = Endpoint.objects.filter(id__in=ids) endpoints = EndpointFilter(request.GET, queryset=endpoints) paged_endpoints = get_page_items(request, endpoints.qs, 25) return render( request, 'dojo/report_endpoints.html', { "endpoints": paged_endpoints, "filtered": endpoints, "title": "endpoint-list", })
def questionnaire(request): user = request.user surveys = Engagement_Survey.objects.all() surveys = QuestionnaireFilter(request.GET, queryset=surveys) paged_surveys = get_page_items(request, surveys.qs, 25) general_surveys = General_Survey.objects.all() for survey in general_surveys: survey_exp = survey.expiration if survey.expiration < tz.now(): survey.delete() messages.add_message(request, messages.INFO, 'Surveys have migrated to core DefectDojo! Please run python3 manage.py migrate_surveys to retrieve data. ' + 'For docker-compose, run `docker ps -a` to find the uwsgi container name then `docker exec -it <conainter_name> ./manage.py migrate_surveys`', extra_tags='alert-info') add_breadcrumb(title="Questionnaires", top_level=True, request=request) return render(request, 'defectDojo-engagement-survey/list_surveys.html', {"surveys": paged_surveys, "filtered": surveys, "general": general_surveys, "name": "Questionnaires", })
def engagement(request): filtered = EngagementFilter(request.GET, queryset=Product.objects.filter( ~Q(engagement=None), engagement__active=True, ).distinct()) prods = get_page_items(request, filtered.qs, 25) name_words = [product.name for product in Product.objects.filter( ~Q(engagement=None), engagement__active=True, ).distinct()] eng_words = [engagement.name for product in Product.objects.filter( ~Q(engagement=None), engagement__active=True, ).distinct() for engagement in product.engagement_set.all()] add_breadcrumb(title="Active Engagements", top_level=not len(request.GET), request=request) return render(request, 'dojo/engagement.html', {'products': prods, 'filtered': filtered, 'name_words': sorted(set(name_words)), 'eng_words': sorted(set(eng_words)), })
def search(request, tid): test = get_object_or_404(Test, id=tid) templates = Finding_Template.objects.all() templates = TemplateFindingFilter(request.GET, queryset=templates) paged_templates = get_page_items(request, templates, 25) title_words = [ word for finding in templates for word in finding.title.split() if len(word) > 2 ] title_words = sorted(set(title_words)) add_breadcrumb(parent=test, title="Add From Template", top_level=False, request=request) return render( request, 'dojo/templates.html', { 'templates': paged_templates, 'filtered': templates, 'title_words': title_words, 'tid': tid, 'add_from_template': True, })
def __init__(self, *args, **kwargs): if 'request' in kwargs: self.request = kwargs.get('request') if 'user_id' in kwargs: self.user_id = kwargs.get('user_id') if 'host' in kwargs: self.host = kwargs.get('host') if 'endpoints' in kwargs: self.endpoints = kwargs.get('endpoints') else: raise Exception("Need to instantiate with endpoint queryset.") if 'finding_notes' in kwargs: self.finding_notes = kwargs.get('finding_notes') else: self.finding_notes = False if 'finding_images' in kwargs: self.finding_images = kwargs.get('finding_images') else: self.finding_images = False super(EndpointList, self).__init__(*args, **kwargs) self.title = 'Endpoint List' self.form = self.endpoints.form self.multiple = 'false' if self.request is not None: self.paged_endpoints = get_page_items(self.request, self.endpoints.qs, 25) else: self.paged_endpoints = self.endpoints self.multiple = 'true' self.extra_help = "You can use this form to filter endpoints and select only the ones to be included in the " \ "report."
def report_findings(request): findings = Finding.objects.filter() findings = ReportAuthedFindingFilter(request.GET, queryset=findings) title_words = get_words_for_field(findings.qs, 'title') component_words = get_words_for_field(findings.qs, 'component_name') paged_findings = get_page_items(request, findings.qs.order_by('numerical_severity'), 25) product_type = None if 'test__engagement__product__prod_type' in request.GET: p = request.GET.getlist('test__engagement__product__prod_type', []) if len(p) == 1: product_type = get_object_or_404(Product_Type, id=p[0]) return render(request, 'dojo/report_findings.html', {"findings": paged_findings, "filtered": findings, "title_words": title_words, "component_words": component_words, "title": "finding-list", })
def engagement(request): products_with_engagements = Product.objects.filter(~Q(engagement=None), engagement__active=True).distinct() filtered = EngagementFilter( request.GET, queryset=products_with_engagements.prefetch_related('engagement_set', 'prod_type', 'engagement_set__lead', 'engagement_set__test_set__lead', 'engagement_set__test_set__test_type')) prods = get_page_items(request, filtered.qs, 25) name_words = products_with_engagements.values_list('name', flat=True) eng_words = Engagement.objects.filter(active=True).values_list('name', flat=True).distinct() add_breadcrumb( title="Active Engagements", top_level=not len(request.GET), request=request) prods.object_list = prefetch_for_products_with_engagments(prods.object_list) return render( request, 'dojo/engagement.html', { 'products': prods, 'filtered': filtered, 'name_words': sorted(set(name_words)), 'eng_words': sorted(set(eng_words)), })
def view_edit_risk_acceptance(request, eid, raid, edit_mode=False): risk_acceptance = get_object_or_404(Risk_Acceptance, pk=raid) eng = get_object_or_404(Engagement, pk=eid) if edit_mode and not eng.product.enable_full_risk_acceptance: raise PermissionDenied() risk_acceptance_form = None errors = False if request.method == 'POST': # deleting before instantiating the form otherwise django messes up and we end up with an empty path value if len(request.FILES) > 0: logger.debug('new proof uploaded') risk_acceptance.path.delete() if 'decision' in request.POST: old_expiration_date = risk_acceptance.expiration_date risk_acceptance_form = EditRiskAcceptanceForm(request.POST, request.FILES, instance=risk_acceptance) errors = errors or not risk_acceptance_form.is_valid() if not errors: logger.debug('path: %s', risk_acceptance_form.cleaned_data['path']) risk_acceptance_form.save() if risk_acceptance.expiration_date != old_expiration_date: # risk acceptance was changed, check if risk acceptance needs to be reinstated and findings made accepted again ra_helper.reinstate(risk_acceptance, old_expiration_date) messages.add_message( request, messages.SUCCESS, 'Risk Acceptance saved successfully.', extra_tags='alert-success') if 'entry' in request.POST: note_form = NoteForm(request.POST) errors = errors or not note_form.is_valid() if not errors: new_note = note_form.save(commit=False) new_note.author = request.user new_note.date = timezone.now() new_note.save() risk_acceptance.notes.add(new_note) messages.add_message( request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') if 'delete_note' in request.POST: note = get_object_or_404(Notes, pk=request.POST['delete_note_id']) if note.author.username == request.user.username: risk_acceptance.notes.remove(note) note.delete() messages.add_message( request, messages.SUCCESS, 'Note deleted successfully.', extra_tags='alert-success') else: messages.add_message( request, messages.ERROR, "Since you are not the note's author, it was not deleted.", extra_tags='alert-danger') if 'remove_finding' in request.POST: finding = get_object_or_404( Finding, pk=request.POST['remove_finding_id']) ra_helper.remove_finding_from_risk_acceptance(risk_acceptance, finding) messages.add_message( request, messages.SUCCESS, 'Finding removed successfully from risk acceptance.', extra_tags='alert-success') if 'replace_file' in request.POST: replace_form = ReplaceRiskAcceptanceProofForm( request.POST, request.FILES, instance=risk_acceptance) errors = errors or not replace_form.is_valid() if not errors: replace_form.save() messages.add_message( request, messages.SUCCESS, 'New Proof uploaded successfully.', extra_tags='alert-success') else: logger.error(replace_form.errors) if 'add_findings' in request.POST: add_findings_form = AddFindingsRiskAcceptanceForm( request.POST, request.FILES, instance=risk_acceptance) errors = errors or not add_findings_form.is_valid() if not errors: findings = add_findings_form.cleaned_data['accepted_findings'] ra_helper.add_findings_to_risk_acceptance(risk_acceptance, findings) messages.add_message( request, messages.SUCCESS, 'Finding%s added successfully.' % ('s' if len(findings) > 1 else ''), extra_tags='alert-success') if not errors: logger.debug('redirecting to return_url') return redirect_to_return_url_or_else(request, reverse("view_risk_acceptance", args=(eid, raid))) else: logger.error('errors found') else: if edit_mode: risk_acceptance_form = EditRiskAcceptanceForm(instance=risk_acceptance) note_form = NoteForm() replace_form = ReplaceRiskAcceptanceProofForm(instance=risk_acceptance) add_findings_form = AddFindingsRiskAcceptanceForm(instance=risk_acceptance) accepted_findings = risk_acceptance.accepted_findings.order_by('numerical_severity') fpage = get_page_items(request, accepted_findings, 15) unaccepted_findings = Finding.objects.filter(test__in=eng.test_set.all()) \ .exclude(id__in=accepted_findings).order_by("title") add_fpage = get_page_items(request, unaccepted_findings, 10, 'apage') # on this page we need to add unaccepted findings as possible findings to add as accepted add_findings_form.fields[ "accepted_findings"].queryset = add_fpage.object_list product_tab = Product_Tab(eng.product.id, title="Risk Acceptance", tab="engagements") product_tab.setEngagement(eng) return render( request, 'dojo/view_risk_acceptance.html', { 'risk_acceptance': risk_acceptance, 'engagement': eng, 'product_tab': product_tab, 'accepted_findings': fpage, 'notes': risk_acceptance.notes.all(), 'eng': eng, 'edit_mode': edit_mode, 'risk_acceptance_form': risk_acceptance_form, 'note_form': note_form, 'replace_form': replace_form, 'add_findings_form': add_findings_form, # 'show_add_findings_form': len(unaccepted_findings), 'request': request, 'add_findings': add_fpage, 'return_url': get_return_url(request), })
def view_engagement(request, eid): eng = get_object_or_404(Engagement, id=eid) tests = eng.test_set.all().order_by('test_type__name', '-updated') default_page_num = 10 tests_filter = EngagementTestFilter(request.GET, queryset=tests, engagement=eng) paged_tests = get_page_items(request, tests_filter.qs, default_page_num) # prefetch only after creating the filters to avoid https://code.djangoproject.com/ticket/23771 and https://code.djangoproject.com/ticket/25375 paged_tests.object_list = prefetch_for_view_tests(paged_tests.object_list) prod = eng.product risks_accepted = eng.risk_acceptance.all().select_related('owner').annotate(accepted_findings_count=Count('accepted_findings__id')) preset_test_type = None network = None if eng.preset: preset_test_type = eng.preset.test_type.all() network = eng.preset.network_locations.all() system_settings = System_Settings.objects.get() jissue = jira_helper.get_jira_issue(eng) jira_project = jira_helper.get_jira_project(eng) try: check = Check_List.objects.get(engagement=eng) except: check = None pass notes = eng.notes.all() note_type_activation = Note_Type.objects.filter(is_active=True).count() if note_type_activation: available_note_types = find_available_notetypes(notes) form = DoneForm() files = eng.files.all() if request.method == 'POST': user_has_permission_or_403(request.user, eng, Permissions.Note_Add) eng.progress = 'check_list' eng.save() if note_type_activation: form = TypedNoteForm(request.POST, available_note_types=available_note_types) else: form = NoteForm(request.POST) if form.is_valid(): new_note = form.save(commit=False) new_note.author = request.user new_note.date = timezone.now() new_note.save() eng.notes.add(new_note) if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types) else: form = NoteForm() url = request.build_absolute_uri(reverse("view_engagement", args=(eng.id,))) title = "Engagement: %s on %s" % (eng.name, eng.product.name) messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') else: if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types) else: form = NoteForm() creds = Cred_Mapping.objects.filter( product=eng.product).select_related('cred_id').order_by('cred_id') cred_eng = Cred_Mapping.objects.filter( engagement=eng.id).select_related('cred_id').order_by('cred_id') add_breadcrumb(parent=eng, top_level=False, request=request) title = "" if eng.engagement_type == "CI/CD": title = " CI/CD" product_tab = Product_Tab(prod.id, title="View" + title + " Engagement", tab="engagements") product_tab.setEngagement(eng) return render( request, 'dojo/view_eng.html', { 'eng': eng, 'product_tab': product_tab, 'system_settings': system_settings, 'tests': paged_tests, 'filter': tests_filter, 'check': check, 'threat': eng.tmodel_path, 'form': form, 'notes': notes, 'files': files, 'risks_accepted': risks_accepted, 'jissue': jissue, 'jira_project': jira_project, 'creds': creds, 'cred_eng': cred_eng, 'network': network, 'preset_test_type': preset_test_type })
def view_risk(request, eid, raid): risk_approval = get_object_or_404(Risk_Acceptance, pk=raid) eng = get_object_or_404(Engagement, pk=eid) if (request.user.is_staff or request.user in eng.product.authorized_users.all()): pass else: raise PermissionDenied a_file = risk_approval.path if request.method == 'POST': note_form = NoteForm(request.POST) if note_form.is_valid(): new_note = note_form.save(commit=False) new_note.author = request.user new_note.date = datetime.now(tz=localtz) new_note.save() risk_approval.notes.add(new_note) messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') if 'delete_note' in request.POST: note = get_object_or_404(Notes, pk=request.POST['delete_note_id']) if note.author.username == request.user.username: risk_approval.notes.remove(note) note.delete() messages.add_message(request, messages.SUCCESS, 'Note deleted successfully.', extra_tags='alert-success') else: messages.add_message( request, messages.ERROR, "Since you are not the note's author, it was not deleted.", extra_tags='alert-danger') if 'remove_finding' in request.POST: finding = get_object_or_404(Finding, pk=request.POST['remove_finding_id']) risk_approval.accepted_findings.remove(finding) finding.active = True finding.save() messages.add_message(request, messages.SUCCESS, 'Finding removed successfully.', extra_tags='alert-success') if 'replace_file' in request.POST: replace_form = ReplaceRiskAcceptanceForm(request.POST, request.FILES, instance=risk_approval) if replace_form.is_valid(): risk_approval.path.delete(save=False) risk_approval.path = replace_form.cleaned_data['path'] risk_approval.save() messages.add_message(request, messages.SUCCESS, 'File replaced successfully.', extra_tags='alert-success') if 'add_findings' in request.POST: add_findings_form = AddFindingsRiskAcceptanceForm( request.POST, request.FILES, instance=risk_approval) if add_findings_form.is_valid(): findings = add_findings_form.cleaned_data['accepted_findings'] for finding in findings: finding.active = False finding.save() risk_approval.accepted_findings.add(finding) risk_approval.save() messages.add_message(request, messages.SUCCESS, 'Finding%s added successfully.' % ('s' if len(findings) > 1 else ''), extra_tags='alert-success') note_form = NoteForm() replace_form = ReplaceRiskAcceptanceForm() add_findings_form = AddFindingsRiskAcceptanceForm() exclude_findings = [ finding.id for ra in eng.risk_acceptance.all() for finding in ra.accepted_findings.all() ] findings = Finding.objects.filter(test__in=eng.test_set.all()) \ .exclude(id__in=exclude_findings).order_by("title") add_fpage = get_page_items(request, findings, 10, 'apage') add_findings_form.fields[ "accepted_findings"].queryset = add_fpage.object_list fpage = get_page_items( request, risk_approval.accepted_findings.order_by('numerical_severity'), 15) authorized = (request.user == risk_approval.reporter.username or request.user.is_staff) add_breadcrumb(parent=risk_approval, top_level=False, request=request) return render( request, 'dojo/view_risk.html', { 'risk_approval': risk_approval, 'accepted_findings': fpage, 'notes': risk_approval.notes.all(), 'a_file': a_file, 'eng': eng, 'note_form': note_form, 'replace_form': replace_form, 'add_findings_form': add_findings_form, 'show_add_findings_form': len(findings), 'request': request, 'add_findings': add_fpage, 'authorized': authorized, })
def view_engagement(request, eid): eng = Engagement.objects.get(id=eid) tests = Test.objects.filter(engagement=eng) risks_accepted = eng.risk_acceptance.all() try: jissue = JIRA_Issue.objects.get(engagement=eng) except: jissue = None pass try: jconf = JIRA_PKey.objects.get(product=eng.product).conf except: jconf = None pass exclude_findings = [ finding.id for ra in eng.risk_acceptance.all() for finding in ra.accepted_findings.all() ] eng_findings = Finding.objects.filter(test__in=eng.test_set.all()) \ .exclude(id__in=exclude_findings).order_by('title') try: check = Check_List.objects.get(engagement=eng) except: check = None pass form = DoneForm() if request.method == 'POST': eng.progress = 'check_list' eng.save() creds = Cred_Mapping.objects.filter( product=eng.product).select_related('cred_id').order_by('cred_id') cred_eng = Cred_Mapping.objects.filter( engagement=eng.id).select_related('cred_id').order_by('cred_id') add_breadcrumb(parent=eng, top_level=False, request=request) if hasattr(settings, 'ENABLE_DEDUPLICATION'): if settings.ENABLE_DEDUPLICATION: enabled = True findings = Finding.objects.filter(test__engagement=eng, duplicate=False) else: enabled = False findings = None else: enabled = False findings = None if findings is not None: fpage = get_page_items(request, findings, 15) else: fpage = None # ---------- try: start_date = Finding.objects.filter( test__engagement__product=eng.product).order_by('date')[:1][0].date except: start_date = localtz.localize(datetime.today()) end_date = localtz.localize(datetime.today()) risk_acceptances = Risk_Acceptance.objects.filter( engagement__in=Engagement.objects.filter(product=eng.product)) accepted_findings = [ finding for ra in risk_acceptances for finding in ra.accepted_findings.all() ] week_date = end_date - timedelta( days=7) # seven days and /newer are considered "new" new_verified_findings = Finding.objects.filter( test__engagement__product=eng.product, date__range=[week_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False).order_by("date") open_findings = Finding.objects.filter( test__engagement__product=eng.product, date__range=[start_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False, active=True, mitigated__isnull=True) closed_findings = Finding.objects.filter( test__engagement__product=eng.product, date__range=[start_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False, mitigated__isnull=False) return render( request, 'dojo/view_eng.html', { 'eng': eng, 'tests': tests, 'findings': fpage, 'enabled': enabled, 'check': check, 'threat': eng.tmodel_path, 'risk': eng.risk_path, 'form': form, 'risks_accepted': risks_accepted, 'can_add_risk': len(eng_findings), 'jissue': jissue, 'jconf': jconf, 'open_findings': open_findings, 'closed_findings': closed_findings, 'accepted_findings': accepted_findings, 'new_findings': new_verified_findings, 'start_date': start_date, 'creds': creds, 'cred_eng': cred_eng })
def view_engagements(request, pid, engagement_type="Interactive"): prod = get_object_or_404(Product, id=pid) auth = request.user.is_staff or request.user in prod.authorized_users.all() if not auth: raise PermissionDenied default_page_num = 10 # In Progress Engagements result_engs = EngagementFilter( request.GET, queryset=Engagement.objects.filter( product=prod, active=True, status="In Progress", engagement_type=engagement_type).order_by('-updated')) engs = get_page_items(request, result_engs.qs, default_page_num, param_name="engs") # Engagements that are queued because they haven't started or paused queued_engs = EngagementFilter( request.GET, queryset=Engagement.objects.filter( ~Q(status="In Progress"), product=prod, active=True, engagement_type=engagement_type).order_by('-updated')) result_queued_engs = get_page_items(request, queued_engs.qs, default_page_num, param_name="queued_engs") # Cancelled or Completed Engagements result = EngagementFilter( request.GET, queryset=Engagement.objects.filter( product=prod, active=False, engagement_type=engagement_type).order_by('-target_end')) i_engs_page = get_page_items(request, result.qs, default_page_num, param_name="i_engs") title = "All Engagements" if engagement_type == "CI/CD": title = "CI/CD Engagements" product_tab = Product_Tab(pid, title=title, tab="engagements") return render( request, 'dojo/view_engagements.html', { 'prod': prod, 'product_tab': product_tab, 'engagement_type': engagement_type, 'engs': engs, 'engs_count': result_engs.qs.count(), 'queued_engs': result_queued_engs, 'queued_engs_count': queued_engs.qs.count(), 'i_engs': i_engs_page, 'i_engs_count': result.qs.count(), 'user': request.user, 'authorized': auth })
def view_product_metrics(request, pid): prod = get_object_or_404(Product, id=pid) engs = Engagement.objects.filter(product=prod, active=True) result = EngagementFilter(request.GET, queryset=Engagement.objects.filter( product=prod, active=False).order_by('-target_end')) i_engs_page = get_page_items(request, result.qs, 10) scan_sets = ScanSettings.objects.filter(product=prod) auth = request.user.is_staff or request.user in prod.authorized_users.all() if not auth: # will render 403 raise PermissionDenied ct = ContentType.objects.get_for_model(prod) product_cf = CustomField.objects.filter(content_type=ct) product_metadata = {} for cf in product_cf: cfv = CustomFieldValue.objects.filter(field=cf, object_id=prod.id) if len(cfv): product_metadata[cf.name] = cfv[0].value try: start_date = Finding.objects.filter( test__engagement__product=prod).order_by('date')[:1][0].date except: start_date = timezone.now() end_date = timezone.now() tests = Test.objects.filter(engagement__product=prod) risk_acceptances = Risk_Acceptance.objects.filter( engagement__in=Engagement.objects.filter(product=prod)) accepted_findings = [ finding for ra in risk_acceptances for finding in ra.accepted_findings.all() ] verified_findings = Finding.objects.filter( test__engagement__product=prod, date__range=[start_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False).order_by("date") week_date = end_date - timedelta( days=7) # seven days and /newnewer are considered "new" new_verified_findings = Finding.objects.filter( test__engagement__product=prod, date__range=[week_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False).order_by("date") open_findings = Finding.objects.filter(test__engagement__product=prod, date__range=[start_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False, active=True, mitigated__isnull=True) closed_findings = Finding.objects.filter( test__engagement__product=prod, date__range=[start_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False, mitigated__isnull=False) start_date = timezone.make_aware( datetime.combine(start_date, datetime.min.time())) r = relativedelta(end_date, start_date) weeks_between = int( ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7))) if weeks_between <= 0: weeks_between += 2 punchcard, ticks, highest_count = get_punchcard_data( verified_findings, weeks_between, start_date) add_breadcrumb(parent=prod, top_level=False, request=request) open_close_weekly = OrderedDict() new_weekly = OrderedDict() severity_weekly = OrderedDict() critical_weekly = OrderedDict() high_weekly = OrderedDict() medium_weekly = OrderedDict() for v in verified_findings: iso_cal = v.date.isocalendar() x = iso_to_gregorian(iso_cal[0], iso_cal[1], 1) y = x.strftime("<span class='small'>%m/%d<br/>%Y</span>") x = (tcalendar.timegm(x.timetuple()) * 1000) if x not in critical_weekly: critical_weekly[x] = {'count': 0, 'week': y} if x not in high_weekly: high_weekly[x] = {'count': 0, 'week': y} if x not in medium_weekly: medium_weekly[x] = {'count': 0, 'week': y} if x in open_close_weekly: if v.mitigated: open_close_weekly[x]['closed'] += 1 else: open_close_weekly[x]['open'] += 1 else: if v.mitigated: open_close_weekly[x] = {'closed': 1, 'open': 0, 'accepted': 0} else: open_close_weekly[x] = {'closed': 0, 'open': 1, 'accepted': 0} open_close_weekly[x]['week'] = y if x in severity_weekly: if v.severity in severity_weekly[x]: severity_weekly[x][v.severity] += 1 else: severity_weekly[x][v.severity] = 1 else: severity_weekly[x] = { 'Critical': 0, 'High': 0, 'Medium': 0, 'Low': 0, 'Info': 0 } severity_weekly[x][v.severity] = 1 severity_weekly[x]['week'] = y if v.severity == 'Critical': if x in critical_weekly: critical_weekly[x]['count'] += 1 else: critical_weekly[x] = {'count': 1, 'week': y} elif v.severity == 'High': if x in high_weekly: high_weekly[x]['count'] += 1 else: high_weekly[x] = {'count': 1, 'week': y} elif v.severity == 'Medium': if x in medium_weekly: medium_weekly[x]['count'] += 1 else: medium_weekly[x] = {'count': 1, 'week': y} for a in accepted_findings: iso_cal = a.date.isocalendar() x = iso_to_gregorian(iso_cal[0], iso_cal[1], 1) y = x.strftime("<span class='small'>%m/%d<br/>%Y</span>") x = (tcalendar.timegm(x.timetuple()) * 1000) if x in open_close_weekly: open_close_weekly[x]['accepted'] += 1 else: open_close_weekly[x] = {'closed': 0, 'open': 0, 'accepted': 1} open_close_weekly[x]['week'] = y test_data = {} for t in tests: if t.test_type.name in test_data: test_data[t.test_type.name] += t.verified_finding_count() else: test_data[t.test_type.name] = t.verified_finding_count() product_tab = Product_Tab(pid, title="Product", tab="metrics") return render( request, 'dojo/product_metrics.html', { 'prod': prod, 'product_tab': product_tab, 'product_metadata': product_metadata, 'engs': engs, 'i_engs': i_engs_page, 'scan_sets': scan_sets, 'verified_findings': verified_findings, 'open_findings': open_findings, 'closed_findings': closed_findings, 'accepted_findings': accepted_findings, 'new_findings': new_verified_findings, 'start_date': start_date, 'punchcard': punchcard, 'ticks': ticks, 'highest_count': highest_count, 'open_close_weekly': open_close_weekly, 'severity_weekly': severity_weekly, 'critical_weekly': critical_weekly, 'high_weekly': high_weekly, 'medium_weekly': medium_weekly, 'test_data': test_data, 'user': request.user, 'authorized': auth })
def view_test(request, tid): test_prefetched = get_authorized_tests(Permissions.Test_View) test_prefetched = test_prefetched.annotate( total_reimport_count=Count('test_import__id', distinct=True)) # tests_prefetched = test_prefetched.prefetch_related(Prefetch('test_import_set', queryset=Test_Import.objects.filter(~Q(findings_affected=None)))) # tests_prefetched = test_prefetched.prefetch_related('test_import_set') # test_prefetched = test_prefetched.prefetch_related('test_import_set__test_import_finding_action_set') test = get_object_or_404(test_prefetched, pk=tid) # test = get_object_or_404(Test, pk=tid) prod = test.engagement.product notes = test.notes.all() note_type_activation = Note_Type.objects.filter(is_active=True).count() if note_type_activation: available_note_types = find_available_notetypes(notes) files = test.files.all() person = request.user.username findings = Finding.objects.filter(test=test).order_by('numerical_severity') findings = FindingFilter(request.GET, queryset=findings) stub_findings = Stub_Finding.objects.filter(test=test) cred_test = Cred_Mapping.objects.filter( test=test).select_related('cred_id').order_by('cred_id') creds = Cred_Mapping.objects.filter( engagement=test.engagement).select_related('cred_id').order_by( 'cred_id') system_settings = get_object_or_404(System_Settings, id=1) if request.method == 'POST': user_has_permission_or_403(request.user, test, Permissions.Note_Add) if note_type_activation: form = TypedNoteForm(request.POST, available_note_types=available_note_types) else: form = NoteForm(request.POST) if form.is_valid(): new_note = form.save(commit=False) new_note.author = request.user new_note.date = timezone.now() new_note.save() test.notes.add(new_note) if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types) else: form = NoteForm() url = request.build_absolute_uri( reverse("view_test", args=(test.id, ))) title = "Test: %s on %s" % (test.test_type.name, test.engagement.product.name) process_notifications(request, new_note, url, title) messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') else: if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types) else: form = NoteForm() title_words = get_words_for_field(Finding, 'title') component_words = get_words_for_field(Finding, 'component_name') # test_imports = test.test_import_set.all() test_imports = Test_Import.objects.filter(test=test) test_import_filter = TestImportFilter(request.GET, test_imports) paged_test_imports = get_page_items_and_count(request, test_import_filter.qs, 5, prefix='test_imports') paged_test_imports.object_list = paged_test_imports.object_list.prefetch_related( 'test_import_finding_action_set') paged_findings = get_page_items_and_count(request, prefetch_for_findings( findings.qs), 25, prefix='findings') paged_stub_findings = get_page_items(request, stub_findings, 25) show_re_upload = any(test.test_type.name in code for code in get_choices_sorted()) product_tab = Product_Tab(prod.id, title="Test", tab="engagements") product_tab.setEngagement(test.engagement) jira_project = jira_helper.get_jira_project(test) finding_groups = test.finding_group_set.all().prefetch_related( 'findings', 'jira_issue', 'creator') bulk_edit_form = FindingBulkUpdateForm(request.GET) google_sheets_enabled = system_settings.enable_google_sheets sheet_url = None if google_sheets_enabled and system_settings.credentials: spreadsheet_name = test.engagement.product.name + "-" + test.engagement.name + "-" + str( test.id) system_settings = get_object_or_404(System_Settings, id=1) service_account_info = json.loads(system_settings.credentials) SCOPES = ['https://www.googleapis.com/auth/drive'] credentials = service_account.Credentials.from_service_account_info( service_account_info, scopes=SCOPES) try: drive_service = googleapiclient.discovery.build( 'drive', 'v3', credentials=credentials, cache_discovery=False) folder_id = system_settings.drive_folder_ID gs_files = drive_service.files().list( q="mimeType='application/vnd.google-apps.spreadsheet' and parents in '%s' and name='%s'" % (folder_id, spreadsheet_name), spaces='drive', pageSize=10, fields='files(id, name)').execute() except googleapiclient.errors.HttpError: messages.add_message( request, messages.ERROR, "There is a problem with the Google Sheets Sync Configuration. Contact your system admin to solve the issue. Until fixed, the Google Sheets Sync feature cannot be used.", extra_tags="alert-danger", ) google_sheets_enabled = False except httplib2.ServerNotFoundError: messages.add_message( request, messages.ERROR, "Unable to reach the Google Sheet API.", extra_tags="alert-danger", ) else: spreadsheets = gs_files.get('files') if len(spreadsheets) == 1: spreadsheetId = spreadsheets[0].get('id') sheet_url = 'https://docs.google.com/spreadsheets/d/' + spreadsheetId return render( request, 'dojo/view_test.html', { 'test': test, 'prod': prod, 'product_tab': product_tab, 'findings': paged_findings, 'filtered': findings, 'stub_findings': paged_stub_findings, 'title_words': title_words, 'component_words': component_words, 'form': form, 'notes': notes, 'files': files, 'person': person, 'request': request, 'show_re_upload': show_re_upload, 'creds': creds, 'cred_test': cred_test, 'jira_project': jira_project, 'show_export': google_sheets_enabled and system_settings.credentials, 'sheet_url': sheet_url, 'bulk_edit_form': bulk_edit_form, 'paged_test_imports': paged_test_imports, 'test_import_filter': test_import_filter, 'finding_groups': finding_groups, 'finding_group_by_options': Finding_Group.GROUP_BY_OPTIONS, })
def view_endpoint(request, eid): endpoint = get_object_or_404(Endpoint, id=eid) host = endpoint.host_no_port endpoints = Endpoint.objects.filter(host__regex="^" + host + ":?", product=endpoint.product).distinct() if (request.user in endpoint.product.authorized_users.all() ) or request.user.is_staff: pass else: raise PermissionDenied ct = ContentType.objects.get_for_model(endpoint) endpoint_cf = CustomField.objects.filter(content_type=ct) endpoint_metadata = {} for cf in endpoint_cf: cfv = CustomFieldValue.objects.filter(field=cf, object_id=endpoint.id) if len(cfv): endpoint_metadata[cf] = cfv[0] all_findings = Finding.objects.filter(endpoints__in=endpoints).distinct() active_findings = Finding.objects.filter(endpoints__in=endpoints, active=True, verified=True).distinct() closed_findings = Finding.objects.filter( endpoints__in=endpoints, mitigated__isnull=False).distinct() if all_findings: start_date = timezone.make_aware( datetime.combine(all_findings.last().date, datetime.min.time())) else: start_date = timezone.now() end_date = timezone.now() r = relativedelta(end_date, start_date) months_between = (r.years * 12) + r.months # include current month months_between += 1 monthly_counts = get_period_counts(active_findings, all_findings, closed_findings, None, months_between, start_date, relative_delta='months') paged_findings = get_page_items(request, active_findings, 25) vulnerable = False if active_findings.count() != 0: vulnerable = True add_breadcrumb(parent=endpoint, top_level=False, request=request) return render( request, "dojo/view_endpoint.html", { "endpoint": endpoint, "endpoints": endpoints, "findings": paged_findings, 'all_findings': all_findings, 'opened_per_month': monthly_counts['opened_per_period'], 'endpoint_metadata': endpoint_metadata, 'vulnerable': vulnerable, })
def generate_report(request, obj): user = Dojo_User.objects.get(id=request.user.id) product_type = None product = None engagement = None test = None endpoint = None endpoints = None endpoint_all_findings = None endpoint_monthly_counts = None endpoint_active_findings = None accepted_findings = None open_findings = None closed_findings = None verified_findings = None report_title = None report_subtitle = None report_info = "Generated By %s on %s" % (user.get_full_name(), ( timezone.now().strftime("%m/%d/%Y %I:%M%p %Z"))) if type(obj).__name__ == "Product": if request.user.is_staff or check_auth_users_list(request.user, obj): pass # user is authorized for this product else: raise PermissionDenied elif type(obj).__name__ == "Endpoint": if request.user.is_staff or check_auth_users_list(request.user, obj): pass # user is authorized for this product else: raise PermissionDenied elif type(obj).__name__ == "QuerySet" or type( obj).__name__ == "CastTaggedQuerySet": # authorization taken care of by only selecting findings from product user is authed to see pass else: if not request.user.is_staff: raise PermissionDenied report_format = request.GET.get('report_type', 'AsciiDoc') include_finding_notes = int(request.GET.get('include_finding_notes', 0)) include_finding_images = int(request.GET.get('include_finding_images', 0)) include_executive_summary = int( request.GET.get('include_executive_summary', 0)) include_table_of_contents = int( request.GET.get('include_table_of_contents', 0)) generate = "_generate" in request.GET report_name = str(obj) report_type = type(obj).__name__ add_breadcrumb(title="Generate Report", top_level=False, request=request) if type(obj).__name__ == "Product_Type": product_type = obj filename = "product_type_finding_report.pdf" template = "dojo/product_type_pdf_report.html" report_name = "Product Type Report: " + str(product_type) report_title = "Product Type Report" report_subtitle = str(product_type) findings = ReportFindingFilter( request.GET, prod_type=product_type, queryset=prefetch_related_findings_for_report( Finding.objects.filter( test__engagement__product__prod_type=product_type))) products = Product.objects.filter( prod_type=product_type, engagement__test__finding__in=findings.qs).distinct() engagements = Engagement.objects.filter( product__prod_type=product_type, test__finding__in=findings.qs).distinct() tests = Test.objects.filter( engagement__product__prod_type=product_type, finding__in=findings.qs).distinct() if len(findings.qs) > 0: start_date = timezone.make_aware( datetime.combine(findings.qs.last().date, datetime.min.time())) else: start_date = timezone.now() end_date = timezone.now() r = relativedelta(end_date, start_date) months_between = (r.years * 12) + r.months # include current month months_between += 1 endpoint_monthly_counts = get_period_counts_legacy( findings.qs.order_by('numerical_severity'), findings.qs.order_by('numerical_severity'), None, months_between, start_date, relative_delta='months') context = { 'product_type': product_type, 'products': products, 'engagements': engagements, 'tests': tests, 'report_name': report_name, 'endpoint_opened_per_month': endpoint_monthly_counts['opened_per_period'] if endpoint_monthly_counts is not None else [], 'endpoint_active_findings': findings.qs.order_by('numerical_severity'), 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'host': report_url_resolver(request), 'user_id': request.user.id } elif type(obj).__name__ == "Product": product = obj filename = "product_finding_report.pdf" template = "dojo/product_pdf_report.html" report_name = "Product Report: " + str(product) report_title = "Product Report" report_subtitle = str(product) findings = ReportFindingFilter( request.GET, product=product, queryset=prefetch_related_findings_for_report( Finding.objects.filter(test__engagement__product=product))) ids = set(finding.id for finding in findings.qs) engagements = Engagement.objects.filter( test__finding__id__in=ids).distinct() tests = Test.objects.filter(finding__id__in=ids).distinct() ids = get_endpoint_ids( Endpoint.objects.filter(product=product).distinct()) endpoints = Endpoint.objects.filter(id__in=ids) context = { 'product': product, 'engagements': engagements, 'tests': tests, 'report_name': report_name, 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'endpoints': endpoints, 'host': report_url_resolver(request), 'user_id': request.user.id } elif type(obj).__name__ == "Engagement": logger.debug('generating report for Engagement') engagement = obj findings = ReportFindingFilter( request.GET, engagement=engagement, queryset=prefetch_related_findings_for_report( Finding.objects.filter(test__engagement=engagement))) report_name = "Engagement Report: " + str(engagement) filename = "engagement_finding_report.pdf" template = 'dojo/engagement_pdf_report.html' report_title = "Engagement Report" report_subtitle = str(engagement) ids = set(finding.id for finding in findings.qs) tests = Test.objects.filter(finding__id__in=ids).distinct() ids = get_endpoint_ids( Endpoint.objects.filter(product=engagement.product).distinct()) endpoints = Endpoint.objects.filter(id__in=ids) context = { 'engagement': engagement, 'tests': tests, 'report_name': report_name, 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'host': report_url_resolver(request), 'user_id': request.user.id, 'endpoints': endpoints } elif type(obj).__name__ == "Test": test = obj findings = ReportFindingFilter( request.GET, engagement=test.engagement, queryset=prefetch_related_findings_for_report( Finding.objects.filter(test=test))) filename = "test_finding_report.pdf" template = "dojo/test_pdf_report.html" report_name = "Test Report: " + str(test) report_title = "Test Report" report_subtitle = str(test) context = { 'test': test, 'report_name': report_name, 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'host': report_url_resolver(request), 'user_id': request.user.id } elif type(obj).__name__ == "Endpoint": endpoint = obj host = endpoint.host_no_port report_name = "Endpoint Report: " + host report_type = "Endpoint" endpoints = Endpoint.objects.filter( host__regex="^" + host + ":?", product=endpoint.product).distinct() filename = "endpoint_finding_report.pdf" template = 'dojo/endpoint_pdf_report.html' report_title = "Endpoint Report" report_subtitle = host findings = ReportFindingFilter( request.GET, queryset=prefetch_related_findings_for_report( Finding.objects.filter(endpoints__in=endpoints))) context = { 'endpoint': endpoint, 'endpoints': endpoints, 'report_name': report_name, 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': get_system_setting('team_name'), 'title': report_title, 'host': report_url_resolver(request), 'user_id': request.user.id } elif type(obj).__name__ == "QuerySet" or type( obj).__name__ == "CastTaggedQuerySet": findings = ReportAuthedFindingFilter( request.GET, queryset=prefetch_related_findings_for_report(obj).distinct()) filename = "finding_report.pdf" report_name = 'Finding' report_type = 'Finding' template = 'dojo/finding_pdf_report.html' report_title = "Finding Report" report_subtitle = '' context = { 'findings': findings.qs.order_by('numerical_severity'), 'report_name': report_name, 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'host': report_url_resolver(request), 'user_id': request.user.id } else: raise Http404() report_form = ReportOptionsForm() if generate: report_form = ReportOptionsForm(request.GET) if report_format == 'AsciiDoc': return render( request, 'dojo/asciidoc_report.html', { 'product_type': product_type, 'product': product, 'engagement': engagement, 'test': test, 'endpoint': endpoint, 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'user_id': request.user.id, 'host': report_url_resolver(request), 'context': context, }) elif report_format == 'PDF': if 'regen' in request.GET: # we should already have a report object, lets get and use it report = get_object_or_404(Report, id=request.GET['regen']) report.datetime = timezone.now() report.status = 'requested' if report.requester.username != request.user.username: report.requester = request.user else: # lets create the report object and send it in to celery task report = Report(name=report_name, type=report_type, format='PDF', requester=request.user, task_id='tbd', options=request.path + "?" + request.GET.urlencode()) report.save() async_pdf_report.delay(report=report, template=template, filename=filename, report_title=report_title, report_subtitle=report_subtitle, report_info=report_info, context=context, uri=request.build_absolute_uri( report.get_url())) messages.add_message(request, messages.SUCCESS, 'Your report is building.', extra_tags='alert-success') return HttpResponseRedirect(reverse('reports')) elif report_format == 'HTML': return render( request, template, { 'product_type': product_type, 'product': product, 'engagement': engagement, 'report_name': report_name, 'test': test, 'endpoint': endpoint, 'endpoints': endpoints, 'findings': findings.qs.order_by('numerical_severity'), 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'user_id': request.user.id, 'host': "", 'context': context, }) else: raise Http404() paged_findings = get_page_items(request, findings.qs.order_by('numerical_severity'), 25) product_tab = None if engagement: product_tab = Product_Tab(engagement.product.id, title="Engagement Report", tab="engagements") product_tab.setEngagement(engagement) elif test: product_tab = Product_Tab(test.engagement.product.id, title="Test Report", tab="engagements") product_tab.setEngagement(test.engagement) elif product: product_tab = Product_Tab(product.id, title="Product Report", tab="findings") elif endpoints: product_tab = Product_Tab(endpoint.product.id, title="Endpoint Report", tab="endpoints") return render( request, 'dojo/request_report.html', { 'product_type': product_type, 'product': product, 'product_tab': product_tab, 'engagement': engagement, 'test': test, 'endpoint': endpoint, 'findings': findings, 'paged_findings': paged_findings, 'report_form': report_form, 'context': context, })
def product_endpoint_report(request, pid): user = Dojo_User.objects.get(id=request.user.id) product = get_object_or_404(Product.objects.all().prefetch_related( 'engagement_set__test_set__test_type', 'engagement_set__test_set__environment'), id=pid) endpoint_ids = Endpoint.objects.filter( product=product, finding__active=True, finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False, ).values_list('id', flat=True) # ids = get_endpoint_ids(endpoints) endpoints = prefetch_related_endpoints_for_report( Endpoint.objects.filter(id__in=endpoint_ids)) endpoints = EndpointReportFilter(request.GET, queryset=endpoints) paged_endpoints = get_page_items(request, endpoints.qs, 25) report_format = request.GET.get('report_type', 'AsciiDoc') include_finding_notes = int(request.GET.get('include_finding_notes', 0)) include_finding_images = int(request.GET.get('include_finding_images', 0)) include_executive_summary = int( request.GET.get('include_executive_summary', 0)) include_table_of_contents = int( request.GET.get('include_table_of_contents', 0)) generate = "_generate" in request.GET add_breadcrumb(parent=product, title="Vulnerable Product Endpoints Report", top_level=False, request=request) report_form = ReportOptionsForm() filename = "product_endpoint_report.pdf" template = "dojo/product_endpoint_pdf_report.html" report_name = "Product Endpoint Report: " + str(product) report_title = "Product Endpoint Report" report_subtitle = str(product) report_info = "Generated By %s on %s" % (user.get_full_name(), ( timezone.now().strftime("%m/%d/%Y %I:%M%p %Z"))) try: start_date = Finding.objects.filter( endpoints__in=endpoints.qs).order_by('date')[:1][0].date except: start_date = timezone.now() end_date = timezone.now() risk_acceptances = Risk_Acceptance.objects.filter( engagement__test__finding__endpoints__in=endpoints.qs) accepted_findings = [ finding for ra in risk_acceptances for finding in ra.accepted_findings.filter(endpoints__in=endpoints.qs) ] verified_findings = Finding.objects.filter( endpoints__in=endpoints.qs, date__range=[start_date, end_date], false_p=False, verified=True, duplicate=False, out_of_scope=False) open_findings = Finding.objects.filter(endpoints__in=endpoints.qs, false_p=False, verified=True, duplicate=False, out_of_scope=False, active=True, mitigated__isnull=True) closed_findings = Finding.objects.filter(endpoints__in=endpoints.qs, false_p=False, verified=True, duplicate=False, out_of_scope=False, mitigated__isnull=False) if generate: report_form = ReportOptionsForm(request.GET) if report_format == 'AsciiDoc': return render( request, 'dojo/asciidoc_report.html', { 'product_type': None, 'product': product, 'accepted_findings': accepted_findings, 'open_findings': open_findings, 'closed_findings': closed_findings, 'verified_findings': verified_findings, 'engagement': None, 'test': None, 'endpoints': endpoints, 'endpoint': None, 'findings': None, 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': request.user, 'title': 'Generate Report', }) elif report_format == 'PDF': endpoints = endpoints.qs.order_by('finding__numerical_severity') # lets create the report object and send it in to celery task if 'regen' in request.GET: # we should already have a report object, lets get and use it report = get_object_or_404(Report, id=request.GET['regen']) report.datetime = timezone.now() report.status = 'requested' if report.requester.username != request.user.username: report.requester = request.user else: report = Report(name="Product Endpoints " + str(product), type="Product Endpoint", format='PDF', requester=request.user, task_id='tbd', options=request.path + "?" + request.GET.urlencode()) report.save() async_pdf_report.delay( report=report, template=template, filename=filename, report_title=report_title, report_subtitle=report_subtitle, report_info=report_info, context={ 'product': product, 'endpoints': endpoints, 'accepted_findings': accepted_findings, 'open_findings': open_findings, 'closed_findings': closed_findings, 'verified_findings': verified_findings, 'report_name': report_name, 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': user, 'team_name': get_system_setting('team_name'), 'title': 'Generate Report', 'host': report_url_resolver(request), 'user_id': request.user.id }, uri=request.build_absolute_uri(report.get_url())) messages.add_message(request, messages.SUCCESS, 'Your report is building.', extra_tags='alert-success') return HttpResponseRedirect(reverse('reports')) elif report_format == 'HTML': return render( request, template, { 'product_type': None, 'product': product, 'engagement': None, 'test': None, 'endpoint': None, 'endpoints': endpoints.qs, 'findings': None, 'include_finding_notes': include_finding_notes, 'include_finding_images': include_finding_images, 'include_executive_summary': include_executive_summary, 'include_table_of_contents': include_table_of_contents, 'user': request.user, 'title': 'Generate Report', }) else: raise Http404() product_tab = Product_Tab(product.id, "Product Endpoint Report", tab="endpoints") return render( request, 'dojo/request_endpoint_report.html', { "endpoints": paged_endpoints, "filtered": endpoints, "product_tab": product_tab, 'report_form': report_form, "name": "Vulnerable Product Endpoints", })