Don't allow canned write queries on immutable DBs, closes #1728

pull/1789/head
Simon Willison 2022-08-14 09:34:31 -07:00
rodzic 1563c22a8c
commit c1396bf860
3 zmienionych plików z 49 dodań i 1 usunięć

Wyświetl plik

@ -28,6 +28,10 @@
{% block content %}
{% if canned_write and db_is_immutable %}
<p class="message-error">This query cannot be executed because the database is immutable.</p>
{% endif %}
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_color(database) }}">{{ metadata.title or database }}{% if canned_query and not metadata.title %}: {{ canned_query }}{% endif %}{% if private %} 🔒{% endif %}</h1>
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
@ -61,7 +65,7 @@
<p>
{% if not hide_sql %}<button id="sql-format" type="button" hidden>Format SQL</button>{% endif %}
{% if canned_write %}<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">{% endif %}
<input type="submit" value="Run SQL">
<input type="submit" value="Run SQL"{% if canned_write and db_is_immutable %} disabled{% endif %}>
{{ show_hide_hidden }}
{% if canned_query and edit_sql_url %}<a href="{{ edit_sql_url }}" class="canned-query-edit-sql">Edit SQL</a>{% endif %}
</p>

Wyświetl plik

@ -273,6 +273,9 @@ class QueryView(DataView):
# Execute query - as write or as read
if write:
if request.method == "POST":
# If database is immutable, return an error
if not db.is_mutable:
raise Forbidden("Database is immutable")
body = await request.post_body()
body = body.decode("utf-8").strip()
if body.startswith("{") and body.endswith("}"):
@ -326,6 +329,7 @@ class QueryView(DataView):
async def extra_template():
return {
"request": request,
"db_is_immutable": not db.is_mutable,
"path_with_added_args": path_with_added_args,
"path_with_removed_args": path_with_removed_args,
"named_parameter_values": named_parameter_values,

Wyświetl plik

@ -53,6 +53,26 @@ def canned_write_client(tmpdir):
yield client
@pytest.fixture
def canned_write_immutable_client():
with make_app_client(
is_immutable=True,
metadata={
"databases": {
"fixtures": {
"queries": {
"add": {
"sql": "insert into sortable (text) values (:text)",
"write": True,
},
}
}
}
},
) as client:
yield client
def test_canned_query_with_named_parameter(app_client):
response = app_client.get("/fixtures/neighborhood_search.json?text=town")
assert [
@ -373,3 +393,23 @@ def test_canned_write_custom_template(canned_write_client):
response.headers["link"]
== 'http://localhost/data/update_name.json; rel="alternate"; type="application/json+datasette"'
)
def test_canned_write_query_disabled_for_immutable_database(
canned_write_immutable_client,
):
response = canned_write_immutable_client.get("/fixtures/add")
assert response.status == 200
assert (
"This query cannot be executed because the database is immutable."
in response.text
)
assert '<input type="submit" value="Run SQL" disabled>' in response.text
# Submitting form should get a forbidden error
response = canned_write_immutable_client.post(
"/fixtures/add",
{"text": "text"},
csrftoken_from=True,
)
assert response.status == 403
assert "Database is immutable" in response.text