From b8d12104b2cf3a1d2d248949d89e87ce7166e303 Mon Sep 17 00:00:00 2001 From: Raghd Hamzeh Date: Wed, 31 Jul 2024 11:56:14 -0400 Subject: [PATCH 1/5] feat: add support for consistency param --- .openapi-generator/FILES | 2 + README.md | 3 +- docs/CheckRequest.md | 1 + docs/ConsistencyPreference.md | 10 ++ docs/ExpandRequest.md | 1 + docs/ListObjectsRequest.md | 1 + docs/ListUsersRequest.md | 1 + docs/OpenFgaApi.md | 8 +- docs/ReadRequest.md | 1 + .../Client/OpenFgaClientTests.cs | 102 +++++++++++++++--- src/OpenFga.Sdk/Api/OpenFgaApi.cs | 2 +- src/OpenFga.Sdk/Client/Client.cs | 27 +++-- .../Client/Model/ClientBatchCheckOptions.cs | 7 +- .../Client/Model/ClientCheckOptions.cs | 10 +- .../Client/Model/ClientConsistencyOptions.cs | 10 ++ .../Client/Model/ClientExpandOptions.cs | 30 ++++++ .../Client/Model/ClientListObjectsOptions.cs | 30 ++++++ .../Model/ClientListRelationsOptions.cs | 5 + .../Client/Model/ClientListUsersOptions.cs | 30 ++++++ .../Client/Model/ClientReadOptions.cs | 7 +- .../ClientRequestOptsWithAuthZModelId.cs | 3 + src/OpenFga.Sdk/Model/CheckRequest.cs | 16 ++- .../Model/ConsistencyPreference.cs | 44 ++++++++ src/OpenFga.Sdk/Model/ExpandRequest.cs | 16 ++- src/OpenFga.Sdk/Model/ListObjectsRequest.cs | 16 ++- src/OpenFga.Sdk/Model/ListUsersRequest.cs | 16 ++- src/OpenFga.Sdk/Model/ReadRequest.cs | 16 ++- 27 files changed, 375 insertions(+), 40 deletions(-) create mode 100644 docs/ConsistencyPreference.md create mode 100644 src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs create mode 100644 src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs create mode 100644 src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs create mode 100644 src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs create mode 100644 src/OpenFga.Sdk/Model/ConsistencyPreference.cs diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index d08e11c..b84768a 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -29,6 +29,7 @@ docs/Computed.md docs/Condition.md docs/ConditionMetadata.md docs/ConditionParamTypeRef.md +docs/ConsistencyPreference.md docs/ContextualTupleKeys.md docs/CreateStoreRequest.md docs/CreateStoreResponse.md @@ -176,6 +177,7 @@ src/OpenFga.Sdk/Model/Computed.cs src/OpenFga.Sdk/Model/Condition.cs src/OpenFga.Sdk/Model/ConditionMetadata.cs src/OpenFga.Sdk/Model/ConditionParamTypeRef.cs +src/OpenFga.Sdk/Model/ConsistencyPreference.cs src/OpenFga.Sdk/Model/ContextualTupleKeys.cs src/OpenFga.Sdk/Model/CreateStoreRequest.cs src/OpenFga.Sdk/Model/CreateStoreResponse.cs diff --git a/README.md b/README.md index 16ff8ca..c809f3a 100644 --- a/README.md +++ b/README.md @@ -832,7 +832,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 | [EXPERIMENTAL] List the users matching the provided filter who have a certain relation to a particular type. | +| [**ListUsers**](docs/OpenFgaApi.md#listusers) | **POST** /stores/{store_id}/list-users | List the users matching the provided filter who have a certain relation to a particular type. | | [**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 | @@ -858,6 +858,7 @@ namespace Example { - [Model.Condition](docs/Condition.md) - [Model.ConditionMetadata](docs/ConditionMetadata.md) - [Model.ConditionParamTypeRef](docs/ConditionParamTypeRef.md) + - [Model.ConsistencyPreference](docs/ConsistencyPreference.md) - [Model.ContextualTupleKeys](docs/ContextualTupleKeys.md) - [Model.CreateStoreRequest](docs/CreateStoreRequest.md) - [Model.CreateStoreResponse](docs/CreateStoreResponse.md) diff --git a/docs/CheckRequest.md b/docs/CheckRequest.md index fa521aa..b511d84 100644 --- a/docs/CheckRequest.md +++ b/docs/CheckRequest.md @@ -9,6 +9,7 @@ Name | Type | Description | Notes **AuthorizationModelId** | **string** | | [optional] **Trace** | **bool** | Defaults to false. Making it true has performance implications. | [optional] [readonly] **Context** | **Object** | Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. | [optional] +**Consistency** | **ConsistencyPreference** | | [optional] [[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md) diff --git a/docs/ConsistencyPreference.md b/docs/ConsistencyPreference.md new file mode 100644 index 0000000..4c95048 --- /dev/null +++ b/docs/ConsistencyPreference.md @@ -0,0 +1,10 @@ +# OpenFga.Sdk.Model.ConsistencyPreference +- UNSPECIFIED: Default if not set. Behavior will be the same as MINIMIZE_LATENCY - MINIMIZE_LATENCY: Minimize latency at the potential expense of lower consistency. - HIGHER_CONSISTENCY: Prefer higher consistency, at the potential expense of increased latency. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/ExpandRequest.md b/docs/ExpandRequest.md index c7c8ea7..f09f08e 100644 --- a/docs/ExpandRequest.md +++ b/docs/ExpandRequest.md @@ -6,6 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **TupleKey** | [**ExpandRequestTupleKey**](ExpandRequestTupleKey.md) | | **AuthorizationModelId** | **string** | | [optional] +**Consistency** | **ConsistencyPreference** | | [optional] [[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md) diff --git a/docs/ListObjectsRequest.md b/docs/ListObjectsRequest.md index 1faa768..3c894a5 100644 --- a/docs/ListObjectsRequest.md +++ b/docs/ListObjectsRequest.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **User** | **string** | | **ContextualTuples** | [**ContextualTupleKeys**](ContextualTupleKeys.md) | | [optional] **Context** | **Object** | Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. | [optional] +**Consistency** | **ConsistencyPreference** | | [optional] [[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md) diff --git a/docs/ListUsersRequest.md b/docs/ListUsersRequest.md index 4436daf..a6ed9b5 100644 --- a/docs/ListUsersRequest.md +++ b/docs/ListUsersRequest.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **UserFilters** | [**List<UserTypeFilter>**](UserTypeFilter.md) | The type of results returned. Only accepts exactly one value. | **ContextualTuples** | [**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] +**Consistency** | **ConsistencyPreference** | | [optional] [[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md) diff --git a/docs/OpenFgaApi.md b/docs/OpenFgaApi.md index f8ddd75..0e34e98 100644 --- a/docs/OpenFgaApi.md +++ b/docs/OpenFgaApi.md @@ -11,7 +11,7 @@ Method | HTTP request | Description [**GetStore**](OpenFgaApi.md#getstore) | **GET** /stores/{store_id} | Get a store [**ListObjects**](OpenFgaApi.md#listobjects) | **POST** /stores/{store_id}/list-objects | List all objects of the given type that the user has a relation with [**ListStores**](OpenFgaApi.md#liststores) | **GET** /stores | List all stores -[**ListUsers**](OpenFgaApi.md#listusers) | **POST** /stores/{store_id}/list-users | [EXPERIMENTAL] List the users matching the provided filter who have a certain relation to a particular type. +[**ListUsers**](OpenFgaApi.md#listusers) | **POST** /stores/{store_id}/list-users | List the users matching the provided filter who have a certain relation to a particular type. [**Read**](OpenFgaApi.md#read) | **POST** /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules [**ReadAssertions**](OpenFgaApi.md#readassertions) | **GET** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID [**ReadAuthorizationModel**](OpenFgaApi.md#readauthorizationmodel) | **GET** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model @@ -579,9 +579,9 @@ Name | Type | Description | Notes # **ListUsers** > ListUsersResponse ListUsers (ListUsersRequest body) -[EXPERIMENTAL] List the users matching the provided filter who have a certain relation to a particular type. +List the users matching the provided filter who have a certain relation to a particular type. -The ListUsers API returns a list of all the users of a specific type that have a relation to a given object. This API is available in an experimental capacity and can be enabled with the `- -experimentals enable-list-users` flag. To arrive at a result, the API uses: an authorization model, explicit tuples written through the Write API, contextual tuples present in the request, and implicit tuples that exist by virtue of applying set theory (such as `document:2021-budget#viewer@document:2021-budget#viewer`; the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`). An `authorization_model_id` may be specified in the body. If it is not specified, the latest authorization model ID will be used. It is strongly recommended to specify authorization model id for better performance. You may also specify `contextual_tuples` that will be treated as regular tuples. Each of these tuples may have an associated `condition`. You may also provide a `context` object that will be used to evaluate the conditioned tuples in the system. It is strongly recommended to provide a value for all the input parameters of all the conditions, to ensure that all tuples be evaluated correctly. The response will contain the related users in an array in the \"users\" field of the response. These results may include specific objects, usersets or type-bound public access. Each of these types of results is encoded in its own type and not represented as a string.In cases where a type-bound public acces result is returned (e.g. `user:*`), it cannot be inferred that all subjects of that type have a relation to the object; it is possible that negations exist and checks should still be queried on individual subjects to ensure access to that document.The number of users in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_USERS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_USERS_MAX_RESULTS, whichever is hit first. The returned users will not be sorted, and therefore two identical calls may yield different sets of users. +The ListUsers API returns a list of all the users of a specific type that have a relation to a given object. To arrive at a result, the API uses: an authorization model, explicit tuples written through the Write API, contextual tuples present in the request, and implicit tuples that exist by virtue of applying set theory (such as `document:2021-budget#viewer@document:2021-budget#viewer`; the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`). An `authorization_model_id` may be specified in the body. If it is not specified, the latest authorization model ID will be used. It is strongly recommended to specify authorization model id for better performance. You may also specify `contextual_tuples` that will be treated as regular tuples. Each of these tuples may have an associated `condition`. You may also provide a `context` object that will be used to evaluate the conditioned tuples in the system. It is strongly recommended to provide a value for all the input parameters of all the conditions, to ensure that all tuples be evaluated correctly. The response will contain the related users in an array in the \"users\" field of the response. These results may include specific objects, usersets or type-bound public access. Each of these types of results is encoded in its own type and not represented as a string.In cases where a type-bound public acces result is returned (e.g. `user:*`), it cannot be inferred that all subjects of that type have a relation to the object; it is possible that negations exist and checks should still be queried on individual subjects to ensure access to that document.The number of users in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_USERS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_USERS_MAX_RESULTS, whichever is hit first. The returned users will not be sorted, and therefore two identical calls may yield different sets of users. ### Example ```csharp @@ -610,7 +610,7 @@ namespace Example try { - // [EXPERIMENTAL] List the users matching the provided filter who have a certain relation to a particular type. + // List the users matching the provided filter who have a certain relation to a particular type. ListUsersResponse response = await openFgaApi.ListUsers(body); Debug.WriteLine(response); } diff --git a/docs/ReadRequest.md b/docs/ReadRequest.md index f097748..6d74edb 100644 --- a/docs/ReadRequest.md +++ b/docs/ReadRequest.md @@ -7,6 +7,7 @@ Name | Type | Description | Notes **TupleKey** | [**ReadRequestTupleKey**](ReadRequestTupleKey.md) | | [optional] **PageSize** | **int** | | [optional] **ContinuationToken** | **string** | | [optional] +**Consistency** | **ConsistencyPreference** | | [optional] [[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md) diff --git a/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs b/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs index 58be0d7..b76d0df 100644 --- a/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs +++ b/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs @@ -994,7 +994,7 @@ public async Task WriteNonTransactionTest() { * Relationship Queries * ************************/ /// - /// Test Batch Check + /// Test Check /// [Fact] public async Task CheckTest() { @@ -1047,6 +1047,65 @@ public async Task CheckTest() { Assert.IsType(response); Assert.True(response.Allowed); } + + /// + /// Test Check with Consistency + /// + [Fact] + public async Task CheckWithConsistencyTest() { + var mockHandler = new Mock(MockBehavior.Strict); + mockHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.Is(req => + req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/check") && + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("MINIMIZE_LATENCY")), + ItExpr.IsAny() + ) + .ReturnsAsync(new HttpResponseMessage() { + StatusCode = HttpStatusCode.OK, + Content = Utils.CreateJsonStringContent(new CheckResponse { Allowed = true }), + }); + + var httpClient = new HttpClient(mockHandler.Object); + var fgaClient = new OpenFgaClient(_config, httpClient); + + var body = new ClientCheckRequest { + User = "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + Relation = "viewer", + Object = "document:roadmap", + ContextualTuples = new List() { + new() { + User = "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + Relation = "editor", + Object = "document:roadmap", + Condition = new RelationshipCondition() { + Name = "ViewCountLessThan200", + Context = new { Name = "Roadmap", Type = "document" } + } + } + }, + Context = new { ViewCount = 100 }, + }; + var options = new ClientCheckOptions { + Consistency = ConsistencyPreference.MINIMIZELATENCY + }; + var response = await fgaClient.Check(body, options); + + mockHandler.Protected().Verify( + "SendAsync", + Times.Exactly(1), + ItExpr.Is(req => + req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/check") && + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("MINIMIZE_LATENCY")), + ItExpr.IsAny() + ); + + Assert.IsType(response); + Assert.True(response.Allowed); + } /// /// Test BatchCheck @@ -1059,7 +1118,8 @@ public async Task BatchCheckTest() { "SendAsync", ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/check") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("HIGHER_CONSISTENCY")), ItExpr.IsAny() ) .Returns(Task.Run(async () => { @@ -1130,7 +1190,9 @@ public async Task BatchCheckTest() { Object = "document:roadmap", } }; - var options = new ClientBatchCheckOptions { }; + var options = new ClientBatchCheckOptions { + Consistency = ConsistencyPreference.HIGHERCONSISTENCY + }; var response = await fgaClient.BatchCheck(body, options); mockHandler.Protected().Verify( @@ -1138,7 +1200,8 @@ public async Task BatchCheckTest() { Times.Exactly(4), ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/check") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("HIGHER_CONSISTENCY")), ItExpr.IsAny() ); @@ -1166,7 +1229,8 @@ public async Task ExpandTest() { "SendAsync", ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/expand") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("HIGHER_CONSISTENCY")), ItExpr.IsAny() ) .ReturnsAsync(new HttpResponseMessage() { @@ -1181,8 +1245,9 @@ public async Task ExpandTest() { Relation = "viewer", Object = "document:roadmap", }; - var response = await fgaClient.Expand(body, new ClientWriteOptions { + var response = await fgaClient.Expand(body, new ClientExpandOptions() { AuthorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1", + Consistency = ConsistencyPreference.HIGHERCONSISTENCY }); mockHandler.Protected().Verify( @@ -1190,7 +1255,8 @@ public async Task ExpandTest() { Times.Exactly(1), ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/expand") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("HIGHER_CONSISTENCY")), ItExpr.IsAny() ); @@ -1254,7 +1320,7 @@ public async Task ExpandComplexResponseTest() { Relation = "viewer", Object = "document:roadmap", }; - var response = await fgaClient.Expand(body, new ClientWriteOptions { + var response = await fgaClient.Expand(body, new ClientExpandOptions { AuthorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1", }); @@ -1283,7 +1349,8 @@ public async Task ListObjectsTest() { "SendAsync", ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/list-objects") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("HIGHER_CONSISTENCY")), ItExpr.IsAny() ) .ReturnsAsync(new HttpResponseMessage() { @@ -1311,8 +1378,9 @@ public async Task ListObjectsTest() { }, }, }; - var response = await fgaClient.ListObjects(body, new ClientWriteOptions { + var response = await fgaClient.ListObjects(body, new ClientListObjectsOptions { AuthorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1", + Consistency = ConsistencyPreference.HIGHERCONSISTENCY }); mockHandler.Protected().Verify( @@ -1320,7 +1388,8 @@ public async Task ListObjectsTest() { Times.Exactly(1), ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/list-objects") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("HIGHER_CONSISTENCY")), ItExpr.IsAny() ); @@ -1340,7 +1409,8 @@ public async Task ListRelationsTest() { "SendAsync", ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/check") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("MINIMIZE_LATENCY")), ItExpr.IsAny() ) .ReturnsAsync(new HttpResponseMessage() { @@ -1376,14 +1446,16 @@ public async Task ListRelationsTest() { } } }; - var response = await fgaClient.ListRelations(body); + var options = new ClientListRelationsOptions { Consistency = ConsistencyPreference.MINIMIZELATENCY }; + var response = await fgaClient.ListRelations(body, options); mockHandler.Protected().Verify( "SendAsync", Times.Exactly(4), ItExpr.Is(req => req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/check") && - req.Method == HttpMethod.Post), + req.Method == HttpMethod.Post && + req.Content.ReadAsStringAsync().Result.Contains("MINIMIZE_LATENCY")), ItExpr.IsAny() ); @@ -1512,7 +1584,7 @@ public async Task ListUsersTest() { Context = new { ViewCount = 100 } }; - var response = await fgaClient.ListUsers(body, new ClientWriteOptions { + var response = await fgaClient.ListUsers(body, new ClientListUsersOptions { AuthorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1", }); diff --git a/src/OpenFga.Sdk/Api/OpenFgaApi.cs b/src/OpenFga.Sdk/Api/OpenFgaApi.cs index 999759d..6e50963 100644 --- a/src/OpenFga.Sdk/Api/OpenFgaApi.cs +++ b/src/OpenFga.Sdk/Api/OpenFgaApi.cs @@ -248,7 +248,7 @@ public async Task ListObjects(string storeId, ListObjectsRe } /// - /// [EXPERIMENTAL] List the users matching the provided filter who have a certain relation to a particular type. The ListUsers API returns a list of all the users of a specific type that have a relation to a given object. This API is available in an experimental capacity and can be enabled with the `- -experimentals enable-list-users` flag. To arrive at a result, the API uses: an authorization model, explicit tuples written through the Write API, contextual tuples present in the request, and implicit tuples that exist by virtue of applying set theory (such as `document:2021-budget#viewer@document:2021-budget#viewer`; the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`). An `authorization_model_id` may be specified in the body. If it is not specified, the latest authorization model ID will be used. It is strongly recommended to specify authorization model id for better performance. You may also specify `contextual_tuples` that will be treated as regular tuples. Each of these tuples may have an associated `condition`. You may also provide a `context` object that will be used to evaluate the conditioned tuples in the system. It is strongly recommended to provide a value for all the input parameters of all the conditions, to ensure that all tuples be evaluated correctly. The response will contain the related users in an array in the \"users\" field of the response. These results may include specific objects, usersets or type-bound public access. Each of these types of results is encoded in its own type and not represented as a string.In cases where a type-bound public acces result is returned (e.g. `user:*`), it cannot be inferred that all subjects of that type have a relation to the object; it is possible that negations exist and checks should still be queried on individual subjects to ensure access to that document.The number of users in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_USERS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_USERS_MAX_RESULTS, whichever is hit first. The returned users will not be sorted, and therefore two identical calls may yield different sets of users. + /// List the users matching the provided filter who have a certain relation to a particular type. The ListUsers API returns a list of all the users of a specific type that have a relation to a given object. To arrive at a result, the API uses: an authorization model, explicit tuples written through the Write API, contextual tuples present in the request, and implicit tuples that exist by virtue of applying set theory (such as `document:2021-budget#viewer@document:2021-budget#viewer`; the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`). An `authorization_model_id` may be specified in the body. If it is not specified, the latest authorization model ID will be used. It is strongly recommended to specify authorization model id for better performance. You may also specify `contextual_tuples` that will be treated as regular tuples. Each of these tuples may have an associated `condition`. You may also provide a `context` object that will be used to evaluate the conditioned tuples in the system. It is strongly recommended to provide a value for all the input parameters of all the conditions, to ensure that all tuples be evaluated correctly. The response will contain the related users in an array in the \"users\" field of the response. These results may include specific objects, usersets or type-bound public access. Each of these types of results is encoded in its own type and not represented as a string.In cases where a type-bound public acces result is returned (e.g. `user:*`), it cannot be inferred that all subjects of that type have a relation to the object; it is possible that negations exist and checks should still be queried on individual subjects to ensure access to that document.The number of users in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_USERS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_USERS_MAX_RESULTS, whichever is hit first. The returned users will not be sorted, and therefore two identical calls may yield different sets of users. /// /// Thrown when fails to make API call /// diff --git a/src/OpenFga.Sdk/Client/Client.cs b/src/OpenFga.Sdk/Client/Client.cs index 4aa62b7..9c9ae94 100644 --- a/src/OpenFga.Sdk/Client/Client.cs +++ b/src/OpenFga.Sdk/Client/Client.cs @@ -182,7 +182,8 @@ public async Task Read(ClientReadRequest? body = default, IClientR new ReadRequest { TupleKey = tupleKey, PageSize = options?.PageSize, - ContinuationToken = options?.ContinuationToken + ContinuationToken = options?.ContinuationToken, + Consistency = options?.Consistency, }, cancellationToken); } @@ -302,7 +303,7 @@ public async Task DeleteTuples(List Check(IClientCheckRequest body, - IClientRequestOptionsWithAuthZModelId? options = default, + IClientCheckOptions? options = default, CancellationToken cancellationToken = default) => await api.Check( GetStoreId(options), @@ -314,7 +315,8 @@ await api.Check( new List() }, Context = body.Context, - AuthorizationModelId = GetAuthorizationModelId(options) + AuthorizationModelId = GetAuthorizationModelId(options), + Consistency = options?.Consistency, }, cancellationToken); /** @@ -347,20 +349,21 @@ await Parallel.ForEachAsync(body, * Expand - Expands the relationships in userset tree format (evaluates) */ public async Task Expand(IClientExpandRequest body, - IClientRequestOptionsWithAuthZModelId? options = default, + IClientExpandOptions? options = default, CancellationToken cancellationToken = default) => await api.Expand( GetStoreId(options), new ExpandRequest { TupleKey = new ExpandRequestTupleKey { Relation = body.Relation, Object = body.Object }, - AuthorizationModelId = GetAuthorizationModelId(options) + AuthorizationModelId = GetAuthorizationModelId(options), + Consistency = options?.Consistency }, cancellationToken); /** * ListObjects - List the objects of a particular type that the user has a certain relation to (evaluates) */ public async Task ListObjects(IClientListObjectsRequest body, - IClientRequestOptionsWithAuthZModelId? options = default, + IClientListObjectsOptions? options = default, CancellationToken cancellationToken = default) => await api.ListObjects(GetStoreId(options), new ListObjectsRequest { User = body.User, @@ -372,8 +375,9 @@ public async Task ListObjects(IClientListObjectsRequest bod new List() }, Context = body.Context, - AuthorizationModelId = GetAuthorizationModelId(options) - }); + AuthorizationModelId = GetAuthorizationModelId(options), + Consistency = options?.Consistency, + }, cancellationToken); /** * ListRelations - List all the relations a user has with an object (evaluates) @@ -414,7 +418,7 @@ public async Task ListRelations(IClientListRelationsReque * ListUsers - List all users of the given type that the object has a relation with (evaluates) */ public async Task ListUsers(IClientListUsersRequest body, - IClientRequestOptionsWithAuthZModelId? options = default, + IClientListUsersOptions? options = default, CancellationToken cancellationToken = default) => await api.ListUsers(GetStoreId(options), new ListUsersRequest { Object = body.Object, @@ -423,8 +427,9 @@ public async Task ListUsers(IClientListUsersRequest body, ContextualTuples = body.ContextualTuples?.ConvertAll(tupleKey => tupleKey.ToTupleKey()) ?? new List(), Context = body.Context, - AuthorizationModelId = GetAuthorizationModelId(options) - }); + AuthorizationModelId = GetAuthorizationModelId(options), + Consistency = options?.Consistency, + }, cancellationToken); /************** * Assertions * diff --git a/src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs index 4680c22..a1d8a10 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs @@ -11,9 +11,11 @@ // +using OpenFga.Sdk.Model; + namespace OpenFga.Sdk.Client.Model; -public interface IClientBatchCheckOptions : IClientRequestOptionsWithAuthZModelId { +public interface IClientBatchCheckOptions : IClientCheckOptions { /// /// Max Requests to issue in parallel /// @@ -31,4 +33,7 @@ public class ClientBatchCheckOptions : IClientBatchCheckOptions { /// Max Requests to issue in parallel /// public int? MaxParallelRequests { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } } \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs index 3f8b90a..9f5af2f 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs @@ -11,12 +11,20 @@ // +using OpenFga.Sdk.Model; + namespace OpenFga.Sdk.Client.Model; -public class ClientCheckOptions : IClientRequestOptionsWithAuthZModelId { +public interface IClientCheckOptions : IClientRequestOptionsWithAuthZModelIdAndConsistency { +} + +public class ClientCheckOptions : IClientCheckOptions { /// public string? StoreId { get; set; } /// public string? AuthorizationModelId { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } } \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs new file mode 100644 index 0000000..6f485a6 --- /dev/null +++ b/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs @@ -0,0 +1,10 @@ +using OpenFga.Sdk.Model; + +namespace OpenFga.Sdk.Client.Model; + +public interface IClientConsistencyOptions { + /// + /// ConsistencyPreference - Can be used to indicate preference for lower latency or higher consistency + /// + public ConsistencyPreference? Consistency { get; set; } +} \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs new file mode 100644 index 0000000..d93c6f1 --- /dev/null +++ b/src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs @@ -0,0 +1,30 @@ +// +// OpenFGA/.NET SDK for OpenFGA +// +// API version: 1.x +// Website: https://openfga.dev +// Documentation: https://openfga.dev/docs +// Support: https://openfga.dev/community +// License: [Apache-2.0](https://github.com/openfga/dotnet-sdk/blob/main/LICENSE) +// +// NOTE: This file was auto generated. DO NOT EDIT. +// + + +using OpenFga.Sdk.Model; + +namespace OpenFga.Sdk.Client.Model; + +public interface IClientExpandOptions : IClientRequestOptionsWithAuthZModelIdAndConsistency { +} + +public class ClientExpandOptions : IClientExpandOptions { + /// + public string? StoreId { get; set; } + + /// + public string? AuthorizationModelId { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } +} \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs new file mode 100644 index 0000000..7dac813 --- /dev/null +++ b/src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs @@ -0,0 +1,30 @@ +// +// OpenFGA/.NET SDK for OpenFGA +// +// API version: 1.x +// Website: https://openfga.dev +// Documentation: https://openfga.dev/docs +// Support: https://openfga.dev/community +// License: [Apache-2.0](https://github.com/openfga/dotnet-sdk/blob/main/LICENSE) +// +// NOTE: This file was auto generated. DO NOT EDIT. +// + + +using OpenFga.Sdk.Model; + +namespace OpenFga.Sdk.Client.Model; + +public interface IClientListObjectsOptions : IClientRequestOptionsWithAuthZModelIdAndConsistency { +} + +public class ClientListObjectsOptions : IClientListObjectsOptions { + /// + public string? StoreId { get; set; } + + /// + public string? AuthorizationModelId { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } +} \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs index c03a3c7..8f59a8f 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs @@ -11,6 +11,8 @@ // +using OpenFga.Sdk.Model; + namespace OpenFga.Sdk.Client.Model; public class ClientListRelationsOptions : IClientBatchCheckOptions { @@ -24,4 +26,7 @@ public class ClientListRelationsOptions : IClientBatchCheckOptions { /// Max Requests to issue in parallel /// public int? MaxParallelRequests { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } } \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs new file mode 100644 index 0000000..cff76c3 --- /dev/null +++ b/src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs @@ -0,0 +1,30 @@ +// +// OpenFGA/.NET SDK for OpenFGA +// +// API version: 1.x +// Website: https://openfga.dev +// Documentation: https://openfga.dev/docs +// Support: https://openfga.dev/community +// License: [Apache-2.0](https://github.com/openfga/dotnet-sdk/blob/main/LICENSE) +// +// NOTE: This file was auto generated. DO NOT EDIT. +// + + +using OpenFga.Sdk.Model; + +namespace OpenFga.Sdk.Client.Model; + +public interface IClientListUsersOptions : IClientRequestOptionsWithAuthZModelIdAndConsistency { +} + +public class ClientListUsersOptions : IClientListUsersOptions { + /// + public string? StoreId { get; set; } + + /// + public string? AuthorizationModelId { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } +} \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs index 2c765ec..2a4e413 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs @@ -11,12 +11,14 @@ // +using OpenFga.Sdk.Model; + namespace OpenFga.Sdk.Client.Model; /// /// ClientReadOptions - Client Options for Read /// -public interface IClientReadOptions : IClientRequestOptionsWithStoreId, ClientPaginationOptions { +public interface IClientReadOptions : IClientRequestOptionsWithStoreId, ClientPaginationOptions, IClientConsistencyOptions { } /// @@ -29,4 +31,7 @@ public class ClientReadOptions : IClientReadOptions { /// public string? ContinuationToken { get; set; } + + /// + public ConsistencyPreference? Consistency { get; set; } } \ No newline at end of file diff --git a/src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithAuthZModelId.cs b/src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithAuthZModelId.cs index d3624c4..4d1da2e 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithAuthZModelId.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithAuthZModelId.cs @@ -15,4 +15,7 @@ namespace OpenFga.Sdk.Client.Model; /// public interface IClientRequestOptionsWithAuthZModelId : IClientRequestOptionsWithStoreId, AuthorizationModelIdOptions { +} + +public interface IClientRequestOptionsWithAuthZModelIdAndConsistency : IClientRequestOptionsWithAuthZModelId, IClientConsistencyOptions { } \ No newline at end of file diff --git a/src/OpenFga.Sdk/Model/CheckRequest.cs b/src/OpenFga.Sdk/Model/CheckRequest.cs index 920c1d1..a907d6d 100644 --- a/src/OpenFga.Sdk/Model/CheckRequest.cs +++ b/src/OpenFga.Sdk/Model/CheckRequest.cs @@ -22,6 +22,13 @@ namespace OpenFga.Sdk.Model { /// [DataContract(Name = "Check_request")] public partial class CheckRequest : IEquatable, IValidatableObject { + + /// + /// Gets or Sets Consistency + /// + [DataMember(Name = "consistency", EmitDefaultValue = false)] + [JsonPropertyName("consistency")] + public ConsistencyPreference? Consistency { get; set; } /// /// Initializes a new instance of the class. /// @@ -37,7 +44,8 @@ public CheckRequest() { /// contextualTuples. /// authorizationModelId. /// Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation.. - public CheckRequest(CheckRequestTupleKey tupleKey = default(CheckRequestTupleKey), ContextualTupleKeys contextualTuples = default(ContextualTupleKeys), string authorizationModelId = default(string), Object context = default(Object)) { + /// consistency. + public CheckRequest(CheckRequestTupleKey tupleKey = default(CheckRequestTupleKey), ContextualTupleKeys contextualTuples = default(ContextualTupleKeys), string authorizationModelId = default(string), Object context = default(Object), ConsistencyPreference? consistency = default(ConsistencyPreference?)) { // to ensure "tupleKey" is required (not null) if (tupleKey == null) { throw new ArgumentNullException("tupleKey is a required property for CheckRequest and cannot be null"); @@ -46,6 +54,7 @@ public CheckRequest() { this.ContextualTuples = contextualTuples; this.AuthorizationModelId = authorizationModelId; this.Context = context; + this.Consistency = consistency; this.AdditionalProperties = new Dictionary(); } @@ -163,6 +172,10 @@ public bool Equals(CheckRequest input) { this.Context == input.Context || (this.Context != null && this.Context.Equals(input.Context)) + ) && + ( + this.Consistency == input.Consistency || + this.Consistency.Equals(input.Consistency) ) && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && !this.AdditionalProperties.Except(input.AdditionalProperties).Any()); } @@ -188,6 +201,7 @@ public override int GetHashCode() { if (this.Context != null) { hashCode = (hashCode * 9923) + this.Context.GetHashCode(); } + hashCode = (hashCode * 9923) + this.Consistency.GetHashCode(); if (this.AdditionalProperties != null) { hashCode = (hashCode * 9923) + this.AdditionalProperties.GetHashCode(); } diff --git a/src/OpenFga.Sdk/Model/ConsistencyPreference.cs b/src/OpenFga.Sdk/Model/ConsistencyPreference.cs new file mode 100644 index 0000000..eb2c556 --- /dev/null +++ b/src/OpenFga.Sdk/Model/ConsistencyPreference.cs @@ -0,0 +1,44 @@ +// +// OpenFGA/.NET SDK for OpenFGA +// +// API version: 1.x +// Website: https://openfga.dev +// Documentation: https://openfga.dev/docs +// Support: https://openfga.dev/community +// License: [Apache-2.0](https://github.com/openfga/dotnet-sdk/blob/main/LICENSE) +// +// NOTE: This file was auto generated. DO NOT EDIT. +// + + +using System.Runtime.Serialization; +using System.Text.Json.Serialization; + +namespace OpenFga.Sdk.Model { + /// + /// - UNSPECIFIED: Default if not set. Behavior will be the same as MINIMIZE_LATENCY - MINIMIZE_LATENCY: Minimize latency at the potential expense of lower consistency. - HIGHER_CONSISTENCY: Prefer higher consistency, at the potential expense of increased latency. + /// + /// - UNSPECIFIED: Default if not set. Behavior will be the same as MINIMIZE_LATENCY - MINIMIZE_LATENCY: Minimize latency at the potential expense of lower consistency. - HIGHER_CONSISTENCY: Prefer higher consistency, at the potential expense of increased latency. + [JsonConverter(typeof(JsonStringEnumMemberConverter))] + public enum ConsistencyPreference { + /// + /// Enum UNSPECIFIED for value: UNSPECIFIED + /// + [EnumMember(Value = "UNSPECIFIED")] + UNSPECIFIED = 1, + + /// + /// Enum MINIMIZELATENCY for value: MINIMIZE_LATENCY + /// + [EnumMember(Value = "MINIMIZE_LATENCY")] + MINIMIZELATENCY = 2, + + /// + /// Enum HIGHERCONSISTENCY for value: HIGHER_CONSISTENCY + /// + [EnumMember(Value = "HIGHER_CONSISTENCY")] + HIGHERCONSISTENCY = 3 + + } + +} \ No newline at end of file diff --git a/src/OpenFga.Sdk/Model/ExpandRequest.cs b/src/OpenFga.Sdk/Model/ExpandRequest.cs index acc4e5c..73a43c7 100644 --- a/src/OpenFga.Sdk/Model/ExpandRequest.cs +++ b/src/OpenFga.Sdk/Model/ExpandRequest.cs @@ -22,6 +22,13 @@ namespace OpenFga.Sdk.Model { /// [DataContract(Name = "Expand_request")] public partial class ExpandRequest : IEquatable, IValidatableObject { + + /// + /// Gets or Sets Consistency + /// + [DataMember(Name = "consistency", EmitDefaultValue = false)] + [JsonPropertyName("consistency")] + public ConsistencyPreference? Consistency { get; set; } /// /// Initializes a new instance of the class. /// @@ -35,13 +42,15 @@ public ExpandRequest() { /// /// tupleKey (required). /// authorizationModelId. - public ExpandRequest(ExpandRequestTupleKey tupleKey = default(ExpandRequestTupleKey), string authorizationModelId = default(string)) { + /// consistency. + public ExpandRequest(ExpandRequestTupleKey tupleKey = default(ExpandRequestTupleKey), string authorizationModelId = default(string), ConsistencyPreference? consistency = default(ConsistencyPreference?)) { // to ensure "tupleKey" is required (not null) if (tupleKey == null) { throw new ArgumentNullException("tupleKey is a required property for ExpandRequest and cannot be null"); } this.TupleKey = tupleKey; this.AuthorizationModelId = authorizationModelId; + this.Consistency = consistency; this.AdditionalProperties = new Dictionary(); } @@ -112,6 +121,10 @@ public bool Equals(ExpandRequest input) { this.AuthorizationModelId == input.AuthorizationModelId || (this.AuthorizationModelId != null && this.AuthorizationModelId.Equals(input.AuthorizationModelId)) + ) && + ( + this.Consistency == input.Consistency || + this.Consistency.Equals(input.Consistency) ) && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && !this.AdditionalProperties.Except(input.AdditionalProperties).Any()); } @@ -130,6 +143,7 @@ public override int GetHashCode() { if (this.AuthorizationModelId != null) { hashCode = (hashCode * 9923) + this.AuthorizationModelId.GetHashCode(); } + hashCode = (hashCode * 9923) + this.Consistency.GetHashCode(); if (this.AdditionalProperties != null) { hashCode = (hashCode * 9923) + this.AdditionalProperties.GetHashCode(); } diff --git a/src/OpenFga.Sdk/Model/ListObjectsRequest.cs b/src/OpenFga.Sdk/Model/ListObjectsRequest.cs index 68afa24..d29b4d3 100644 --- a/src/OpenFga.Sdk/Model/ListObjectsRequest.cs +++ b/src/OpenFga.Sdk/Model/ListObjectsRequest.cs @@ -22,6 +22,13 @@ namespace OpenFga.Sdk.Model { /// [DataContract(Name = "ListObjects_request")] public partial class ListObjectsRequest : IEquatable, IValidatableObject { + + /// + /// Gets or Sets Consistency + /// + [DataMember(Name = "consistency", EmitDefaultValue = false)] + [JsonPropertyName("consistency")] + public ConsistencyPreference? Consistency { get; set; } /// /// Initializes a new instance of the class. /// @@ -39,7 +46,8 @@ public ListObjectsRequest() { /// user (required). /// contextualTuples. /// Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation.. - public ListObjectsRequest(string authorizationModelId = default(string), string type = default(string), string relation = default(string), string user = default(string), ContextualTupleKeys contextualTuples = default(ContextualTupleKeys), Object context = default(Object)) { + /// consistency. + public ListObjectsRequest(string authorizationModelId = default(string), string type = default(string), string relation = default(string), string user = default(string), ContextualTupleKeys contextualTuples = default(ContextualTupleKeys), Object context = default(Object), ConsistencyPreference? consistency = default(ConsistencyPreference?)) { // to ensure "type" is required (not null) if (type == null) { throw new ArgumentNullException("type is a required property for ListObjectsRequest and cannot be null"); @@ -58,6 +66,7 @@ public ListObjectsRequest() { this.AuthorizationModelId = authorizationModelId; this.ContextualTuples = contextualTuples; this.Context = context; + this.Consistency = consistency; this.AdditionalProperties = new Dictionary(); } @@ -181,6 +190,10 @@ public bool Equals(ListObjectsRequest input) { this.Context == input.Context || (this.Context != null && this.Context.Equals(input.Context)) + ) && + ( + this.Consistency == input.Consistency || + this.Consistency.Equals(input.Consistency) ) && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && !this.AdditionalProperties.Except(input.AdditionalProperties).Any()); } @@ -211,6 +224,7 @@ public override int GetHashCode() { if (this.Context != null) { hashCode = (hashCode * 9923) + this.Context.GetHashCode(); } + hashCode = (hashCode * 9923) + this.Consistency.GetHashCode(); if (this.AdditionalProperties != null) { hashCode = (hashCode * 9923) + this.AdditionalProperties.GetHashCode(); } diff --git a/src/OpenFga.Sdk/Model/ListUsersRequest.cs b/src/OpenFga.Sdk/Model/ListUsersRequest.cs index 85751e1..e581658 100644 --- a/src/OpenFga.Sdk/Model/ListUsersRequest.cs +++ b/src/OpenFga.Sdk/Model/ListUsersRequest.cs @@ -22,6 +22,13 @@ namespace OpenFga.Sdk.Model { /// [DataContract(Name = "ListUsers_request")] public partial class ListUsersRequest : IEquatable, IValidatableObject { + + /// + /// Gets or Sets Consistency + /// + [DataMember(Name = "consistency", EmitDefaultValue = false)] + [JsonPropertyName("consistency")] + public ConsistencyPreference? Consistency { get; set; } /// /// Initializes a new instance of the class. /// @@ -39,7 +46,8 @@ public ListUsersRequest() { /// The type of results returned. Only accepts exactly one value. (required). /// contextualTuples. /// Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation.. - public ListUsersRequest(string authorizationModelId = default(string), FgaObject _object = default(FgaObject), string relation = default(string), List userFilters = default(List), List contextualTuples = default(List), Object context = default(Object)) { + /// consistency. + public ListUsersRequest(string authorizationModelId = default(string), FgaObject _object = default(FgaObject), string relation = default(string), List userFilters = default(List), List contextualTuples = default(List), Object context = default(Object), ConsistencyPreference? consistency = default(ConsistencyPreference?)) { // to ensure "_object" is required (not null) if (_object == null) { throw new ArgumentNullException("_object is a required property for ListUsersRequest and cannot be null"); @@ -58,6 +66,7 @@ public ListUsersRequest() { this.AuthorizationModelId = authorizationModelId; this.ContextualTuples = contextualTuples; this.Context = context; + this.Consistency = consistency; this.AdditionalProperties = new Dictionary(); } @@ -184,6 +193,10 @@ public bool Equals(ListUsersRequest input) { this.Context == input.Context || (this.Context != null && this.Context.Equals(input.Context)) + ) && + ( + this.Consistency == input.Consistency || + this.Consistency.Equals(input.Consistency) ) && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && !this.AdditionalProperties.Except(input.AdditionalProperties).Any()); } @@ -214,6 +227,7 @@ public override int GetHashCode() { if (this.Context != null) { hashCode = (hashCode * 9923) + this.Context.GetHashCode(); } + hashCode = (hashCode * 9923) + this.Consistency.GetHashCode(); if (this.AdditionalProperties != null) { hashCode = (hashCode * 9923) + this.AdditionalProperties.GetHashCode(); } diff --git a/src/OpenFga.Sdk/Model/ReadRequest.cs b/src/OpenFga.Sdk/Model/ReadRequest.cs index befdc3a..f605138 100644 --- a/src/OpenFga.Sdk/Model/ReadRequest.cs +++ b/src/OpenFga.Sdk/Model/ReadRequest.cs @@ -22,6 +22,13 @@ namespace OpenFga.Sdk.Model { /// [DataContract(Name = "Read_request")] public partial class ReadRequest : IEquatable, IValidatableObject { + + /// + /// Gets or Sets Consistency + /// + [DataMember(Name = "consistency", EmitDefaultValue = false)] + [JsonPropertyName("consistency")] + public ConsistencyPreference? Consistency { get; set; } /// /// Initializes a new instance of the class. /// @@ -36,10 +43,12 @@ public ReadRequest() { /// tupleKey. /// pageSize. /// continuationToken. - public ReadRequest(ReadRequestTupleKey tupleKey = default(ReadRequestTupleKey), int pageSize = default(int), string continuationToken = default(string)) { + /// consistency. + public ReadRequest(ReadRequestTupleKey tupleKey = default(ReadRequestTupleKey), int pageSize = default(int), string continuationToken = default(string), ConsistencyPreference? consistency = default(ConsistencyPreference?)) { this.TupleKey = tupleKey; this.PageSize = pageSize; this.ContinuationToken = continuationToken; + this.Consistency = consistency; this.AdditionalProperties = new Dictionary(); } @@ -122,6 +131,10 @@ public bool Equals(ReadRequest input) { this.ContinuationToken == input.ContinuationToken || (this.ContinuationToken != null && this.ContinuationToken.Equals(input.ContinuationToken)) + ) && + ( + this.Consistency == input.Consistency || + this.Consistency.Equals(input.Consistency) ) && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && !this.AdditionalProperties.Except(input.AdditionalProperties).Any()); } @@ -141,6 +154,7 @@ public override int GetHashCode() { if (this.ContinuationToken != null) { hashCode = (hashCode * 9923) + this.ContinuationToken.GetHashCode(); } + hashCode = (hashCode * 9923) + this.Consistency.GetHashCode(); if (this.AdditionalProperties != null) { hashCode = (hashCode * 9923) + this.AdditionalProperties.GetHashCode(); } From 013193f451e8625da00beceef72d5d79b59223ca Mon Sep 17 00:00:00 2001 From: Raghd Hamzeh Date: Wed, 31 Jul 2024 12:56:01 -0400 Subject: [PATCH 2/5] fix: patch consistency preference unspecified due to conflict --- src/OpenFga.Sdk/Model/ConsistencyPreference.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenFga.Sdk/Model/ConsistencyPreference.cs b/src/OpenFga.Sdk/Model/ConsistencyPreference.cs index eb2c556..083e5f3 100644 --- a/src/OpenFga.Sdk/Model/ConsistencyPreference.cs +++ b/src/OpenFga.Sdk/Model/ConsistencyPreference.cs @@ -25,7 +25,7 @@ public enum ConsistencyPreference { /// Enum UNSPECIFIED for value: UNSPECIFIED /// [EnumMember(Value = "UNSPECIFIED")] - UNSPECIFIED = 1, + CONSISTENCY_PREFERENCE_UNSPECIFIED = 1, /// /// Enum MINIMIZELATENCY for value: MINIMIZE_LATENCY From 2c678b369d3465c2cf104440eac9a6c14d595f96 Mon Sep 17 00:00:00 2001 From: Jim Anderson Date: Mon, 19 Aug 2024 14:12:10 -0500 Subject: [PATCH 3/5] Revert "fix: patch consistency preference unspecified due to conflict" This reverts commit e7bf34e98dae616e7f0a3d0b53874a574487a579. --- src/OpenFga.Sdk/Model/ConsistencyPreference.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenFga.Sdk/Model/ConsistencyPreference.cs b/src/OpenFga.Sdk/Model/ConsistencyPreference.cs index 083e5f3..eb2c556 100644 --- a/src/OpenFga.Sdk/Model/ConsistencyPreference.cs +++ b/src/OpenFga.Sdk/Model/ConsistencyPreference.cs @@ -25,7 +25,7 @@ public enum ConsistencyPreference { /// Enum UNSPECIFIED for value: UNSPECIFIED /// [EnumMember(Value = "UNSPECIFIED")] - CONSISTENCY_PREFERENCE_UNSPECIFIED = 1, + UNSPECIFIED = 1, /// /// Enum MINIMIZELATENCY for value: MINIMIZE_LATENCY From d6775e3bdb705e711a7508e2548c38f1c3bbdb20 Mon Sep 17 00:00:00 2001 From: Jim Anderson Date: Mon, 19 Aug 2024 16:22:38 -0500 Subject: [PATCH 4/5] handle enums with value same as EnumMember value --- src/OpenFga.Sdk/Model/JsonStringEnumMemberConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenFga.Sdk/Model/JsonStringEnumMemberConverter.cs b/src/OpenFga.Sdk/Model/JsonStringEnumMemberConverter.cs index a7aaf23..8d99d4b 100644 --- a/src/OpenFga.Sdk/Model/JsonStringEnumMemberConverter.cs +++ b/src/OpenFga.Sdk/Model/JsonStringEnumMemberConverter.cs @@ -40,7 +40,7 @@ public JsonStringEnumMemberConverter() { _stringToEnum.Add(value.ToString(), value); - if (attr?.Value != null) { + if (attr?.Value != null && value.ToString() != attr?.Value) { _stringToEnum.Add(attr.Value, value); _enumToString.Add(value, attr.Value); } From fe663b48974fc3bb81e600cce8c9f59e858eaed7 Mon Sep 17 00:00:00 2001 From: Jim Anderson Date: Tue, 20 Aug 2024 12:28:17 -0500 Subject: [PATCH 5/5] from generation --- .openapi-generator/FILES | 4 ++++ src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs | 3 +-- src/OpenFga.Sdk/Client/Client.cs | 5 +++-- .../Client/Model/ClientConsistencyOptions.cs | 13 +++++++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index b84768a..221405f 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -119,14 +119,18 @@ src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs src/OpenFga.Sdk/Client/Model/ClientBatchCheckResponse.cs src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs src/OpenFga.Sdk/Client/Model/ClientCheckRequest.cs +src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs src/OpenFga.Sdk/Client/Model/ClientCreateStoreOptions.cs src/OpenFga.Sdk/Client/Model/ClientCreateStoreRequest.cs +src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs src/OpenFga.Sdk/Client/Model/ClientExpandRequest.cs +src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs src/OpenFga.Sdk/Client/Model/ClientListObjectsRequest.cs 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/ClientListUsersOptions.cs src/OpenFga.Sdk/Client/Model/ClientListUsersRequest.cs src/OpenFga.Sdk/Client/Model/ClientPaginationOptions.cs src/OpenFga.Sdk/Client/Model/ClientReadAssertionsOptions.cs diff --git a/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs b/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs index b76d0df..d7326ff 100644 --- a/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs +++ b/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs @@ -1047,7 +1047,7 @@ public async Task CheckTest() { Assert.IsType(response); Assert.True(response.Allowed); } - + /// /// Test Check with Consistency /// @@ -1106,7 +1106,6 @@ public async Task CheckWithConsistencyTest() { Assert.IsType(response); Assert.True(response.Allowed); } - /// /// Test BatchCheck /// diff --git a/src/OpenFga.Sdk/Client/Client.cs b/src/OpenFga.Sdk/Client/Client.cs index 9c9ae94..05a06aa 100644 --- a/src/OpenFga.Sdk/Client/Client.cs +++ b/src/OpenFga.Sdk/Client/Client.cs @@ -379,6 +379,7 @@ public async Task ListObjects(IClientListObjectsRequest bod Consistency = options?.Consistency, }, cancellationToken); + /** * ListRelations - List all the relations a user has with an object (evaluates) */ @@ -428,8 +429,8 @@ public async Task ListUsers(IClientListUsersRequest body, new List(), Context = body.Context, AuthorizationModelId = GetAuthorizationModelId(options), - Consistency = options?.Consistency, - }, cancellationToken); + Consistency = options?.Consistency + }); /************** * Assertions * diff --git a/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs b/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs index 6f485a6..085069b 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientConsistencyOptions.cs @@ -1,3 +1,16 @@ +// +// OpenFGA/.NET SDK for OpenFGA +// +// API version: 1.x +// Website: https://openfga.dev +// Documentation: https://openfga.dev/docs +// Support: https://openfga.dev/community +// License: [Apache-2.0](https://github.com/openfga/dotnet-sdk/blob/main/LICENSE) +// +// NOTE: This file was auto generated. DO NOT EDIT. +// + + using OpenFga.Sdk.Model; namespace OpenFga.Sdk.Client.Model;