def test_calendar(request): if 'lead' not in request.GET or '0' in request.GET.getlist('lead'): tests = get_authorized_tests(Permissions.Test_View) else: filters = [] leads = request.GET.getlist('lead', '') if '-1' in request.GET.getlist('lead'): leads.remove('-1') filters.append(Q(lead__isnull=True)) filters.append(Q(lead__in=leads)) tests = get_authorized_tests(Permissions.Test_View).filter(reduce(operator.or_, filters)) tests = tests.prefetch_related('test_type', 'lead', 'engagement__product') add_breadcrumb(title="Test Calendar", top_level=True, request=request) return render(request, 'dojo/calendar.html', { 'caltype': 'tests', 'leads': request.GET.getlist('lead', ''), 'tests': tests, 'users': Dojo_User.objects.all()})
def view_test(request, tid): test_prefetched = get_authorized_tests(Permissions.Test_View) test_prefetched = test_prefetched.annotate( total_reimport_count=Count('test_import__id', distinct=True)) # tests_prefetched = test_prefetched.prefetch_related(Prefetch('test_import_set', queryset=Test_Import.objects.filter(~Q(findings_affected=None)))) # tests_prefetched = test_prefetched.prefetch_related('test_import_set') # test_prefetched = test_prefetched.prefetch_related('test_import_set__test_import_finding_action_set') test = get_object_or_404(test_prefetched, pk=tid) # test = get_object_or_404(Test, pk=tid) prod = test.engagement.product notes = test.notes.all() note_type_activation = Note_Type.objects.filter(is_active=True).count() if note_type_activation: available_note_types = find_available_notetypes(notes) files = test.files.all() person = request.user.username findings = Finding.objects.filter(test=test).order_by('numerical_severity') findings = FindingFilter(request.GET, queryset=findings) stub_findings = Stub_Finding.objects.filter(test=test) cred_test = Cred_Mapping.objects.filter( test=test).select_related('cred_id').order_by('cred_id') creds = Cred_Mapping.objects.filter( engagement=test.engagement).select_related('cred_id').order_by( 'cred_id') system_settings = get_object_or_404(System_Settings, id=1) if request.method == 'POST': user_has_permission_or_403(request.user, test, Permissions.Note_Add) if note_type_activation: form = TypedNoteForm(request.POST, available_note_types=available_note_types) else: form = NoteForm(request.POST) if form.is_valid(): new_note = form.save(commit=False) new_note.author = request.user new_note.date = timezone.now() new_note.save() test.notes.add(new_note) if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types) else: form = NoteForm() url = request.build_absolute_uri( reverse("view_test", args=(test.id, ))) title = "Test: %s on %s" % (test.test_type.name, test.engagement.product.name) process_notifications(request, new_note, url, title) messages.add_message(request, messages.SUCCESS, 'Note added successfully.', extra_tags='alert-success') else: if note_type_activation: form = TypedNoteForm(available_note_types=available_note_types) else: form = NoteForm() title_words = get_words_for_field(Finding, 'title') component_words = get_words_for_field(Finding, 'component_name') # test_imports = test.test_import_set.all() test_imports = Test_Import.objects.filter(test=test) test_import_filter = TestImportFilter(request.GET, test_imports) paged_test_imports = get_page_items_and_count(request, test_import_filter.qs, 5, prefix='test_imports') paged_test_imports.object_list = paged_test_imports.object_list.prefetch_related( 'test_import_finding_action_set') paged_findings = get_page_items_and_count(request, prefetch_for_findings( findings.qs), 25, prefix='findings') paged_stub_findings = get_page_items(request, stub_findings, 25) show_re_upload = any(test.test_type.name in code for code in get_choices_sorted()) product_tab = Product_Tab(prod.id, title="Test", tab="engagements") product_tab.setEngagement(test.engagement) jira_project = jira_helper.get_jira_project(test) finding_groups = test.finding_group_set.all().prefetch_related( 'findings', 'jira_issue', 'creator') bulk_edit_form = FindingBulkUpdateForm(request.GET) google_sheets_enabled = system_settings.enable_google_sheets sheet_url = None if google_sheets_enabled and system_settings.credentials: spreadsheet_name = test.engagement.product.name + "-" + test.engagement.name + "-" + str( test.id) system_settings = get_object_or_404(System_Settings, id=1) service_account_info = json.loads(system_settings.credentials) SCOPES = ['https://www.googleapis.com/auth/drive'] credentials = service_account.Credentials.from_service_account_info( service_account_info, scopes=SCOPES) try: drive_service = googleapiclient.discovery.build( 'drive', 'v3', credentials=credentials, cache_discovery=False) folder_id = system_settings.drive_folder_ID gs_files = drive_service.files().list( q="mimeType='application/vnd.google-apps.spreadsheet' and parents in '%s' and name='%s'" % (folder_id, spreadsheet_name), spaces='drive', pageSize=10, fields='files(id, name)').execute() except googleapiclient.errors.HttpError: messages.add_message( request, messages.ERROR, "There is a problem with the Google Sheets Sync Configuration. Contact your system admin to solve the issue. Until fixed, the Google Sheets Sync feature cannot be used.", extra_tags="alert-danger", ) google_sheets_enabled = False except httplib2.ServerNotFoundError: messages.add_message( request, messages.ERROR, "Unable to reach the Google Sheet API.", extra_tags="alert-danger", ) else: spreadsheets = gs_files.get('files') if len(spreadsheets) == 1: spreadsheetId = spreadsheets[0].get('id') sheet_url = 'https://docs.google.com/spreadsheets/d/' + spreadsheetId return render( request, 'dojo/view_test.html', { 'test': test, 'prod': prod, 'product_tab': product_tab, 'findings': paged_findings, 'filtered': findings, 'stub_findings': paged_stub_findings, 'title_words': title_words, 'component_words': component_words, 'form': form, 'notes': notes, 'files': files, 'person': person, 'request': request, 'show_re_upload': show_re_upload, 'creds': creds, 'cred_test': cred_test, 'jira_project': jira_project, 'show_export': google_sheets_enabled and system_settings.credentials, 'sheet_url': sheet_url, 'bulk_edit_form': bulk_edit_form, 'paged_test_imports': paged_test_imports, 'test_import_filter': test_import_filter, 'finding_groups': finding_groups, 'finding_group_by_options': Finding_Group.GROUP_BY_OPTIONS, })
def 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 '''