mirror of
https://github.com/simonw/datasette.git
synced 2026-09-11 11:04:07 +02:00
Authorize configured full-text search targets
This commit is contained in:
parent
22c601b3d0
commit
6aa58bf4e5
4 changed files with 25 additions and 9 deletions
|
|
@ -51,13 +51,20 @@ def search_filters(request, database, table, datasette):
|
|||
human_descriptions = []
|
||||
extra_context = {}
|
||||
|
||||
# Figure out which fts_table to use
|
||||
# Figure out which trusted fts_table to use. Query string parameters can
|
||||
# repeat this mapping (for backwards compatibility), but must not select
|
||||
# a different table or primary key.
|
||||
table_metadata = await datasette.table_config(database, table)
|
||||
db = datasette.get_database(database)
|
||||
fts_table = request.args.get("_fts_table")
|
||||
fts_table = fts_table or table_metadata.get("fts_table")
|
||||
fts_table = table_metadata.get("fts_table")
|
||||
fts_table = fts_table or await db.fts_table(table)
|
||||
fts_pk = request.args.get("_fts_pk", table_metadata.get("fts_pk", "rowid"))
|
||||
fts_pk = table_metadata.get("fts_pk", "rowid")
|
||||
requested_fts_table = request.args.get("_fts_table")
|
||||
requested_fts_pk = request.args.get("_fts_pk")
|
||||
if (requested_fts_table and requested_fts_table != fts_table) or (
|
||||
requested_fts_pk and requested_fts_pk != fts_pk
|
||||
):
|
||||
raise BadRequest("Invalid _fts_table or _fts_pk")
|
||||
search_args = {
|
||||
key: request.args[key]
|
||||
for key in request.args
|
||||
|
|
@ -75,6 +82,11 @@ def search_filters(request, database, table, datasette):
|
|||
extra_context["supports_search"] = bool(fts_table)
|
||||
|
||||
if fts_table and search_args:
|
||||
await datasette.ensure_permission(
|
||||
action="view-table",
|
||||
resource=TableResource(database=database, table=fts_table),
|
||||
actor=request.actor,
|
||||
)
|
||||
if "_search" in search_args:
|
||||
# Simple ?_search=xxx
|
||||
search = search_args["_search"]
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ Configuring full-text search for a table or view
|
|||
|
||||
If a table has a corresponding FTS table set up using the ``content=`` argument to ``CREATE VIRTUAL TABLE`` shown below, Datasette will detect it automatically and add a search interface to the table page for that table.
|
||||
|
||||
You can also manually configure which table should be used for full-text search using query string parameters or table configuration in ``datasette.yaml`` (see :ref:`table_configuration_fts`). You can set the associated FTS table for a specific table and you can also set one for a view - if you do that, the page for that SQL view will offer a search option.
|
||||
You can also manually configure which table should be used for full-text search using table configuration in ``datasette.yaml`` (see :ref:`table_configuration_fts`). You can set the associated FTS table for a specific table and you can also set one for a view - if you do that, the page for that SQL view will offer a search option.
|
||||
|
||||
Use ``?_fts_table=x`` to over-ride the FTS table for a specific page. If the primary key was something other than ``rowid`` you can use ``?_fts_pk=col`` to set that as well. This is particularly useful for views, for example:
|
||||
The legacy ``?_fts_table=x`` and ``?_fts_pk=col`` query string parameters are accepted only if they exactly match the configured or automatically detected FTS mapping. They cannot be used to select a different FTS table or primary key. This prevents a public table from being used to probe the contents of a private FTS table.
|
||||
|
||||
https://latest.datasette.io/fixtures/searchable_view?_fts_table=searchable_fts&_fts_pk=pk
|
||||
Searching also requires the current actor to have ``view-table`` permission for the FTS table itself, in addition to permission to view the table or view being searched.
|
||||
|
||||
The ``fts_table`` metadata property can be used to specify an associated FTS table. If the primary key column in your table which was used to populate the FTS table is something other than ``rowid``, you can specify the column to use with the ``fts_pk`` property.
|
||||
|
||||
|
|
|
|||
|
|
@ -619,7 +619,10 @@ def test_searchmode(table_metadata, querystring, expected_rows):
|
|||
],
|
||||
),
|
||||
(
|
||||
"/fixtures/searchable_view.json?_shape=arrays&_search=weasel&_fts_table=searchable_fts&_fts_pk=pk",
|
||||
(
|
||||
"/fixtures/searchable_view_configured_by_metadata.json"
|
||||
"?_shape=arrays&_search=weasel&_fts_table=searchable_fts&_fts_pk=pk"
|
||||
),
|
||||
[[2, "terry dog", "sara weasel", "puma"]],
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -270,7 +270,8 @@ async def test_empty_search_parameter_gets_removed(ds_client):
|
|||
async def test_searchable_view_persists_fts_table(ds_client):
|
||||
# The search form should persist ?_fts_table as a hidden field
|
||||
response = await ds_client.get(
|
||||
"/fixtures/searchable_view?_fts_table=searchable_fts&_fts_pk=pk"
|
||||
"/fixtures/searchable_view_configured_by_metadata"
|
||||
"?_fts_table=searchable_fts&_fts_pk=pk"
|
||||
)
|
||||
inputs = Soup(response.text, "html.parser").find("form").find_all("input")
|
||||
hiddens = [i for i in inputs if i["type"] == "hidden"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue