Skip to content
Merged
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
16 changes: 8 additions & 8 deletions backend/src/baserow/contrib/database/api/rows/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,16 +599,16 @@ def post(self, request: Request, table_id: int, query_params) -> Response:
validation_serializer, request_data, partial=True, return_validated=True
)

view_id = query_params.get("view")
view = ViewHandler().get_view(view_id) if view_id else None

before_id = query_params.get("before")
before_row = (
RowHandler().get_row(request.user, table, before_id, model)
RowHandler().get_row(request.user, table, before_id, model, view=view)
if before_id
else None
)

view_id = query_params.get("view")
view = ViewHandler().get_view(view_id) if view_id else None

try:
row = action_type_registry.get_by_type(CreateRowActionType).do(
request.user,
Expand Down Expand Up @@ -1366,18 +1366,18 @@ def post(self, request: Request, table_id: int, query_params) -> Response:
model = table.get_model()
request_data = deepcopy(request.data)

view_id = query_params.get("view")
view = ViewHandler().get_view(view_id) if view_id else None

user_field_names = extract_user_field_names_from_params(request.GET)
send_webhook_events = extract_send_webhook_events_from_params(request.GET)
before_id = query_params.get("before")
before_row = (
RowHandler().get_row(request.user, table, before_id, model)
RowHandler().get_row(request.user, table, before_id, model, view=view)
if before_id
else None
)

view_id = query_params.get("view")
view = ViewHandler().get_view(view_id) if view_id else None

row_validation_serializer = get_row_serializer_class(
model, user_field_names=user_field_names
)
Expand Down
6 changes: 3 additions & 3 deletions backend/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "bug",
"message": "Fixes inserting rows above or below in restricted views",
"issue_origin": "github",
"issue_number": 5344,
"domain": "database",
"bullet_points": [],
"created_at": "2026-05-11"
}
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,16 @@ def test_cannot_get_row_outside_of_restricted_view(api_client, enterprise_data_f

@pytest.mark.django_db
@override_settings(DEBUG=True)
def test_create_row_with_only_view_permissions(api_client, enterprise_data_fixture):
@pytest.mark.parametrize(
"url_name, prepare_payload",
[
("api:database:rows:list", lambda row: row),
("api:database:rows:batch", lambda row: {"items": [row]}),
],
)
def test_create_row_with_only_view_permissions(
api_client, enterprise_data_fixture, url_name, prepare_payload
):
enterprise_data_fixture.enable_enterprise()

user, token = enterprise_data_fixture.create_user_and_token()
Expand Down Expand Up @@ -318,13 +327,13 @@ def test_create_row_with_only_view_permissions(api_client, enterprise_data_fixtu
scope=View.objects.get(id=normal_view.id),
)

url = reverse("api:database:rows:list", kwargs={"table_id": table.id})
url = reverse(url_name, kwargs={"table_id": table.id})

# Expect permission denied when trying to create a row in the table because the
# user does not have access to the table.
response = api_client.post(
url,
{f"field_{text_field.id}": "Test 1"},
prepare_payload({f"field_{text_field.id}": "Test 1"}),
format="json",
HTTP_AUTHORIZATION=f"JWT {token2}",
)
Expand All @@ -335,7 +344,7 @@ def test_create_row_with_only_view_permissions(api_client, enterprise_data_fixtu
# view ownership type does not allow a user to create a row.
response = api_client.post(
url + f"?view={normal_view.id}",
{f"field_{text_field.id}": "Test 1"},
prepare_payload({f"field_{text_field.id}": "Test 1"}),
format="json",
HTTP_AUTHORIZATION=f"JWT {token2}",
)
Expand All @@ -345,7 +354,17 @@ def test_create_row_with_only_view_permissions(api_client, enterprise_data_fixtu
# Should come through because the user has access to the view.
response = api_client.post(
url + f"?view={restricted_view.id}",
{f"field_{text_field.id}": "Test 1"},
prepare_payload({f"field_{text_field.id}": "Test 1"}),
format="json",
HTTP_AUTHORIZATION=f"JWT {token2}",
)
assert response.status_code == HTTP_200_OK
created_row_id = table.get_model().objects.first().id

# Should also be possible to reference another row as before_row
response = api_client.post(
url + f"?view={restricted_view.id}&before={created_row_id}",
prepare_payload({f"field_{text_field.id}": "Test 1"}),
format="json",
HTTP_AUTHORIZATION=f"JWT {token2}",
)
Expand Down
Loading