Skip to content

feat: support list users #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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