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

feat: allow automatic loading of required libraries when performing a domain import #1409

Conversation

Mohamed-Hacene
Copy link
Collaborator

@Mohamed-Hacene Mohamed-Hacene commented Jan 23, 2025

Summary by CodeRabbit

  • New Features

    • Added option to load missing libraries during domain import.
    • Enhanced library import process with more flexible handling of dependencies.
    • Introduced new localization keys for loading missing libraries and providing help text.
  • Bug Fixes

    • Improved error handling for missing or outdated libraries during import.
  • Documentation

    • Updated localization messages to provide clearer guidance on library import process.
  • Refactor

    • Simplified form components related to folder and library import.
    • Modified library loading and export logic.

Copy link

coderabbitai bot commented Jan 23, 2025

Walkthrough

This pull request introduces enhancements to the library import functionality across multiple files. The core change is the addition of a new load_missing_libraries parameter that provides more control over importing libraries with missing or outdated dependencies. The changes span backend and frontend components, modifying import processes, form handling, and error messaging to support more flexible library imports. The implementation allows users to choose whether to load missing libraries during the import process, with updated schemas, localization messages, and UI components to support this new feature.

Changes

File Change Summary
backend/core/views.py Added load_missing_libraries parameter to import_domain method, updating library import logic. Updated _import_objects to handle missing libraries based on the new parameter.
backend/library/utils.py Removed debug print statement in import_objects method.
backend/serdes/utils.py Modified get_domain_export_objects to enhance library dependency retrieval.
frontend/messages/en.json Updated localization messages for missing libraries and added new keys for user prompts.
frontend/src/lib/components/Forms/ModelForm.svelte Updated conditional rendering for FolderForm to include additional model type.
frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte Replaced text input with checkbox for loading missing libraries and removed unnecessary props.
frontend/src/lib/utils/schemas.ts Added load_missing_libraries to FolderImportSchema.
frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.server.ts Added folderImportModel and updated import endpoint logic to include load_missing_libraries.
frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.svelte Modified modal configuration for folder import to reference new model property.
frontend/messages/fr.json Added new keys for localization related to loading missing libraries.
enterprise/frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte Updated form structure to replace text input with checkbox for loading missing libraries and adjusted file input properties.

Possibly related PRs

Suggested Reviewers

  • ab-smith
  • eric-intuitem
  • nas-tabchiche

Poem

🐰 A Rabbit's Import Tale 🐰
Libraries missing, no need to despair,
With a checkbox click, we'll load with care!
Dependencies dance, versions align,
Import magic works, simply divine!
Hop to it, code friends, let libraries shine! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68d19b3 and 0009755.

📒 Files selected for processing (1)
  • backend/core/views.py (4 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
backend/core/views.py

2290-2290: LoadedLibrary may be undefined, or defined from star imports

(F405)


2294-2294: StoredLibrary may be undefined, or defined from star imports

(F405)


2299-2299: StoredLibrary may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: startup-functional-test (3.12)
  • GitHub Check: startup-docker-compose-test
  • GitHub Check: enterprise-startup-functional-test (3.12)
  • GitHub Check: functional-tests (3.12, chromium)
  • GitHub Check: enterprise-startup-docker-compose-test
  • GitHub Check: test (3.12)
  • GitHub Check: enterprise-functional-tests (3.12, chromium)
  • GitHub Check: build (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
backend/core/views.py (3)

2138-2141: LGTM! Clean implementation of the new parameter.

The boolean conversion from query parameters is implemented safely.


2242-2244: LGTM! Method signature updated correctly.

The new parameter is properly typed and follows the method's existing style.


2368-2376: LGTM! Library validation logic is sound.

The implementation correctly tracks required libraries and skips library objects during validation.

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Mohamed-Hacene Mohamed-Hacene marked this pull request as ready for review January 23, 2025 13:09
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
backend/core/views.py (1)

2140-2143: Improve boolean parsing of load_missing_libraries parameter

The current parsing of load_missing_libraries compares the lowercase string directly to "true". To handle more truthy values and improve robustness, consider using Django's built-in utilities or a function like strtobool.

Apply this diff to enhance the parsing:

+from distutils.util import strtobool

 load_missing_libraries = (
-    request.query_params.get("load_missing_libraries", "false").lower()
+    strtobool(request.query_params.get("load_missing_libraries", "false"))
-    == "true"
 )
frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.server.ts (1)

104-106: Refactor endpoint URL construction for clarity

When constructing the endpoint URL, consider separating the base URL and query parameters for better readability and maintainability.

Apply this diff to refactor the URL construction:

 const endpoint =
-    `${BASE_API_URL}/folders/import/` +
-    (form.data.load_missing_libraries ? `?load_missing_libraries=true` : '');
+    `${BASE_API_URL}/folders/import/${form.data.load_missing_libraries ? '?load_missing_libraries=true' : ''}`;

Or use URLSearchParams for handling multiple query parameters:

+import { URLSearchParams } from 'url';

+const params = new URLSearchParams();

+if (form.data.load_missing_libraries) {
+    params.append('load_missing_libraries', 'true');
+}

 const endpoint =
     `${BASE_API_URL}/folders/import/${params.toString() ? '?' + params.toString() : ''}`;
backend/serdes/utils.py (1)

519-530: LGTM! The library loading logic has been improved to include dependencies.

The changes correctly implement a two-step process to load libraries:

  1. First, load directly related libraries
  2. Then, include their dependencies through a union operation

This ensures comprehensive library coverage during domain export.

Consider using a single query with Q objects to improve performance:

-    initial_loaded_libraries = LoadedLibrary.objects.filter(
-        Q(folder__in=folders)
-        | Q(threats__in=threats)
-        | Q(reference_controls__in=reference_controls)
-        | Q(risk_matrices__in=risk_matrices)
-        | Q(frameworks__in=frameworks)
-    ).distinct()
-    loaded_libraries = initial_loaded_libraries.union(
-        LoadedLibrary.objects.filter(
-            pk__in=initial_loaded_libraries.values_list("dependencies", flat=True)
-        ).distinct()
-    )
+    loaded_libraries = LoadedLibrary.objects.filter(
+        Q(folder__in=folders)
+        | Q(threats__in=threats)
+        | Q(reference_controls__in=reference_controls)
+        | Q(risk_matrices__in=risk_matrices)
+        | Q(frameworks__in=frameworks)
+        | Q(pk__in=LoadedLibrary.objects.filter(
+            Q(folder__in=folders)
+            | Q(threats__in=threats)
+            | Q(reference_controls__in=reference_controls)
+            | Q(risk_matrices__in=risk_matrices)
+            | Q(frameworks__in=frameworks)
+        ).values_list("dependencies", flat=True))
+    ).distinct()
frontend/src/lib/utils/schemas.ts (1)

72-74: LGTM! The schema has been updated to support library loading control.

The addition of load_missing_libraries with z.coerce.boolean().default(false) is well-implemented and safely defaults to false.

Consider expanding the comment to explain why the coerce workaround is needed:

-	//NOTE: coerce is a workaround because without we get an inconsistent error in form validation
+	//NOTE: coerce is used to handle checkbox form values which can be strings ('true'/'false')
+	//or booleans (true/false). Without coerce, form validation fails inconsistently when
+	//string values are received.
frontend/messages/en.json (1)

1129-1130: LGTM! Clear and helpful messages for the new feature.

The new messages provide clear UI text for the automatic library loading feature:

  • A concise label for the control
  • Helpful explanatory text that guides users on when to use this option

Consider adding a period at the end of the help text for consistency with other help texts in the file:

-  "loadMissingLibrariesHelpText": "Load the missing libraries to complete the import if they are available",
+  "loadMissingLibrariesHelpText": "Load the missing libraries to complete the import if they are available.",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7acf337 and 150540f.

📒 Files selected for processing (9)
  • backend/core/views.py (4 hunks)
  • backend/library/utils.py (0 hunks)
  • backend/serdes/utils.py (1 hunks)
  • frontend/messages/en.json (1 hunks)
  • frontend/src/lib/components/Forms/ModelForm.svelte (1 hunks)
  • frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte (2 hunks)
  • frontend/src/lib/utils/schemas.ts (1 hunks)
  • frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.server.ts (3 hunks)
  • frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.svelte (1 hunks)
💤 Files with no reviewable changes (1)
  • backend/library/utils.py
🧰 Additional context used
🪛 Ruff (0.8.2)
backend/core/views.py

2292-2292: LoadedLibrary may be undefined, or defined from star imports

(F405)


2296-2296: StoredLibrary may be undefined, or defined from star imports

(F405)


2301-2301: StoredLibrary may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: startup-functional-test (3.12)
  • GitHub Check: enterprise-startup-docker-compose-test
  • GitHub Check: startup-docker-compose-test
  • GitHub Check: enterprise-functional-tests (3.12, chromium)
  • GitHub Check: test (3.12)
  • GitHub Check: enterprise-startup-functional-test (3.12)
  • GitHub Check: functional-tests (3.12, chromium)
  • GitHub Check: build (3.12)
🔇 Additional comments (8)
backend/core/views.py (2)

2292-2292: Address possible undefined variables reported by static analysis

Static analysis indicates that LoadedLibrary may be undefined. Ensure that LoadedLibrary is properly imported.

🧰 Tools
🪛 Ruff (0.8.2)

2292-2292: LoadedLibrary may be undefined, or defined from star imports

(F405)


2296-2296: Address possible undefined variables reported by static analysis

Static analysis indicates that StoredLibrary may be undefined. Ensure that StoredLibrary is properly imported.

🧰 Tools
🪛 Ruff (0.8.2)

2296-2296: StoredLibrary may be undefined, or defined from star imports

(F405)

frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte (2)

5-5: Import of Checkbox component is necessary

The import of the Checkbox component is correctly added and used in the form, ensuring the new checkbox functionality works as intended.


20-25: Implementation of load_missing_libraries checkbox is correct

The Checkbox component for load_missing_libraries is properly implemented with correct bindings to the form. Labels and help texts are correctly sourced from the messages module.

frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.server.ts (1)

74-74: Ensure folderImportModel is utilized correctly

The folderImportModel is added to the model object. Verify that this new property is correctly referenced in the frontend components to prevent any undefined property issues.

frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.svelte (1)

57-57: LGTM! The model property access has been updated correctly.

The change to access folderImportModel from data.model aligns with the new data structure supporting the library loading feature.

frontend/src/lib/components/Forms/ModelForm.svelte (1)

192-193: LGTM! The form rendering logic has been enhanced.

The changes correctly:

  1. Support both 'folders' and 'folders-import' URL models
  2. Simplify the props passed to FolderForm
frontend/messages/en.json (1)

1128-1128: LGTM! Improved message clarity.

The updated message now clearly indicates that libraries can be either missing or outdated, which better reflects the actual state of dependencies during import.

Comment on lines 2292 to 2305
if not LoadedLibrary.objects.filter(
urn=library["urn"], version=library["version"]
).exists():
if (
StoredLibrary.objects.filter(
urn=library["urn"], version=library["version"]
).exists()
and load_missing_libraries
):
StoredLibrary.objects.get(
urn=library["urn"], version=library["version"]
).load()
else:
missing_libraries.append(library)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Import missing models LoadedLibrary and StoredLibrary

The models LoadedLibrary and StoredLibrary are used but not imported in this module, which will result in a NameError at runtime.

Add the necessary imports at the top of the file:

+from core.models import LoadedLibrary, StoredLibrary

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

2292-2292: LoadedLibrary may be undefined, or defined from star imports

(F405)


2296-2296: StoredLibrary may be undefined, or defined from star imports

(F405)


2301-2301: StoredLibrary may be undefined, or defined from star imports

(F405)

@intuitem intuitem deleted a comment from coderabbitai bot Jan 23, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3522141 and f056926.

📒 Files selected for processing (2)
  • enterprise/frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte (2 hunks)
  • frontend/src/lib/components/Forms/ModelForm.svelte (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/lib/components/Forms/ModelForm.svelte
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: startup-functional-test (3.12)
  • GitHub Check: startup-docker-compose-test
  • GitHub Check: functional-tests (3.12, chromium)
  • GitHub Check: enterprise-startup-functional-test (3.12)
  • GitHub Check: enterprise-functional-tests (3.12, chromium)
  • GitHub Check: enterprise-startup-docker-compose-test
  • GitHub Check: build (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.12)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
enterprise/frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte (1)

Line range hint 7-16: LGTM! Clean component setup with proper type definitions.

The import statements and component setup are well-structured. The addition of the Checkbox component aligns with the PR objective of allowing control over library loading during import.

Comment on lines +19 to +31
<FileInput
{form}
field="name"
label={m.name()}
cacheLock={cacheLocks['name']}
bind:cachedValue={formDataCache['name']}
data-focusindex="0"
allowPaste={true}
field="file"
label={m.file()}
allowedExtensions={['bak', 'zip']}
helpText={m.importFolderHelpText()}
/>
<Checkbox
{form}
field="load_missing_libraries"
label={m.loadMissingLibraries()}
helpText={m.loadMissingLibrariesHelpText()}
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Frontend file extension validation doesn't match backend requirements

The frontend allows both .bak and .zip files, but the backend only processes ZIP files containing a data.json. Remove .bak from the allowed extensions in FolderForm.svelte to prevent users from uploading unsupported file types.

  • enterprise/frontend/src/lib/components/Forms/ModelForm/FolderForm.svelte: Update allowedExtensions to only include ['zip']
🔗 Analysis chain

LGTM! Well-structured form with clear user guidance.

The form implementation provides a good user experience with:

  • Clear file input restrictions (.bak, .zip)
  • Explicit control over library loading through the checkbox
  • Helpful guidance text for both inputs

Consider adding frontend validation to ensure the file extension check is consistent with backend expectations.

Let's verify the file extension validation consistency:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for file extension validation in backend views
rg -A 5 "allowed.*extension" backend/

Length of output: 1091


Script:

#!/bin/bash
# Search for folder import related views and validation
rg -l "folder.*import|import.*folder" backend/
rg -A 5 "\.bak|\.zip" backend/

Length of output: 3552


Script:

#!/bin/bash
# Search for import views, serializers, and models
rg -A 5 "class.*Import.*View|class.*Upload.*View" backend/
rg -A 5 "@action.*import|def.*import" backend/
rg -A 5 "class.*ImportSerializer" backend/

Length of output: 14448


Script:

#!/bin/bash
# Search for folder serializer and import validation
rg -A 10 "class FolderImportExportSerializer" backend/
rg -B 5 -A 10 "def import_domain" backend/

Length of output: 1688


Script:

#!/bin/bash
# Search for file processing implementation
rg -B 2 -A 10 "_process_uploaded_file" backend/

Length of output: 1798

@ab-smith ab-smith changed the title Ca 817 allow automatic loading of required libraries when performing a domain import feat: (Ca 817) allow automatic loading of required libraries when performing a domain import Jan 23, 2025
@nas-tabchiche nas-tabchiche changed the title feat: (Ca 817) allow automatic loading of required libraries when performing a domain import feat: allow automatic loading of required libraries when performing a domain import Jan 23, 2025
Copy link
Collaborator

@eric-intuitem eric-intuitem left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/core/views.py (2)

16-16: Consider alternatives to distutils.util.strtobool.
distutils is deprecated in Python 3.12. For forward compatibility, a recommended approach is to define a helper function or use an available library function (such as from django.utils) to parse boolean-like strings.


2242-2244: Document the new parameter in _import_objects.
Enhance the method docstring or inline comments to clarify how load_missing_libraries influences the import process.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b523be4 and 68d19b3.

📒 Files selected for processing (1)
  • backend/core/views.py (5 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
backend/core/views.py

2290-2290: LoadedLibrary may be undefined, or defined from star imports

(F405)


2294-2294: StoredLibrary may be undefined, or defined from star imports

(F405)


2299-2299: StoredLibrary may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: startup-docker-compose-test
  • GitHub Check: enterprise-startup-functional-test (3.12)
  • GitHub Check: functional-tests (3.12, chromium)
  • GitHub Check: build (3.12)
  • GitHub Check: enterprise-startup-docker-compose-test
  • GitHub Check: enterprise-functional-tests (3.12, chromium)
  • GitHub Check: startup-functional-test (3.12)
  • GitHub Check: test (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
backend/core/views.py (3)

2139-2141: Potential exception for invalid query param.
If the load_missing_libraries query parameter doesn't match valid strings like true or false, strtobool can raise a ValueError. Consider handling malformed inputs gracefully.


2147-2149: Implementation looks correct.
This call to _import_objects properly threads the new load_missing_libraries parameter.


2290-2303: Handle missing imports and verify library version check.

  • Ensure LoadedLibrary and StoredLibrary are properly imported to avoid NameErrors.
  • Double-check whether version__gte is intentional. If only exact matches are valid, you may want version=library["version"].
🧰 Tools
🪛 Ruff (0.8.2)

2290-2290: LoadedLibrary may be undefined, or defined from star imports

(F405)


2294-2294: StoredLibrary may be undefined, or defined from star imports

(F405)


2299-2299: StoredLibrary may be undefined, or defined from star imports

(F405)

Comment on lines +2368 to +2375
required_libraries.append(
{"urn": fields["urn"], "version": fields["version"]}
)
logger.info(
"Adding library to required libraries", urn=fields["library"]
"Adding library to required libraries", urn=fields["urn"]
)
continue
if fields.get("library"):
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Confirm completeness of the library creation logic.
Currently, objects of type LoadedLibrary are skipped rather than created. Validate usage scenarios to ensure that libraries needed during import are properly persisted.

@eric-intuitem eric-intuitem merged commit 7f732ac into main Jan 24, 2025
20 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants