From 1f746536c21fbf462a09c05fd72e82934477f277 Mon Sep 17 00:00:00 2001 From: Evan Sims Date: Thu, 13 Jun 2024 00:40:04 -0500 Subject: [PATCH 1/3] fix: `list_users` should accept `FgaObject` type --- .../client/models/list_users_request.py | 23 ++++++++++--------- test/test_client.py | 5 ++-- test/test_client_sync.py | 5 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/openfga_sdk/client/models/list_users_request.py b/openfga_sdk/client/models/list_users_request.py index ac484a8..988b072 100644 --- a/openfga_sdk/client/models/list_users_request.py +++ b/openfga_sdk/client/models/list_users_request.py @@ -11,6 +11,7 @@ """ from openfga_sdk.client.models.tuple import ClientTuple +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.models.user_type_filter import UserTypeFilter @@ -21,7 +22,7 @@ class ClientListUsersRequest: def __init__( self, - object: str = None, + object: FgaObject = None, relation: str = None, user_filters: list[UserTypeFilter] = None, contextual_tuples: list[ClientTuple] = None, @@ -34,7 +35,7 @@ def __init__( self._context = context @property - def object(self): + def object(self) -> FgaObject: """Gets the object of this ClientListUsersRequest. @@ -44,7 +45,7 @@ def object(self): return self._object @object.setter - def object(self, object): + def object(self, object: FgaObject): """Sets the object of this ClientListUsersRequest. @@ -55,7 +56,7 @@ def object(self, object): self._object = object @property - def relation(self): + def relation(self) -> str: """Gets the relation of this ClientListUsersRequest. @@ -65,7 +66,7 @@ def relation(self): return self._relation @relation.setter - def relation(self, relation): + def relation(self, relation: str): """Sets the relation of this ClientListUsersRequest. @@ -76,7 +77,7 @@ def relation(self, relation): self._relation = relation @property - def user_filters(self): + def user_filters(self) -> list[UserTypeFilter]: """Gets the user_filters of this ClientListUsersRequest. @@ -86,7 +87,7 @@ def user_filters(self): return self._user_filters @user_filters.setter - def user_filters(self, user_filters): + def user_filters(self, user_filters: list[UserTypeFilter]): """Sets the user_filters of this ClientListUsersRequest. @@ -97,7 +98,7 @@ def user_filters(self, user_filters): self._user_filters = user_filters @property - def contextual_tuples(self): + def contextual_tuples(self) -> list[ClientTuple]: """Gets the contextual_tuples of this ClientListUsersRequest. @@ -107,7 +108,7 @@ def contextual_tuples(self): return self._contextual_tuples @contextual_tuples.setter - def contextual_tuples(self, contextual_tuples): + def contextual_tuples(self, contextual_tuples: list[ClientTuple]): """Sets the contextual_tuples of this ClientListUsersRequest. @@ -118,7 +119,7 @@ def contextual_tuples(self, contextual_tuples): self._contextual_tuples = contextual_tuples @property - def context(self): + def context(self) -> object: """Gets the context of this ClientListUsersRequest. Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. @@ -129,7 +130,7 @@ def context(self): return self._context @context.setter - def context(self, context): + def context(self, context: object): """Sets the context of this ClientListUsersRequest. Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. diff --git a/test/test_client.py b/test/test_client.py index 9834954..dca929b 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -41,6 +41,7 @@ from openfga_sdk.models.create_store_request import CreateStoreRequest from openfga_sdk.models.create_store_response import CreateStoreResponse from openfga_sdk.models.expand_response import ExpandResponse +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.models.get_store_response import GetStoreResponse from openfga_sdk.models.leaf import Leaf from openfga_sdk.models.list_objects_response import ListObjectsResponse @@ -2508,7 +2509,7 @@ async def test_list_users(self, mock_request): async with OpenFgaClient(configuration) as api_client: body = ClientListUsersRequest( - object="document:2021-budget", + object=FgaObject(type="document", id="2021-budget"), relation="can_read", user_filters=[ UserTypeFilter(type="user"), @@ -2565,7 +2566,7 @@ async def test_list_users(self, mock_request): post_params=[], body={ "authorization_model_id": "01G5JAVJ41T49E9TT3SKVS7X1J", - "object": "document:2021-budget", + "object": {"id": "2021-budget", "type": "document"}, "relation": "can_read", "user_filters": [ {"type": "user"}, diff --git a/test/test_client_sync.py b/test/test_client_sync.py index 5fbeb3e..6e5cb28 100644 --- a/test/test_client_sync.py +++ b/test/test_client_sync.py @@ -39,6 +39,7 @@ from openfga_sdk.models.create_store_request import CreateStoreRequest from openfga_sdk.models.create_store_response import CreateStoreResponse from openfga_sdk.models.expand_response import ExpandResponse +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.models.get_store_response import GetStoreResponse from openfga_sdk.models.leaf import Leaf from openfga_sdk.models.list_objects_response import ListObjectsResponse @@ -2508,7 +2509,7 @@ def test_list_users(self, mock_request): with OpenFgaClient(configuration) as api_client: body = ClientListUsersRequest() - body.object = "document:2021-budget" + body.object = FgaObject(type="document", id="2021-budget") body.relation = "can_read" body.user_filters = [ UserTypeFilter(type="user"), @@ -2564,7 +2565,7 @@ def test_list_users(self, mock_request): post_params=[], body={ "authorization_model_id": "01G5JAVJ41T49E9TT3SKVS7X1J", - "object": "document:2021-budget", + "object": {"id": "2021-budget", "type": "document"}, "relation": "can_read", "user_filters": [ {"type": "user"}, From e9bc4e427bac30fa4d26507d0a38cfb8d55731d5 Mon Sep 17 00:00:00 2001 From: Evan Sims Date: Thu, 13 Jun 2024 00:40:04 -0500 Subject: [PATCH 2/3] fix: `list_users` should accept `FgaObject` type --- .../client/models/list_users_request.py | 23 ++++++++++--------- test/test_client.py | 5 ++-- test/test_client_sync.py | 5 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/openfga_sdk/client/models/list_users_request.py b/openfga_sdk/client/models/list_users_request.py index ac484a8..988b072 100644 --- a/openfga_sdk/client/models/list_users_request.py +++ b/openfga_sdk/client/models/list_users_request.py @@ -11,6 +11,7 @@ """ from openfga_sdk.client.models.tuple import ClientTuple +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.models.user_type_filter import UserTypeFilter @@ -21,7 +22,7 @@ class ClientListUsersRequest: def __init__( self, - object: str = None, + object: FgaObject = None, relation: str = None, user_filters: list[UserTypeFilter] = None, contextual_tuples: list[ClientTuple] = None, @@ -34,7 +35,7 @@ def __init__( self._context = context @property - def object(self): + def object(self) -> FgaObject: """Gets the object of this ClientListUsersRequest. @@ -44,7 +45,7 @@ def object(self): return self._object @object.setter - def object(self, object): + def object(self, object: FgaObject): """Sets the object of this ClientListUsersRequest. @@ -55,7 +56,7 @@ def object(self, object): self._object = object @property - def relation(self): + def relation(self) -> str: """Gets the relation of this ClientListUsersRequest. @@ -65,7 +66,7 @@ def relation(self): return self._relation @relation.setter - def relation(self, relation): + def relation(self, relation: str): """Sets the relation of this ClientListUsersRequest. @@ -76,7 +77,7 @@ def relation(self, relation): self._relation = relation @property - def user_filters(self): + def user_filters(self) -> list[UserTypeFilter]: """Gets the user_filters of this ClientListUsersRequest. @@ -86,7 +87,7 @@ def user_filters(self): return self._user_filters @user_filters.setter - def user_filters(self, user_filters): + def user_filters(self, user_filters: list[UserTypeFilter]): """Sets the user_filters of this ClientListUsersRequest. @@ -97,7 +98,7 @@ def user_filters(self, user_filters): self._user_filters = user_filters @property - def contextual_tuples(self): + def contextual_tuples(self) -> list[ClientTuple]: """Gets the contextual_tuples of this ClientListUsersRequest. @@ -107,7 +108,7 @@ def contextual_tuples(self): return self._contextual_tuples @contextual_tuples.setter - def contextual_tuples(self, contextual_tuples): + def contextual_tuples(self, contextual_tuples: list[ClientTuple]): """Sets the contextual_tuples of this ClientListUsersRequest. @@ -118,7 +119,7 @@ def contextual_tuples(self, contextual_tuples): self._contextual_tuples = contextual_tuples @property - def context(self): + def context(self) -> object: """Gets the context of this ClientListUsersRequest. Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. @@ -129,7 +130,7 @@ def context(self): return self._context @context.setter - def context(self, context): + def context(self, context: object): """Sets the context of this ClientListUsersRequest. Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. diff --git a/test/test_client.py b/test/test_client.py index 4228171..c858a14 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -41,6 +41,7 @@ from openfga_sdk.models.create_store_request import CreateStoreRequest from openfga_sdk.models.create_store_response import CreateStoreResponse from openfga_sdk.models.expand_response import ExpandResponse +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.models.get_store_response import GetStoreResponse from openfga_sdk.models.leaf import Leaf from openfga_sdk.models.list_objects_response import ListObjectsResponse @@ -2430,7 +2431,7 @@ async def test_list_users(self, mock_request): async with OpenFgaClient(configuration) as api_client: body = ClientListUsersRequest( - object="document:2021-budget", + object=FgaObject(type="document", id="2021-budget"), relation="can_read", user_filters=[ UserTypeFilter(type="user"), @@ -2487,7 +2488,7 @@ async def test_list_users(self, mock_request): post_params=[], body={ "authorization_model_id": "01G5JAVJ41T49E9TT3SKVS7X1J", - "object": "document:2021-budget", + "object": {"id": "2021-budget", "type": "document"}, "relation": "can_read", "user_filters": [ {"type": "user"}, diff --git a/test/test_client_sync.py b/test/test_client_sync.py index 3fcb593..0363d0d 100644 --- a/test/test_client_sync.py +++ b/test/test_client_sync.py @@ -39,6 +39,7 @@ from openfga_sdk.models.create_store_request import CreateStoreRequest from openfga_sdk.models.create_store_response import CreateStoreResponse from openfga_sdk.models.expand_response import ExpandResponse +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.models.get_store_response import GetStoreResponse from openfga_sdk.models.leaf import Leaf from openfga_sdk.models.list_objects_response import ListObjectsResponse @@ -2431,7 +2432,7 @@ def test_list_users(self, mock_request): with OpenFgaClient(configuration) as api_client: body = ClientListUsersRequest() - body.object = "document:2021-budget" + body.object = FgaObject(type="document", id="2021-budget") body.relation = "can_read" body.user_filters = [ UserTypeFilter(type="user"), @@ -2487,7 +2488,7 @@ def test_list_users(self, mock_request): post_params=[], body={ "authorization_model_id": "01G5JAVJ41T49E9TT3SKVS7X1J", - "object": "document:2021-budget", + "object": {"id": "2021-budget", "type": "document"}, "relation": "can_read", "user_filters": [ {"type": "user"}, From caa0f255be0d6e5fde81de9e917e0c10acb4067c Mon Sep 17 00:00:00 2001 From: Evan Sims Date: Thu, 13 Jun 2024 23:57:26 -0500 Subject: [PATCH 3/3] Update README and Example --- README.md | 3 ++- example/example1/example1.py | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99e73d1..83756f2 100644 --- a/README.md +++ b/README.md @@ -914,6 +914,7 @@ List the users who have a certain relation to a particular type. ```python from openfga_sdk import OpenFgaClient +from openfga_sdk.models.fga_object import FgaObject from openfga_sdk.client.models import ClientListUsersRequest, ClientTuple configuration = ClientConfiguration( @@ -927,7 +928,7 @@ async with OpenFgaClient(configuration) as api_client: } request = ClientListUsersRequest( - object="document:2021-budget", + object=FgaObject(type="document", id="2021-budget"), relation="can_read", user_filters=[ UserTypeFilter(type="user"), diff --git a/example/example1/example1.py b/example/example1/example1.py index 92d79f5..3ae7f88 100644 --- a/example/example1/example1.py +++ b/example/example1/example1.py @@ -28,7 +28,9 @@ ClientWriteRequest, WriteTransactionOpts, ) +from openfga_sdk.client.models.list_users_request import ClientListUsersRequest from openfga_sdk.credentials import CredentialConfiguration, Credentials +from openfga_sdk.models.fga_object import FgaObject async def main(): @@ -264,7 +266,7 @@ async def main(): print(f"Allowed: {response.allowed}") # List objects with context - print("Listing objects for access with context") + print("Listing objects for access with context") response = await fga_client.list_objects( ClientListObjectsRequest( @@ -301,6 +303,20 @@ async def main(): ) print(f"Relations: {response}") + # ListUsers + print("Listing user who have access to object") + + response = await fga_client.list_objects( + ClientListUsersRequest( + relation="viewer", + object=FgaObject(type="document", id="roadmap"), + user_filters=[ + FgaObject(type="user"), + ], + ) + ) + print(f"Users: {response.objects}") + # WriteAssertions await fga_client.write_assertions( [