diff --git a/docs/authentication.rst b/docs/authentication.rst index 2f72e89a..e658e78b 100644 --- a/docs/authentication.rst +++ b/docs/authentication.rst @@ -1093,7 +1093,7 @@ All three endpoints support both HTML and JSON responses. Visit the endpoint dir .. _PermissionRulesView: Permission rules view -====================== +===================== The ``/-/rules`` endpoint displays all permission rules (both allow and deny) for each candidate resource for the requested action. @@ -1106,7 +1106,7 @@ Pass ``?action=`` as a query parameter to specify which action to check. .. _PermissionCheckView: Permission check view -====================== +===================== The ``/-/check`` endpoint evaluates a single action/resource pair and returns information indicating whether the access was allowed along with diagnostic information. @@ -1212,7 +1212,7 @@ Default *allow*. .. _permissions_view_database_download: view-database-download ------------------------ +---------------------- Actor is allowed to download a database, e.g. https://latest.datasette.io/fixtures.db diff --git a/docs/changelog.rst b/docs/changelog.rst index c21ba0a9..35b3c3ac 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -577,7 +577,7 @@ Documentation .. _v0_62: 0.62 (2022-08-14) -------------------- +----------------- Datasette can now run entirely in your browser using WebAssembly. Try out `Datasette Lite `__, take a look `at the code `__ or read more about it in `Datasette Lite: a server-side Python web application running in a browser `__. diff --git a/docs/deploying.rst b/docs/deploying.rst index 3754267d..95b4b52e 100644 --- a/docs/deploying.rst +++ b/docs/deploying.rst @@ -79,7 +79,7 @@ Datasette will not be accessible from outside the server because it is listening .. _deploying_openrc: Running Datasette using OpenRC -=============================== +============================== OpenRC is the service manager on non-systemd Linux distributions like `Alpine Linux `__ and `Gentoo `__. Create an init script at ``/etc/init.d/datasette`` with the following contents: diff --git a/docs/internals.rst b/docs/internals.rst index d71c3906..3f94f361 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -419,7 +419,7 @@ For legacy string/tuple based permission checking, use :ref:`datasette_permissio .. _datasette_ensure_permission: await .ensure_permission(action, resource=None, actor=None) ------------------------------------------------------------- +----------------------------------------------------------- ``action`` - string The action to check. See :ref:`permissions` for a list of available actions. @@ -1047,7 +1047,7 @@ These methods each return a ``datasette.utils.PrefixedUrlString`` object, which .. _internals_permission_classes: Permission classes and utilities -================================= +================================ .. _internals_permission_sql: @@ -1296,7 +1296,7 @@ Example usage: .. _database_execute_write: await db.execute_write(sql, params=None, block=True) ------------------------------------------------------ +---------------------------------------------------- SQLite only allows one database connection to write at a time. Datasette handles this for you by maintaining a queue of writes to be executed against a given database. Plugins can submit write operations to this queue and they will be executed in the order in which they are received. @@ -1313,7 +1313,7 @@ Each call to ``execute_write()`` will be executed inside a transaction. .. _database_execute_write_script: await db.execute_write_script(sql, block=True) ------------------------------------------------ +---------------------------------------------- Like ``execute_write()`` but can be used to send multiple SQL statements in a single string separated by semicolons, using the ``sqlite3`` `conn.executescript() `__ method. @@ -1322,7 +1322,7 @@ Each call to ``execute_write_script()`` will be executed inside a transaction. .. _database_execute_write_many: await db.execute_write_many(sql, params_seq, block=True) ---------------------------------------------------------- +-------------------------------------------------------- Like ``execute_write()`` but uses the ``sqlite3`` `conn.executemany() `__ method. This will efficiently execute the same SQL statement against each of the parameters in the ``params_seq`` iterator, for example: diff --git a/docs/plugin_hooks.rst b/docs/plugin_hooks.rst index 979baa84..b1615e27 100644 --- a/docs/plugin_hooks.rst +++ b/docs/plugin_hooks.rst @@ -780,7 +780,7 @@ The plugin hook can then be used to register the new facet class like this: .. _plugin_register_permissions: register_permissions(datasette) --------------------------------- +------------------------------- .. note:: This hook is deprecated. Use :ref:`plugin_register_actions` instead, which provides a more flexible resource-based permission system. @@ -830,7 +830,7 @@ The fields of the ``Permission`` class are as follows: .. _plugin_register_actions: register_actions(datasette) ----------------------------- +--------------------------- If your plugin needs to register actions that can be checked with Datasette's new resource-based permission system, return a list of those actions from this hook. @@ -931,7 +931,7 @@ The fields of the ``Action`` dataclass are as follows: - Have an ``__init__`` method that accepts appropriate parameters and calls ``super().__init__(parent=..., child=...)`` The ``resources_sql()`` method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``resources_sql()`` classmethod is crucial to Datasette's permission system. It returns a SQL query that lists all resources of that type that exist in the system. @@ -1445,7 +1445,7 @@ Example: `datasette-permissions-sql = 5 and + len(set(next_line)) == 1 and + next_line[0] in underline_chars): + # Skip if the previous line is empty (blank line before underline) + if not current_line: + continue + + # Check if this is an overline+underline style heading + # Look at the line before current_line to see if it's also an underline + if i > 0: + prev_line = lines[i - 1] + if (prev_line and + len(prev_line) >= 5 and + len(set(prev_line)) == 1 and + prev_line[0] in underline_chars and + len(prev_line) == len(next_line)): + # This is overline+underline style, skip it + continue + + # This is a heading underline + title_length = len(current_line) + underline_length = len(next_line) + + if title_length != underline_length: + errors.append( + f"{rst_file.name}:{i+1}: Title length {title_length} != underline length {underline_length}\n" + f" Title: {current_line!r}\n" + f" Underline: {next_line!r}" + ) + + if errors: + raise AssertionError( + f"Found {len(errors)} RST heading(s) with mismatched underline length:\n\n" + + "\n\n".join(errors) + ) + + # Tests for testing_plugins.rst documentation # fmt: off