Skip to content

Commit

Permalink
feat: support list users (#57)
Browse files Browse the repository at this point in the history
<!-- Thanks for opening a PR! Here are some quick tips:
If this is your first time contributing, [read our Contributing
Guidelines](https://github.com/openfga/.github/blob/main/CONTRIBUTING.md)
to learn how to create an acceptable PR for this repo.
By submitting a PR to this repository, you agree to the terms within the
[OpenFGA Code of
Conduct](https://github.com/openfga/.github/blob/main/CODE_OF_CONDUCT.md)

If your PR is under active development, please submit it as a "draft".
Once it's ready, open it up for review.
-->

<!-- Provide a brief summary of the changes -->

## Description
<!-- Provide a detailed description of the changes -->

## References
<!-- Provide a list of any applicable references here (GitHub Issue,
[OpenFGA RFC](https://github.com/openfga/rfcs), other PRs, etc..) -->

## Review Checklist
- [ ] I have clicked on ["allow edits by
maintainers"](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork).
- [ ] I have added documentation for new/changed functionality in this
PR or in a PR to [openfga.dev](https://github.com/openfga/openfga.dev)
[Provide a link to any relevant PRs in the references section above]
- [ ] The correct base branch is being used, if not `main`
- [ ] I have added tests to validate that the change in functionality is
working as expected
  • Loading branch information
rhamzeh committed Apr 30, 2024
2 parents e7feab8 + 175258c commit cc110af
Show file tree
Hide file tree
Showing 35 changed files with 2,183 additions and 24 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest

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

Expand All @@ -35,7 +35,7 @@ jobs:
path: src/OpenFga.Sdk/bin/Release/OpenFga.Sdk.*.nupkg

- 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 @@ -47,7 +47,7 @@ jobs:
needs: [test]

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

Expand Down Expand Up @@ -81,7 +81,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
fetch-depth: 0
- run: semgrep ci --no-suppress-errors
Expand Down
21 changes: 21 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,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 @@ -73,11 +77,17 @@ docs/TupleOperation.md
docs/TupleToUserset.md
docs/TypeDefinition.md
docs/TypeName.md
docs/TypedWildcard.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 @@ -116,6 +126,7 @@ src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs
src/OpenFga.Sdk/Client/Model/ClientListRelationsRequest.cs
src/OpenFga.Sdk/Client/Model/ClientListRelationsResponse.cs
src/OpenFga.Sdk/Client/Model/ClientListStoresOptions.cs
src/OpenFga.Sdk/Client/Model/ClientListUsersRequest.cs
src/OpenFga.Sdk/Client/Model/ClientPaginationOptions.cs
src/OpenFga.Sdk/Client/Model/ClientReadAssertionsOptions.cs
src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelOptions.cs
Expand Down Expand Up @@ -173,6 +184,7 @@ src/OpenFga.Sdk/Model/ErrorCode.cs
src/OpenFga.Sdk/Model/ExpandRequest.cs
src/OpenFga.Sdk/Model/ExpandRequestTupleKey.cs
src/OpenFga.Sdk/Model/ExpandResponse.cs
src/OpenFga.Sdk/Model/FgaObject.cs
src/OpenFga.Sdk/Model/GetStoreResponse.cs
src/OpenFga.Sdk/Model/InternalErrorCode.cs
src/OpenFga.Sdk/Model/InternalErrorMessageResponse.cs
Expand All @@ -181,11 +193,14 @@ src/OpenFga.Sdk/Model/Leaf.cs
src/OpenFga.Sdk/Model/ListObjectsRequest.cs
src/OpenFga.Sdk/Model/ListObjectsResponse.cs
src/OpenFga.Sdk/Model/ListStoresResponse.cs
src/OpenFga.Sdk/Model/ListUsersRequest.cs
src/OpenFga.Sdk/Model/ListUsersResponse.cs
src/OpenFga.Sdk/Model/Metadata.cs
src/OpenFga.Sdk/Model/Node.cs
src/OpenFga.Sdk/Model/Nodes.cs
src/OpenFga.Sdk/Model/NotFoundErrorCode.cs
src/OpenFga.Sdk/Model/NullValue.cs
src/OpenFga.Sdk/Model/ObjectOrUserset.cs
src/OpenFga.Sdk/Model/ObjectRelation.cs
src/OpenFga.Sdk/Model/PathUnknownErrorMessageResponse.cs
src/OpenFga.Sdk/Model/ReadAssertionsResponse.cs
Expand All @@ -209,11 +224,17 @@ src/OpenFga.Sdk/Model/TupleOperation.cs
src/OpenFga.Sdk/Model/TupleToUserset.cs
src/OpenFga.Sdk/Model/TypeDefinition.cs
src/OpenFga.Sdk/Model/TypeName.cs
src/OpenFga.Sdk/Model/TypedWildcard.cs
src/OpenFga.Sdk/Model/UnprocessableContentErrorCode.cs
src/OpenFga.Sdk/Model/UnprocessableContentMessageResponse.cs
src/OpenFga.Sdk/Model/User.cs
src/OpenFga.Sdk/Model/UserTypeFilter.cs
src/OpenFga.Sdk/Model/Users.cs
src/OpenFga.Sdk/Model/Userset.cs
src/OpenFga.Sdk/Model/UsersetTree.cs
src/OpenFga.Sdk/Model/UsersetTreeDifference.cs
src/OpenFga.Sdk/Model/UsersetTreeTupleToUserset.cs
src/OpenFga.Sdk/Model/UsersetUser.cs
src/OpenFga.Sdk/Model/Usersets.cs
src/OpenFga.Sdk/Model/ValidationErrorMessageResponse.cs
src/OpenFga.Sdk/Model/WriteAssertionsRequest.cs
Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v0.3.2

### [0.3.2](https://github.com/openfga/dotnet-sdk/compare/v0.3.1...v0.3.2) (2024-04-30)

- feat: support the [ListUsers](https://github.com/openfga/rfcs/blob/main/20231214-listUsers-api.md) endpoint (#57)
- feat: add retries to client credential requests (#51)
- feat: add support for modular models metadata (#53)

## v0.3.1

### [0.3.1](https://github.com/openfga/dotnet-sdk/compare/v0.3.0...v0.3.1) (2024-02-13)
Expand Down Expand Up @@ -38,7 +46,7 @@ Some of the changes to expect:
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Optional, can be overridden per request
};
var fgaClient = new OpenFgaClient(configuration);
```
Expand Down
63 changes: 59 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ This is an autogenerated SDK for OpenFGA. It provides a wrapper around the [Open
- [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 @@ -111,7 +112,7 @@ namespace Example {
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Optional, can be overridden per request
};
var fgaClient = new OpenFgaClient(configuration);
var response = await fgaClient.ReadAuthorizationModels();
Expand All @@ -137,7 +138,7 @@ namespace Example {
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Optional, can be overridden per request
Credentials = new Credentials() {
Method = CredentialsMethod.ApiToken,
Config = new CredentialsConfig() {
Expand Down Expand Up @@ -169,7 +170,7 @@ namespace Example {
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Optional, can be overridden per request
Credentials = new Credentials() {
Method = CredentialsMethod.ClientCredentials,
Config = new CredentialsConfig() {
Expand Down Expand Up @@ -705,6 +706,49 @@ var response = await fgaClient.ListRelations(body);
// 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)

```csharp
const options = {};

// To override the authorization model id for this request
options.authorization_model_id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw";

// Only a single filter is allowed for the time being
const userFilters = [{type: "user"}];
// user filters can also be of the form
// const userFilters = [{type: "team", relation: "member"}];
const response = await fgaClient.listUsers({
object: {
type: "document",
id: "roadmap"
},
relation: "can_read",
user_filters: userFilters,
context: {
"view_count": 100
},
contextualTuples:
[{
user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
relation: "editor",
object: "folder:product"
}, {
user: "folder:product",
relation: "parent",
object: "document:roadmap"
}]
}, 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 @@ -762,7 +806,7 @@ namespace Example {
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Optional, can be overridden per request
RetryParams = new RetryParams() {
MaxRetry = 3, // retry up to 3 times on API requests
MinWaitInMs = 250 // wait a minimum of 250 milliseconds between requests
Expand All @@ -789,6 +833,7 @@ namespace Example {
| [**GetStore**](docs/OpenFgaApi.md#getstore) | **GET** /stores/{store_id} | Get a store |
| [**ListObjects**](docs/OpenFgaApi.md#listobjects) | **POST** /stores/{store_id}/list-objects | List all objects of the given type that the user has a relation with |
| [**ListStores**](docs/OpenFgaApi.md#liststores) | **GET** /stores | List all stores |
| [**ListUsers**](docs/OpenFgaApi.md#listusers) | **POST** /stores/{store_id}/list-users | List all users of the given type that the object has a relation with |
| [**Read**](docs/OpenFgaApi.md#read) | **POST** /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules |
| [**ReadAssertions**](docs/OpenFgaApi.md#readassertions) | **GET** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID |
| [**ReadAuthorizationModel**](docs/OpenFgaApi.md#readauthorizationmodel) | **GET** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model |
Expand Down Expand Up @@ -822,18 +867,22 @@ namespace Example {
- [Model.ExpandRequest](docs/ExpandRequest.md)
- [Model.ExpandRequestTupleKey](docs/ExpandRequestTupleKey.md)
- [Model.ExpandResponse](docs/ExpandResponse.md)
- [Model.FgaObject](docs/FgaObject.md)
- [Model.GetStoreResponse](docs/GetStoreResponse.md)
- [Model.InternalErrorCode](docs/InternalErrorCode.md)
- [Model.InternalErrorMessageResponse](docs/InternalErrorMessageResponse.md)
- [Model.Leaf](docs/Leaf.md)
- [Model.ListObjectsRequest](docs/ListObjectsRequest.md)
- [Model.ListObjectsResponse](docs/ListObjectsResponse.md)
- [Model.ListStoresResponse](docs/ListStoresResponse.md)
- [Model.ListUsersRequest](docs/ListUsersRequest.md)
- [Model.ListUsersResponse](docs/ListUsersResponse.md)
- [Model.Metadata](docs/Metadata.md)
- [Model.Node](docs/Node.md)
- [Model.Nodes](docs/Nodes.md)
- [Model.NotFoundErrorCode](docs/NotFoundErrorCode.md)
- [Model.NullValue](docs/NullValue.md)
- [Model.ObjectOrUserset](docs/ObjectOrUserset.md)
- [Model.ObjectRelation](docs/ObjectRelation.md)
- [Model.PathUnknownErrorMessageResponse](docs/PathUnknownErrorMessageResponse.md)
- [Model.ReadAssertionsResponse](docs/ReadAssertionsResponse.md)
Expand All @@ -857,11 +906,17 @@ namespace Example {
- [Model.TupleToUserset](docs/TupleToUserset.md)
- [Model.TypeDefinition](docs/TypeDefinition.md)
- [Model.TypeName](docs/TypeName.md)
- [Model.TypedWildcard](docs/TypedWildcard.md)
- [Model.UnprocessableContentErrorCode](docs/UnprocessableContentErrorCode.md)
- [Model.UnprocessableContentMessageResponse](docs/UnprocessableContentMessageResponse.md)
- [Model.User](docs/User.md)
- [Model.UserTypeFilter](docs/UserTypeFilter.md)
- [Model.Users](docs/Users.md)
- [Model.Userset](docs/Userset.md)
- [Model.UsersetTree](docs/UsersetTree.md)
- [Model.UsersetTreeDifference](docs/UsersetTreeDifference.md)
- [Model.UsersetTreeTupleToUserset](docs/UsersetTreeTupleToUserset.md)
- [Model.UsersetUser](docs/UsersetUser.md)
- [Model.Usersets](docs/Usersets.md)
- [Model.ValidationErrorMessageResponse](docs/ValidationErrorMessageResponse.md)
- [Model.WriteAssertionsRequest](docs/WriteAssertionsRequest.md)
Expand Down
12 changes: 12 additions & 0 deletions docs/FgaObject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# OpenFga.Sdk.Model.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** | **string** | |
**Id** | **string** | |

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

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

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**AuthorizationModelId** | **string** | | [optional]
**Object** | [**FgaObject**](FgaObject.md) | |
**Relation** | **string** | |
**UserFilters** | [**List&lt;UserTypeFilter&gt;**](UserTypeFilter.md) | |
**ContextualTuples** | [**List&lt;TupleKey&gt;**](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#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)

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

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Users** | [**List&lt;User&gt;**](User.md) | |
**ExcludedUsers** | [**List&lt;ObjectOrUserset&gt;**](ObjectOrUserset.md) | |

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

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

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Object** | [**FgaObject**](FgaObject.md) | | [optional]
**Userset** | [**UsersetUser**](UsersetUser.md) | | [optional]

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

Loading

0 comments on commit cc110af

Please sign in to comment.