Example #1
0
def generate_report(request, obj):
    user = Dojo_User.objects.get(id=request.user.id)
    customer = None
    product = None
    engagement = None
    test = None
    endpoint = 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 request.user in obj.authorized_users.all():
            pass  # user is authorized for this product
        else:
            raise PermissionDenied
    elif type(obj).__name__ == "Endpoint":
        if request.user.is_staff or request.user in obj.product.authorized_users.all(
        ):
            pass  # user is authorized for this product
        else:
            raise PermissionDenied
    elif type(obj).__name__ == "QuerySet":
        # 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')
    report_template = int(request.GET.get('report_template', 0))
    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__ == "Customer":
        customer = obj
        filename = "customer_finding_report.pdf"
        template = "dojo/customer_pdf_report.html"
        report_name = "Customer Report: " + str(customer)
        report_title = "Customer Report"
        report_subtitle = str(customer)

        findings = ReportFindingFilter(
            request.GET,
            queryset=Finding.objects.filter(
                test__engagement__product__customer=customer).distinct(
                ).prefetch_related('test', 'test__engagement__product',
                                   'test__engagement__product__customer'))
        products = Product.objects.filter(
            customer=customer,
            engagement__test__finding__in=findings.qs).distinct()
        engagements = Engagement.objects.filter(
            product__customer=customer,
            test__finding__in=findings.qs).distinct()
        tests = Test.objects.filter(engagement__product__customer=customer,
                                    finding__in=findings.qs).distinct()
        if findings:
            start_date = 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,
            findings.qs,
            None,
            months_between,
            start_date,
            relative_delta='months')

        context = {
            'customer':
            customer,
            '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,
            'findings':
            findings.qs,
            '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':
            'Generate Report',
            '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,
            queryset=Finding.objects.filter(
                test__engagement__product=product).distinct().prefetch_related(
                    'test', 'test__engagement__product',
                    'test__engagement__product__customer'))
        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()

        context = {
            'product': product,
            'engagements': engagements,
            'tests': tests,
            'report_name': report_name,
            'findings': findings.qs,
            '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': 'Generate Report',
            'host': report_url_resolver(request),
            'user_id': request.user.id
        }

    elif type(obj).__name__ == "Engagement":
        engagement = obj
        findings = ReportFindingFilter(
            request.GET,
            queryset=Finding.objects.filter(
                test__engagement=engagement, ).order_by(
                    '-score').prefetch_related(
                        'test', 'test__engagement__product',
                        'test__engagement__product__customer').distinct())
        report_name = '%s - %s - %s' % (engagement.product.customer,
                                        engagement.product, engagement)
        filename = "engagement_finding_report.pdf"
        template = 'dojo/engagement_pdf_report_new.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()

        context = {
            'engagement': engagement,
            'tests': tests,
            'report_name': report_name,
            'findings': findings.qs,
            '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
        }

    elif type(obj).__name__ == "Test":
        test = obj
        findings = ReportFindingFilter(
            request.GET,
            queryset=Finding.objects.filter(test=test).prefetch_related(
                'test', 'test__engagement__product',
                'test__engagement__product__customer').distinct())
        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,
            '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': 'Generate Report',
            '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=Finding.objects.filter(
                endpoints__in=endpoints, ).prefetch_related(
                    'test', 'test__engagement__product',
                    'test__engagement__product__customer').distinct())

        context = {
            'endpoint': endpoint,
            'endpoints': endpoints,
            'report_name': report_name,
            'findings': findings.qs,
            '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
        }
    elif type(obj).__name__ == "QuerySet":
        findings = ReportAuthedFindingFilter(
            request.GET,
            queryset=obj.prefetch_related(
                'test', 'test__engagement__product',
                'test__engagement__product__customer').distinct(),
            user=request.user)
        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,
            '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': 'Generate Report',
            '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', {
                    'customer': customer,
                    'product': product,
                    'engagement': engagement,
                    'test': test,
                    'endpoint': endpoint,
                    'findings': findings.qs,
                    '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': 'Generate Report',
                    'user_id': request.user.id,
                    'host': report_url_resolver(request),
                })

        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 == 'docx':
            template = glob(settings.DOJO_ROOT +
                            '/templates/dojo/*.docx')[report_template]
            filename = "engagement_finding_report.docx"
            report_title = "Engagement Report"
            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.template = template
                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='docx',
                                requester=request.user,
                                task_id='tbd',
                                options=request.path + "?" +
                                request.GET.urlencode())
            report.save()
            async_docx_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()))
            return HttpResponseRedirect(reverse('reports'))
        else:
            raise Http404()
    paged_findings = get_page_items(request, findings.qs, 25)
    return render(
        request, 'dojo/request_report.html', {
            'customer': customer,
            'product': product,
            'engagement': engagement,
            'test': test,
            'endpoint': endpoint,
            'findings': findings,
            'paged_findings': paged_findings,
            'report_form': report_form,
        })