mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Error for drop against immutable database, closes #1874
This commit is contained in:
parent
612da8eae6
commit
65521f03db
3 changed files with 30 additions and 12 deletions
|
|
@ -1236,7 +1236,8 @@ class TableDropView(BaseView):
|
||||||
request.actor, "drop-table", resource=(database_name, table_name)
|
request.actor, "drop-table", resource=(database_name, table_name)
|
||||||
):
|
):
|
||||||
return _error(["Permission denied"], 403)
|
return _error(["Permission denied"], 403)
|
||||||
|
if not db.is_mutable:
|
||||||
|
return _error(["Database is immutable"], 403)
|
||||||
confirm = False
|
confirm = False
|
||||||
try:
|
try:
|
||||||
data = json.loads(await request.post_body())
|
data = json.loads(await request.post_body())
|
||||||
|
|
@ -1248,6 +1249,8 @@ class TableDropView(BaseView):
|
||||||
return Response.json(
|
return Response.json(
|
||||||
{
|
{
|
||||||
"ok": True,
|
"ok": True,
|
||||||
|
"database": database_name,
|
||||||
|
"table": table_name,
|
||||||
"row_count": (
|
"row_count": (
|
||||||
await db.execute("select count(*) from [{}]".format(table_name))
|
await db.execute("select count(*) from [{}]".format(table_name))
|
||||||
).single_value(),
|
).single_value(),
|
||||||
|
|
|
||||||
|
|
@ -578,6 +578,8 @@ Without a POST body this will return a status ``200`` with a note about how many
|
||||||
|
|
||||||
{
|
{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
|
"database": "<database>",
|
||||||
|
"table": "<table>",
|
||||||
"row_count": 5,
|
"row_count": 5,
|
||||||
"message": "Pass \"confirm\": true to confirm"
|
"message": "Pass \"confirm\": true to confirm"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,15 @@ import time
|
||||||
def ds_write(tmp_path_factory):
|
def ds_write(tmp_path_factory):
|
||||||
db_directory = tmp_path_factory.mktemp("dbs")
|
db_directory = tmp_path_factory.mktemp("dbs")
|
||||||
db_path = str(db_directory / "data.db")
|
db_path = str(db_directory / "data.db")
|
||||||
db = sqlite3.connect(str(db_path))
|
db_path_immutable = str(db_directory / "immutable.db")
|
||||||
db.execute("vacuum")
|
db1 = sqlite3.connect(str(db_path))
|
||||||
db.execute("create table docs (id integer primary key, title text, score float)")
|
db2 = sqlite3.connect(str(db_path_immutable))
|
||||||
ds = Datasette([db_path])
|
for db in (db1, db2):
|
||||||
|
db.execute("vacuum")
|
||||||
|
db.execute(
|
||||||
|
"create table docs (id integer primary key, title text, score float)"
|
||||||
|
)
|
||||||
|
ds = Datasette([db_path], immutables=[db_path_immutable])
|
||||||
yield ds
|
yield ds
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
|
|
@ -339,7 +344,9 @@ async def test_delete_row(ds_write, scenario):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.parametrize("scenario", ("no_token", "no_perm", "bad_table", "has_perm"))
|
@pytest.mark.parametrize(
|
||||||
|
"scenario", ("no_token", "no_perm", "bad_table", "has_perm", "immutable")
|
||||||
|
)
|
||||||
async def test_drop_table(ds_write, scenario):
|
async def test_drop_table(ds_write, scenario):
|
||||||
if scenario == "no_token":
|
if scenario == "no_token":
|
||||||
token = "bad_token"
|
token = "bad_token"
|
||||||
|
|
@ -351,7 +358,10 @@ async def test_drop_table(ds_write, scenario):
|
||||||
await ds_write.get_database("data").execute_write(
|
await ds_write.get_database("data").execute_write(
|
||||||
"insert into docs (id, title) values (1, 'Row 1')"
|
"insert into docs (id, title) values (1, 'Row 1')"
|
||||||
)
|
)
|
||||||
path = "/data/{}/-/drop".format("docs" if scenario != "bad_table" else "bad_table")
|
path = "/{database}/{table}/-/drop".format(
|
||||||
|
database="immutable" if scenario == "immutable" else "data",
|
||||||
|
table="docs" if scenario != "bad_table" else "bad_table",
|
||||||
|
)
|
||||||
response = await ds_write.client.post(
|
response = await ds_write.client.post(
|
||||||
path,
|
path,
|
||||||
headers={
|
headers={
|
||||||
|
|
@ -366,17 +376,20 @@ async def test_drop_table(ds_write, scenario):
|
||||||
else 404
|
else 404
|
||||||
)
|
)
|
||||||
assert response.json()["ok"] is False
|
assert response.json()["ok"] is False
|
||||||
assert (
|
expected_error = "Permission denied"
|
||||||
response.json()["errors"] == ["Permission denied"]
|
if scenario == "bad_table":
|
||||||
if scenario == "no_token"
|
expected_error = "Table not found: bad_table"
|
||||||
else ["Table not found: bad_table"]
|
elif scenario == "immutable":
|
||||||
)
|
expected_error = "Database is immutable"
|
||||||
|
assert response.json()["errors"] == [expected_error]
|
||||||
assert (await ds_write.client.get("/data/docs")).status_code == 200
|
assert (await ds_write.client.get("/data/docs")).status_code == 200
|
||||||
else:
|
else:
|
||||||
# It should show a confirmation page
|
# It should show a confirmation page
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"ok": True,
|
"ok": True,
|
||||||
|
"database": "data",
|
||||||
|
"table": "docs",
|
||||||
"row_count": 1,
|
"row_count": 1,
|
||||||
"message": 'Pass "confirm": true to confirm',
|
"message": 'Pass "confirm": true to confirm',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue