Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Rebase release/2.2.0 with latest master changes #228

Merged
merged 93 commits into from
Nov 10, 2024
Merged

Conversation

psyray
Copy link
Contributor

@psyray psyray commented Nov 9, 2024

Synchronize release/2.2.0 branch with latest master updates to ensure all recent fixes and improvements are included in the upcoming release.

Summary by Sourcery

Rebase the release/2.2.0 branch with the latest master changes to incorporate recent updates and improvements. Enhance error handling, logging, and user role management across the codebase. Improve the robustness of HTTP request handling and refactor code for better readability and maintainability.

Enhancements:

  • Improve error handling and logging across various modules to provide more informative error messages and logs.
  • Refactor the handling of user roles and permissions to enhance security and maintainability.
  • Enhance the handling of HTTP requests and responses to improve robustness and error handling.
  • Refactor the code to improve readability and maintainability, including the use of helper functions and better variable naming.

Chores:

  • Rebase the release/2.2.0 branch with the latest changes from the master branch to synchronize updates.

psyray and others added 30 commits August 13, 2024 00:02
build(deps): bump Django deps to fix security issues
…-permissions

build(ci): fix missing write permissions
…link

fix(docs): change art logo and fix doc link
Deleting this as it should be part of 2.1.0, which we have #138 for.
…ng-issues-when-pr-is-merged

build(ci): add CI for closing issues when PR is merged
docs(readme): set badge to latest release automatically
…-in-url

fix(readme): remove space after url
AnonymousWP and others added 24 commits September 26, 2024 20:26
…ration

feat: reintroduce Lark notification fields in scanEngine
…esults-parsing

refactor: improve robustness of nuclei result parsing
refactor: replace hardcoded API URLs with dynamic endpoint URLs
- Refactored modal handling by standardizing the use of #modal_dialog and .modal-text for content updates across various JavaScript files.
- Enhanced the CMS detection functionality by introducing a new event listener for detecting CMS on subdomains, utilizing data attributes for passing necessary information.
- Updated modal dismissal buttons to use data-bs-dismiss for Bootstrap 5 compatibility.
- Removed redundant IDs from modal elements in HTML templates to streamline the code and prevent potential conflicts.
- Improved the handling of project-specific data by passing the current project slug to relevant functions.
- The changes involve removing duplicate data-bs-dismiss="modal" attributes from the close buttons in multiple modal headers within the top_bar.html template. This ensures that each button has a single data-bs-dismiss attribute, improving code clarity and potentially preventing unexpected behavior.
- Changed the method for setting the modal title from html() to text() to ensure proper handling of text content.
- Updated the jQuery selectors for modal elements in the get_dork_details function to ensure they specifically target elements within the #modal_dialog container. This change enhances the specificity and reliability of the modal rendering process.
refactor: update modal handling and improve CMS detection
The changes refactor the delete functionality across multiple templates and JavaScript files to use URL endpoints instead of constructing URLs manually. This update enhances the maintainability and readability of the code by leveraging Django's URL template tags for generating URLs dynamically.
refactor: update delete functions to use URL endpoints
- Refactored JavaScript functions to use url_endpoint instead of slug for setting form actions, enhancing flexibility in URL handling.
- Updated HTML templates to use Django's {% url %} template tag for generating URLs dynamically, improving maintainability.
Modified Docker development configuration to enable remote debugging and added a new port mapping.
- Adjusted CSS link paths in the notification settings template for better organization.
- Changed URL patterns in urls.py for consistency in endpoint naming.
- Removed an unnecessary filter in the detail_vuln_scan view function to streamline the code.
- Implemented caching for external IP retrieval in the misc function to reduce unnecessary requests and improve performance.
- Added error handling and logging for external IP retrieval failures.
…ternal-ip

feat: enhance IP retrieval with caching
…ros (#211)

* build(docker): refactor detection of OS

This commit also adds support for RHEL distros

* build(install): use functions for installing dependencies

* feat(install): enhance installation script with Docker Compose version check and refactor package installation

- Refactored the installation script to include a Docker Compose version check, ensuring compatibility with version 2.0.0 or higher.
- Consolidated package installation functions into a generic install_package function to streamline the installation process for various packages like nano, curl, and make.
- Improved error handling and logging for package installations and Docker setup.

* feat(install): enhance Docker and Docker Compose checks in installation script

- Added functions to check Docker and Docker Compose installations, including version checks and guidance for installation or upgrade if necessary.
- Removed automatic installation of Docker and Docker Compose, replacing it with user guidance for manual installation.
- Updated the installation script to ensure Docker is installed and running before proceeding.

* fix: improve Docker installation checks and update Makefile

- Enhanced the Docker installation script to repeatedly prompt the user until a valid choice is made.
- Updated the Makefile to include checks for Docker Compose installation and user permissions, ensuring the user is in the docker group or running as root.

* build(install): move pre-req check after env check

* build(install): specify color meaning and change some

* build(install): provide more specific error information

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

* build(make): use `getent`

---------

Co-authored-by: psyray <[email protected]>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
- Enhanced error logging in user management functions by adding descriptive messages for delete, update, and create operations.
- Improved file handling in get_cms_details by using a context manager for file operations.
- Removed duplicate code in settings.py related to reading the version file.
- Standardized error responses in user management functions to provide consistent error messages.
- Initialized URL variables in JavaScript modal functions to prevent potential undefined variable issues.
- Added a comment to clarify the handling of KeyError in the api_vault_delete function.
…recommendations

fix: apply github-advanced-security recommendations
- Updated the wordlist used in startScan.json from dicc.txt to fuzz-Bo0oM.txt for directory scanning commands.
- Refactored the configuration in tasks.py to use default wordlist names and paths for Amass and FFUF, improving maintainability.
- Modified definitions.py to define default wordlist names and paths for Amass and FFUF, centralizing configuration.
- Adjusted default_scan_engines.yaml and default_yaml_config.yaml to remove file extensions from the dir_file_fuzz configuration and set the recursive level to 0.
- Updated scanEngine.json configurations to reflect changes in wordlist names and recursive levels, aligning with the new defaults.
- Converted wordlist paths to string format using Path for compatibility.
- Changed the default recursive level for FFUF from 2 to 0.
- Added a commented list of file extensions to the default_yaml_config.yaml file for potential future use or reference.
…-heavy

refactor: update wordlists and configuration defaults
@psyray psyray self-assigned this Nov 9, 2024
Copy link
Contributor

sourcery-ai bot commented Nov 9, 2024

Reviewer's Guide by Sourcery

This pull request performs a major refactoring and cleanup of the codebase to improve code quality, security, and maintainability. The changes include URL routing optimization, improved error handling, code standardization, and security enhancements across multiple components.

Updated class diagram for APIView classes

classDiagram
    class OllamaManager {
        +get(request)
        +delete(request)
        +put(request)
    }
    class GPTAttackSuggestion {
        +get(request)
    }
    class CreateProjectApi {
        +get(request)
    }
    class QueryInterestingSubdomains {
        +get(request)
    }
    class WafDetector {
        +get(request)
    }
    class FetchMostCommonVulnerability {
        +post(request)
    }
    class FetchMostVulnerable {
        +post(request)
    }
    class ToggleSubdomainImportantStatus {
        +post(request)
    }
    class AddDomainAsTarget {
        +post(request)
    }
    class FetchSubscanResults {
        +get(request)
    }
    class ListSubScans {
        +post(request)
    }
    class DeleteMultipleRows {
        +post(request)
    }
    class StopScan {
        +post(request)
    }
    class InitiateSubTask {
        +post(request)
    }
    class DeleteSubdomain {
        +post(request)
    }
    class DeleteVulnerability {
        +post(request)
    }
    class ListInterestingKeywords {
        +get(request, format=None)
    }
    class UninstallTool {
        +get(request)
    }
    class UpdateTool {
        +get(request)
    }
    class GetExternalToolCurrentVersion {
        +get(request)
    }
    class GithubToolCheckGetLatestRelease {
        +get(request)
    }
    class CMSDetector {
        +get(request)
    }
    class IPToDomain {
        +get(request)
    }
    class VulnerabilityReport {
        +get(request)
    }
    class ListTodoNotes {
        +get(request, format=None)
    }
    class ListOrganizations {
        +get(request, format=None)
    }
    class ListTargetsInOrganization {
        +get(request, format=None)
    }
    class VisualiseData {
        +get(request, format=None)
        +process_visualisation_data(data)
    }
    class ListTechnology {
        +get(request, format=None)
    }
    class ListDorkTypes {
        +get(request, format=None)
    }
    class ListEmails {
        +get(request, format=None)
    }
    class ListDorks {
        +get(request, format=None)
    }
    class ListEmployees {
        +get(request, format=None)
    }
    class ListPorts {
        +get(request, format=None)
    }
    class ListSubdomains {
        +get(request, format=None)
    }
    class ListOsintUsers {
        +get(request, format=None)
    }
    class ListMetadata {
        +get(request, format=None)
    }
    class ListIPs {
        +get(request, format=None)
    }
    class IpAddressViewSet {
        +get_queryset()
        +paginate_queryset(queryset, view=None)
    }
    class SubdomainsViewSet {
        +get_queryset()
        +paginate_queryset(queryset, view=None)
    }
    class SubdomainChangesViewSet {
        +get_queryset()
        +paginate_queryset(queryset, view=None)
    }
    class EndPointChangesViewSet {
        +get_queryset()
        +paginate_queryset(queryset, view=None)
    }
    class InterestingSubdomainViewSet {
        +get_queryset()
        +paginate_queryset(queryset, view=None)
    }
    class InterestingEndpointViewSet {
        +get_queryset()
        +paginate_queryset(queryset, view=None)
    }
    class SubdomainDatatableViewSet {
        +get_queryset()
    }
    class ListActivityLogsViewSet {
        +get_queryset()
    }
    class ListScanLogsViewSet {
        +get_queryset()
    }
    class ListEndpoints {
        +get(request, format=None)
    }
    class EndPointViewSet {
        +get_queryset()
    }
    class DirectoryViewSet {
        +get_queryset()
    }
    class ProjectViewSet {
        +get_queryset()
        +perform_create(serializer)
        +perform_update(serializer)
    }
    class VulnerabilityViewSet {
        +get_queryset()
    }
Loading

File-Level Changes

Change Details Files
Improved URL routing and navigation structure
  • Simplified URL patterns by removing redundant slug parameters
  • Standardized URL naming conventions across the application
  • Added URL reversing using named URLs instead of hardcoded paths
  • Improved URL parameter handling and validation
web/scanEngine/urls.py
web/targetApp/urls.py
web/startScan/urls.py
Enhanced error handling and input validation
  • Added proper error handling for API responses
  • Implemented input validation for form submissions
  • Added type checking and sanitization for user inputs
  • Improved exception handling with proper error messages
web/api/views.py
web/dashboard/views.py
web/targetApp/views.py
Security improvements and code hardening
  • Added CSRF protection to forms and API endpoints
  • Implemented proper permission checks
  • Added input sanitization for user-provided data
  • Improved file handling security
web/reNgine/common_func.py
web/reNgine/tasks.py
Frontend code optimization and modernization
  • Refactored JavaScript code to use modern practices
  • Improved modal handling and UI interactions
  • Enhanced error message display
  • Added proper event handling for UI components
web/static/custom/custom.js
web/static/custom/toolbox.js
web/recon_note/static/note/js/todo.js
Installation script improvements
  • Added better Docker installation checks
  • Improved error handling during installation
  • Added version compatibility checks
  • Enhanced user feedback during installation
install.sh

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

subprocess.Popen: The Popen object for the executed command.
"""
return subprocess.Popen(
command,

Check failure

Code scanning / CodeQL

Uncontrolled command line Critical

This command line depends on a
user-provided value
.

Copilot Autofix AI about 2 months ago

To fix the problem, we need to ensure that the command passed to subprocess.Popen is safe and not directly influenced by user input. This can be achieved by using a predefined allowlist of commands or by properly sanitizing the user input.

  1. Use an allowlist: Define a set of allowed commands and only execute those commands if they match the predefined list.
  2. Sanitize user input: Use shlex.split to safely parse the command string into a list of arguments, which can then be safely passed to subprocess.Popen.

In this case, we will implement the allowlist approach to ensure that only predefined commands are executed.

Suggested changeset 1
web/reNgine/common_func.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/web/reNgine/common_func.py b/web/reNgine/common_func.py
--- a/web/reNgine/common_func.py
+++ b/web/reNgine/common_func.py
@@ -1262,22 +1262,36 @@
 
-def execute_command(command, shell, cwd):
-    """
-    Execute a command using subprocess.
-
-    Args:
-        command (str or list): The command to execute.
-        shell (bool): Whether to use shell execution.
-        cwd (str): The working directory for the command.
-
-    Returns:
-        subprocess.Popen: The Popen object for the executed command.
-    """
-    return subprocess.Popen(
-        command,
-        stdout=subprocess.PIPE,
-        stderr=subprocess.STDOUT,
-        universal_newlines=True,
-        shell=shell,
-        cwd=cwd
-    )
+ALLOWED_COMMANDS = {
+    "ls": ["ls"],
+    "stat": ["stat"],
+    # Add other allowed commands here
+}
+
+def execute_command(command, shell, cwd):
+    """
+    Execute a command using subprocess.
+
+    Args:
+        command (str or list): The command to execute.
+        shell (bool): Whether to use shell execution.
+        cwd (str): The working directory for the command.
+
+    Returns:
+        subprocess.Popen: The Popen object for the executed command.
+    """
+    if isinstance(command, str):
+        command_list = shlex.split(command)
+    else:
+        command_list = command
+
+    if command_list[0] not in ALLOWED_COMMANDS:
+        raise ValueError(f"Command '{command_list[0]}' is not allowed.")
+
+    return subprocess.Popen(
+        ALLOWED_COMMANDS[command_list[0]] + command_list[1:],
+        stdout=subprocess.PIPE,
+        stderr=subprocess.STDOUT,
+        universal_newlines=True,
+        shell=shell,
+        cwd=cwd
+    )
 
EOF
@@ -1262,22 +1262,36 @@

def execute_command(command, shell, cwd):
"""
Execute a command using subprocess.

Args:
command (str or list): The command to execute.
shell (bool): Whether to use shell execution.
cwd (str): The working directory for the command.

Returns:
subprocess.Popen: The Popen object for the executed command.
"""
return subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
shell=shell,
cwd=cwd
)
ALLOWED_COMMANDS = {
"ls": ["ls"],
"stat": ["stat"],
# Add other allowed commands here
}

def execute_command(command, shell, cwd):
"""
Execute a command using subprocess.

Args:
command (str or list): The command to execute.
shell (bool): Whether to use shell execution.
cwd (str): The working directory for the command.

Returns:
subprocess.Popen: The Popen object for the executed command.
"""
if isinstance(command, str):
command_list = shlex.split(command)
else:
command_list = command

if command_list[0] not in ALLOWED_COMMANDS:
raise ValueError(f"Command '{command_list[0]}' is not allowed.")

return subprocess.Popen(
ALLOWED_COMMANDS[command_list[0]] + command_list[1:],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
shell=shell,
cwd=cwd
)

Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -1510,7 +1590,7 @@
}).then(response => response.json()).then(function(response) {
swal.close();
if (response.status) {
display_whois_on_modal(response, show_add_target_btn=show_add_target_btn);
display_whois_on_modal(response, addTargetUrl, project_slug, show_add_target_btn=show_add_target_btn);

Check warning

Code scanning / CodeQL

Self assignment Warning

This expression assigns variable show_add_target_btn to itself.
var domain_name = $('#target_name_modal').val();
var description = $('#target_description_modal').val();
var h1_handle = $('#h1_handle_modal').val();
var organization = $('#target_organization_modal').val();
add_target(domain_name, h1_handle = h1_handle, description = description, organization = organization);
}
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);

Check warning

Code scanning / CodeQL

Self assignment Warning

This expression assigns variable h1_handle to itself.
var domain_name = $('#target_name_modal').val();
var description = $('#target_description_modal').val();
var h1_handle = $('#h1_handle_modal').val();
var organization = $('#target_organization_modal').val();
add_target(domain_name, h1_handle = h1_handle, description = description, organization = organization);
}
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning

The value assigned to h1_handle here is unused.
var domain_name = $('#target_name_modal').val();
var description = $('#target_description_modal').val();
var h1_handle = $('#h1_handle_modal').val();
var organization = $('#target_organization_modal').val();
add_target(domain_name, h1_handle = h1_handle, description = description, organization = organization);
}
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);

Check warning

Code scanning / CodeQL

Self assignment Warning

This expression assigns variable description to itself.
@@ -55,7 +55,7 @@
</div>
</div>
<div class="text-center mt-3 mb-4">
<a href="javascript:getScanStatusSidebar(project='{{current_project.slug}}', reload=true)" class="btn btn-md btn-primary">
<a href="javascript:getScanStatusSidebar('{% url 'api:scan_status' %}', '{% url 'api:stop_scan' %}', '{% url 'api:fetch_subscan_results' %}', project='{{current_project.slug}}', reload=true)" class="btn btn-md btn-primary">

Check notice

Code scanning / CodeQL

Syntax error Note

Error: Unexpected token
</a>
{% endfor %}
<div class="dropdown-divider"></div>
<a href="#" onclick="add_project_modal()" class="dropdown-item"><i class="mdi mdi-account-plus"></i> Create New Project</a>
<a href="#" onclick="add_project_modal('{% url 'api:create_project' %}')" class="dropdown-item"><i class="mdi mdi-account-plus"></i> Create New Project</a>

Check notice

Code scanning / CodeQL

Syntax error Note

Error: Unexpected token
@@ -161,7 +161,7 @@
</a>
</li>
<li class="dropdown top-activity-counter">
<a class="nav-link dropdown-toggle waves-effect waves-light right-bar-toggle" href="javascript:getScanStatusSidebar(project='{{current_project.slug}}', reload=false)">
<a class="nav-link dropdown-toggle waves-effect waves-light right-bar-toggle" href="javascript:getScanStatusSidebar('{% url 'api:scan_status' %}', '{% url 'api:stop_scan' %}', '{% url 'api:fetch_subscan_results' %}', project='{{current_project.slug}}', reload=false)">

Check notice

Code scanning / CodeQL

Syntax error Note

Error: Unexpected token
@@ -26,7 +26,7 @@
{% if vulnerability.cve_ids %}
<br>
{% for cve in vulnerability.cve_ids.all %}
<span class="badge badge-soft-danger badge-link" data-toggle="tooltip" data-placement="top" title="CVE ID" onclick="get_and_render_cve_details('{{cve.name}}')">{{cve.name}}</span>
<span class="badge badge-soft-danger badge-link" data-toggle="tooltip" data-placement="top" title="CVE ID" onclick="get_and_render_cve_details('{% url 'api:cve_details' %}', '{{cve.name}}')">{{cve.name}}</span>

Check notice

Code scanning / CodeQL

Syntax error Note

Error: Unexpected token
@@ -122,7 +121,7 @@
// reNgine-ng will also check everyday if update exists for reNgine-ng
checkDailyUpdate();

getScanStatusSidebar(project='{{current_project.slug}}', reload=false);
getScanStatusSidebar('{% url 'api:scan_status' %}', '{% url 'api:stop_scan' %}', '{% url 'api:fetch_subscan_results' %}', project='{{current_project.slug}}', reload=false);

Check notice

Code scanning / CodeQL

Syntax error Note

Error: Unexpected token
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @psyray - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • Add path traversal protection for file uploads (link)

Overall Comments:

  • Consider adding more comprehensive error logging in the Docker installation checks to help diagnose installation issues. The current error messages could be more detailed.
  • The JavaScript code still has some instances of string concatenation for HTML generation. Consider using template literals consistently throughout for better readability and security.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🔴 Security: 1 blocking issue
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 3 issues found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.


class GPTAttackSuggestion(APIView):
def get(self, request):
req = self.request
subdomain_id = req.query_params.get('subdomain_id')
subdomain_id = safe_int_cast(req.query_params.get('subdomain_id'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Add validation for the safe_int_cast return values

The safe_int_cast results should be validated before use. Consider adding explicit checks for None or invalid values.

		subdomain_id = safe_int_cast(req.query_params.get('subdomain_id'))
		if subdomain_id is None or subdomain_id < 1:
			return Response({'error': 'Invalid subdomain ID'}, status=400)

def handle_nuclei_upload(request):
handle_file_upload(request, 'nucleiFileUpload', 'nuclei-templates', 'yaml', 'Nuclei Pattern')

def handle_file_upload(request, file_key, directory, expected_extension, pattern_name):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 issue (security): Add path traversal protection for file uploads

The file path handling could be vulnerable to path traversal. Consider using os.path.basename and validating the final path.

if external_ip is None:
try:
# If the IP address is not in the cache, make the request
external_ip = requests.get('https://checkip.amazonaws.com').text.strip()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Add request timeout to external IP fetch

The requests.get() call should include a timeout parameter to prevent hanging if the external service is slow to respond.

Suggested change
external_ip = requests.get('https://checkip.amazonaws.com').text.strip()
external_ip = requests.get('https://checkip.amazonaws.com', timeout=5).text.strip()

@@ -367,99 +420,62 @@


class FetchMostCommonVulnerability(APIView):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider refactoring FetchMostCommonVulnerability to use a query builder pattern.

The FetchMostCommonVulnerability class can be simplified by using a query builder pattern to reduce code duplication and nesting. Here's how to refactor it:

class FetchMostCommonVulnerability(APIView):
    def post(self, request):
        data = request.data
        limit = safe_int_cast(data.get('limit', 20))
        project_slug = data.get('slug')
        scan_history_id = safe_int_cast(data.get('scan_history_id'))
        target_id = safe_int_cast(data.get('target_id'))
        is_ignore_info = data.get('ignore_info', False)

        # Start with base queryset
        vulnerabilities = (Vulnerability.objects
            .filter(scan_history__domain__project__slug=project_slug) 
            if project_slug else Vulnerability.objects.all())

        # Build query filters
        if scan_history_id:
            vulnerabilities = vulnerabilities.filter(scan_history__id=scan_history_id)
        elif target_id:
            vulnerabilities = vulnerabilities.filter(target_domain__id=target_id)

        # Get vulnerability counts
        vuln_query = vulnerabilities.values("name", "severity")
        if is_ignore_info:
            vuln_query = vuln_query.exclude(severity=0)

        most_common = (vuln_query
            .annotate(count=Count('name'))
            .order_by("-count")[:limit])

        return Response({
            'status': bool(most_common),
            'result': list(most_common)
        })

This refactoring:

  1. Eliminates duplicate query logic by building the query incrementally
  2. Removes nested if-else chains using early returns
  3. Simplifies error handling
  4. Maintains all existing functionality while reducing code complexity

The query builder pattern makes the code more maintainable and easier to extend with new filters in the future.

checkbox.parentNode.parentNode.parentNode.classList.remove("text-strike");
}
change_vuln_status(id);
function updateVulnStatus(endpoint_url, element, id, status) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider consolidating vulnerability status management into a dedicated VulnerabilityManager class.

The vulnerability status management code has unnecessary complexity that should be simplified. Consider consolidating the scattered state management into a single VulnerabilityManager class:

class VulnerabilityManager {
  constructor() {
    this.selectedCount = 0;
    this.initializeEventHandlers();
  }

  initializeEventHandlers() {
    $('#select_all_checkbox').on('click', e => this.handleSelectAll(e));
    $('.vulnerability_checkbox').on('change', e => this.handleCheckboxChange(e));
  }

  handleSelectAll(e) {
    const checked = $(e.target).is(':checked');
    $("tr").find("[type=checkbox]").prop('checked', checked);
    this.updateUI();
  }

  handleCheckboxChange() {
    this.selectedCount = $('.vulnerability_checkbox:checked').length;
    this.updateUI();
  }

  updateUI() {
    const hasSelection = this.selectedCount > 0;
    $('#select_all_checkbox').prop('checked', this.selectedCount >= 2);
    $(".vulnerability_btns").toggleClass("disabled", !hasSelection);
    $('#vulnaribilities_selected_count')
      .toggle(hasSelection)
      .text(`${this.selectedCount} Vulnerabilities Selected x`);
  }
}

// Usage
const vulnManager = new VulnerabilityManager();

This refactoring:

  1. Centralizes vulnerability selection state management
  2. Reduces code duplication
  3. Makes the code more maintainable by grouping related functionality
  4. Simplifies the event handling logic

var domain_name = $('#target_name_modal').val();
var description = $('#target_description_modal').val();
var h1_handle = $('#h1_handle_modal').val();
var organization = $('#target_organization_modal').val();
add_target(domain_name, h1_handle = h1_handle, description = description, organization = organization);
}
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Assigning a variable to itself has no effect. (dont-self-assign-variables)

Suggested change
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);
add_target(endpoint_url, current_slug, domain_name, , description = description, organization = organization);


ExplanationAssigning a variable to itself has no effect, and is therefore either redundant or a mistake.

var domain_name = $('#target_name_modal').val();
var description = $('#target_description_modal').val();
var h1_handle = $('#h1_handle_modal').val();
var organization = $('#target_organization_modal').val();
add_target(domain_name, h1_handle = h1_handle, description = description, organization = organization);
}
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Assigning a variable to itself has no effect. (dont-self-assign-variables)

Suggested change
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, , organization = organization);


ExplanationAssigning a variable to itself has no effect, and is therefore either redundant or a mistake.

var domain_name = $('#target_name_modal').val();
var description = $('#target_description_modal').val();
var h1_handle = $('#h1_handle_modal').val();
var organization = $('#target_organization_modal').val();
add_target(domain_name, h1_handle = h1_handle, description = description, organization = organization);
}
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Assigning a variable to itself has no effect. (dont-self-assign-variables)

Suggested change
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, organization = organization);
add_target(endpoint_url, current_slug, domain_name, h1_handle = h1_handle, description = description, );


ExplanationAssigning a variable to itself has no effect, and is therefore either redundant or a mistake.

// this function will fetch and render ips in widget
var url = '/api/queryIps/?';
var url = `${endpoint}?`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Use const or let instead of var. (avoid-using-var)

Explanation`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code). `let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than function-scoped.

From the Airbnb JavaScript Style Guide

// this function will fetch and render tech in widget
var url = '/api/queryTechnologies/?';
var url = `${endpoint_url}?`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Use const or let instead of var. (avoid-using-var)

Explanation`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code). `let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than function-scoped.

From the Airbnb JavaScript Style Guide

@psyray psyray requested a review from AnonymousWP November 9, 2024 19:11
@psyray psyray merged commit 0ec7383 into release/2.2.0 Nov 10, 2024
54 of 55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants