Esempio n. 1
0
def open_findings(request):
    findings = Finding.objects.filter(mitigated__isnull=True,
                                      verified=True,
                                      false_p=False,
                                      duplicate=False,
                                      out_of_scope=False)

    if request.user.is_staff:
        findings = OpenFingingSuperFilter(request.GET, queryset=findings, user=request.user)
    else:
        findings = findings.filter(test__engagement__product__authorized_users__in=[request.user])
        findings = OpenFindingFilter(request.GET, queryset=findings, user=request.user)

    title_words = [word
                   for finding in findings
                   for word in finding.title.split() if len(word) > 2]

    title_words = sorted(set(title_words))
    paged_findings = get_page_items(request, findings, 25)

    product_type = None
    if 'test__engagement__product__prod_type' in request.GET:
        p = request.GET.getlist('test__engagement__product__prod_type', [])
        if len(p) == 1:
            product_type = get_object_or_404(Product_Type, id=p[0])

    add_breadcrumb(title="Open findings", top_level=not len(request.GET), request=request)

    return render(request,
                  'dojo/open_findings.html',
                  {"findings": paged_findings,
                   "filtered": findings,
                   "title_words": title_words,
                   })
Esempio n. 2
0
def view_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    prod = test.engagement.product
    tags = Tag.objects.usage_for_model(Finding)
    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)
    person = request.user.username
    findings = Finding.objects.filter(test=test).order_by('numerical_severity')
    findings = OpenFindingFilter(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' and request.user.is_staff:
        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(findings.qs, 'title')
    component_words = get_words_for_field(findings.qs, 'component_name')

    paged_findings, total_findings_count = get_page_items_and_count(
        request, prefetch_for_findings(findings.qs), 25)
    paged_stub_findings = get_page_items(request, stub_findings, 25)
    show_re_upload = any(test.test_type.name in code
                         for code in ImportScanForm.SCAN_TYPE_CHOICES)

    product_tab = Product_Tab(prod.id, title="Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    jira_config = JIRA_PKey.objects.filter(product=prod.id).first()
    if jira_config:
        jira_config = jira_config.conf_id

    google_sheets_enabled = system_settings.enable_google_sheets
    sheet_url = None
    if google_sheets_enabled:
        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
            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 Google Shet Sync feature can not 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 = 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,
            'product_tab': product_tab,
            'findings': paged_findings,
            'filtered': findings,
            'findings_count': total_findings_count,
            'stub_findings': paged_stub_findings,
            'title_words': title_words,
            'component_words': component_words,
            'form': form,
            'notes': notes,
            'person': person,
            'request': request,
            'show_re_upload': show_re_upload,
            'creds': creds,
            'cred_test': cred_test,
            'tag_input': tags,
            'jira_config': jira_config,
            'show_export': google_sheets_enabled,
            'sheet_url': sheet_url
        })
Esempio n. 3
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

    max_results = settings.SEARCH_MAX_RESULTS

    # if request.method == 'GET' and "query" in request.GET:
    if request.method == 'GET':
        form = SimpleSearchForm(request.GET)
        if form.is_valid():
            # logger.debug('form vars: %s', vars(form))
            cookie = True
            clean_query = form.cleaned_data['query'] or ''
            search_operator, operator = "", ""
            # Check for search operator like finding:, endpoint:, test: product:
            original_clean_query = clean_query
            # print('clean_query: ', clean_query)
            if ":" in clean_query:
                operator = clean_query.split(":")
                search_operator = operator[0]
                clean_query = operator[1].lstrip()

            logger.debug('operator: %s', operator)
            logger.debug('search_operator: %s', search_operator)
            logger.debug('clean_query: %s', clean_query)

            # if the query contains hyphens, django-watson will escape these leading to problems.
            # for cve we make this workaround because we really want to be able to search for CVEs
            # problem still remains for other case, i.e. searching for "valentijn-scholten" will return no results because of the hyphen.
            # see:
            # - https://github.com/etianen/django-watson/issues/223
            # - https://github.com/DefectDojo/django-DefectDojo/issues/1092
            # - https://github.com/DefectDojo/django-DefectDojo/issues/2081

            # it's not google grade parsing, but let's do some basic stuff right
            query_parts = clean_query.split(" ")
            new_parts = ""
            for part in query_parts:
                if bool(cve_pattern.match(part)):
                    part = '\'' + part + '\''
                    clean_query = '\'' + clean_query + '\''
                    print('new part: ', part)
                else:
                    print('old part: ', part)

                new_parts += (part + " ")

            clean_query = new_parts.strip()

            # clean_query = '\'' + clean_query + '\''

            logger.debug('cve clean_query: [%s]', clean_query)

            search_tags = "tag" in search_operator or search_operator == ""
            search_findings = "finding" in search_operator or "cve" in search_operator or "id" in search_operator or search_operator == ""
            search_finding_templates = "template" in search_operator or search_operator == ""
            search_tests = "test" in search_operator or search_operator == ""
            search_engagements = "engagement" in search_operator or search_operator == ""
            search_products = "product" in search_operator or search_operator == ""
            search_endpoints = "endpoint" in search_operator or search_operator == ""
            search_languages = "language" in search_operator or search_operator == ""
            search_technologies = "technology" in search_operator or search_operator == ""

            findings = Finding.objects.all()
            tests = Test.objects.all()
            engagements = Engagement.objects.all()
            products = Product.objects.all()
            endpoints = Endpoint.objects.all()
            finding_templates = Finding_Template.objects.all()

            if not request.user.is_staff:
                findings = findings.filter(
                    Q(test__engagement__product__authorized_users__in=[
                        request.user
                    ]) |
                    Q(test__engagement__product__prod_type__authorized_users__in
                      =[request.user]))
                tests = tests.filter(
                    Q(engagement__product__authorized_users__in=[request.user])
                    | Q(engagement__product__prod_type__authorized_users__in=[
                        request.user
                    ]))
                engagements = engagements.filter(
                    Q(product__authorized_users__in=[request.user]) |
                    Q(product__prod_type__authorized_users__in=[request.user]))
                products = products.filter(
                    Q(authorized_users__in=[request.user])
                    | Q(prod_type__authorized_users__in=[request.user]))
                endpoints = endpoints.filter(
                    Q(product__authorized_users__in=[request.user]) |
                    Q(product__prod_type__authorized_users__in=[request.user]))

            # 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_filter = None
            title_words = None
            component_words = None

            tags = clean_query
            # search tags first to avoid errors due to slicing too early
            if search_tags:
                tagged_findings = TaggedItem.objects.get_by_model(
                    findings, tags)[:max_results]
                tagged_finding_templates = TaggedItem.objects.get_by_model(
                    Finding_Template, tags)[:max_results]
                tagged_tests = TaggedItem.objects.get_by_model(
                    tests, tags)[:max_results]
                tagged_engagements = TaggedItem.objects.get_by_model(
                    engagements, tags)[:max_results]
                tagged_products = TaggedItem.objects.get_union_by_model(
                    products, tags)[:max_results]
                tagged_endpoints = TaggedItem.objects.get_by_model(
                    endpoints, tags)[:max_results]
            else:
                tagged_findings = None
                tagged_finding_templates = None
                tagged_tests = None
                tagged_engagements = None
                tagged_products = None
                tagged_endpoints = None

            if search_findings:
                findings_filter = OpenFindingFilter(request.GET,
                                                    queryset=findings,
                                                    user=request.user,
                                                    pid=None,
                                                    prefix='finding')
                title_words = get_words_for_field(findings_filter.qs, 'title')
                component_words = get_words_for_field(findings_filter.qs,
                                                      'component_name')
                findings = findings_filter.qs

                if clean_query:
                    logger.debug('going watson with: %s', clean_query)
                    watson_results = watson.filter(findings_filter.qs,
                                                   clean_query)[:max_results]
                    findings = findings.filter(
                        id__in=[watson.id for watson in watson_results])

                # prefetch after watson to avoid inavlid query errors due to watson not understanding prefetching
                findings = prefetch_for_findings(findings)
                # some over the top tag displaying happening...
                findings = findings.prefetch_related(
                    'test__engagement__product__tagged_items__tag')

                findings = findings[:max_results]
            else:
                findings = None
                findings_filter = None
                component_words = None

                # logger.debug('%s', findings.query)
                # paged_findings = get_page_items(request, findings, 25)

                # findings = prefetch_for_findings(findings)
                # some over the top tag displaying happening...
                # findings = findings.prefetch_related('test__engagement__product__tagged_items__tag')

                # paged_findings.object_list = findings

            # for result in findings:
            #     if False:
            #         logger.debug('findings result: %s', vars(result))

            if search_finding_templates:
                watson_results = watson.filter(finding_templates, clean_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:
                watson_results = watson.filter(tests, clean_query)
                tests = tests.filter(
                    id__in=[watson.id for watson in watson_results])
                tests = tests.prefetch_related(
                    'engagement', 'engagement__product', 'test_type',
                    'tagged_items__tag', 'engagement__tagged_items__tag',
                    'engagement__product__tagged_items__tag')
                tests = tests[:max_results]
            else:
                tests = None

            if search_engagements:
                watson_results = watson.filter(engagements, clean_query)
                engagements = engagements.filter(
                    id__in=[watson.id for watson in watson_results])
                engagements = engagements.prefetch_related(
                    'product', 'product__tagged_items__tag',
                    'tagged_items__tag')
                engagements = engagements[:max_results]
            else:
                engagements = None

            if search_products:
                watson_results = watson.filter(products, clean_query)
                products = products.filter(
                    id__in=[watson.id for watson in watson_results])
                products = products.prefetch_related('tagged_items__tag')
                products = products[:max_results]
            else:
                products = None

            if search_endpoints:
                endpoints = endpoints.filter(
                    Q(host__icontains=clean_query)
                    | Q(path__icontains=clean_query)
                    | Q(fqdn__icontains=clean_query)
                    | Q(protocol__icontains=clean_query))
                endpoints = endpoints.prefetch_related(
                    'product', 'tagged_items__tag',
                    'product__tagged_items__tag')
                endpoints = endpoints[:max_results]
            else:
                endpoints = None

            if search_languages:
                languages = Languages.objects.filter(
                    language__language__icontains=clean_query)
                languages = languages.prefetch_related(
                    'product', 'product__tagged_items__tag')
                languages = languages[:max_results]
            else:
                languages = None

            if search_technologies:
                app_analysis = App_Analysis.objects.filter(
                    name__icontains=clean_query)
                app_analysis = app_analysis[:max_results]
            else:
                app_analysis = None

            # generic = watson.search(clean_query, models=(Finding,)).prefetch_related('object')
            generic = watson.search(clean_query).prefetch_related(
                'object')[:max_results]

            # 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')

            # for result in generic:
            #     if False:
            #         logger.debug('generic result: %s', vars(result))

        else:
            logger.debug('search form invalid')
            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 \
                            'generic' if generic else \
                                'tagged'

    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=clean_query,
                            max_age=None,
                            expires=None,
                            path='/',
                            secure=True,
                            httponly=False)
    else:
        response.delete_cookie("highlight", path='/')
    return response
Esempio n. 4
0
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 = OpenFindingFilter(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':
        if settings.FEATURE_AUTHORIZATION_V2:
            user_has_permission_or_403(request.user, test,
                                       Permissions.Note_Add)
        else:
            if not request.user.is_staff:
                raise PermissionDenied
        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 ImportScanForm.SORTED_SCAN_TYPE_CHOICES)

    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:
        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,
            '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,
        })
Esempio n. 5
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():
            # logger.debug('form vars: %s', vars(form))
            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 = Test.objects.all()
            authorized_engagements = Engagement.objects.all()
            authorized_products = Product.objects.all()
            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_tests = authorized_tests.filter(
                    Q(engagement__product__authorized_users__in=[request.user])
                    | Q(engagement__product__prod_type__authorized_users__in=[
                        request.user
                    ]))
                authorized_engagements = authorized_engagements.filter(
                    Q(product__authorized_users__in=[request.user]) |
                    Q(product__prod_type__authorized_users__in=[request.user]))
                authorized_products = authorized_products.filter(
                    Q(authorized_users__in=[request.user])
                    | Q(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 = prefetch_for_findings(findings)
                # some over the top tag displaying happening...
                findings = findings.prefetch_related(
                    'test__engagement__product__tags')

                findings = findings[:max_results]

            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]
                tagged_finding_templates = authorized_finding_templates.filter(
                    Q1 | Q2).distinct()[:max_results]
                tagged_tests = authorized_tests.filter(
                    Q1 | Q2).distinct()[:max_results]
                tagged_engagements = authorized_engagements.filter(
                    Q1 | Q2).distinct()[:max_results]
                tagged_products = authorized_products.filter(
                    Q1 | Q2).distinct()[:max_results]
                tagged_endpoints = authorized_endpoints.filter(
                    Q1 | Q2).distinct()[:max_results]
            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
    '''