Skip to content

Commit

Permalink
feat: support list users (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
evansims authored Jun 6, 2024
2 parents 5a5e26c + f410a6a commit ca36899
Show file tree
Hide file tree
Showing 140 changed files with 3,321 additions and 140 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
fetch-depth: 0

Expand Down Expand Up @@ -59,7 +59,7 @@ jobs:

- if: matrix.python-version == '3.10'
name: Upload coverage to Codecov
uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1
uses: codecov/codecov-action@84508663e988701840491b86de86b666e8a86bed # v4.3.0
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand All @@ -74,7 +74,7 @@ jobs:
id-token: write # Required for PyPI trusted publishing

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
fetch-depth: 0

Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
needs: [publish]

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
fetch-depth: 0

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/semgrep.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
image: returntocorp/semgrep
if: (github.actor != 'dependabot[bot]' && github.actor != 'snyk-bot')
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
- run: semgrep ci --no-suppress-errors
Expand Down
23 changes: 23 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,22 @@ docs/ErrorCode.md
docs/ExpandRequest.md
docs/ExpandRequestTupleKey.md
docs/ExpandResponse.md
docs/FgaObject.md
docs/GetStoreResponse.md
docs/InternalErrorCode.md
docs/InternalErrorMessageResponse.md
docs/Leaf.md
docs/ListObjectsRequest.md
docs/ListObjectsResponse.md
docs/ListStoresResponse.md
docs/ListUsersRequest.md
docs/ListUsersResponse.md
docs/Metadata.md
docs/Node.md
docs/Nodes.md
docs/NotFoundErrorCode.md
docs/NullValue.md
docs/ObjectOrUserset.md
docs/ObjectRelation.md
docs/OpenFgaApi.md
docs/PathUnknownErrorMessageResponse.md
Expand All @@ -71,11 +75,18 @@ docs/TupleOperation.md
docs/TupleToUserset.md
docs/TypeDefinition.md
docs/TypeName.md
docs/TypedWildcard.md
docs/UnauthenticatedResponse.md
docs/UnprocessableContentErrorCode.md
docs/UnprocessableContentMessageResponse.md
docs/User.md
docs/UserTypeFilter.md
docs/Users.md
docs/Userset.md
docs/UsersetTree.md
docs/UsersetTreeDifference.md
docs/UsersetTreeTupleToUserset.md
docs/UsersetUser.md
docs/Usersets.md
docs/ValidationErrorMessageResponse.md
docs/WriteAssertionsRequest.md
Expand Down Expand Up @@ -105,6 +116,7 @@ openfga_sdk/client/models/check_request.py
openfga_sdk/client/models/expand_request.py
openfga_sdk/client/models/list_objects_request.py
openfga_sdk/client/models/list_relations_request.py
openfga_sdk/client/models/list_users_request.py
openfga_sdk/client/models/read_changes_request.py
openfga_sdk/client/models/tuple.py
openfga_sdk/client/models/write_request.py
Expand Down Expand Up @@ -136,18 +148,22 @@ openfga_sdk/models/error_code.py
openfga_sdk/models/expand_request.py
openfga_sdk/models/expand_request_tuple_key.py
openfga_sdk/models/expand_response.py
openfga_sdk/models/fga_object.py
openfga_sdk/models/get_store_response.py
openfga_sdk/models/internal_error_code.py
openfga_sdk/models/internal_error_message_response.py
openfga_sdk/models/leaf.py
openfga_sdk/models/list_objects_request.py
openfga_sdk/models/list_objects_response.py
openfga_sdk/models/list_stores_response.py
openfga_sdk/models/list_users_request.py
openfga_sdk/models/list_users_response.py
openfga_sdk/models/metadata.py
openfga_sdk/models/node.py
openfga_sdk/models/nodes.py
openfga_sdk/models/not_found_error_code.py
openfga_sdk/models/null_value.py
openfga_sdk/models/object_or_userset.py
openfga_sdk/models/object_relation.py
openfga_sdk/models/path_unknown_error_message_response.py
openfga_sdk/models/read_assertions_response.py
Expand All @@ -171,11 +187,18 @@ openfga_sdk/models/tuple_operation.py
openfga_sdk/models/tuple_to_userset.py
openfga_sdk/models/type_definition.py
openfga_sdk/models/type_name.py
openfga_sdk/models/typed_wildcard.py
openfga_sdk/models/unauthenticated_response.py
openfga_sdk/models/unprocessable_content_error_code.py
openfga_sdk/models/unprocessable_content_message_response.py
openfga_sdk/models/user.py
openfga_sdk/models/user_type_filter.py
openfga_sdk/models/users.py
openfga_sdk/models/userset.py
openfga_sdk/models/userset_tree.py
openfga_sdk/models/userset_tree_difference.py
openfga_sdk/models/userset_tree_tuple_to_userset.py
openfga_sdk/models/userset_user.py
openfga_sdk/models/usersets.py
openfga_sdk/models/validation_error_message_response.py
openfga_sdk/models/write_assertions_request.py
Expand Down
76 changes: 68 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ This is an autogenerated python SDK for OpenFGA. It provides a wrapper around th
- [Expand](#expand)
- [List Objects](#list-objects)
- [List Relations](#list-relations)
- [List Users](#list-users)
- [Assertions](#assertions)
- [Read Assertions](#read-assertions)
- [Write Assertions](#write-assertions)
Expand Down Expand Up @@ -132,7 +133,7 @@ async def main():
configuration = ClientConfiguration(
api_url=FGA_API_URL, # required
store_id=FGA_STORE_ID, # optional, not needed when calling `CreateStore` or `ListStores`
authorization_model_id=FGA_AUTHORIZATION_MODEL_ID, # Optional, can be overridden per request
authorization_model_id=FGA_MODEL_ID, # Optional, can be overridden per request
)
# Enter a context with an instance of the OpenFgaClient
async with OpenFgaClient(configuration) as fga_client:
Expand All @@ -152,7 +153,7 @@ async def main():
configuration = ClientConfiguration(
api_url=FGA_API_URL, # required
store_id=FGA_STORE_ID, # optional, not needed when calling `CreateStore` or `ListStores`
authorization_model_id=FGA_AUTHORIZATION_MODEL_ID, # Optional, can be overridden per request
authorization_model_id=FGA_MODEL_ID, # Optional, can be overridden per request
credentials=Credentials(
method='api_token',
configuration=CredentialConfiguration(
Expand All @@ -178,7 +179,7 @@ async def main():
configuration = ClientConfiguration(
api_url=FGA_API_URL, # required
store_id=FGA_STORE_ID, # optional, not needed when calling `CreateStore` or `ListStores`
authorization_model_id=FGA_AUTHORIZATION_MODEL_ID, # Optional, can be overridden per request
authorization_model_id=FGA_MODEL_ID, # Optional, can be overridden per request
credentials=Credentials(
method='client_credentials',
configuration=CredentialConfiguration(
Expand Down Expand Up @@ -210,7 +211,7 @@ def main():
configuration = ClientConfiguration(
api_url=FGA_API_URL, # required
store_id=FGA_STORE_ID, # optional, not needed when calling `CreateStore` or `ListStores`
authorization_model_id=FGA_AUTHORIZATION_MODEL_ID, # optional, can be overridden per request
authorization_model_id=FGA_MODEL_ID, # optional, can be overridden per request
)
# Enter a context with an instance of the OpenFgaClient
with OpenFgaClient(configuration) as fga_client:
Expand Down Expand Up @@ -444,7 +445,7 @@ Reads the latest authorization model (note: this ignores the model id in configu
# Create the cofiguration object
# configuration = ClientConfiguration(
# ...
# authorization_model_id = FGA_AUTHORIZATION_MODEL_ID,
# authorization_model_id = FGA_MODEL_ID,
# ...
# )

Expand Down Expand Up @@ -832,8 +833,7 @@ response = await fga_client.expand(body. options)
# response = ExpandResponse({"tree": UsersetTree({"root": Node({"name": "document:roadmap#viewer", "leaf": Leaf({"users": Users({"users": ["user:81684243-9356-4421-8fbf-a4f8d36aa31b", "user:f52a4f7a-054d-47ff-bb6e-3ac81269988f"]})})})})})
```


##### List Objects
#### List Objects

List the objects of a particular type a user has access to.

Expand Down Expand Up @@ -870,7 +870,7 @@ response = await fga_client.list_objects(body)
# response.objects = ["document:roadmap"]
```

##### List Relations
#### List Relations

List the relations a user has on an object.

Expand Down Expand Up @@ -906,6 +906,54 @@ response = await fga_client.list_relations(body, options)
# response.relations = ["can_view", "can_edit"]
```

#### List Users

List the users who have a certain relation to a particular type.

[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/ListUsers)

```python
from openfga_sdk import OpenFgaClient
from openfga_sdk.client.models import ClientListUsersRequest, ClientTuple

configuration = ClientConfiguration(
api_url=FGA_API_URL,
# ...
)

async with OpenFgaClient(configuration) as api_client:
options = {
"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1"
}

request = ClientListUsersRequest(
object="document:2021-budget",
relation="can_read",
user_filters=[
UserTypeFilter(type="user"),
UserTypeFilter(type="team", relation="member"),
],
context={},
contextual_tuples=[
ClientTuple(
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
relation="editor",
object="folder:product",
),
ClientTuple(
user="folder:product",
relation="parent",
object="document:roadmap",
),
],
)

response = await api_client.list_users(request, options)

# response.users = [{object: {type: "user", id: "81684243-9356-4421-8fbf-a4f8d36aa31b"}}, {userset: { type: "user" }}, ...]
# response.excluded_users = [ {object: {type: "user", id: "4a455e27-d15a-4434-82e0-136f9c2aa4cf"}}, ... ]
```

#### Assertions

##### Read Assertions
Expand Down Expand Up @@ -994,6 +1042,7 @@ Class | Method | HTTP request | Description
*OpenFgaApi* | [**get_store**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#get_store) | **GET** /stores/{store_id} | Get a store
*OpenFgaApi* | [**list_objects**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#list_objects) | **POST** /stores/{store_id}/list-objects | List all objects of the given type that the user has a relation with
*OpenFgaApi* | [**list_stores**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#list_stores) | **GET** /stores | List all stores
*OpenFgaApi* | [**list_users**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#list_users) | **POST** /stores/{store_id}/list-users | [EXPERIMENTAL] List the users matching the provided filter who have a certain relation to a particular type.
*OpenFgaApi* | [**read**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#read) | **POST** /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules
*OpenFgaApi* | [**read_assertions**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#read_assertions) | **GET** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID
*OpenFgaApi* | [**read_authorization_model**](https://github.com/openfga/python-sdk/blob/main/docs/OpenFgaApi.md#read_authorization_model) | **GET** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model
Expand Down Expand Up @@ -1029,18 +1078,22 @@ Class | Method | HTTP request | Description
- [ExpandRequest](https://github.com/openfga/python-sdk/blob/main/docs/ExpandRequest.md)
- [ExpandRequestTupleKey](https://github.com/openfga/python-sdk/blob/main/docs/ExpandRequestTupleKey.md)
- [ExpandResponse](https://github.com/openfga/python-sdk/blob/main/docs/ExpandResponse.md)
- [FgaObject](https://github.com/openfga/python-sdk/blob/main/docs/FgaObject.md)
- [GetStoreResponse](https://github.com/openfga/python-sdk/blob/main/docs/GetStoreResponse.md)
- [InternalErrorCode](https://github.com/openfga/python-sdk/blob/main/docs/InternalErrorCode.md)
- [InternalErrorMessageResponse](https://github.com/openfga/python-sdk/blob/main/docs/InternalErrorMessageResponse.md)
- [Leaf](https://github.com/openfga/python-sdk/blob/main/docs/Leaf.md)
- [ListObjectsRequest](https://github.com/openfga/python-sdk/blob/main/docs/ListObjectsRequest.md)
- [ListObjectsResponse](https://github.com/openfga/python-sdk/blob/main/docs/ListObjectsResponse.md)
- [ListStoresResponse](https://github.com/openfga/python-sdk/blob/main/docs/ListStoresResponse.md)
- [ListUsersRequest](https://github.com/openfga/python-sdk/blob/main/docs/ListUsersRequest.md)
- [ListUsersResponse](https://github.com/openfga/python-sdk/blob/main/docs/ListUsersResponse.md)
- [Metadata](https://github.com/openfga/python-sdk/blob/main/docs/Metadata.md)
- [Node](https://github.com/openfga/python-sdk/blob/main/docs/Node.md)
- [Nodes](https://github.com/openfga/python-sdk/blob/main/docs/Nodes.md)
- [NotFoundErrorCode](https://github.com/openfga/python-sdk/blob/main/docs/NotFoundErrorCode.md)
- [NullValue](https://github.com/openfga/python-sdk/blob/main/docs/NullValue.md)
- [ObjectOrUserset](https://github.com/openfga/python-sdk/blob/main/docs/ObjectOrUserset.md)
- [ObjectRelation](https://github.com/openfga/python-sdk/blob/main/docs/ObjectRelation.md)
- [PathUnknownErrorMessageResponse](https://github.com/openfga/python-sdk/blob/main/docs/PathUnknownErrorMessageResponse.md)
- [ReadAssertionsResponse](https://github.com/openfga/python-sdk/blob/main/docs/ReadAssertionsResponse.md)
Expand All @@ -1064,11 +1117,18 @@ Class | Method | HTTP request | Description
- [TupleToUserset](https://github.com/openfga/python-sdk/blob/main/docs/TupleToUserset.md)
- [TypeDefinition](https://github.com/openfga/python-sdk/blob/main/docs/TypeDefinition.md)
- [TypeName](https://github.com/openfga/python-sdk/blob/main/docs/TypeName.md)
- [TypedWildcard](https://github.com/openfga/python-sdk/blob/main/docs/TypedWildcard.md)
- [UnauthenticatedResponse](https://github.com/openfga/python-sdk/blob/main/docs/UnauthenticatedResponse.md)
- [UnprocessableContentErrorCode](https://github.com/openfga/python-sdk/blob/main/docs/UnprocessableContentErrorCode.md)
- [UnprocessableContentMessageResponse](https://github.com/openfga/python-sdk/blob/main/docs/UnprocessableContentMessageResponse.md)
- [User](https://github.com/openfga/python-sdk/blob/main/docs/User.md)
- [UserTypeFilter](https://github.com/openfga/python-sdk/blob/main/docs/UserTypeFilter.md)
- [Users](https://github.com/openfga/python-sdk/blob/main/docs/Users.md)
- [Userset](https://github.com/openfga/python-sdk/blob/main/docs/Userset.md)
- [UsersetTree](https://github.com/openfga/python-sdk/blob/main/docs/UsersetTree.md)
- [UsersetTreeDifference](https://github.com/openfga/python-sdk/blob/main/docs/UsersetTreeDifference.md)
- [UsersetTreeTupleToUserset](https://github.com/openfga/python-sdk/blob/main/docs/UsersetTreeTupleToUserset.md)
- [UsersetUser](https://github.com/openfga/python-sdk/blob/main/docs/UsersetUser.md)
- [Usersets](https://github.com/openfga/python-sdk/blob/main/docs/Usersets.md)
- [ValidationErrorMessageResponse](https://github.com/openfga/python-sdk/blob/main/docs/ValidationErrorMessageResponse.md)
- [WriteAssertionsRequest](https://github.com/openfga/python-sdk/blob/main/docs/WriteAssertionsRequest.md)
Expand Down
13 changes: 13 additions & 0 deletions docs/FgaObject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# FgaObject

Object represents an OpenFGA Object. An Object is composed of a type and identifier (e.g. 'document:1') See https://openfga.dev/docs/concepts#what-is-an-object

## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**type** | **str** | |
**id** | **str** | |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


16 changes: 16 additions & 0 deletions docs/ListUsersRequest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# ListUsersRequest


## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**authorization_model_id** | **str** | | [optional]
**object** | [**FgaObject**](FgaObject.md) | |
**relation** | **str** | |
**user_filters** | [**list[UserTypeFilter]**](UserTypeFilter.md) | The type of results returned. Only accepts exactly one value. |
**contextual_tuples** | [**list[TupleKey]**](TupleKey.md) | | [optional]
**context** | **object** | Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. | [optional]

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


12 changes: 12 additions & 0 deletions docs/ListUsersResponse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ListUsersResponse


## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**users** | [**list[User]**](User.md) | |
**excluded_users** | [**list[ObjectOrUserset]**](ObjectOrUserset.md) | |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


12 changes: 12 additions & 0 deletions docs/ObjectOrUserset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ObjectOrUserset


## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**object** | [**FgaObject**](FgaObject.md) | | [optional]
**userset** | [**UsersetUser**](UsersetUser.md) | | [optional]

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


Loading

0 comments on commit ca36899

Please sign in to comment.