def add_product_endpoint(request): if not settings.FEATURE_AUTHORIZATION_V2 and not request.user.is_staff: raise PermissionDenied form = AddEndpointForm() if request.method == 'POST': form = AddEndpointForm(request.POST) if form.is_valid(): if not settings.FEATURE_AUTHORIZATION_V2: if not user_is_authorized(request.user, 'change', form.product): raise PermissionDenied else: user_has_permission_or_403(request.user, form.product, Permissions.Endpoint_Add) endpoints = form.save() tags = request.POST.get('tags') for e in endpoints: e.tags = tags e.save() messages.add_message(request, messages.SUCCESS, 'Endpoint added successfully.', extra_tags='alert-success') return HttpResponseRedirect( reverse('endpoints') + "?product=%s" % form.product.id) add_breadcrumb(title="Add Endpoint", top_level=False, request=request) return render(request, 'dojo/add_endpoint.html', { 'name': 'Add Endpoint', 'form': form, })
def test_user_has_permission_or_403_success(self, mock_foo): mock_foo.select_related.return_value = mock_foo mock_foo.select_related.return_value = mock_foo mock_foo.filter.return_value = [self.product_type_member_owner] user_has_permission_or_403(self.user, self.product_type, Permissions.Product_Type_Delete) mock_foo.filter.assert_called_with(user=self.user)
def test_user_has_permission_or_403_success(self, mock_get): mock_get.return_value = self.product_type_member_owner user_has_permission_or_403(self.user, self.product_type, Permissions.Product_Type_Delete) self.assertEqual(mock_get.call_args[1]['user'], self.user) self.assertEqual(mock_get.call_args[1]['product_type'], self.product_type)
def process_endpoints_view(request, host_view=False, vulnerable=False): if vulnerable: endpoints = Endpoint.objects.filter(finding__active=True, finding__verified=True, finding__false_p=False, finding__duplicate=False, finding__out_of_scope=False, mitigated=False) else: endpoints = Endpoint.objects.all() endpoints = endpoints.prefetch_related('product', 'product__tags', 'tags').distinct() endpoints = get_authorized_endpoints(Permissions.Endpoint_View, endpoints, request.user) if host_view: 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) else: endpoints = EndpointFilter(request.GET, queryset=endpoints, user=request.user) paged_endpoints = get_page_items(request, endpoints.qs, 25) if vulnerable: view_name = "Vulnerable" else: view_name = "All" if host_view: view_name += " Endpoint Hosts" else: view_name += " Endpoints" add_breadcrumb(title=view_name, top_level=not len(request.GET), request=request) product_tab = None if 'product' in request.GET: p = request.GET.getlist('product', []) if len(p) == 1: product = get_object_or_404(Product, id=p[0]) if not settings.FEATURE_AUTHORIZATION_V2: if not user_is_authorized(request.user, 'view', product): raise PermissionDenied else: user_has_permission_or_403(request.user, product, Permissions.Product_View) product_tab = Product_Tab(product.id, view_name, tab="endpoints") return render( request, 'dojo/endpoints.html', { 'product_tab': product_tab, "endpoints": paged_endpoints, "filtered": endpoints, "name": view_name, "host_view": host_view, "product_tab": product_tab })
def all_endpoints(request): endpoints = Endpoint.objects.prefetch_related('product', 'tags', 'product__tags') endpoints = get_authorized_endpoints(Permissions.Endpoint_View, endpoints, request.user) show_uri = get_system_setting('display_endpoint_uri') 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]) if not settings.FEATURE_AUTHORIZATION_V2: if not user_is_authorized(request.user, 'view', product): raise PermissionDenied else: user_has_permission_or_403(request.user, product, Permissions.Product_View) if show_uri: endpoints = EndpointFilter(request.GET, queryset=endpoints, user=request.user) paged_endpoints = get_page_items(request, endpoints.qs, 25) else: 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="All Endpoints", top_level=not len(request.GET), request=request) product_tab = None view_name = "All Endpoints" if product: view_name = "Endpoints" product_tab = Product_Tab(product.id, "Endpoints", tab="endpoints") return render( request, 'dojo/endpoints.html', { 'product_tab': product_tab, "endpoints": paged_endpoints, "filtered": endpoints, "name": view_name, "show_uri": show_uri })
def _wrapped(request, *args, **kwargs): # Fetch object from database if isinstance(arg, int): # Lookup value came as a positional argument args = list(args) lookup_value = args[arg] else: # Lookup value was passed as keyword argument lookup_value = kwargs.get(arg) # object must exist obj = get_object_or_404(model.objects.filter(**{lookup: lookup_value})) user_has_permission_or_403(request.user, obj, permission) return func(request, *args, **kwargs)
def delete_issue(request, id, page, objid): note = get_object_or_404(Notes, id=id) reverse_url = None object_id = None if page == "engagement": object = get_object_or_404(Engagement, id=objid) object_id = object.id reverse_url = "view_engagement" elif page == "test": object = get_object_or_404(Test, id=objid) object_id = object.id reverse_url = "view_test" elif page == "finding": object = get_object_or_404(Finding, id=objid) object_id = object.id reverse_url = "view_finding" form = DeleteNoteForm(request.POST, instance=note) if page is None: raise PermissionDenied if str(request.user) != note.author.username: if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, object, Permissions.Note_Delete) else: if not request.user.is_staff: raise PermissionDenied if form.is_valid(): note.delete() messages.add_message(request, messages.SUCCESS, 'Note deleted.', extra_tags='alert-success') else: messages.add_message(request, messages.SUCCESS, 'Note was not succesfully deleted.', extra_tags='alert-danger') return HttpResponseRedirect(reverse(reverse_url, args=(object_id, )))
def generate_quick_report(request, findings, obj=None): product = engagement = test = None if obj: if type(obj).__name__ == "Product": product = obj user_has_permission_or_403(request.user, product, Permissions.Product_View) elif type(obj).__name__ == "Engagement": engagement = obj user_has_permission_or_403(request.user, engagement, Permissions.Engagement_View) elif type(obj).__name__ == "Test": test = obj user_has_permission_or_403(request.user, test, Permissions.Test_View) return render(request, 'dojo/finding_pdf_report.html', { 'report_name': 'Finding Report', 'product': product, 'engagement': engagement, 'test': test, 'findings': findings, 'user': request.user, 'team_name': settings.TEAM_NAME, 'title': 'Finding Report', 'user_id': request.user.id, })
def note_history(request, id, page, objid): note = get_object_or_404(Notes, id=id) reverse_url = None object_id = None if page == "engagement": object = get_object_or_404(Engagement, id=objid) object_id = object.id reverse_url = "view_engagement" elif page == "test": object = get_object_or_404(Test, id=objid) object_id = object.id reverse_url = "view_test" elif page == "finding": object = get_object_or_404(Finding, id=objid) object_id = object.id reverse_url = "view_finding" if page is None: raise PermissionDenied if str(request.user) != note.author.username: if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, object, Permissions.Note_View_History) else: if not request.user.is_staff: raise PermissionDenied history = note.history.all() if request.method == 'POST': return HttpResponseRedirect(reverse(reverse_url, args=(object_id, ))) return render(request, 'dojo/view_note_history.html', { 'history': history, 'note': note, 'page': page, 'objid': objid, })
def add_product_endpoint(request): form = AddEndpointForm() if request.method == 'POST': form = AddEndpointForm(request.POST) if form.is_valid(): user_has_permission_or_403(request.user, form.product, Permissions.Endpoint_Add) endpoints = form.save() tags = request.POST.get('tags') for e in endpoints: e.tags = tags e.save() messages.add_message(request, messages.SUCCESS, 'Endpoint added successfully.', extra_tags='alert-success') return HttpResponseRedirect(reverse('endpoint') + "?product=%s" % form.product.id) add_breadcrumb(title="Add Endpoint", top_level=False, request=request) return render(request, 'dojo/add_endpoint.html', {'name': 'Add Endpoint', 'form': form, })
def _wrapped(request, *args, **kwargs): # Fetch object from database if isinstance(arg, int): # Lookup value came as a positional argument args = list(args) lookup_value = args[arg] else: # Lookup value was passed as keyword argument lookup_value = kwargs.get(arg) # object must exist obj = get_object_or_404(model.objects.filter(**{lookup: lookup_value})) if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, obj, permission) else: if legacy_permission: if not legacy_check(request.user, legacy_permission, obj): raise PermissionDenied() elif not request.user.is_staff: raise PermissionDenied() return func(request, *args, **kwargs)
def endpoint_bulk_update_all(request, pid=None): if request.method == "POST": endpoints_to_update = request.POST.getlist('endpoints_to_update') finds = Endpoint.objects.filter( id__in=endpoints_to_update).order_by("endpoint_meta__product__id") total_endpoint_count = finds.count() if request.POST.get('delete_bulk_endpoints') and endpoints_to_update: if pid is None: if not request.user.is_staff: raise PermissionDenied else: product = get_object_or_404(Product, id=pid) user_has_permission_or_403(request.user, product, Permissions.Endpoint_Delete) finds = get_authorized_endpoints(Permissions.Endpoint_Delete, finds, request.user) skipped_endpoint_count = total_endpoint_count - finds.count() deleted_endpoint_count = finds.count() product_calc = list( Product.objects.filter( endpoint__id__in=endpoints_to_update).distinct()) finds.delete() for prod in product_calc: calculate_grade(prod) if skipped_endpoint_count > 0: add_error_message_to_response( 'Skipped deletion of {} endpoints because you are not authorized.' .format(skipped_endpoint_count)) if deleted_endpoint_count > 0: messages.add_message( request, messages.SUCCESS, 'Bulk delete of {} endpoints was successful.'.format( deleted_endpoint_count), extra_tags='alert-success') else: if endpoints_to_update: if pid is None: if not request.user.is_staff: raise PermissionDenied else: product = get_object_or_404(Product, id=pid) user_has_permission_or_403(request.user, product, Permissions.Finding_Edit) finds = get_authorized_endpoints(Permissions.Endpoint_Edit, finds, request.user) skipped_endpoint_count = total_endpoint_count - finds.count() updated_endpoint_count = finds.count() if skipped_endpoint_count > 0: add_error_message_to_response( 'Skipped mitigation of {} endpoints because you are not authorized.' .format(skipped_endpoint_count)) for endpoint in finds: endpoint.mitigated = not endpoint.mitigated endpoint.save() if updated_endpoint_count > 0: messages.add_message( request, messages.SUCCESS, 'Bulk mitigation of {} endpoints was successful.'. format(updated_endpoint_count), extra_tags='alert-success') else: messages.add_message( request, messages.ERROR, 'Unable to process bulk update. Required fields were not selected.', extra_tags='alert-danger') return HttpResponseRedirect(reverse('endpoint', args=()))
def product_type_counts(request): form = ProductTypeCountsForm() opened_in_period_list = [] oip = None cip = None aip = None all_current_in_pt = None top_ten = None pt = None today = timezone.now() first_of_month = today.replace(day=1, hour=0, minute=0, second=0, microsecond=0) mid_month = first_of_month.replace(day=15, hour=23, minute=59, second=59, microsecond=999999) end_of_month = mid_month.replace(day=monthrange(today.year, today.month)[1], hour=23, minute=59, second=59, microsecond=999999) start_date = first_of_month end_date = end_of_month if request.method == 'GET' and 'month' in request.GET and 'year' in request.GET and 'product_type' in request.GET: form = ProductTypeCountsForm(request.GET) if form.is_valid(): pt = form.cleaned_data['product_type'] if not settings.FEATURE_AUTHORIZATION_V2: if not user_is_authorized(request.user, 'view', pt): raise PermissionDenied else: user_has_permission_or_403(request.user, pt, Permissions.Product_Type_View) month = int(form.cleaned_data['month']) year = int(form.cleaned_data['year']) first_of_month = first_of_month.replace(month=month, year=year) month_requested = datetime(year, month, 1) end_of_month = month_requested.replace(day=monthrange(month_requested.year, month_requested.month)[1], hour=23, minute=59, second=59, microsecond=999999) start_date = first_of_month start_date = datetime(start_date.year, start_date.month, start_date.day, tzinfo=timezone.get_current_timezone()) end_date = end_of_month end_date = datetime(end_date.year, end_date.month, end_date.day, tzinfo=timezone.get_current_timezone()) oip = opened_in_period(start_date, end_date, pt) # trending data - 12 months for x in range(12, 0, -1): opened_in_period_list.append( opened_in_period(start_date + relativedelta(months=-x), end_of_month + relativedelta(months=-x), pt)) opened_in_period_list.append(oip) closed_in_period = Finding.objects.filter(mitigated__date__range=[start_date, end_date], test__engagement__product__prod_type=pt, severity__in=('Critical', 'High', 'Medium', 'Low')).values( 'numerical_severity').annotate(Count('numerical_severity')).order_by('numerical_severity') total_closed_in_period = Finding.objects.filter(mitigated__date__range=[start_date, end_date], test__engagement__product__prod_type=pt, severity__in=( 'Critical', 'High', 'Medium', 'Low')).aggregate( total=Sum( Case(When(severity__in=('Critical', 'High', 'Medium', 'Low'), then=Value(1)), output_field=IntegerField())))['total'] overall_in_pt = Finding.objects.filter(date__lt=end_date, verified=True, false_p=False, duplicate=False, out_of_scope=False, mitigated__isnull=True, test__engagement__product__prod_type=pt, severity__in=('Critical', 'High', 'Medium', 'Low')).values( 'numerical_severity').annotate(Count('numerical_severity')).order_by('numerical_severity') total_overall_in_pt = Finding.objects.filter(date__lte=end_date, verified=True, false_p=False, duplicate=False, out_of_scope=False, mitigated__isnull=True, test__engagement__product__prod_type=pt, severity__in=('Critical', 'High', 'Medium', 'Low')).aggregate( total=Sum( Case(When(severity__in=('Critical', 'High', 'Medium', 'Low'), then=Value(1)), output_field=IntegerField())))['total'] all_current_in_pt = Finding.objects.filter(date__lte=end_date, verified=True, false_p=False, duplicate=False, out_of_scope=False, mitigated__isnull=True, test__engagement__product__prod_type=pt, severity__in=( 'Critical', 'High', 'Medium', 'Low')).prefetch_related( 'test__engagement__product', 'test__engagement__product__prod_type', 'test__engagement__risk_acceptance', 'reporter').order_by( 'numerical_severity') top_ten = Product.objects.filter(engagement__test__finding__date__lte=end_date, engagement__test__finding__verified=True, engagement__test__finding__false_p=False, engagement__test__finding__duplicate=False, engagement__test__finding__out_of_scope=False, engagement__test__finding__mitigated__isnull=True, engagement__test__finding__severity__in=( 'Critical', 'High', 'Medium', 'Low'), prod_type=pt) top_ten = severity_count(top_ten, 'annotate', 'engagement__test__finding__severity').order_by('-critical', '-high', '-medium', '-low')[:10] cip = {'S0': 0, 'S1': 0, 'S2': 0, 'S3': 0, 'Total': total_closed_in_period} aip = {'S0': 0, 'S1': 0, 'S2': 0, 'S3': 0, 'Total': total_overall_in_pt} for o in closed_in_period: cip[o['numerical_severity']] = o['numerical_severity__count'] for o in overall_in_pt: aip[o['numerical_severity']] = o['numerical_severity__count'] else: messages.add_message(request, messages.ERROR, "Please choose month and year and the Product Type.", extra_tags='alert-danger') add_breadcrumb(title="Bi-Weekly Metrics", top_level=True, request=request) return render(request, 'dojo/pt_counts.html', {'form': form, 'start_date': start_date, 'end_date': end_date, 'opened_in_period': oip, 'trending_opened': opened_in_period_list, 'closed_in_period': cip, 'overall_in_pt': aip, 'all_current_in_pt': all_current_in_pt, 'top_ten': top_ten, 'pt': pt} )
def test_user_has_permission_or_403_exception(self): with self.assertRaises(PermissionDenied): user_has_permission_or_403(self.user, self.product_type, Permissions.Product_Type_Delete)
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 edit_issue(request, id, page, objid): note = get_object_or_404(Notes, id=id) reverse_url = None object_id = None if page == "engagement": object = get_object_or_404(Engagement, id=objid) object_id = object.id reverse_url = "view_engagement" elif page == "test": object = get_object_or_404(Test, id=objid) object_id = object.id reverse_url = "view_test" elif page == "finding": object = get_object_or_404(Finding, id=objid) object_id = object.id reverse_url = "view_finding" if page is None: raise PermissionDenied if str(request.user) != note.author.username: if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, object, Permissions.Note_Edit) else: if not request.user.is_staff: raise PermissionDenied note_type_activation = Note_Type.objects.filter(is_active=True).count() if note_type_activation: available_note_types = find_available_notetypes(object, note) if request.method == 'POST': if note_type_activation: form = TypedNoteForm(request.POST, available_note_types=available_note_types, instance=note) else: form = NoteForm(request.POST, instance=note) if form.is_valid(): note = form.save(commit=False) note.edited = True note.editor = request.user note.edit_time = timezone.now() if note_type_activation: history = NoteHistory(note_type=note.note_type, data=note.entry, time=note.edit_time, current_editor=note.editor) else: history = NoteHistory(data=note.entry, time=note.edit_time, current_editor=note.editor) history.save() note.history.add(history) note.save() object.last_reviewed = note.date object.last_reviewed_by = request.user object.save() form = NoteForm() messages.add_message(request, messages.SUCCESS, 'Note edited.', extra_tags='alert-success') return HttpResponseRedirect( reverse(reverse_url, args=(object_id, ))) else: messages.add_message(request, messages.SUCCESS, 'Note was not succesfully edited.', extra_tags='alert-danger') else: if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types, instance=note) else: form = NoteForm(instance=note) return render(request, 'dojo/edit_note.html', { 'note': note, 'form': form, 'page': page, 'objid': objid, })
def get_findings(request): url = request.META.get('QUERY_STRING') if not url: raise Http404('Please use the report button when viewing findings') else: if url.startswith('url='): url = url[4:] views = [ 'all', 'open', 'inactive', 'verified', 'closed', 'accepted', 'out_of_scope', 'false_positive', 'inactive' ] # request.path = url obj_name = obj_id = view = query = None path_items = list(filter(None, re.split('/|\?', url))) # noqa W605 try: finding_index = path_items.index('finding') except ValueError: finding_index = -1 # There is a engagement or product here if finding_index > 0: # path_items ['product', '1', 'finding', 'closed', 'test__engagement__product=1'] obj_name = get_list_index(path_items, 0) obj_id = get_list_index(path_items, 1) view = get_list_index(path_items, 3) query = get_list_index(path_items, 4) # Try to catch a mix up query = query if view in views else view # This is findings only. Accomodate view and query elif finding_index == 0: # path_items ['finding', 'closed', 'title=blah'] obj_name = get_list_index(path_items, 0) view = get_list_index(path_items, 1) query = get_list_index(path_items, 2) # Try to catch a mix up query = query if view in views else view # This is a test or engagement only elif finding_index == -1: # path_items ['test', '1', 'test__engagement__product=1'] obj_name = get_list_index(path_items, 0) obj_id = get_list_index(path_items, 1) query = get_list_index(path_items, 2) filter_name = None if view: if view == 'open': filter_name = 'Open' elif view == 'inactive': filter_name = 'Inactive' elif view == 'verified': filter_name = 'Verified' elif view == 'closed': filter_name = 'Closed' elif view == 'accepted': filter_name = 'Accepted' elif view == 'out_of_scope': filter_name = 'Out of Scope' elif view == 'false_positive': filter_name = 'False Positive' obj = pid = eid = tid = None if obj_id: if 'product' in obj_name: pid = obj_id obj = get_object_or_404(Product, id=pid) user_has_permission_or_403(request.user, obj, Permissions.Product_View) elif 'engagement' in obj_name: eid = obj_id obj = get_object_or_404(Engagement, id=eid) user_has_permission_or_403(request.user, obj, Permissions.Engagement_View) elif 'test' in obj_name: tid = obj_id obj = get_object_or_404(Test, id=tid) user_has_permission_or_403(request.user, obj, Permissions.Test_View) request.GET = QueryDict(query) findings = get_filtered_findings(request, pid, eid, tid, filter_name).qs return findings, obj
def generate_report(request, obj, host_view=False): user = Dojo_User.objects.get(id=request.user.id) product_type = None product = None engagement = None test = None endpoint = None endpoints = 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_Type": if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, obj, Permissions.Product_Type_View) else: if not (request.user.is_staff or check_auth_users_list(request.user, obj)): raise PermissionDenied elif type(obj).__name__ == "Product": if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, obj, Permissions.Product_View) else: if not (request.user.is_staff or check_auth_users_list(request.user, obj)): raise PermissionDenied elif type(obj).__name__ == "Engagement": if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, obj, Permissions.Engagement_View) else: if not (request.user.is_staff or check_auth_users_list(request.user, obj)): raise PermissionDenied elif type(obj).__name__ == "Test": if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, obj, Permissions.Test_View) else: if not (request.user.is_staff or check_auth_users_list(request.user, obj)): raise PermissionDenied elif type(obj).__name__ == "Endpoint": if settings.FEATURE_AUTHORIZATION_V2: user_has_permission_or_403(request.user, obj, Permissions.Endpoint_View) else: if not (request.user.is_staff or check_auth_users_list(request.user, obj)): 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)) include_disclaimer = int(request.GET.get('include_disclaimer', 0)) disclaimer = get_system_setting('disclaimer') if include_disclaimer and len(disclaimer) == 0: disclaimer = 'Please configure in System Settings.' 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 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.distinct().order_by('numerical_severity'), 'findings': findings.qs.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, '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 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() endpoints = Endpoint.objects.filter(product=product).distinct() context = { 'product': product, 'engagements': engagements, 'tests': tests, 'report_name': report_name, 'findings': findings.qs.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, '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) 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() endpoints = Endpoint.objects.filter( product=engagement.product).distinct() context = { 'engagement': engagement, 'tests': tests, 'report_name': report_name, 'findings': findings.qs.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, '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))) 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.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, '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 if host_view: report_name = "Endpoint Host Report: " + endpoint.host endpoints = Endpoint.objects.filter( host=endpoint.host, product=endpoint.product).distinct() report_title = "Endpoint Host Report" report_subtitle = endpoint.host else: report_name = "Endpoint Report: " + str(endpoint) endpoints = Endpoint.objects.filter(pk=endpoint.id).distinct() report_title = "Endpoint Report" report_subtitle = str(endpoint) report_type = "Endpoint" template = 'dojo/endpoint_pdf_report.html' 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.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, '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 = ReportFindingFilter( request.GET, queryset=prefetch_related_findings_for_report(obj).distinct()) report_name = 'Finding' report_type = 'Finding' template = 'dojo/finding_pdf_report.html' report_title = "Finding Report" report_subtitle = '' context = { 'findings': findings.qs.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, '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.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'user_id': request.user.id, 'host': report_url_resolver(request), 'host_view': host_view, 'context': context, }) 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.distinct().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, 'include_disclaimer': include_disclaimer, 'disclaimer': disclaimer, 'user': user, 'team_name': settings.TEAM_NAME, 'title': report_title, 'user_id': request.user.id, 'host': "", 'host_view': host_view, 'context': context, }) else: raise Http404() paged_findings = get_page_items( request, findings.qs.distinct().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: if host_view: product_tab = Product_Tab(endpoint.product.id, title="Endpoint Host Report", tab="endpoints") else: 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, 'host_view': host_view, 'context': context, })
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 manage_files(request, oid, obj_type): if obj_type == 'Engagement': obj = get_object_or_404(Engagement, pk=oid) user_has_permission_or_403(request.user, obj, Permissions.Engagement_Edit) obj_vars = ('view_engagement', 'engagement_set') elif obj_type == 'Test': obj = get_object_or_404(Test, pk=oid) user_has_permission_or_403(request.user, obj, Permissions.Test_Edit) obj_vars = ('view_test', 'test_set') elif obj_type == 'Finding': obj = get_object_or_404(Finding, pk=oid) user_has_permission_or_403(request.user, obj, Permissions.Finding_Edit) obj_vars = ('view_finding', 'finding_set') else: raise Http404() files_formset = ManageFileFormSet(queryset=obj.files.all()) error = False if request.method == 'POST': files_formset = ManageFileFormSet(request.POST, request.FILES, queryset=obj.files.all()) if files_formset.is_valid(): # remove all from database and disk files_formset.save() for o in files_formset.deleted_objects: logger.debug("removing file: %s", o.file.name) os.remove(os.path.join(settings.MEDIA_ROOT, o.file.name)) for o in files_formset.new_objects: logger.debug("adding file: %s", o.file.name) obj.files.add(o) orphan_files = FileUpload.objects.filter(engagement__isnull=True, test__isnull=True, finding__isnull=True) for o in orphan_files: logger.debug("purging orphan file: %s", o.file.name) os.remove(os.path.join(settings.MEDIA_ROOT, o.file.name)) o.delete() messages.add_message(request, messages.SUCCESS, 'Files updated successfully.', extra_tags='alert-success') else: error = True messages.add_message(request, messages.ERROR, 'Please check form data and try again.', extra_tags='alert-danger') if not error: return HttpResponseRedirect(reverse(obj_vars[0], args=(oid, ))) return render(request, 'dojo/manage_files.html', { 'files_formset': files_formset, 'obj': obj, 'obj_type': obj_type, })
def import_scan_results(request, eid=None, pid=None): engagement = None form = ImportScanForm() cred_form = CredMappingForm() finding_count = 0 jform = None user = request.user if eid: engagement = get_object_or_404(Engagement, id=eid) engagement_or_product = engagement cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter(engagement=engagement).order_by('cred_id') elif pid: product = get_object_or_404(Product, id=pid) engagement_or_product = product elif not user.is_staff: raise PermissionDenied user_has_permission_or_403(user, engagement_or_product, Permissions.Import_Scan_Result) push_all_jira_issues = jira_helper.is_push_all_issues(engagement_or_product) if request.method == "POST": form = ImportScanForm(request.POST, request.FILES) cred_form = CredMappingForm(request.POST) cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter( engagement=engagement).order_by('cred_id') if jira_helper.get_jira_project(engagement_or_product): jform = JIRAImportScanForm(request.POST, push_all=push_all_jira_issues, prefix='jiraform') logger.debug('jform valid: %s', jform.is_valid()) logger.debug('jform errors: %s', jform.errors) if form.is_valid() and (jform is None or jform.is_valid()): scan = request.FILES.get('file', None) scan_date = form.cleaned_data['scan_date'] minimum_severity = form.cleaned_data['minimum_severity'] active = form.cleaned_data['active'] verified = form.cleaned_data['verified'] scan_type = request.POST['scan_type'] tags = form.cleaned_data['tags'] version = form.cleaned_data['version'] branch_tag = form.cleaned_data.get('branch_tag', None) build_id = form.cleaned_data.get('build_id', None) commit_hash = form.cleaned_data.get('commit_hash', None) api_scan_configuration = form.cleaned_data.get('api_scan_configuration', None) service = form.cleaned_data.get('service', None) close_old_findings = form.cleaned_data.get('close_old_findings', None) # Will save in the provided environment or in the `Development` one if absent environment_id = request.POST.get('environment', 'Development') environment = Development_Environment.objects.get(id=environment_id) group_by = form.cleaned_data.get('group_by', None) # TODO move to form validation? if scan and is_scan_file_too_large(scan): messages.add_message(request, messages.ERROR, "Report file is too large. Maximum supported size is {} MB".format(settings.SCAN_FILE_MAX_SIZE), extra_tags='alert-danger') return HttpResponseRedirect(reverse('import_scan_results', args=(engagement,))) # Allows for a test to be imported with an engagement created on the fly if engagement is None: engagement = Engagement() engagement.name = "AdHoc Import - " + strftime("%a, %d %b %Y %X", timezone.now().timetuple()) engagement.threat_model = False engagement.api_test = False engagement.pen_test = False engagement.check_list = False engagement.target_start = timezone.now().date() engagement.target_end = timezone.now().date() engagement.product = product engagement.active = True engagement.status = 'In Progress' engagement.version = version engagement.branch_tag = branch_tag engagement.build_id = build_id engagement.commit_hash = commit_hash engagement.save() # can't use helper as when push_all_jira_issues is True, the checkbox gets disabled and is always false # push_to_jira = jira_helper.is_push_to_jira(new_finding, jform.cleaned_data.get('push_to_jira')) push_to_jira = push_all_jira_issues or (jform and jform.cleaned_data.get('push_to_jira')) error = False # Save newly added endpoints added_endpoints = save_endpoints_to_add(form.endpoints_to_add_list, engagement.product) try: importer = Importer() test, finding_count, closed_finding_count = importer.import_scan(scan, scan_type, engagement, user, environment, active=active, verified=verified, tags=tags, minimum_severity=minimum_severity, endpoints_to_add=list(form.cleaned_data['endpoints']) + added_endpoints, scan_date=scan_date, version=version, branch_tag=branch_tag, build_id=build_id, commit_hash=commit_hash, push_to_jira=push_to_jira, close_old_findings=close_old_findings, group_by=group_by, api_scan_configuration=api_scan_configuration, service=service) message = f'{scan_type} processed a total of {finding_count} findings' if close_old_findings: message = message + ' and closed %d findings' % (closed_finding_count) message = message + "." add_success_message_to_response(message) except Exception as e: logger.exception(e) add_error_message_to_response('An exception error occurred during the report import:%s' % str(e)) error = True # Save the credential to the test if cred_form.is_valid(): if cred_form.cleaned_data['cred_user']: # Select the credential mapping object from the selected list and only allow if the credential is associated with the product cred_user = Cred_Mapping.objects.filter( pk=cred_form.cleaned_data['cred_user'].id, engagement=eid).first() new_f = cred_form.save(commit=False) new_f.test = test new_f.cred_id = cred_user.cred_id new_f.save() if not error: return HttpResponseRedirect( reverse('view_test', args=(test.id, ))) prod_id = None custom_breadcrumb = None title = "Import Scan Results" if engagement: prod_id = engagement.product.id product_tab = Product_Tab(prod_id, title=title, tab="engagements") product_tab.setEngagement(engagement) else: prod_id = pid custom_breadcrumb = {"", ""} product_tab = Product_Tab(prod_id, title=title, tab="findings") if jira_helper.get_jira_project(engagement_or_product): jform = JIRAImportScanForm(push_all=push_all_jira_issues, prefix='jiraform') form.fields['endpoints'].queryset = Endpoint.objects.filter(product__id=product_tab.product.id) form.fields['api_scan_configuration'].queryset = Product_API_Scan_Configuration.objects.filter(product__id=product_tab.product.id) return render(request, 'dojo/import_scan_results.html', {'form': form, 'product_tab': product_tab, 'engagement_or_product': engagement_or_product, 'custom_breadcrumb': custom_breadcrumb, 'title': title, 'cred_form': cred_form, 'jform': jform, 'scan_types': get_scan_types_sorted(), })
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, ObjectDoesNotExist): raise Http404() product_id = None active_tab = None finding = None test = False object_value = None if ct.model == "product": user_has_permission_or_403(request.user, obj, Permissions.Product_View) product_id = obj.id active_tab = "overview" object_value = Product.objects.get(id=obj.id) elif ct.model == "engagement": user_has_permission_or_403(request.user, obj, Permissions.Engagement_View) object_value = Engagement.objects.get(id=obj.id) product_id = object_value.product.id active_tab = "engagements" elif ct.model == "test": user_has_permission_or_403(request.user, obj, Permissions.Test_View) object_value = Test.objects.get(id=obj.id) product_id = object_value.engagement.product.id active_tab = "engagements" test = True elif ct.model == "finding": user_has_permission_or_403(request.user, obj, Permissions.Finding_View) object_value = Finding.objects.get(id=obj.id) product_id = object_value.test.engagement.product.id active_tab = "findings" finding = object_value elif ct.model == "endpoint": user_has_permission_or_403(request.user, obj, Permissions.Endpoint_View) object_value = Endpoint.objects.get(id=obj.id) product_id = object_value.product.id active_tab = "endpoints" elif ct.model == "risk_acceptance": engagements = Engagement.objects.filter(risk_acceptance=obj) authorized = False for engagement in engagements: if user_has_permission(request.user, engagement, Permissions.Engagement_View): authorized = True break if not authorized: raise PermissionDenied else: if not request.user.is_superuser: raise PermissionDenied 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) if not get_system_setting('enable_auditlog'): messages.add_message( request, messages.WARNING, 'Audit logging is currently disabled in System Settings.', extra_tags='alert-danger') 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 })