kopia lustrzana https://github.com/simonw/datasette
Backported default_allow_sql for 0.63.x, closes #1409
rodzic
b8cf864fa6
commit
1ec9c9995c
|
@ -116,6 +116,11 @@ SETTINGS = (
|
||||||
True,
|
True,
|
||||||
"Allow users to specify columns to facet using ?_facet= parameter",
|
"Allow users to specify columns to facet using ?_facet= parameter",
|
||||||
),
|
),
|
||||||
|
Setting(
|
||||||
|
"default_allow_sql",
|
||||||
|
True,
|
||||||
|
"Allow anyone to run arbitrary SQL queries",
|
||||||
|
),
|
||||||
Setting(
|
Setting(
|
||||||
"allow_download",
|
"allow_download",
|
||||||
True,
|
True,
|
||||||
|
|
|
@ -36,12 +36,16 @@ def permission_allowed(datasette, actor, action, resource):
|
||||||
return None
|
return None
|
||||||
return actor_matches_allow(actor, allow)
|
return actor_matches_allow(actor, allow)
|
||||||
elif action == "execute-sql":
|
elif action == "execute-sql":
|
||||||
|
# Only use default_allow_sql setting if it is set to False:
|
||||||
|
default_allow_sql = (
|
||||||
|
None if datasette.setting("default_allow_sql") else False
|
||||||
|
)
|
||||||
# Use allow_sql block from database block, or from top-level
|
# Use allow_sql block from database block, or from top-level
|
||||||
database_allow_sql = datasette.metadata("allow_sql", database=resource)
|
database_allow_sql = datasette.metadata("allow_sql", database=resource)
|
||||||
if database_allow_sql is None:
|
if database_allow_sql is None:
|
||||||
database_allow_sql = datasette.metadata("allow_sql")
|
database_allow_sql = datasette.metadata("allow_sql")
|
||||||
if database_allow_sql is None:
|
if database_allow_sql is None:
|
||||||
return None
|
return default_allow_sql
|
||||||
return actor_matches_allow(actor, database_allow_sql)
|
return actor_matches_allow(actor, database_allow_sql)
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
|
@ -307,7 +307,13 @@ To limit access to the ``add_name`` canned query in your ``dogs.db`` database to
|
||||||
Controlling the ability to execute arbitrary SQL
|
Controlling the ability to execute arbitrary SQL
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
The ``"allow_sql"`` block can be used to control who is allowed to execute arbitrary SQL queries, both using the form on the database page e.g. https://latest.datasette.io/fixtures or by appending a ``?_where=`` parameter to the table page as seen on https://latest.datasette.io/fixtures/facetable?_where=city_id=1.
|
Datasette defaults to allowing any site visitor to execute their own custom SQL queries, for example using the form on `the database page <https://latest.datasette.io/fixtures>`__ or by appending a ``?_where=`` parameter to the table page `like this <https://latest.datasette.io/fixtures/facetable?_where=_city_id=1>`__.
|
||||||
|
|
||||||
|
Access to this ability is controlled by the :ref:`permissions_execute_sql` permission.
|
||||||
|
|
||||||
|
The easiest way to disable arbitrary SQL queries is using the :ref:`default_allow_sql setting <setting_default_allow_sql>` when you first start Datasette running.
|
||||||
|
|
||||||
|
You can alternatively use an ``"allow_sql"`` block to control who is allowed to execute arbitrary SQL queries.
|
||||||
|
|
||||||
To enable just the :ref:`root user<authentication_root>` to execute SQL for all databases in your instance, use the following:
|
To enable just the :ref:`root user<authentication_root>` to execute SQL for all databases in your instance, use the following:
|
||||||
|
|
||||||
|
@ -515,7 +521,7 @@ Actor is allowed to run arbitrary SQL queries against a specific database, e.g.
|
||||||
``resource`` - string
|
``resource`` - string
|
||||||
The name of the database
|
The name of the database
|
||||||
|
|
||||||
Default *allow*.
|
Default *allow*. See also :ref:`the default_allow_sql setting <setting_default_allow_sql>`.
|
||||||
|
|
||||||
.. _permissions_permissions_debug:
|
.. _permissions_permissions_debug:
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,8 @@ These can be passed to ``datasette serve`` using ``datasette serve --setting nam
|
||||||
(default=50)
|
(default=50)
|
||||||
allow_facet Allow users to specify columns to facet using
|
allow_facet Allow users to specify columns to facet using
|
||||||
?_facet= parameter (default=True)
|
?_facet= parameter (default=True)
|
||||||
|
default_allow_sql Allow anyone to run arbitrary SQL queries
|
||||||
|
(default=True)
|
||||||
allow_download Allow users to download the original SQLite
|
allow_download Allow users to download the original SQLite
|
||||||
database files (default=True)
|
database files (default=True)
|
||||||
suggest_facets Calculate and display suggested facets
|
suggest_facets Calculate and display suggested facets
|
||||||
|
|
|
@ -59,6 +59,21 @@ Settings
|
||||||
|
|
||||||
The following options can be set using ``--setting name value``, or by storing them in the ``settings.json`` file for use with :ref:`config_dir`.
|
The following options can be set using ``--setting name value``, or by storing them in the ``settings.json`` file for use with :ref:`config_dir`.
|
||||||
|
|
||||||
|
.. _setting_default_allow_sql:
|
||||||
|
|
||||||
|
default_allow_sql
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Should users be able to execute arbitrary SQL queries by default?
|
||||||
|
|
||||||
|
Setting this to ``off`` causes permission checks for :ref:`permissions_execute_sql` to fail by default.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
datasette mydatabase.db --setting default_allow_sql off
|
||||||
|
|
||||||
|
There are two ways to achieve this: the other is to add ``"allow_sql": false`` to your ``metadata.json`` file, as described in :ref:`authentication_permissions_execute_sql`. This setting offers a more convenient way to do this.
|
||||||
|
|
||||||
.. _setting_default_page_size:
|
.. _setting_default_page_size:
|
||||||
|
|
||||||
default_page_size
|
default_page_size
|
||||||
|
|
|
@ -805,6 +805,7 @@ def test_settings_json(app_client):
|
||||||
assert {
|
assert {
|
||||||
"default_page_size": 50,
|
"default_page_size": 50,
|
||||||
"default_facet_size": 30,
|
"default_facet_size": 30,
|
||||||
|
"default_allow_sql": True,
|
||||||
"facet_suggest_time_limit_ms": 50,
|
"facet_suggest_time_limit_ms": 50,
|
||||||
"facet_time_limit_ms": 200,
|
"facet_time_limit_ms": 200,
|
||||||
"max_returned_rows": 100,
|
"max_returned_rows": 100,
|
||||||
|
|
|
@ -215,6 +215,28 @@ def test_setting_type_validation():
|
||||||
assert '"default_page_size" should be an integer' in result.stderr
|
assert '"default_page_size" should be an integer' in result.stderr
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("default_allow_sql", (True, False))
|
||||||
|
def test_setting_default_allow_sql(default_allow_sql):
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(
|
||||||
|
cli,
|
||||||
|
[
|
||||||
|
"--setting",
|
||||||
|
"default_allow_sql",
|
||||||
|
"on" if default_allow_sql else "off",
|
||||||
|
"--get",
|
||||||
|
"/_memory.json?sql=select+21&_shape=objects",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
if default_allow_sql:
|
||||||
|
assert result.exit_code == 0, result.output
|
||||||
|
assert json.loads(result.output)["rows"][0] == {"21": 21}
|
||||||
|
else:
|
||||||
|
assert result.exit_code == 1, result.output
|
||||||
|
# This isn't JSON at the moment, maybe it should be though
|
||||||
|
assert "Forbidden" in result.output
|
||||||
|
|
||||||
|
|
||||||
def test_config_deprecated():
|
def test_config_deprecated():
|
||||||
# The --config option should show a deprecation message
|
# The --config option should show a deprecation message
|
||||||
runner = CliRunner(mix_stderr=False)
|
runner = CliRunner(mix_stderr=False)
|
||||||
|
|
Ładowanie…
Reference in New Issue