Skip to content

Conversation

erichare
Copy link
Collaborator

@erichare erichare commented Oct 10, 2025

This pull request introduces comprehensive security improvements around flow ownership and access control throughout the backend. The main focus is to ensure that users can only access, modify, or interact with flows that they own, effectively preventing unauthorized or cross-account access. A new set of utility functions for secure flow retrieval and validation has been added, and these are now used consistently across API endpoints and internal helpers.

Security and Access Control Enhancements:

  • Added a new module langflow/api/security.py containing async helper functions (get_flow_with_ownership, get_flow_with_ownership_by_name_or_id, get_public_flow_by_name_or_id) that enforce strict flow ownership checks and public access validation. These functions are now the standard for flow retrieval throughout the backend.
  • Updated core utility functions (_get_flow_name, build_graph_from_db_no_cache) to use the new secure flow retrieval helpers, ensuring that any access to flow data is validated against the requesting user's ownership or explicit public status. [1] [2]
  • Modified file upload, download, image retrieval, file listing, and file deletion endpoints in api/v1/files.py to use a new internal dependency (_get_flow_with_validation) that wraps the secure ownership check, replacing previous manual checks. [1] [2] [3] [4] [5] [6] [7]

API Endpoint Security:

  • Enforced ownership validation in chat-related endpoints (retrieve_vertices_order, build_flow, build_vertex) by invoking get_flow_with_ownership before any operation that accesses or builds on a flow. This ensures only the owner can trigger these actions. [1] [2] [3] [4] [5] [6] [7]

Internal Helper Refactoring:

  • Updated the load_flow helper to use the secure ownership validation function, replacing direct database access with explicit security checks. This ensures all internal graph loading is protected against unauthorized access. [1] [2]

These changes collectively provide a robust and consistent security layer for flow access across the backend, reducing the risk of unauthorized data exposure or manipulation.

References:
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19]

Copy link
Contributor

coderabbitai bot commented Oct 10, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Introduces a new security module for flow ownership/public access checks and integrates it across core graph building, chat, file endpoints, and helper utilities. Multiple functions now delegate to centralized ownership/public retrieval. Tests are added for ownership validation and public access, with some endpoint test scaffolding.

Changes

Cohort / File(s) Summary
Security helpers module
src/backend/base/langflow/api/security.py
Adds async helpers: get_flow_with_ownership, get_flow_with_ownership_by_name_or_id, and get_public_flow_by_name_or_id for ownership/public access validation by UUID or endpoint name; raises 404 on not found/unauthorized.
Core build + chat ownership integration
src/backend/base/langflow/api/utils/core.py, src/backend/base/langflow/api/v1/chat.py
Core: _get_flow_name optionally validates ownership; build_graph_from_db_no_cache checks ownership when requesting_user_id provided. Chat: build_flow now uses ownership check before proceeding.
Files API refactor to Flow dependency
src/backend/base/langflow/api/v1/files.py
Centralizes ownership via get_flow dependency that calls get_flow_with_ownership. Updates upload_file, download_file, and download_image signatures to accept flow: Flow via Depends(get_flow); adds SettingsService to upload. Removes inline ownership checks.
Helpers refactor (flow/user)
src/backend/base/langflow/helpers/flow.py, src/backend/base/langflow/helpers/user.py
Flow helper: load_flow and get_flow_by_id_or_endpoint_name delegate to security helpers; get_flow_by_id_or_endpoint_name now requires user_id. User helper: get_user_by_flow_id_or_endpoint_name accepts optional requesting_user_id, tries ownership then public retrieval paths.
Tests: unit and integration
src/backend/tests/integration/test_security_integration.py, src/backend/tests/unit/security/test_flow_access_security.py
Adds unit tests for ownership/public access (UUID and endpoint name), cross-account blocking, and placeholders for endpoint security tests. Integration tests include import/signature checks and placeholders for end-to-end scenarios.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant API as API Endpoint (e.g., Files/Build)
  participant Dep as Depends(get_flow)
  participant Sec as Security Helpers
  participant DB as DB (AsyncSession)

  U->>API: Request (flow_id or endpoint_name)
  API->>Dep: Resolve Flow dependency
  Dep->>Sec: get_flow_with_ownership(session, id/name, user_id)
  Sec->>DB: Query Flow (by UUID or endpoint_name + owner)
  DB-->>Sec: Flow or None
  alt Found and owned
    Sec-->>Dep: Flow
    Dep-->>API: Flow
    API-->>U: Proceed with operation
  else Not found / not owned
    Sec-->>Dep: HTTP 404
    Dep-->>API: Propagate error
    API-->>U: 404 Not Found
  end
Loading
sequenceDiagram
  autonumber
  actor Any as Any User/Anon
  participant API as Public Access (e.g., Resolve Owner by Flow)
  participant Sec as Security Helpers
  participant DB as DB

  Any->>API: Request with flow id/name
  API->>Sec: get_public_flow_by_name_or_id(session, id/name)
  Sec->>DB: Query Flow where access_type = PUBLIC
  DB-->>Sec: Flow or None
  alt Public flow found
    Sec-->>API: Flow
    API-->>Any: Public data (e.g., owner info)
  else Not public or missing
    Sec-->>API: HTTP 404
    API-->>Any: 404 Not Found
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested labels

size:L, lgtm, refactor

Suggested reviewers

  • ogabrielluiz
  • edwinjosechittilappilly
  • Empreiteiro

Pre-merge checks and finishing touches

❌ Failed checks (1 error, 2 warnings)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error The PR introduces substantial security-sensitive logic but the accompanying tests remain largely placeholder scaffolding that never exercises the new behavior, despite review feedback instructing their removal or completion. Both the new integration suite in tests/integration/test_security_integration.py and several unit tests in tests/unit/security/test_flow_access_security.py contain empty bodies or TODO comments, so they neither validate ownership enforcement nor guard against regressions. Because the check requires that added tests actually cover the new functionality, the presence of these no-op tests means the PR fails the coverage requirements. Replace the placeholder tests with real assertions that hit the secured code paths (or remove/skip them until proper coverage is available), and then re-run the check so we can confirm the new security helpers are genuinely exercised.
Test Quality And Coverage ⚠️ Warning The new security helpers underpin critical ownership enforcement, yet the accompanying tests remain largely placeholders: in src/backend/tests/integration/test_security_integration.py the key integration methods are empty stubs, and src/backend/tests/unit/security/test_flow_access_security.py still contains unimplemented endpoint checks plus dummy session/client fixtures, so real HTTP behavior and negative cases are untested. Existing assertions only confirm helper importability and signature shape, leaving crucial coverage gaps for both success and error paths, and async execution isn’t actually exercised through pytest since the placeholder fixtures never return real async clients or sessions. Because the PR’s primary functionality lacks meaningful test verification and deviates from established testing practices, the custom check fails. Please replace the placeholder integration and endpoint-unit tests with real pytest implementations that drive the async helpers or API endpoints through valid sessions/clients, ensuring both authorized and unauthorized scenarios are asserted and re-using the project’s existing fixtures; once meaningful coverage is added, the check can pass.
Test File Naming And Structure ⚠️ Warning Both new backend test modules follow the expected pytest naming pattern, but their internal structure currently violates the guidelines. The integration test file consists largely of placeholder methods without real assertions, so it neither offers meaningful coverage nor exercises positive/negative paths or edge cases. Likewise, the unit test module still contains placeholder test classes and helper fixtures that provide no actual setup or teardown logic, leaving large sections of the file empty and non-functional. Because these placeholders remain, the tests are not logically organized nor comprehensive despite the filename compliance, so the custom check fails. Replace all placeholder tests and fixtures in the new backend test files with real implementations that exercise the intended security behaviors—covering both success and failure scenarios with proper setup/teardown—and ensure the integration tests live in the correct directory with substantive assertions before re-running this check.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely describes the primary change of scoping flow access to the user who owns the flow, aligning directly with the PR’s central objective of enforcing ownership validation across the backend.
Docstring Coverage ✅ Passed Docstring coverage is 86.84% which is sufficient. The required threshold is 80.00%.
Excessive Mock Usage Warning ✅ Passed I inspected the new and modified test modules introduced in this PR—src/backend/tests/integration/test_security_integration.py and src/backend/tests/unit/security/test_flow_access_security.py—and verified that they rely on real fixtures and direct database interactions without creating or relying on mock objects. There are no mock imports or usage patterns that would obscure the tested behavior, and the tests focus on actual flow ownership and access logic rather than mocking core components. Therefore, the custom check for excessive mock usage is satisfied.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the bug Something isn't working label Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
Copy link
Contributor

@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: 5

♻️ Duplicate comments (1)
src/backend/tests/unit/security/test_flow_access_security.py (1)

74-77: Duplicate User instantiation issue across multiple tests.

The same User instantiation pattern (without hashed_password) appears in multiple test methods at lines 74-77, 93-96, and 138. If the User model requires hashed_password, all these tests will fail.

See the earlier comment on lines 34-37 for the verification script and fix.

Also applies to: 93-96, 138-138

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f24a064 and 2a3a979.

📒 Files selected for processing (8)
  • src/backend/base/langflow/api/security.py (1 hunks)
  • src/backend/base/langflow/api/utils/core.py (2 hunks)
  • src/backend/base/langflow/api/v1/chat.py (1 hunks)
  • src/backend/base/langflow/api/v1/files.py (4 hunks)
  • src/backend/base/langflow/helpers/flow.py (3 hunks)
  • src/backend/base/langflow/helpers/user.py (1 hunks)
  • src/backend/tests/integration/test_security_integration.py (1 hunks)
  • src/backend/tests/unit/security/test_flow_access_security.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/base/langflow/api/v1/chat.py
  • src/backend/tests/integration/test_security_integration.py
  • src/backend/base/langflow/helpers/flow.py
  • src/backend/base/langflow/helpers/user.py
  • src/backend/tests/unit/security/test_flow_access_security.py
  • src/backend/base/langflow/api/utils/core.py
  • src/backend/base/langflow/api/security.py
  • src/backend/base/langflow/api/v1/files.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Unit tests for backend code must be located in the 'src/backend/tests/' directory, with component tests organized by component subdirectory under 'src/backend/tests/unit/components/'.
Test files should use the same filename as the component under test, with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests in backend Python tests, as defined in 'src/backend/tests/conftest.py'.
When writing component tests, inherit from the appropriate base class in 'src/backend/tests/base.py' (ComponentTestBase, ComponentTestBaseWithClient, or ComponentTestBaseWithoutClient) and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping'.
Each test in backend Python test files should have a clear docstring explaining its purpose, and complex setups or mocks should be well-commented.
Test both sync and async code paths in backend Python tests, using '@pytest.mark.asyncio' for async tests.
Mock external dependencies appropriately in backend Python tests to isolate unit tests from external services.
Test error handling and edge cases in backend Python tests, including using 'pytest.raises' and asserting error messages.
Validate input/output behavior and test component initialization and configuration in backend Python tests.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests when necessary.
Be aware of ContextVar propagation in async tests; test both direct event loop execution and 'asyncio.to_thread' scenarios to ensure proper context isolation.
Test error handling by mocking internal functions using monkeypatch in backend Python tests.
Test resource cleanup in backend Python tests by using fixtures that ensure proper initialization and cleanup of resources.
Test timeout and performance constraints in backend Python tests using 'asyncio.wait_for' and timing assertions.
Test Langflow's Messag...

Files:

  • src/backend/tests/integration/test_security_integration.py
  • src/backend/tests/unit/security/test_flow_access_security.py
**/{test_*.py,*.test.ts,*.test.tsx}

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/{test_*.py,*.test.ts,*.test.tsx}: Review tests for excessive numbers of mocks that obscure the behavior under test
Warn when mocks replace real behavior/interactions that should be exercised by tests
Suggest using real objects or lightweight test doubles when mocks become excessive
Ensure mocks are reserved for external dependencies, not core domain logic
Recommend integration tests when unit tests rely heavily on mocks
Check that test files follow project naming conventions (backend: test_*.py; frontend: *.test.ts/tsx)
Verify tests actually exercise the new functionality (avoid placeholder tests)
Test files should use descriptive test names that explain the behavior under test
Organize tests logically with proper setup and teardown
Include edge cases and error conditions for comprehensive coverage
Cover both positive and negative scenarios where appropriate
Tests should cover the main functionality being implemented
Avoid smoke-only tests; assert concrete behaviors and outcomes
Follow project testing tools: pytest for backend, Playwright for frontend
For API endpoints, include tests for both success and error responses

Files:

  • src/backend/tests/integration/test_security_integration.py
  • src/backend/tests/unit/security/test_flow_access_security.py
**/test_*.py

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/test_*.py: Backend tests must use pytest structure with files named test_*.py
For async Python functions, use proper async testing patterns with pytest

Files:

  • src/backend/tests/integration/test_security_integration.py
  • src/backend/tests/unit/security/test_flow_access_security.py
src/backend/tests/unit/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Test component integration within flows using create_flow, build_flow, and get_build_events utilities

Files:

  • src/backend/tests/unit/security/test_flow_access_security.py
🧠 Learnings (1)
📚 Learning: 2025-07-21T14:16:14.125Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-07-21T14:16:14.125Z
Learning: Applies to src/backend/tests/**/*.py : Test Langflow's REST API endpoints in backend Python tests using the async client fixture and asserting response codes and payloads.

Applied to files:

  • src/backend/tests/unit/security/test_flow_access_security.py
🧬 Code graph analysis (8)
src/backend/base/langflow/api/v1/chat.py (2)
src/backend/base/langflow/api/security.py (1)
  • get_flow_with_ownership (11-37)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/tests/integration/test_security_integration.py (1)
src/backend/base/langflow/api/security.py (3)
  • get_flow_with_ownership (11-37)
  • get_flow_with_ownership_by_name_or_id (40-71)
  • get_public_flow_by_name_or_id (74-106)
src/backend/base/langflow/helpers/flow.py (3)
src/backend/base/langflow/api/security.py (2)
  • get_flow_with_ownership (11-37)
  • get_flow_with_ownership_by_name_or_id (40-71)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • FlowRead (221-225)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/base/langflow/helpers/user.py (3)
src/backend/base/langflow/services/database/models/user/model.py (1)
  • UserRead (62-72)
src/backend/base/langflow/api/security.py (2)
  • get_flow_with_ownership_by_name_or_id (40-71)
  • get_public_flow_by_name_or_id (74-106)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/tests/unit/security/test_flow_access_security.py (2)
src/backend/base/langflow/api/security.py (3)
  • get_flow_with_ownership (11-37)
  • get_flow_with_ownership_by_name_or_id (40-71)
  • get_public_flow_by_name_or_id (74-106)
src/backend/base/langflow/services/database/models/flow/model.py (2)
  • AccessTypeEnum (27-29)
  • Flow (186-212)
src/backend/base/langflow/api/utils/core.py (3)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/base/langflow/api/security.py (1)
  • get_flow_with_ownership (11-37)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • Flow (186-212)
src/backend/base/langflow/api/security.py (2)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/base/langflow/services/database/models/flow/model.py (2)
  • Flow (186-212)
  • AccessTypeEnum (27-29)
src/backend/base/langflow/api/v1/files.py (4)
src/backend/base/langflow/api/security.py (1)
  • get_flow_with_ownership (11-37)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • Flow (186-212)
src/backend/base/langflow/services/storage/service.py (1)
  • StorageService (16-52)
src/backend/base/langflow/services/deps.py (1)
  • get_storage_service (88-96)
🔇 Additional comments (5)
src/backend/base/langflow/helpers/user.py (2)

30-35: Verify exception handling doesn't mask non-ownership errors.

The empty pass block silently swallows all HTTPException instances raised by get_flow_with_ownership_by_name_or_id. While this enables the intended fallback to public flow access, it may also mask unexpected errors (e.g., database connection issues, malformed flow data) that should bubble up.

Consider narrowing the exception handling to only catch ownership-related 404s, or add logging to track when the fallback path is taken:

         if requesting_user_id:
             try:
                 flow = await get_flow_with_ownership_by_name_or_id(session, flow_id_or_name, requesting_user_id)
-            except HTTPException:
+            except HTTPException as e:
+                if e.status_code != 404:
+                    raise
                 # If ownership fails, try public flow access
-                pass

Alternatively, verify through testing or code inspection that get_flow_with_ownership_by_name_or_id only raises 404 HTTPExceptions for ownership failures.


9-45: Ownership validation logic is well-structured.

The two-step flow resolution (ownership-validated → public fallback) appropriately enforces security while maintaining backward compatibility for public flows. The function-scoped import at line 24 is an acceptable pattern to avoid circular dependencies.

src/backend/tests/unit/security/test_flow_access_security.py (1)

23-128: Comprehensive security test coverage in TestFlowAccessSecurity.

The implemented tests in TestFlowAccessSecurity thoroughly validate:

  • Owner access control
  • Cross-account blocking
  • Nonexistent flow handling
  • UUID and endpoint name resolution
  • Public vs private flow access

This provides strong coverage of the core security functions.

src/backend/base/langflow/api/v1/files.py (2)

27-32: Centralized ownership validation improves security posture.

The get_flow dependency consolidates flow ownership checks in a single location, eliminating duplicate validation logic and reducing the risk of bypassing security checks. This follows the DRY principle and makes future security updates easier to maintain.


35-65: Consistent security refactoring across all file endpoints.

All file operation endpoints (upload_file, download_file, download_image, list_files, delete_file) have been successfully refactored to use the centralized get_flow dependency. The ownership validation is now enforced uniformly, preventing potential cross-account file access vulnerabilities.

Also applies to: 68-96, 99-121, 165-175, 178-189

Copy link
Contributor

@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: 6

♻️ Duplicate comments (1)
src/backend/tests/unit/security/test_flow_access_security.py (1)

153-165: Implement or remove placeholder tests.

Similar to the file endpoint tests, these are placeholder tests that don't verify any behavior. As per coding guidelines, tests should cover the main functionality being implemented, not just provide empty scaffolding.

🧹 Nitpick comments (2)
src/backend/base/langflow/api/v1/files.py (1)

23-32: Move import to top of file per PEP 8.

The import of get_flow_with_ownership should be placed with the other imports at the top of the file to follow Python style conventions (PEP 8).

Apply this diff to move the import:

 from langflow.api.utils import CurrentActiveUser, DbSession
 from langflow.api.v1.schemas import UploadFileResponse
+from langflow.api.security import get_flow_with_ownership
 from langflow.services.database.models.flow.model import Flow
 from langflow.services.deps import get_settings_service, get_storage_service
 from langflow.services.storage.service import StorageService

 router = APIRouter(tags=["Files"], prefix="/files")


-from langflow.api.security import get_flow_with_ownership
-

 # Secure dependency that validates flow ownership
 async def get_flow(
src/backend/tests/unit/security/test_flow_access_security.py (1)

1-1: Add init.py to security test directory.

The src/backend/tests/unit/security/ directory is missing an __init__.py file, making it an implicit namespace package. Add an empty __init__.py file to properly structure the package.

Create an empty file:

# src/backend/tests/unit/security/__init__.py
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f24a064 and 2a3a979.

📒 Files selected for processing (8)
  • src/backend/base/langflow/api/security.py (1 hunks)
  • src/backend/base/langflow/api/utils/core.py (2 hunks)
  • src/backend/base/langflow/api/v1/chat.py (1 hunks)
  • src/backend/base/langflow/api/v1/files.py (4 hunks)
  • src/backend/base/langflow/helpers/flow.py (3 hunks)
  • src/backend/base/langflow/helpers/user.py (1 hunks)
  • src/backend/tests/integration/test_security_integration.py (1 hunks)
  • src/backend/tests/unit/security/test_flow_access_security.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/base/langflow/api/v1/chat.py
  • src/backend/tests/integration/test_security_integration.py
  • src/backend/base/langflow/api/utils/core.py
  • src/backend/base/langflow/api/security.py
  • src/backend/base/langflow/helpers/user.py
  • src/backend/base/langflow/helpers/flow.py
  • src/backend/base/langflow/api/v1/files.py
  • src/backend/tests/unit/security/test_flow_access_security.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Unit tests for backend code must be located in the 'src/backend/tests/' directory, with component tests organized by component subdirectory under 'src/backend/tests/unit/components/'.
Test files should use the same filename as the component under test, with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests in backend Python tests, as defined in 'src/backend/tests/conftest.py'.
When writing component tests, inherit from the appropriate base class in 'src/backend/tests/base.py' (ComponentTestBase, ComponentTestBaseWithClient, or ComponentTestBaseWithoutClient) and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping'.
Each test in backend Python test files should have a clear docstring explaining its purpose, and complex setups or mocks should be well-commented.
Test both sync and async code paths in backend Python tests, using '@pytest.mark.asyncio' for async tests.
Mock external dependencies appropriately in backend Python tests to isolate unit tests from external services.
Test error handling and edge cases in backend Python tests, including using 'pytest.raises' and asserting error messages.
Validate input/output behavior and test component initialization and configuration in backend Python tests.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests when necessary.
Be aware of ContextVar propagation in async tests; test both direct event loop execution and 'asyncio.to_thread' scenarios to ensure proper context isolation.
Test error handling by mocking internal functions using monkeypatch in backend Python tests.
Test resource cleanup in backend Python tests by using fixtures that ensure proper initialization and cleanup of resources.
Test timeout and performance constraints in backend Python tests using 'asyncio.wait_for' and timing assertions.
Test Langflow's Messag...

Files:

  • src/backend/tests/integration/test_security_integration.py
  • src/backend/tests/unit/security/test_flow_access_security.py
**/{test_*.py,*.test.ts,*.test.tsx}

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/{test_*.py,*.test.ts,*.test.tsx}: Review tests for excessive numbers of mocks that obscure the behavior under test
Warn when mocks replace real behavior/interactions that should be exercised by tests
Suggest using real objects or lightweight test doubles when mocks become excessive
Ensure mocks are reserved for external dependencies, not core domain logic
Recommend integration tests when unit tests rely heavily on mocks
Check that test files follow project naming conventions (backend: test_*.py; frontend: *.test.ts/tsx)
Verify tests actually exercise the new functionality (avoid placeholder tests)
Test files should use descriptive test names that explain the behavior under test
Organize tests logically with proper setup and teardown
Include edge cases and error conditions for comprehensive coverage
Cover both positive and negative scenarios where appropriate
Tests should cover the main functionality being implemented
Avoid smoke-only tests; assert concrete behaviors and outcomes
Follow project testing tools: pytest for backend, Playwright for frontend
For API endpoints, include tests for both success and error responses

Files:

  • src/backend/tests/integration/test_security_integration.py
  • src/backend/tests/unit/security/test_flow_access_security.py
**/test_*.py

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/test_*.py: Backend tests must use pytest structure with files named test_*.py
For async Python functions, use proper async testing patterns with pytest

Files:

  • src/backend/tests/integration/test_security_integration.py
  • src/backend/tests/unit/security/test_flow_access_security.py
src/backend/tests/unit/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Test component integration within flows using create_flow, build_flow, and get_build_events utilities

Files:

  • src/backend/tests/unit/security/test_flow_access_security.py
🧠 Learnings (1)
📚 Learning: 2025-07-21T14:16:14.125Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-07-21T14:16:14.125Z
Learning: Applies to src/backend/tests/**/*.py : Test Langflow's REST API endpoints in backend Python tests using the async client fixture and asserting response codes and payloads.

Applied to files:

  • src/backend/tests/unit/security/test_flow_access_security.py
🧬 Code graph analysis (8)
src/backend/base/langflow/api/v1/chat.py (3)
src/backend/base/langflow/api/security.py (1)
  • get_flow_with_ownership (11-37)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/tests/integration/test_security_integration.py (1)
src/backend/base/langflow/api/security.py (3)
  • get_flow_with_ownership (11-37)
  • get_flow_with_ownership_by_name_or_id (40-71)
  • get_public_flow_by_name_or_id (74-106)
src/backend/base/langflow/api/utils/core.py (4)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/base/langflow/api/security.py (1)
  • get_flow_with_ownership (11-37)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • Flow (186-212)
src/backend/base/langflow/api/security.py (2)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/base/langflow/services/database/models/flow/model.py (2)
  • Flow (186-212)
  • AccessTypeEnum (27-29)
src/backend/base/langflow/helpers/user.py (3)
src/backend/base/langflow/services/database/models/user/model.py (1)
  • UserRead (62-72)
src/backend/base/langflow/api/security.py (2)
  • get_flow_with_ownership_by_name_or_id (40-71)
  • get_public_flow_by_name_or_id (74-106)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/base/langflow/helpers/flow.py (3)
src/backend/base/langflow/api/security.py (2)
  • get_flow_with_ownership (11-37)
  • get_flow_with_ownership_by_name_or_id (40-71)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • FlowRead (221-225)
src/backend/base/langflow/services/deps.py (1)
  • session_scope (151-173)
src/backend/base/langflow/api/v1/files.py (4)
src/backend/base/langflow/api/security.py (1)
  • get_flow_with_ownership (11-37)
src/backend/base/langflow/services/database/models/flow/model.py (1)
  • Flow (186-212)
src/backend/base/langflow/services/storage/service.py (1)
  • StorageService (16-52)
src/backend/base/langflow/services/deps.py (1)
  • get_storage_service (88-96)
src/backend/tests/unit/security/test_flow_access_security.py (3)
src/backend/base/langflow/api/security.py (3)
  • get_flow_with_ownership (11-37)
  • get_flow_with_ownership_by_name_or_id (40-71)
  • get_public_flow_by_name_or_id (74-106)
src/backend/tests/conftest.py (1)
  • flow (544-560)
src/backend/base/langflow/services/database/models/flow/model.py (2)
  • AccessTypeEnum (27-29)
  • Flow (186-212)
🪛 GitHub Actions: Ruff Style Check
src/backend/base/langflow/api/security.py

[error] 70-70: B904 Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling.

🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/base/langflow/api/v1/chat.py

[failure] 170-170: Ruff (F841)
src/backend/base/langflow/api/v1/chat.py:170:9: F841 Local variable flow is assigned to but never used

src/backend/base/langflow/api/utils/core.py

[failure] 224-224: Ruff (F821)
src/backend/base/langflow/api/utils/core.py:224:64: F821 Undefined name UUID

src/backend/base/langflow/api/security.py

[failure] 70-70: Ruff (B904)
src/backend/base/langflow/api/security.py:70:13: B904 Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

src/backend/base/langflow/helpers/user.py

[failure] 31-35: Ruff (SIM105)
src/backend/base/langflow/helpers/user.py:31:13: SIM105 Use contextlib.suppress(HTTPException) instead of try-except-pass

src/backend/base/langflow/api/v1/files.py

[failure] 23-23: Ruff (E402)
src/backend/base/langflow/api/v1/files.py:23:1: E402 Module level import not at top of file

src/backend/tests/unit/security/test_flow_access_security.py

[failure] 90-90: Ruff (ARG002)
src/backend/tests/unit/security/test_flow_access_security.py:90:66: ARG002 Unused method argument: created_user


[failure] 71-71: Ruff (ARG002)
src/backend/tests/unit/security/test_flow_access_security.py:71:83: ARG002 Unused method argument: created_user


[failure] 31-31: Ruff (ARG002)
src/backend/tests/unit/security/test_flow_access_security.py:31:73: ARG002 Unused method argument: created_user


[failure] 1-1: Ruff (INP001)
src/backend/tests/unit/security/test_flow_access_security.py:1:1: INP001 File src/backend/tests/unit/security/test_flow_access_security.py is part of an implicit namespace package. Add an __init__.py.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Validate PR
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Run Frontend Tests / Determine Test Suites and Shard Distribution
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Starter Projects
🔇 Additional comments (7)
src/backend/base/langflow/api/utils/core.py (1)

153-178: Import UUID (currently undefined).

Both _get_flow_name and build_graph_from_db_no_cache reference UUID, but the module only imports import uuid. At runtime this raises NameError. Add from uuid import UUID at the top or use uuid.UUID.

-from __future__ import annotations
-
-import uuid
+from __future__ import annotations
+
+import uuid
+from uuid import UUID

Likely an incorrect or invalid review comment.

src/backend/base/langflow/api/security.py (2)

11-37: LGTM!

The ownership validation logic is correct and secure. By combining both flow_id and user_id in the WHERE clause, this function ensures that flows can only be accessed by their owners, effectively preventing cross-account access vulnerabilities.


74-106: LGTM!

The public flow retrieval logic is correct. By filtering on access_type == AccessTypeEnum.PUBLIC, this function ensures that only explicitly public flows can be accessed without ownership validation. The warning in the docstring appropriately highlights the security considerations.

src/backend/base/langflow/api/v1/files.py (3)

35-65: LGTM!

The refactor to use Flow dependency with ownership validation is excellent. By moving the security check to the get_flow dependency, you've centralized the ownership validation and made it impossible to bypass. The comment at line 54 correctly notes that the security check is handled by the dependency.


68-96: LGTM!

The refactor correctly uses the Flow dependency to enforce ownership validation before allowing file downloads.


99-121: LGTM!

The refactor correctly uses the Flow dependency to enforce ownership validation before allowing image downloads.

src/backend/tests/unit/security/test_flow_access_security.py (1)

20-129: LGTM!

The test suite comprehensively validates the ownership and access control logic. Tests cover:

  • Valid owner access
  • Cross-account blocking
  • Nonexistent flow handling
  • UUID and endpoint name resolution
  • Public vs private flow access

Each test is well-documented and properly uses pytest patterns.

Note on unused argument warnings: The static analysis warnings about unused created_user arguments in some tests are false positives. These fixture arguments are necessary to ensure the user exists in the database and to establish the proper test state, even if not directly referenced in the test body.

@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
erichare and others added 2 commits October 10, 2025 13:43
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@github-actions github-actions bot removed the bug Something isn't working label Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@langflow-ai langflow-ai deleted a comment from coderabbitai bot Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Oct 10, 2025
Copy link

@Cristhianzl
Copy link
Member

Please follow up this PR with the fix: #10306
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants