Skip to content

Commit

Permalink
Require update-row to use insert replace, closes #2279
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Feb 19, 2024
1 parent 3856a8c commit b36a2d8
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
5 changes: 5 additions & 0 deletions datasette/views/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,11 @@ async def post(self, request, upsert=False):
if upsert and (ignore or replace):
return _error(["Upsert does not support ignore or replace"], 400)

if replace and not await self.ds.permission_allowed(
request.actor, "update-row", resource=(database_name, table_name)
):
return _error(['Permission denied: need update-row to use "replace"'], 403)

initial_schema = None
if alter:
# Must have alter-table permission
Expand Down
4 changes: 2 additions & 2 deletions docs/json_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ Pass ``"ignore": true`` to ignore these errors and insert the other rows:
"ignore": true
}
Or you can pass ``"replace": true`` to replace any rows with conflicting primary keys with the new values.
Or you can pass ``"replace": true`` to replace any rows with conflicting primary keys with the new values. This requires the :ref:`permissions_update_row` permission.

Pass ``"alter: true`` to automatically add any missing columns to the table. This requires the :ref:`permissions_alter_table` permission.

Expand Down Expand Up @@ -854,7 +854,7 @@ The JSON here describes the table that will be created:

* ``pks`` can be used instead of ``pk`` to create a compound primary key. It should be a JSON list of column names to use in that primary key.
* ``ignore`` can be set to ``true`` to ignore existing rows by primary key if the table already exists.
* ``replace`` can be set to ``true`` to replace existing rows by primary key if the table already exists.
* ``replace`` can be set to ``true`` to replace existing rows by primary key if the table already exists. This requires the :ref:`permissions_update_row` permission.
* ``alter`` can be set to ``true`` if you want to automatically add any missing columns to the table. This requires the :ref:`permissions_alter_table` permission.

If the table is successfully created this will return a ``201`` status code and the following response:
Expand Down
8 changes: 8 additions & 0 deletions tests/test_api_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ async def test_insert_rows(ds_write, return_rows):
400,
['Cannot use "ignore" and "replace" at the same time'],
),
(
# Replace is not allowed if you don't have update-row
"/data/docs/-/insert",
{"rows": [{"title": "Test"}], "replace": True},
"insert-but-not-update",
403,
['Permission denied: need update-row to use "replace"'],
),
(
"/data/docs/-/insert",
{"rows": [{"title": "Test"}], "invalid_param": True},
Expand Down

0 comments on commit b36a2d8

Please sign in to comment.