diff --git a/README.rst b/README.rst index 638ee3b..23097bb 100644 --- a/README.rst +++ b/README.rst @@ -196,6 +196,19 @@ The objects permissions can be specified or modified by passing a ``permissions` client.update_record(data=record) +In order to obtain a list of all the permissions, on every object, use the ``get_permissions()`` method: + +.. code-block:: python + + all_perms = client.get_permissions(exclude_resource_names=("record",)) + + has_collection_perms = any( + p for p in all_perms + if p["collection_id"] == "my-collection" + and "write" in p["permissions"] + ) + + Get or create ------------- diff --git a/src/kinto_http/client.py b/src/kinto_http/client.py index 3cde794..f731246 100644 --- a/src/kinto_http/client.py +++ b/src/kinto_http/client.py @@ -667,6 +667,16 @@ def get_paginated_records(self, *, collection=None, bucket=None, **kwargs) -> Li return self._paginated_generator(endpoint, **kwargs) + @retry_timeout + def get_permissions(self, exclude_resource_names=None, **kwargs): + endpoint = self._get_endpoint("permissions") + params = kwargs.setdefault("params", {}) + params.setdefault("_sort", "id") + if exclude_resource_names: + params["exclude_resource_name"] = ",".join(exclude_resource_names) + body, _ = self.session.request("get", endpoint, **kwargs) + return body["data"] + def _paginated_generator(self, endpoint, *, if_none_match=None, **kwargs): headers = {} if if_none_match is not None: diff --git a/src/kinto_http/endpoints.py b/src/kinto_http/endpoints.py index 5844aed..f632c55 100644 --- a/src/kinto_http/endpoints.py +++ b/src/kinto_http/endpoints.py @@ -11,6 +11,7 @@ class Endpoints(object): endpoints = { "root": "{root}/", "batch": "{root}/batch", + "permissions": "{root}/permissions", "buckets": "{root}/buckets", "bucket": "{root}/buckets/{bucket}", "history": "{root}/buckets/{bucket}/history", diff --git a/tests/config/kinto.ini b/tests/config/kinto.ini index a60038f..4989356 100644 --- a/tests/config/kinto.ini +++ b/tests/config/kinto.ini @@ -16,6 +16,8 @@ kinto.bucket_create_principals = account:user kinto.attachment.base_path = /tmp +kinto.experimental_permissions_endpoint = true + [server:main] use = egg:waitress#main host = 0.0.0.0 diff --git a/tests/test_client.py b/tests/test_client.py index 205d351..b15620a 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1414,3 +1414,22 @@ def test_add_attachment_guesses_mimetype(record_setup: Client, tmp_path): permissions=None, files=[("attachment", ("file.txt", b"hello", "text/plain"))], ) + + +def test_get_permissions(client_setup: Client): + client = client_setup + mock_response(client.session) + + client.get_permissions() + url = "/permissions" + client.session.request.assert_called_with("get", url, params={"_sort": "id"}) + + client.get_permissions(exclude_resource_names=("record", "group")) + client.session.request.assert_called_with( + "get", + url, + params={ + "exclude_resource_name": "record,group", + "_sort": "id", + }, + ) diff --git a/tests/test_functional.py b/tests/test_functional.py index adbbd18..2995292 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -582,3 +582,11 @@ def test_removing_an_attachment(functional_setup, tmp_path): record = client.get_record(id="abc") assert record["data"]["attachment"] is None + + +def test_get_permissions(functional_setup): + client = functional_setup + perms = client.get_permissions() + + perms_by_uri = {p["uri"]: p for p in perms} + assert perms_by_uri["/accounts/user"]["permissions"] == ["read", "write"]