Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/base/langflow/api/v1/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ async def read_project(
try:
# Check if pagination is explicitly requested by the user (both page and size provided)
if page is not None and size is not None:
stmt = select(Flow).where(Flow.folder_id == project_id)
stmt = select(Flow).where(Flow.folder_id == project_id, Flow.user_id == current_user.id)

if Flow.updated_at is not None:
stmt = stmt.order_by(Flow.updated_at.desc()) # type: ignore[attr-defined]
Expand Down
7 changes: 3 additions & 4 deletions src/backend/base/langflow/initial_setup/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@

def update_projects_components_with_latest_component_versions(project_data, all_types_dict):
# Flatten the all_types_dict for easy access
all_types_dict_flat = {}
for category in all_types_dict.values():
for key, component in category.items():
all_types_dict_flat[key] = component
all_types_dict_flat = {
key: component for category in all_types_dict.values() for key, component in category.items()
}

node_changes_log = defaultdict(list)
project_data_copy = deepcopy(project_data)
Expand Down
43 changes: 43 additions & 0 deletions src/backend/tests/unit/api/v1/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,49 @@ async def test_read_project_error_handling_consistency(self, client: AsyncClient
f"Error message should mention 'not found' for params: {params}"
)

async def test_read_project_paginated_flows_match_current_user_visibility(
self, client: AsyncClient, logged_in_headers, basic_case
):
project_response = await client.post("api/v1/projects/", json=basic_case, headers=logged_in_headers)
assert project_response.status_code == status.HTTP_201_CREATED
project_id = project_response.json()["id"]

own_flow_payload = {
"name": "Owned flow",
"description": "Visible to the project owner",
"data": {},
"folder_id": project_id,
}
own_flow_response = await client.post("api/v1/flows/", json=own_flow_payload, headers=logged_in_headers)
assert own_flow_response.status_code == status.HTTP_201_CREATED
own_flow_id = own_flow_response.json()["id"]

other_user_flow_id = uuid4()
async with session_scope() as session:
flow_create = FlowCreate(
id=other_user_flow_id,
name="Other user's flow",
description="Should stay hidden from paginated project reads",
data={},
folder_id=project_id,
user_id=uuid4(),
)
flow = Flow.model_validate(flow_create, from_attributes=True)
session.add(flow)
await session.commit()

response = await client.get(
f"api/v1/projects/{project_id}?page=1&size=10",
headers=logged_in_headers,
)
assert response.status_code == status.HTTP_200_OK

result = response.json()
flow_ids = {flow["id"] for flow in result["flows"]["items"]}

assert own_flow_id in flow_ids
assert str(other_user_flow_id) not in flow_ids


async def test_download_file_starter_project(client: AsyncClient, logged_in_headers, active_user, json_flow):
"""Test downloading a project with multiple flows.
Expand Down
20 changes: 10 additions & 10 deletions src/lfx/src/lfx/_assets/component_index.json
Original file line number Diff line number Diff line change
Expand Up @@ -73431,7 +73431,7 @@
"dependencies": [
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "lfx",
Expand Down Expand Up @@ -73579,7 +73579,7 @@
"dependencies": [
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "googleapiclient",
Expand Down Expand Up @@ -73740,7 +73740,7 @@
"dependencies": [
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "langchain_core",
Expand Down Expand Up @@ -73869,7 +73869,7 @@
"dependencies": [
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "langchain_google_community",
Expand Down Expand Up @@ -73998,7 +73998,7 @@
"dependencies": [
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "googleapiclient",
Expand Down Expand Up @@ -74288,7 +74288,7 @@
},
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "langchain_google_genai",
Expand Down Expand Up @@ -74648,7 +74648,7 @@
"dependencies": [
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
},
{
"name": "google_auth_oauthlib",
Expand Down Expand Up @@ -113845,7 +113845,7 @@
},
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
}
],
"total_dependencies": 3
Expand Down Expand Up @@ -114229,7 +114229,7 @@
},
{
"name": "google",
"version": "2.30.0"
"version": "2.8.0"
}
],
"total_dependencies": 3
Expand Down Expand Up @@ -118487,6 +118487,6 @@
"num_components": 359,
"num_modules": 97
},
"sha256": "dcb9a6e44e2405967f6fd4881e5bc5d3748bb507b3a0e57fc90c9b86c2536730",
"sha256": "adb51913c419daf5f3f496820e732dc9d7d562f0f0963f11a760f39fe8aaecd8",
"version": "0.3.1"
}
Loading