mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
allow_sql block to control execute-sql upermission in metadata.json, closes #813
Also removed the --config allow_sql:0 mechanism in favour of the new allow_sql block.
This commit is contained in:
parent
e0a4664fba
commit
49d6d2f7b0
16 changed files with 92 additions and 44 deletions
|
|
@ -110,7 +110,6 @@ CONFIG_OPTIONS = (
|
|||
"Allow users to download the original SQLite database files",
|
||||
),
|
||||
ConfigOption("suggest_facets", True, "Calculate and display suggested facets"),
|
||||
ConfigOption("allow_sql", True, "Allow arbitrary SQL queries via ?sql= parameter"),
|
||||
ConfigOption(
|
||||
"default_cache_ttl",
|
||||
5,
|
||||
|
|
|
|||
|
|
@ -34,3 +34,11 @@ def permission_allowed(datasette, actor, action, resource):
|
|||
if allow is None:
|
||||
return True
|
||||
return actor_matches_allow(actor, allow)
|
||||
elif action == "execute-sql":
|
||||
# Use allow_sql block from database block, or from top-level
|
||||
database_allow_sql = datasette.metadata("allow_sql", database=resource)
|
||||
if database_allow_sql is None:
|
||||
database_allow_sql = datasette.metadata("allow_sql")
|
||||
if database_allow_sql is None:
|
||||
return True
|
||||
return actor_matches_allow(actor, database_allow_sql)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
|
||||
|
||||
{% if config.allow_sql %}
|
||||
{% if allow_execute_sql %}
|
||||
<form class="sql" action="{{ database_url(database) }}" method="get">
|
||||
<h3>Custom SQL query</h3>
|
||||
<p><textarea id="sql-editor" name="sql">{% if tables %}select * from {{ tables[0].name|escape_sqlite }}{% else %}select sqlite_version(){% endif %}</textarea></p>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
<form class="sql" action="{{ database_url(database) }}{% if canned_query %}/{{ canned_query }}{% endif %}" method="{% if canned_write %}post{% else %}get{% endif %}">
|
||||
<h3>Custom SQL query{% if display_rows %} returning {% if truncated %}more than {% endif %}{{ "{:,}".format(display_rows|length) }} row{% if display_rows|length == 1 %}{% else %}s{% endif %}{% endif %} <span class="show-hide-sql">{% if hide_sql %}(<a href="{{ path_with_removed_args(request, {'_hide_sql': '1'}) }}">show</a>){% else %}(<a href="{{ path_with_added_args(request, {'_hide_sql': '1'}) }}">hide</a>){% endif %}</span></h3>
|
||||
{% if not hide_sql %}
|
||||
{% if editable and config.allow_sql %}
|
||||
{% if editable and allow_execute_sql %}
|
||||
<p><textarea id="sql-editor" name="sql">{% if query and query.sql %}{{ query.sql }}{% else %}select * from {{ tables[0].name|escape_sqlite }}{% endif %}</textarea></p>
|
||||
{% else %}
|
||||
<pre id="sql-query">{% if query %}{{ query.sql }}{% endif %}</pre>
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if query.sql and config.allow_sql %}
|
||||
{% if query.sql and allow_execute_sql %}
|
||||
<p><a class="not-underlined" title="{{ query.sql }}" href="{{ database_url(database) }}?{{ {'sql': query.sql}|urlencode|safe }}{% if query.params %}&{{ query.params|urlencode|safe }}{% endif %}">✎ <span class="underlined">View and edit SQL</span></a></p>
|
||||
{% endif %}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ class DatabaseView(DataView):
|
|||
self.ds.update_with_inherited_metadata(metadata)
|
||||
|
||||
if request.args.get("sql"):
|
||||
if not self.ds.config("allow_sql"):
|
||||
raise DatasetteError("sql= is not allowed", status=400)
|
||||
sql = request.args.get("sql")
|
||||
validate_sql_select(sql)
|
||||
return await QueryView(self.ds).data(
|
||||
|
|
@ -90,6 +88,9 @@ class DatabaseView(DataView):
|
|||
"private": not await self.ds.permission_allowed(
|
||||
None, "view-database", database
|
||||
),
|
||||
"allow_execute_sql": await self.ds.permission_allowed(
|
||||
request.actor, "execute-sql", database, default=True
|
||||
),
|
||||
},
|
||||
{
|
||||
"show_hidden": request.args.get("_show_hidden"),
|
||||
|
|
@ -289,6 +290,9 @@ class QueryView(DataView):
|
|||
"columns": columns,
|
||||
"query": {"sql": sql, "params": params},
|
||||
"private": private,
|
||||
"allow_execute_sql": await self.ds.permission_allowed(
|
||||
request.actor, "execute-sql", database, default=True
|
||||
),
|
||||
},
|
||||
extra_template,
|
||||
templates,
|
||||
|
|
|
|||
|
|
@ -342,8 +342,10 @@ class TableView(RowTableShared):
|
|||
extra_wheres_for_ui = []
|
||||
# Add _where= from querystring
|
||||
if "_where" in request.args:
|
||||
if not self.ds.config("allow_sql"):
|
||||
raise DatasetteError("_where= is not allowed", status=400)
|
||||
if not await self.ds.permission_allowed(
|
||||
request.actor, "execute-sql", resource=database, default=True,
|
||||
):
|
||||
raise DatasetteError("_where= is not allowed", status=403)
|
||||
else:
|
||||
where_clauses.extend(request.args.getlist("_where"))
|
||||
extra_wheres_for_ui = [
|
||||
|
|
@ -839,6 +841,9 @@ class TableView(RowTableShared):
|
|||
"next": next_value and str(next_value) or None,
|
||||
"next_url": next_url,
|
||||
"private": private,
|
||||
"allow_execute_sql": await self.ds.permission_allowed(
|
||||
request.actor, "execute-sql", database, default=True
|
||||
),
|
||||
},
|
||||
extra_template,
|
||||
(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue