Skip to content

Commit 72f55a0

Browse files
authored
Merge pull request DefectDojo#639 from aaronweaver/dev
Veracode filepath for importer
2 parents c19e683 + 52e2c4e commit 72f55a0

File tree

12 files changed

+242
-151
lines changed

12 files changed

+242
-151
lines changed

dojo/api.py

Lines changed: 83 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
BurpRawRequestResponse, Endpoint, Notes, JIRA_PKey, JIRA_Conf, \
2323
JIRA_Issue, Tool_Product_Settings, Tool_Configuration, Tool_Type, \
2424
Languages, Language_Type, App_Analysis
25-
from dojo.forms import ProductForm, EngForm2, TestForm, \
25+
from dojo.forms import ProductForm, EngForm, TestForm, \
2626
ScanSettingsForm, FindingForm, StubFindingForm, FindingTemplateForm, \
2727
ImportScanForm, SEVERITY_CHOICES, JIRAForm, JIRA_PKeyForm, EditEndpointForm, \
2828
JIRA_IssueForm, ToolConfigForm, ToolProductSettingsForm, \
@@ -391,6 +391,78 @@ def obj_update(self, bundle, request=None, **kwargs):
391391
return bundle
392392

393393

394+
"""
395+
/api/v1/tool_configurations/
396+
GET [/id/], DELETE [/id/]
397+
Expects: no params or id
398+
Returns Tool_ConfigurationResource
399+
Relevant apply filter ?test_type=?, ?id=?
400+
401+
POST, PUT, DLETE [/id/]
402+
"""
403+
404+
405+
class Tool_TypeResource(BaseModelResource):
406+
407+
class Meta:
408+
resource_name = 'tool_types'
409+
list_allowed_methods = ['get', 'post', 'put', 'delete']
410+
detail_allowed_methods = ['get', 'post', 'put', 'delete']
411+
queryset = Tool_Type.objects.all()
412+
include_resource_uri = True
413+
filtering = {
414+
'id': ALL,
415+
'name': ALL,
416+
'description': ALL,
417+
}
418+
authentication = DojoApiKeyAuthentication()
419+
authorization = DjangoAuthorization()
420+
serializer = Serializer(formats=['json'])
421+
422+
@property
423+
def validation(self):
424+
return ModelFormValidation(form_class=ToolTypeForm, resource=Tool_TypeResource)
425+
426+
427+
"""
428+
/api/v1/tool_configurations/
429+
GET [/id/], DELETE [/id/]
430+
Expects: no params or id
431+
Returns Tool_ConfigurationResource
432+
Relevant apply filter ?test_type=?, ?id=?
433+
434+
POST, PUT, DLETE [/id/]
435+
"""
436+
437+
438+
class Tool_ConfigurationResource(BaseModelResource):
439+
440+
tool_type = fields.ForeignKey(Tool_TypeResource, 'tool_type', full=False, null=False)
441+
442+
class Meta:
443+
resource_name = 'tool_configurations'
444+
list_allowed_methods = ['get', 'post', 'put', 'delete']
445+
detail_allowed_methods = ['get', 'post', 'put', 'delete']
446+
queryset = Tool_Configuration.objects.all()
447+
include_resource_uri = True
448+
filtering = {
449+
'id': ALL,
450+
'name': ALL,
451+
'tool_type': ALL_WITH_RELATIONS,
452+
'name': ALL,
453+
'tool_project_id': ALL,
454+
'url': ALL,
455+
'authentication_type': ALL,
456+
}
457+
authentication = DojoApiKeyAuthentication()
458+
authorization = DjangoAuthorization()
459+
serializer = Serializer(formats=['json'])
460+
461+
@property
462+
def validation(self):
463+
return ModelFormValidation(form_class=ToolConfigForm, resource=Tool_ConfigurationResource)
464+
465+
394466
"""
395467
POST, PUT [/id/]
396468
Expects *product *target_start, *target_end, *status[In Progress, On Hold,
@@ -403,12 +475,18 @@ class EngagementResource(BaseModelResource):
403475
full=False, null=False)
404476
lead = fields.ForeignKey(UserResource, 'lead',
405477
full=False, null=True)
478+
source_code_management_server = fields.ForeignKey(Tool_ConfigurationResource, 'source_code_management_server',
479+
full=False, null=False)
480+
build_server = fields.ForeignKey(Tool_ConfigurationResource, 'build_server',
481+
full=False, null=False)
482+
orchestration_engine = fields.ForeignKey(Tool_ConfigurationResource, 'orchestration_engine',
483+
full=False, null=False)
406484

407485
class Meta:
408486
resource_name = 'engagements'
409-
list_allowed_methods = ['get', 'post']
487+
list_allowed_methods = ['get', 'post', 'patch']
410488
# disabled delete for /id/
411-
detail_allowed_methods = ['get', 'post', 'put']
489+
detail_allowed_methods = ['get', 'post', 'put', 'patch']
412490
queryset = Engagement.objects.all()
413491
include_resource_uri = True
414492
filtering = {
@@ -425,14 +503,15 @@ class Meta:
425503
'pen_test': ALL,
426504
'status': ALL,
427505
'product': ALL,
506+
'tool_configuration': ALL_WITH_RELATIONS,
428507
}
429508
authentication = DojoApiKeyAuthentication()
430509
authorization = DjangoAuthorization()
431510
serializer = Serializer(formats=['json'])
432511

433512
@property
434513
def validation(self):
435-
return ModelFormValidation(form_class=EngForm2, resource=EngagementResource)
514+
return ModelFormValidation(form_class=EngForm, resource=EngagementResource)
436515

437516
def dehydrate(self, bundle):
438517
if bundle.obj.eng_type is not None:
@@ -564,78 +643,6 @@ def validation(self):
564643
return ModelFormValidation(form_class=LanguagesTypeForm, resource=LanguagesResource)
565644

566645

567-
"""
568-
/api/v1/tool_configurations/
569-
GET [/id/], DELETE [/id/]
570-
Expects: no params or id
571-
Returns Tool_ConfigurationResource
572-
Relevant apply filter ?test_type=?, ?id=?
573-
574-
POST, PUT, DLETE [/id/]
575-
"""
576-
577-
578-
class Tool_TypeResource(BaseModelResource):
579-
580-
class Meta:
581-
resource_name = 'tool_types'
582-
list_allowed_methods = ['get', 'post', 'put', 'delete']
583-
detail_allowed_methods = ['get', 'post', 'put', 'delete']
584-
queryset = Tool_Type.objects.all()
585-
include_resource_uri = True
586-
filtering = {
587-
'id': ALL,
588-
'name': ALL,
589-
'description': ALL,
590-
}
591-
authentication = DojoApiKeyAuthentication()
592-
authorization = DjangoAuthorization()
593-
serializer = Serializer(formats=['json'])
594-
595-
@property
596-
def validation(self):
597-
return ModelFormValidation(form_class=ToolTypeForm, resource=Tool_TypeResource)
598-
599-
600-
"""
601-
/api/v1/tool_configurations/
602-
GET [/id/], DELETE [/id/]
603-
Expects: no params or id
604-
Returns Tool_ConfigurationResource
605-
Relevant apply filter ?test_type=?, ?id=?
606-
607-
POST, PUT, DLETE [/id/]
608-
"""
609-
610-
611-
class Tool_ConfigurationResource(BaseModelResource):
612-
613-
tool_type = fields.ForeignKey(Tool_TypeResource, 'tool_type', full=False, null=False)
614-
615-
class Meta:
616-
resource_name = 'tool_configurations'
617-
list_allowed_methods = ['get', 'post', 'put', 'delete']
618-
detail_allowed_methods = ['get', 'post', 'put', 'delete']
619-
queryset = Tool_Configuration.objects.all()
620-
include_resource_uri = True
621-
filtering = {
622-
'id': ALL,
623-
'name': ALL,
624-
'tool_type': ALL_WITH_RELATIONS,
625-
'name': ALL,
626-
'tool_project_id': ALL,
627-
'url': ALL,
628-
'authentication_type': ALL,
629-
}
630-
authentication = DojoApiKeyAuthentication()
631-
authorization = DjangoAuthorization()
632-
serializer = Serializer(formats=['json'])
633-
634-
@property
635-
def validation(self):
636-
return ModelFormValidation(form_class=ToolConfigForm, resource=Tool_ConfigurationResource)
637-
638-
639646
"""
640647
/api/v1/tool_product_settings/
641648
GET [/id/], DELETE [/id/]

dojo/finding/urls.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
urlpatterns = [
66
# findings
7+
url(r'^finding$', views.open_findings, {'view': 'All'},
8+
name='all_findings'),
79
url(r'^finding$', views.open_findings,
810
name='findings'),
911
url(r'^finding/bulk$', views.finding_bulk_update_all,
@@ -14,6 +16,8 @@
1416
name='open_findings'),
1517
url(r'^product/(?P<pid>\d+)/finding/open$', views.open_findings,
1618
name='product_open_findings'),
19+
url(r'^product/(?P<pid>\d+)/finding/all$', views.open_findings, {'view': 'All'},
20+
name='product_all_findings'),
1721
url(r'^product/(?P<pid>\d+)/finding/closed$', views.closed_findings,
1822
name='product_closed_findings'),
1923
url(r'^product/(?P<pid>\d+)/finding/accepted$', views.accepted_findings,

dojo/finding/views.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
FindingFormID, FindingBulkUpdateForm, MergeFindings
3232
from dojo.models import Product_Type, Finding, Notes, \
3333
Risk_Acceptance, BurpRawRequestResponse, Stub_Finding, Endpoint, Finding_Template, FindingImage, \
34-
FindingImageAccessToken, JIRA_Issue, JIRA_PKey, Dojo_User, Cred_Mapping, Test, Product
34+
FindingImageAccessToken, JIRA_Issue, JIRA_PKey, Dojo_User, Cred_Mapping, Test, Product, User
3535
from dojo.utils import get_page_items, add_breadcrumb, FileIterWrapper, process_notifications, \
3636
add_comment, jira_get_resolution_id, jira_change_resolution_id, get_jira_connection, \
3737
get_system_setting, create_notification, apply_cwe_to_template, Product_Tab, calculate_grade
@@ -42,15 +42,23 @@
4242
logger = logging.getLogger(__name__)
4343

4444

45-
def open_findings(request, pid=None):
45+
def open_findings(request, pid=None, view=None):
4646
show_product_column = True
4747
title = None
4848
custom_breadcrumb = None
49-
49+
filter_name = "Open"
5050
if pid:
51-
findings = Finding.objects.filter(test__engagement__product__id=pid, active=True, duplicate=False).order_by('numerical_severity')
51+
if view == "All":
52+
filter_name = "All"
53+
findings = Finding.objects.filter(test__engagement__product__id=pid).order_by('numerical_severity')
54+
else:
55+
findings = Finding.objects.filter(test__engagement__product__id=pid, active=True, duplicate=False).order_by('numerical_severity')
5256
else:
53-
findings = Finding.objects.filter(active=True, duplicate=False).order_by('numerical_severity')
57+
if view == "All":
58+
filter_name = "All"
59+
findings = Finding.objects.all().order_by('numerical_severity')
60+
else:
61+
findings = Finding.objects.filter(active=True, duplicate=False).order_by('numerical_severity')
5462

5563
if request.user.is_staff:
5664
findings = OpenFingingSuperFilter(
@@ -111,7 +119,7 @@ def open_findings(request, pid=None):
111119
"title_words": title_words,
112120
'found_by': found_by,
113121
'custom_breadcrumb': custom_breadcrumb,
114-
'filter_name': "Open",
122+
'filter_name': filter_name,
115123
'title': title
116124
})
117125

@@ -1040,21 +1048,31 @@ def apply_cwe_mitigation(apply_to_findings, template, update=True):
10401048

10411049
finding_ids = None
10421050
result_list = None
1051+
# Exclusion list
10431052
for title_template in finding_templates:
10441053
finding_ids = Finding.objects.filter(active=True, verified=True, cwe=title_template.cwe, title__icontains=title_template.title).values_list('id', flat=True)
10451054
if result_list is None:
10461055
result_list = finding_ids
10471056
else:
10481057
result_list = list(chain(result_list, finding_ids))
10491058

1050-
count = Finding.objects.filter(active=True, verified=True, cwe=template.cwe).exclude(id__in=result_list)
1059+
# If result_list is None the filter exclude won't work
1060+
if result_list:
1061+
count = Finding.objects.filter(active=True, verified=True, cwe=template.cwe).exclude(id__in=result_list)
1062+
else:
1063+
count = Finding.objects.filter(active=True, verified=True, cwe=template.cwe)
10511064

10521065
if update:
1053-
# MySQL won't allow an 'update in satement' so loop will have to do
1066+
# MySQL won't allow an 'update in statement' so loop will have to do
10541067
for finding in count:
10551068
finding.mitigation = template.mitigation
10561069
finding.impact = template.impact
10571070
finding.references = template.references
1071+
new_note = Notes()
1072+
new_note.entry = 'CWE remediation text applied to finding for CWE: %s using template: %s.' % (template.cwe, template.title)
1073+
new_note.author, created = User.objects.get_or_create(username='System')
1074+
new_note.save()
1075+
finding.notes.add(new_note)
10581076
finding.save()
10591077

10601078
count = count.count()

dojo/forms.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,9 @@ class Meta:
625625
exclude = ['name', 'version', 'eng_type', 'first_contacted', 'target_start',
626626
'target_end', 'lead', 'requester', 'reason', 'report_type',
627627
'product', 'test_strategy', 'threat_model', 'api_test', 'pen_test',
628-
'check_list', 'status', 'description']
628+
'check_list', 'status', 'description', 'engagement_type', 'build_id',
629+
'commit_hash', 'branch_tag', 'build_server', 'source_code_management_server',
630+
'source_code_management_uri', 'orchestration_engine']
629631

630632

631633
class TestForm(forms.ModelForm):

dojo/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ class Finding_Template(models.Model):
12381238
impact = models.TextField(null=True, blank=True)
12391239
references = models.TextField(null=True, blank=True, db_column="refs")
12401240
numerical_severity = models.CharField(max_length=4, null=True, blank=True, editable=False)
1241-
template_match = models.BooleanField(default=False, verbose_name='Template Match Enabled', help_text="Enables this template on matching for global advice.")
1241+
template_match = models.BooleanField(default=False, verbose_name='Template Match Enabled', help_text="Enables this template for matching remediation advice. Match will be applied to all active, verified findings by CWE.")
12421242
template_match_title = models.BooleanField(default=False, verbose_name='Match Template by Title and CWE', help_text="Matches by title text (contains search) and CWE.")
12431243

12441244
SEVERITIES = {'Info': 4, 'Low': 3, 'Medium': 2,

dojo/templates/base.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@
181181
<li>
182182
<a href="{% url 'accepted_findings' %}">Accepted Findings</a>
183183
</li>
184+
<li>
185+
<a href="{% url 'all_findings' %}">All Findings</a>
186+
</li>
184187
<li>
185188
<a href="{% url 'closed_findings' %}">Closed Findings</a>
186189
</li>
@@ -329,6 +332,7 @@ <h3 class="no-margin-top" style="padding-bottom: 5px;">
329332
<li><a href="{% url 'product_open_findings' product_tab.product.id %}?active=2&verified=2&false_p=3&duplicate=2&out_of_scope=1&test__engagement__product={{ product_tab.product.id }}&date=2"><i class="fa fa-calendar"></i> View Findings from Last 7 Days </a></li>
330333
<li role="separator" class="divider"></li>
331334
<li><a href="{% url 'product_accepted_findings' product_tab.product.id %}?test__engagement__product={{ product_tab.product.id }}"><i class="fa fa-check"></i> View Accepted Findings</a></li>
335+
<li><a href="{% url 'product_all_findings' product_tab.product.id %}?test__engagement__product={{ product_tab.product.id }}"><i class="fa fa-search"></i> View All Findings</a></li>
332336
<li><a href="{% url 'product_closed_findings' product_tab.product.id %}?test__engagement__product={{ product_tab.product.id }}"><i class="fa fa-fire-extinguisher"></i>&nbsp;&nbsp;View Closed Findings </a></li>
333337
<li role="separator" class="divider"></li>
334338
<li><a href="{% url 'ad_hoc_finding' product_tab.product.id %}"><i class="fa fa-plus"></i> Add New Finding</a></li>

dojo/templates/dojo/findings_list.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<div class="panel panel-default">
99
<div class="panel-heading tight">
1010
<h3 class="has-filters">
11-
{{filter_name }} Findings
11+
{{ filter_name }} Findings
1212
<div class="dropdown pull-right"></div>
1313
</h3>
1414
</div>
@@ -278,7 +278,7 @@ <h3 class="has-filters">
278278
<a href="{{finding.jira_conf.url}}/browse/{{finding.jira.jira_key}}" target="_blank"> {{finding.jira.jira_key}} </a>
279279
</td>
280280
{% endif %}
281-
<td>{% if finding.under_review %}Under Review, {% endif %}{{ finding.status }}{% if finding.duplicate_finding.id %}, <a href="{% url 'view_finding' finding.duplicate_finding.id%}">Original</a>
281+
<td>{% if finding.under_review %}Under Review, {% endif %}{{ finding.status }}{% if finding.duplicate_finding.id %}, <a href="{% url 'view_finding' finding.duplicate_finding.id%}" data-toggle="tooltip" data-placement="top" title="{{ finding.title }}, {{ finding.created }}">Original</a>
282282
{% endif %}
283283
</td>
284284
{% if show_product_column and product_tab is None %}
@@ -323,6 +323,9 @@ <h3 class="has-filters">
323323
}
324324
}
325325
$(function () {
326+
$(document).ready(function(){
327+
$('[data-toggle="tooltip"]').tooltip();
328+
});
326329
check_checked_finding();
327330

328331
$('#id_status').on('click', function (e) {

0 commit comments

Comments
 (0)