mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
actor_matches_allow utility function, refs #800
This commit is contained in:
parent
d4c7b85f55
commit
14f6b4d200
3 changed files with 62 additions and 2 deletions
|
|
@ -854,3 +854,22 @@ def call_with_supported_arguments(fn, **kwargs):
|
|||
)
|
||||
call_with.append(kwargs[parameter])
|
||||
return fn(*call_with)
|
||||
|
||||
|
||||
def actor_matches_allow(actor, allow):
|
||||
if allow is None:
|
||||
return True
|
||||
for key, values in allow.items():
|
||||
if values == "*" and key in actor:
|
||||
return True
|
||||
if isinstance(values, str):
|
||||
values = [values]
|
||||
actor_values = actor.get(key)
|
||||
if actor_values is None:
|
||||
return False
|
||||
if isinstance(actor_values, str):
|
||||
actor_values = [actor_values]
|
||||
actor_values = set(actor_values)
|
||||
if actor_values.intersection(values):
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ The URL on the first line includes a one-use token which can be used to sign in
|
|||
|
||||
.. _authentication_permissions_canned_queries:
|
||||
|
||||
Setting permissions for canned queries
|
||||
======================================
|
||||
Permissions for canned queries
|
||||
==============================
|
||||
|
||||
Datasette's :ref:`canned_queries` default to allowing any user to execute them.
|
||||
|
||||
|
|
@ -120,6 +120,20 @@ If you want to provide access to any actor with a value for a specific key, use
|
|||
|
||||
These keys act as an "or" mechanism. A actor will be able to execute the query if any of their JSON properties match any of the values in the corresponding lists in the ``allow`` block.
|
||||
|
||||
.. _authentication_actor_matches_allow:
|
||||
|
||||
actor_matches_allow()
|
||||
=====================
|
||||
|
||||
Plugins that wish to implement the same permissions scheme as canned queries can take advantage of the ``datasette.utils.actor_matches_allow(actor, allow)`` function:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette.utils import actor_matches_allow
|
||||
|
||||
actor_matches_allow({"id": "root"}, {"id": "*"})
|
||||
# returns True
|
||||
|
||||
.. _PermissionsDebugView:
|
||||
|
||||
Permissions Debug
|
||||
|
|
|
|||
|
|
@ -459,3 +459,30 @@ def test_multi_params(data, should_raise):
|
|||
p1 = utils.MultiParams(data)
|
||||
assert "bar" == p1["foo"]
|
||||
assert ["bar", "baz"] == list(p1.getlist("foo"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"actor,allow,expected",
|
||||
[
|
||||
({"id": "root"}, None, True),
|
||||
({"id": "root"}, {}, False),
|
||||
# Special "*" value for any key:
|
||||
({"id": "root"}, {"id": "*"}, True),
|
||||
({}, {"id": "*"}, False),
|
||||
({"name": "root"}, {"id": "*"}, False),
|
||||
# Supports single strings or list of values:
|
||||
({"id": "root"}, {"id": "bob"}, False),
|
||||
({"id": "root"}, {"id": ["bob"]}, False),
|
||||
({"id": "root"}, {"id": "root"}, True),
|
||||
({"id": "root"}, {"id": ["root"]}, True),
|
||||
# Any matching role will work:
|
||||
({"id": "garry", "roles": ["staff", "dev"]}, {"roles": ["staff"]}, True),
|
||||
({"id": "garry", "roles": ["staff", "dev"]}, {"roles": ["dev"]}, True),
|
||||
({"id": "garry", "roles": ["staff", "dev"]}, {"roles": ["otter"]}, False),
|
||||
({"id": "garry", "roles": ["staff", "dev"]}, {"roles": ["dev", "otter"]}, True),
|
||||
({"id": "garry", "roles": []}, {"roles": ["staff"]}, False),
|
||||
({"id": "garry"}, {"roles": ["staff"]}, False),
|
||||
],
|
||||
)
|
||||
def test_actor_matches_allow(actor, allow, expected):
|
||||
assert expected == utils.actor_matches_allow(actor, allow)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue