예제 #1
0
def engagements(request, view):

    if not view:
        view = 'active'

    filtered_engagements = get_filtered_engagements(request, view)

    engs = get_page_items(request, filtered_engagements.qs, 25)
    product_name_words = sorted(get_authorized_products(Permissions.Product_View).values_list('name', flat=True))
    engagement_name_words = sorted(get_authorized_engagements(Permissions.Engagement_View).values_list('name', flat=True).distinct())

    add_breadcrumb(
        title=f"{view.capitalize()} Engagements",
        top_level=not len(request.GET),
        request=request)

    return render(
        request, 'dojo/engagement.html', {
            'engagements': engs,
            'engagement_test_counts': get_test_counts(filtered_engagements.qs),
            'filter_form': filtered_engagements.form,
            'product_name_words': product_name_words,
            'engagement_name_words': engagement_name_words,
            'view': view.capitalize(),
        })
예제 #2
0
def update_product_access(backend,
                          uid,
                          user=None,
                          social=None,
                          *args,
                          **kwargs):
    if settings.GITLAB_PROJECT_AUTO_IMPORT is True:
        # Get user's product names
        user_product_names = [
            prod.name
            for prod in get_authorized_products(Permissions.Product_View, user)
        ]
        # Get Gitlab access token
        soc = user.social_auth.get()
        token = soc.extra_data['access_token']
        # Get user's projects list on Gitlab
        gl = gitlab.Gitlab(settings.SOCIAL_AUTH_GITLAB_API_URL,
                           oauth_token=token)
        # Get each project path_with_namespace as future product name
        projects = gl.projects.list(
            membership=True,
            min_access_level=settings.GITLAB_PROJECT_MIN_ACCESS_LEVEL,
            all=True)
        project_names = [project.path_with_namespace for project in projects]
        # Create product_type if necessary
        product_type, created = Product_Type.objects.get_or_create(
            name='Gitlab Import')
        # For each project: create a new product or update product's authorized_users
        for project_name in project_names:
            if project_name not in user_product_names:
                # Create new product
                product, created = Product.objects.get_or_create(
                    name=project_name, prod_type=product_type)
                if not settings.FEATURE_AUTHORIZATION_V2:
                    product.authorized_users.add(user)
                    product.save()
                else:
                    product_member, created = Product_Member.objects.get_or_create(
                        product=product, user=user)
                    if created:
                        # Make product member an Owner of the product
                        product_member.role = 4
                        product_member.save()

        # For each product: if user is not project member any more, remove him from product's authorized users
        for product_name in user_product_names:
            if product_name not in project_names:
                product = Product.objects.get(name=product_name)
                if not settings.FEATURE_AUTHORIZATION_V2:
                    product.authorized_users.remove(user)
                    product.save()
                else:
                    Product_Member.objects.filter(product=product,
                                                  user=user).delete()
예제 #3
0
def engagement(request):
    products = get_authorized_products(Permissions.Engagement_View).distinct()
    engagements = Engagement.objects.filter(
        product__in=products
    ).select_related(
        'product',
        'product__prod_type',
    ).prefetch_related(
        'lead',
        'tags',
        'product__tags',
    )

    # Get the test counts per engagments. As a separate query, this is much
    # faster than annotating the above `engagements` query.
    engagement_test_counts = {
        test['engagement']: test['test_count']
        for test in Test.objects.filter(
            engagement__in=engagements
        ).values(
            'engagement'
        ).annotate(
            test_count=Count('engagement')
        )
    }

    if System_Settings.objects.get().enable_jira:
        engagements = engagements.prefetch_related(
            'jira_project__jira_instance',
            'product__jira_project_set__jira_instance'
        )

    filtered_engagements = EngagementDirectFilter(
        request.GET,
        queryset=engagements
    )

    engs = get_page_items(request, filtered_engagements.qs, 25)
    product_name_words = sorted(products.values_list('name', flat=True))
    engagement_name_words = sorted(engagements.values_list('name', flat=True).distinct())

    add_breadcrumb(
        title="Active Engagements",
        top_level=not len(request.GET),
        request=request)

    return render(
        request, 'dojo/engagement.html', {
            'engagements': engs,
            'engagement_test_counts': engagement_test_counts,
            'filter_form': filtered_engagements.form,
            'product_name_words': product_name_words,
            'engagement_name_words': engagement_name_words,
        })
예제 #4
0
def view_product_type(request, ptid):
    pt = get_object_or_404(Product_Type, pk=ptid)
    members = get_authorized_members(pt, Permissions.Product_Type_View)
    products = get_authorized_products(
        Permissions.Product_View).filter(prod_type=pt)
    add_breadcrumb(title="View Product Type", top_level=False, request=request)
    return render(
        request, 'dojo/view_product_type.html', {
            'name': 'View Product Type',
            'pt': pt,
            'products': products,
            'members': members
        })
예제 #5
0
def engagements_all(request):

    products_with_engagements = get_authorized_products(Permissions.Engagement_View)
    products_with_engagements = products_with_engagements.filter(~Q(engagement=None)).distinct()

    # count using prefetch instead of just using 'engagement__set_test_test` to avoid loading all test in memory just to count them
    filter_qs = products_with_engagements.prefetch_related(
        Prefetch('engagement_set', queryset=Engagement.objects.all().annotate(test_count=Count('test__id')))
    )

    filter_qs = filter_qs.prefetch_related(
        'engagement_set__tags',
        'prod_type',
        'engagement_set__lead',
        'tags',
    )
    if System_Settings.objects.get().enable_jira:
        filter_qs = filter_qs.prefetch_related(
            'engagement_set__jira_project__jira_instance',
            'jira_project_set__jira_instance'
        )

    filtered = EngagementFilter(
        request.GET,
        queryset=filter_qs
    )

    prods = get_page_items(request, filtered.qs, 25)

    name_words = products_with_engagements.values_list('name', flat=True)
    eng_words = get_authorized_engagements(Permissions.Engagement_View).values_list('name', flat=True).distinct()

    add_breadcrumb(
        title="All Engagements",
        top_level=not len(request.GET),
        request=request)

    return render(
        request, 'dojo/engagements_all.html', {
            'products': prods,
            'filter_form': filtered.form,
            'name_words': sorted(set(name_words)),
            'eng_words': sorted(set(eng_words)),
        })
예제 #6
0
def update_product_access(backend, uid, user=None, social=None, *args, **kwargs):
    if settings.GITLAB_PROJECT_AUTO_IMPORT is True:
        # Get user's product names
        user_product_names = [prod.name for prod in get_authorized_products(Permissions.Product_View, user)]
        # Get Gitlab access token
        soc = user.social_auth.get()
        token = soc.extra_data['access_token']
        # Get user's projects list on Gitlab
        gl = gitlab.Gitlab(settings.SOCIAL_AUTH_GITLAB_API_URL, oauth_token=token)
        # Get each project path_with_namespace as future product name
        projects = gl.projects.list(membership=True, min_access_level=settings.GITLAB_PROJECT_MIN_ACCESS_LEVEL, all=True)
        project_names = [project.path_with_namespace for project in projects]
        # Create product_type if necessary
        product_type, created = Product_Type.objects.get_or_create(name='Gitlab Import')
        # For each project: create a new product or update product's authorized_users
        for project in projects:
            if project.path_with_namespace not in user_product_names:
                try:
                    # Check if there is a product with the name of the GitLab project
                    product = Product.objects.get(name=project.path_with_namespace)
                except Product.DoesNotExist:
                    # If not, create a product with that name and the GitLab product type
                    product = Product(name=project.path_with_namespace, prod_type=product_type)
                    product.save()
                product_member, created = Product_Member.objects.get_or_create(product=product, user=user, defaults={'role': Role.objects.get(id=Roles.Owner)})
                # Import tags and/orl URL if necessary
                if settings.GITLAB_PROJECT_IMPORT_TAGS:
                    if hasattr(project, 'topics'):
                        if len(project.topics) > 0:
                            product.tags = ",".join(project.topics)
                    elif hasattr(project, 'tag_list') and len(project.tag_list) > 0:
                        product.tags = ",".join(project.tag_list)
                if settings.GITLAB_PROJECT_IMPORT_URL:
                    if hasattr(project, 'web_url') and len(project.web_url) > 0:
                        product.description = "[" + project.web_url + "](" + project.web_url + ")"
                if settings.GITLAB_PROJECT_IMPORT_TAGS or settings.GITLAB_PROJECT_IMPORT_URL:
                    product.save()

        # For each product: if user is not project member any more, remove him from product's list of product members
        for product_name in user_product_names:
            if product_name not in project_names:
                product = Product.objects.get(name=product_name)
                Product_Member.objects.filter(product=product, user=user).delete()
예제 #7
0
def simple_search(request):
    ip_addresses = []
    dashes = []
    query = []
    tests = None
    findings = None
    finding_templates = None
    products = None
    tagged_tests = None
    tagged_findings = None
    tagged_products = None
    tagged_endpoints = None
    tagged_engagements = None
    tagged_finding_templates = None
    engagements = None
    endpoints = None
    languages = None
    app_analysis = None
    clean_query = ''
    cookie = False
    terms = ''
    form = SimpleSearchForm()

    original_clean_query = ""
    findings_filter = None
    title_words = None
    component_words = None
    paged_generic = None

    # if request.method == 'GET' and "query" in request.GET:
    if request.method == 'GET':
        form = SimpleSearchForm(request.GET)
        if form.is_valid():
            cookie = True

            clean_query = form.cleaned_data['query'] or ''
            original_clean_query = clean_query

            operators, keywords = parse_search_query(clean_query)

            search_tags = "tag" in operators or "test-tag" in operators or "engagement-tag" in operators or "product-tag" in operators or\
                          "tags" in operators or "test-tags" in operators or "engagement-tags" in operators or "product-tags" in operators

            search_cve = "cve" in operators

            search_finding_id = "id" in operators
            search_findings = "finding" in operators or search_cve or search_finding_id or search_tags or not operators

            search_finding_templates = "template" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_tests = "test" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_engagements = "engagement" in operators or search_tags or not (
                operators or search_finding_id or search_cve)

            search_products = "product" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_endpoints = "endpoint" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_languages = "language" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_technologies = "technology" in operators or search_tags or not (
                operators or search_finding_id or search_cve)

            authorized_findings = Finding.objects.all()
            authorized_tests = get_authorized_tests(Permissions.Test_View)
            authorized_engagements = get_authorized_engagements(
                Permissions.Engagement_View)
            authorized_products = get_authorized_products(
                Permissions.Product_View)
            authorized_endpoints = Endpoint.objects.all()
            authorized_finding_templates = Finding_Template.objects.all()

            if not request.user.is_staff:
                authorized_findings = authorized_findings.filter(
                    Q(test__engagement__product__authorized_users__in=[
                        request.user
                    ]) |
                    Q(test__engagement__product__prod_type__authorized_users__in
                      =[request.user]))
                authorized_endpoints = authorized_endpoints.filter(
                    Q(product__authorized_users__in=[request.user]) |
                    Q(product__prod_type__authorized_users__in=[request.user]))
                # can't filter templates

            # TODO better get findings in their own query and match on id. that would allow filtering on additional fields such cve, prod_id, etc.

            findings = authorized_findings
            tests = authorized_tests
            engagements = authorized_engagements
            products = authorized_products
            endpoints = authorized_endpoints

            findings_filter = None
            title_words = None
            component_words = None

            keywords_query = ' '.join(keywords)

            if search_finding_id:
                logger.debug('searching finding id')

                findings = authorized_findings
                findings = findings.filter(id=operators['id'][0])

            elif search_findings:
                logger.debug('searching findings')

                findings_filter = OpenFindingFilter(request.GET,
                                                    queryset=findings,
                                                    user=request.user,
                                                    pid=None,
                                                    prefix='finding')
                # setting initial values for filters is not supported and discouraged: https://django-filter.readthedocs.io/en/stable/guide/tips.html#using-initial-values-as-defaults
                # we could try to modify request.GET before generating the filter, but for now we'll leave it as is

                title_words = get_words_for_field(authorized_findings, 'title')
                component_words = get_words_for_field(authorized_findings,
                                                      'component_name')

                findings = findings_filter.qs

                findings = apply_tag_filters(findings, operators)
                findings = apply_endpoint_filter(findings, operators)
                findings = apply_cve_filter(findings, operators)

                findings = perform_keyword_search_for_operator(
                    findings, operators, 'finding', keywords_query)

            else:
                findings = None
                findings_filter = None
                component_words = None

            # prefetch after watson to avoid inavlid query errors due to watson not understanding prefetching
            if findings is not None:  # check for None to avoid query execution
                logger.debug('prefetching findings')

                findings = get_page_items(request, findings, 25)

                findings.object_list = prefetch_for_findings(
                    findings.object_list)

                # some over the top tag displaying happening...
                findings.object_list = findings.object_list.prefetch_related(
                    'test__engagement__product__tags')

            tag = operators['tag'] if 'tag' in operators else keywords
            tags = operators['tags'] if 'tags' in operators else keywords
            if search_tags and tag or tags:
                logger.debug('searching tags')

                Q1, Q2 = Q(), Q()

                if tag:
                    tag = ','.join(tag)  # contains needs a single value
                    Q1 = Q(tags__name__contains=tag)

                if tags:
                    Q2 = Q(tags__name__in=tags)

                tagged_findings = authorized_findings.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_finding_templates = authorized_finding_templates.filter(
                    Q1 | Q2).distinct()[:max_results]
                tagged_tests = authorized_tests.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_engagements = authorized_engagements.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_products = authorized_products.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_endpoints = authorized_endpoints.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
            else:
                tagged_findings = None
                tagged_finding_templates = None
                tagged_tests = None
                tagged_engagements = None
                tagged_products = None
                tagged_endpoints = None

            tagged_results = tagged_findings or tagged_finding_templates or tagged_tests or tagged_engagements or tagged_products or tagged_endpoints

            if search_finding_templates:
                logger.debug('searching finding templates')

                finding_templates = authorized_finding_templates
                finding_templates = apply_tag_filters(finding_templates,
                                                      operators)

                if keywords_query:
                    watson_results = watson.filter(finding_templates,
                                                   keywords_query)
                    finding_templates = finding_templates.filter(
                        id__in=[watson.id for watson in watson_results])

                finding_templates = finding_templates[:max_results]
            else:
                finding_templates = None

            if search_tests:
                logger.debug('searching tests')

                tests = authorized_tests
                tests = apply_tag_filters(tests, operators)

                if keywords_query:
                    watson_results = watson.filter(tests, keywords_query)
                    tests = tests.filter(
                        id__in=[watson.id for watson in watson_results])

                tests = tests.prefetch_related('engagement',
                                               'engagement__product',
                                               'test_type', 'tags',
                                               'engagement__tags',
                                               'engagement__product__tags')
                tests = tests[:max_results]
            else:
                tests = None

            if search_engagements:
                logger.debug('searching engagements')

                engagements = authorized_engagements
                engagements = apply_tag_filters(engagements, operators)

                if keywords_query:
                    watson_results = watson.filter(engagements, keywords_query)
                    engagements = engagements.filter(
                        id__in=[watson.id for watson in watson_results])

                engagements = engagements.prefetch_related(
                    'product', 'product__tags', 'tags')
                engagements = engagements[:max_results]
            else:
                engagements = None

            if search_products:
                logger.debug('searching products')

                products = authorized_products
                products = apply_tag_filters(products, operators)

                if keywords_query:
                    watson_results = watson.filter(products, keywords_query)
                    products = products.filter(
                        id__in=[watson.id for watson in watson_results])

                products = products.prefetch_related('tags')
                products = products[:max_results]
            else:
                products = None

            if search_endpoints:
                logger.debug('searching endpoint')

                endpoints = authorized_endpoints
                endpoints = apply_tag_filters(endpoints, operators)

                endpoints = endpoints.filter(
                    Q(host__icontains=keywords_query)
                    | Q(path__icontains=keywords_query)
                    | Q(fqdn__icontains=keywords_query)
                    | Q(protocol__icontains=keywords_query))
                endpoints = prefetch_for_endpoints(endpoints)
                endpoints = endpoints[:max_results]
            else:
                endpoints = None

            if search_languages:
                logger.debug('searching languages')

                languages = Languages.objects.filter(
                    language__language__icontains=keywords_query)
                languages = languages.prefetch_related('product',
                                                       'product__tags')
                languages = languages[:max_results]
            else:
                languages = None

            if search_technologies:
                logger.debug('searching technologies')

                app_analysis = App_Analysis.objects.filter(
                    name__icontains=keywords_query)
                app_analysis = app_analysis[:max_results]
            else:
                app_analysis = None

            # make sure watson only searches in authorized model instances
            if keywords_query and False:
                logger.debug('searching generic')
                logger.debug('going generic with: %s', keywords_query)
                generic = watson.search(
                    keywords_query,
                    models=(
                        authorized_findings, authorized_tests,
                        authorized_engagements, authorized_products,
                        authorized_endpoints, authorized_finding_templates,
                        App_Analysis)).prefetch_related('object')[:max_results]
            else:
                generic = None

            # paging doesn't work well with django_watson
            # paged_generic = get_page_items(request, generic, 25)

            # generic = get_page_items(request, generic, 25)
            # generic = watson.search(original_clean_query)[:50].prefetch_related('object')
            # generic = watson.search("qander document 'CVE-2019-8331'")[:10].prefetch_related('object')
            # generic = watson.search("'CVE-2020-6754'")[:10].prefetch_related('object')
            # generic = watson.search(" 'ISEC-433'")[:10].prefetch_related('object')

            logger.debug('all searched')

        else:
            logger.debug(form.errors)
            form = SimpleSearchForm()

        add_breadcrumb(title="Simple Search", top_level=True, request=request)

        activetab = 'findings' if findings \
            else 'products' if products \
                else 'engagements' if engagements else \
                    'tests' if tests else \
                         'endpoint' if endpoints else \
                            'tagged' if tagged_results else \
                                'generic'

    response = render(
        request, 'dojo/simple_search.html', {
            'clean_query': original_clean_query,
            'languages': languages,
            'app_analysis': app_analysis,
            'tests': tests,
            'findings': findings,
            'finding_templates': finding_templates,
            'filtered': findings_filter,
            'title_words': title_words,
            'component_words': component_words,
            'products': products,
            'tagged_tests': tagged_tests,
            'tagged_findings': tagged_findings,
            'tagged_finding_templates': tagged_finding_templates,
            'tagged_products': tagged_products,
            'tagged_endpoints': tagged_endpoints,
            'tagged_engagements': tagged_engagements,
            'engagements': engagements,
            'endpoints': endpoints,
            'name': 'Simple Search',
            'metric': False,
            'user': request.user,
            'form': form,
            'activetab': activetab,
            'show_product_column': True,
            'generic': generic
        })

    if cookie:
        response.set_cookie("highlight",
                            value=keywords_query,
                            max_age=None,
                            expires=None,
                            path='/',
                            secure=True,
                            httponly=False)
    else:
        response.delete_cookie("highlight", path='/')
    return response
    '''
예제 #8
0
def view_engineer(request, eid):
    user = get_object_or_404(Dojo_User, pk=eid)
    if not (request.user.is_superuser or
            request.user.username == 'root' or
            request.user.username == user.username):
        return HttpResponseRedirect(reverse('engineer_metrics'))
    now = timezone.now()

    findings = Finding.objects.filter(reporter=user, verified=True)
    closed_findings = Finding.objects.filter(mitigated_by=user)
    open_findings = findings.exclude(mitigated__isnull=False)
    open_month = findings.filter(date__year=now.year, date__month=now.month)
    accepted_month = [finding for ra in Risk_Acceptance.objects.filter(
        created__range=[datetime(now.year,
                                 now.month, 1,
                                 tzinfo=timezone.get_current_timezone()),
                        datetime(now.year,
                                 now.month,
                                 monthrange(now.year,
                                            now.month)[1],
                                 tzinfo=timezone.get_current_timezone())],
        owner=user)
                      for finding in ra.accepted_findings.all()]
    closed_month = []
    for f in closed_findings:
        if f.mitigated and f.mitigated.year == now.year and f.mitigated.month == now.month:
            closed_month.append(f)

    o_dict, open_count = count_findings(open_month)
    c_dict, closed_count = count_findings(closed_month)
    a_dict, accepted_count = count_findings(accepted_month)
    day_list = [now - relativedelta(weeks=1,
                                    weekday=x,
                                    hour=0,
                                    minute=0,
                                    second=0)
                for x in range(now.weekday())]
    day_list.append(now)

    q_objects = (Q(date=d) for d in day_list)
    closed_week = []
    open_week = findings.filter(reduce(operator.or_, q_objects))

    accepted_week = [finding for ra in Risk_Acceptance.objects.filter(
        owner=user, created__range=[day_list[0], day_list[-1]])
                     for finding in ra.accepted_findings.all()]

    q_objects = (Q(mitigated=d) for d in day_list)
    # closed_week= findings.filter(reduce(operator.or_, q_objects))
    for f in closed_findings:
        if f.mitigated and f.mitigated >= day_list[0]:
            closed_week.append(f)

    o_week_dict, open_week_count = count_findings(open_week)
    c_week_dict, closed_week_count = count_findings(closed_week)
    a_week_dict, accepted_week_count = count_findings(accepted_week)

    stuff = []
    o_stuff = []
    a_stuff = []
    findings_this_period(findings, 1, stuff, o_stuff, a_stuff)
    # findings_this_period no longer fits the need for accepted findings
    # however will use its week finding output to use here
    for month in a_stuff:
        month_start = datetime.strptime(
            month[0].strip(), "%b %Y")
        month_end = datetime(month_start.year,
                             month_start.month,
                             monthrange(
                                 month_start.year,
                                 month_start.month)[1],
                             tzinfo=timezone.get_current_timezone())
        for finding in [finding for ra in Risk_Acceptance.objects.filter(
                created__range=[month_start, month_end], owner=user)
                        for finding in ra.accepted_findings.all()]:
            if finding.severity == 'Critical':
                month[1] += 1
            if finding.severity == 'High':
                month[2] += 1
            if finding.severity == 'Medium':
                month[3] += 1
            if finding.severity == 'Low':
                month[4] += 1

        month[5] = sum(month[1:])
    week_stuff = []
    week_o_stuff = []
    week_a_stuff = []
    findings_this_period(findings, 0, week_stuff, week_o_stuff, week_a_stuff)

    # findings_this_period no longer fits the need for accepted findings
    # however will use its week finding output to use here
    for week in week_a_stuff:
        wk_range = week[0].split('-')
        week_start = datetime.strptime(
            wk_range[0].strip() + " " + str(now.year), "%b %d %Y")
        week_end = datetime.strptime(
            wk_range[1].strip() + " " + str(now.year), "%b %d %Y")

        for finding in [finding for ra in Risk_Acceptance.objects.filter(
                created__range=[week_start, week_end], owner=user)
                        for finding in ra.accepted_findings.all()]:
            if finding.severity == 'Critical':
                week[1] += 1
            if finding.severity == 'High':
                week[2] += 1
            if finding.severity == 'Medium':
                week[3] += 1
            if finding.severity == 'Low':
                week[4] += 1

        week[5] = sum(week[1:])

    products = get_authorized_products(Permissions.Product_Type_View)
    vulns = {}
    for product in products:
        f_count = 0
        engs = Engagement.objects.filter(product=product)
        for eng in engs:
            tests = Test.objects.filter(engagement=eng)
            for test in tests:
                f_count += findings.filter(test=test,
                                           mitigated__isnull=True,
                                           active=True).count()
        vulns[product.id] = f_count
    od = OrderedDict(sorted(list(vulns.items()), key=itemgetter(1)))
    items = list(od.items())
    items.reverse()
    top = items[: 10]
    update = []
    for t in top:
        product = t[0]
        z_count = 0
        o_count = 0
        t_count = 0
        h_count = 0
        engs = Engagement.objects.filter(
            product=Product.objects.get(id=product))
        for eng in engs:
            tests = Test.objects.filter(engagement=eng)
            for test in tests:
                z_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='Critical'
                ).count()
                o_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='High'
                ).count()
                t_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='Medium'
                ).count()
                h_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='Low'
                ).count()
        prod = Product.objects.get(id=product)
        all_findings_link = "<a href='%s'>%s</a>" % (
            reverse('product_open_findings', args=(prod.id,)), escape(prod.name))
        update.append([all_findings_link, z_count, o_count, t_count, h_count,
                       z_count + o_count + t_count + h_count])
    total_update = []
    for i in items:
        product = i[0]
        z_count = 0
        o_count = 0
        t_count = 0
        h_count = 0
        engs = Engagement.objects.filter(
            product=Product.objects.get(id=product))
        for eng in engs:
            tests = Test.objects.filter(engagement=eng)
            for test in tests:
                z_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='Critical').count()
                o_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='High').count()
                t_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='Medium').count()
                h_count += findings.filter(
                    test=test,
                    mitigated__isnull=True,
                    severity='Low').count()
        prod = Product.objects.get(id=product)
        all_findings_link = "<a href='%s'>%s</a>" % (
            reverse('product_open_findings', args=(prod.id,)), escape(prod.name))
        total_update.append([all_findings_link, z_count, o_count, t_count,
                             h_count, z_count + o_count + t_count + h_count])

    neg_length = len(stuff)
    findz = findings.filter(mitigated__isnull=True, active=True,
                            risk_acceptance=None)
    findz = findz.filter(Q(severity="Critical") | Q(severity="High"))
    less_thirty = 0
    less_sixty = 0
    less_nine = 0
    more_nine = 0
    for finding in findz:
        elapsed = date.today() - finding.date
        if elapsed <= timedelta(days=30):
            less_thirty += 1
        elif elapsed <= timedelta(days=60):
            less_sixty += 1
        elif elapsed <= timedelta(days=90):
            less_nine += 1
        else:
            more_nine += 1

    # Data for the monthly charts
    chart_data = [['Date', 'S0', 'S1', 'S2', 'S3', 'Total']]
    for thing in o_stuff:
        chart_data.insert(1, thing)

    a_chart_data = [['Date', 'S0', 'S1', 'S2', 'S3', 'Total']]
    for thing in a_stuff:
        a_chart_data.insert(1, thing)

    # Data for the weekly charts
    week_chart_data = [['Date', 'S0', 'S1', 'S2', 'S3', 'Total']]
    for thing in week_o_stuff:
        week_chart_data.insert(1, thing)

    week_a_chart_data = [['Date', 'S0', 'S1', 'S2', 'S3', 'Total']]
    for thing in week_a_stuff:
        week_a_chart_data.insert(1, thing)

    details = []
    for find in open_findings:
        team = find.test.engagement.product.prod_type.name
        name = find.test.engagement.product.name
        severity = find.severity
        description = find.title
        life = date.today() - find.date
        life = life.days
        status = 'Active'
        if find.risk_accepted:
            status = 'Accepted'
        detail = [team, name, severity, description, life, status, find.reporter]
        details.append(detail)

    details = sorted(details, key=lambda x: x[2])

    add_breadcrumb(title="%s Metrics" % user.get_full_name(), top_level=False, request=request)

    return render(request, 'dojo/view_engineer.html', {
        'open_month': open_month,
        'a_month': accepted_month,
        'low_a_month': accepted_count["low"],
        'medium_a_month': accepted_count["med"],
        'high_a_month': accepted_count["high"],
        'critical_a_month': accepted_count["crit"],
        'closed_month': closed_month,
        'low_open_month': open_count["low"],
        'medium_open_month': open_count["med"],
        'high_open_month': open_count["high"],
        'critical_open_month': open_count["crit"],
        'low_c_month': closed_count["low"],
        'medium_c_month': closed_count["med"],
        'high_c_month': closed_count["high"],
        'critical_c_month': closed_count["crit"],
        'week_stuff': week_stuff,
        'week_a_stuff': week_a_stuff,
        'a_total': a_stuff,
        'total': stuff,
        'sub': neg_length,
        'update': update,
        'lt': less_thirty,
        'ls': less_sixty,
        'ln': less_nine,
        'mn': more_nine,
        'chart_data': chart_data,
        'a_chart_data': a_chart_data,
        'week_chart_data': week_chart_data,
        'week_a_chart_data': week_a_chart_data,
        'name': '%s Metrics' % user.get_full_name(),
        'metric': True,
        'total_update': total_update,
        'details': details,
        'open_week': open_week,
        'closed_week': closed_week,
        'accepted_week': accepted_week,
        'a_dict': a_dict,
        'o_dict': o_dict,
        'c_dict': c_dict,
        'o_week_dict': o_week_dict,
        'a_week_dict': a_week_dict,
        'c_week_dict': c_week_dict,
        'open_week_count': open_week_count,
        'accepted_week_count': accepted_week_count,
        'closed_week_count': closed_week_count,
        'user': request.user,
    })
예제 #9
0
def endpoint_querys(prod_type, request):
    endpoints_query = Endpoint_Status.objects.filter(mitigated=False,
                                      finding__severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')).prefetch_related(
        'finding__test__engagement__product',
        'finding__test__engagement__product__prod_type',
        'finding__test__engagement__risk_acceptance',
        'finding__risk_acceptance_set',
        'finding__reporter')

    endpoints_query = get_authorized_endpoint_status(Permissions.Endpoint_View, endpoints_query, request.user)

    active_endpoints_query = Endpoint_Status.objects.filter(mitigated=False,
                                      finding__severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')).prefetch_related(
        'finding__test__engagement__product',
        'finding__test__engagement__product__prod_type',
        'finding__test__engagement__risk_acceptance',
        'finding__risk_acceptance_set',
        'finding__reporter')

    active_endpoints_query = get_authorized_endpoint_status(Permissions.Endpoint_View, active_endpoints_query, request.user)

    endpoints = MetricsEndpointFilter(request.GET, queryset=endpoints_query)
    active_endpoints = MetricsEndpointFilter(request.GET, queryset=active_endpoints_query)

    endpoints_qs = queryset_check(endpoints)
    active_endpoints_qs = queryset_check(active_endpoints)

    if not endpoints_qs:
        endpoints = endpoints_query
        active_endpoints = active_endpoints_query
        endpoints_qs = endpoints if isinstance(endpoints, QuerySet) else endpoints.qs
        active_endpoints_qs = active_endpoints if isinstance(active_endpoints, QuerySet) else active_endpoints.qs
        messages.add_message(request,
                                     messages.ERROR,
                                     'All objects have been filtered away. Displaying all objects',
                                     extra_tags='alert-danger')

    try:
        start_date = endpoints_qs.earliest('date').date
        start_date = datetime(start_date.year,
                            start_date.month, start_date.day,
                            tzinfo=timezone.get_current_timezone())
        end_date = endpoints_qs.latest('date').date
        end_date = datetime(end_date.year,
                            end_date.month, end_date.day,
                            tzinfo=timezone.get_current_timezone())
    except:
        start_date = timezone.now()
        end_date = timezone.now()

    if len(prod_type) > 0:
        endpoints_closed = Endpoint_Status.objects.filter(mitigated_time__range=[start_date, end_date],
                                                 finding__test__engagement__product__prod_type__in=prod_type).prefetch_related(
            'finding__test__engagement__product')
        # capture the accepted findings in period
        accepted_endpoints = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True,
                                                   finding__test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('finding__test__engagement__product')
        accepted_endpoints_counts = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True,
                                                          finding__test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('finding__test__engagement__product')
    else:
        endpoints_closed = Endpoint_Status.objects.filter(mitigated_time__range=[start_date, end_date]).prefetch_related(
            'finding__test__engagement__product')
        accepted_endpoints = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True). \
            prefetch_related('finding__test__engagement__product')
        accepted_endpoints_counts = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True). \
            prefetch_related('finding__test__engagement__product')

    endpoints_closed = get_authorized_endpoint_status(Permissions.Endpoint_View, endpoints_closed, request.user)
    accepted_endpoints = get_authorized_endpoint_status(Permissions.Endpoint_View, accepted_endpoints, request.user)
    accepted_endpoints_counts = get_authorized_endpoint_status(Permissions.Endpoint_View, accepted_endpoints_counts, request.user)
    accepted_endpoints_counts = severity_count(accepted_endpoints_counts, 'aggregate', 'finding__severity')

    r = relativedelta(end_date, start_date)
    months_between = (r.years * 12) + r.months
    # include current month
    months_between += 1

    weeks_between = int(ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7)))
    if weeks_between <= 0:
        weeks_between += 2

    monthly_counts = get_period_counts(active_endpoints_qs, endpoints_qs, endpoints_closed, accepted_endpoints, months_between, start_date,
                                       relative_delta='months')
    weekly_counts = get_period_counts(active_endpoints_qs, endpoints_qs, endpoints_closed, accepted_endpoints, weeks_between, start_date,
                                      relative_delta='weeks')

    top_ten = get_authorized_products(Permissions.Product_View)
    top_ten = top_ten.filter(engagement__test__finding__endpoint_status__mitigated=False,
                                     engagement__test__finding__endpoint_status__false_positive=False,
                                     engagement__test__finding__endpoint_status__out_of_scope=False,
                                     engagement__test__finding__severity__in=(
                                         'Critical', 'High', 'Medium', 'Low'),
                                     prod_type__in=prod_type)
    top_ten = severity_count(top_ten, 'annotate', 'engagement__test__finding__severity').order_by('-critical', '-high', '-medium', '-low')[:10]

    return {
        'all': endpoints,
        'closed': endpoints_closed,
        'accepted': accepted_endpoints,
        'accepted_count': accepted_endpoints_counts,
        'top_ten': top_ten,
        'monthly_counts': monthly_counts,
        'weekly_counts': weekly_counts,
        'weeks_between': weeks_between,
        'start_date': start_date,
        'end_date': end_date,
    }