diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index ab398ad..deb5bf5 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -19,6 +19,7 @@ docs/AbortedMessageResponse.md docs/Any.md docs/Assertion.md docs/AssertionTupleKey.md +docs/AuthErrorCode.md docs/AuthorizationModel.md docs/CheckRequest.md docs/CheckRequestTupleKey.md @@ -37,6 +38,7 @@ docs/ExpandRequest.md docs/ExpandRequestTupleKey.md docs/ExpandResponse.md docs/FgaObject.md +docs/ForbiddenResponse.md docs/GetStoreResponse.md docs/InternalErrorCode.md docs/InternalErrorMessageResponse.md @@ -140,6 +142,7 @@ openfga_sdk/models/aborted_message_response.py openfga_sdk/models/any.py openfga_sdk/models/assertion.py openfga_sdk/models/assertion_tuple_key.py +openfga_sdk/models/auth_error_code.py openfga_sdk/models/authorization_model.py openfga_sdk/models/check_request.py openfga_sdk/models/check_request_tuple_key.py @@ -158,6 +161,7 @@ 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/forbidden_response.py openfga_sdk/models/get_store_response.py openfga_sdk/models/internal_error_code.py openfga_sdk/models/internal_error_message_response.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 7522437..2d6bbf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,7 +196,7 @@ Updated to include support for [OpenFGA 0.3.0](https://github.com/openfga/openfg Changes: - [BREAKING] feat(list-objects)!: response has been changed to include the object type - e.g. response that was `{"object_ids":["roadmap"]}`, will now be `{"objects":["document:roadmap"]}` + e.g. response that was `{"object_ids":["roadmap"]}`, will now be `{"objects":["document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"]}` Fixes: - fix(models): update interfaces that had incorrectly optional fields to make them required diff --git a/README.md b/README.md index 50984a8..0fdc2a6 100644 --- a/README.md +++ b/README.md @@ -502,7 +502,7 @@ Reads the relationship tuples stored in the database. It does not evaluate nor e body = ReadRequestTupleKey( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ) response = await fga_client.read(body) @@ -518,7 +518,7 @@ response = await fga_client.read(body) # Find all relationship tuples where a certain user has a relationship as any relation to a certain document body = ReadRequestTupleKey( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ) response = await fga_client.read(body) @@ -551,7 +551,7 @@ response = await fga_client.read(body) # Find all relationship tuples where any user has a relationship as any relation with a particular document body = ReadRequestTupleKey( - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ) response = await fga_client.read(body) @@ -597,7 +597,7 @@ body = ClientWriteRequest( ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", condition=RelationshipCondition( name='ViewCountLessThan200', context=dict( @@ -609,14 +609,14 @@ body = ClientWriteRequest( ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:budget", + object="document:0192ab2d-d36e-7cb3-a4a8-5d1d67a300c5", ), ], deletes=[ ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="writer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ], ) @@ -651,12 +651,12 @@ body = ClientWriteRequest( ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:budget", + object="document:0192ab2d-d36e-7cb3-a4a8-5d1d67a300c5", condition=RelationshipCondition( name='ViewCountLessThan200', context=dict( @@ -670,7 +670,7 @@ body = ClientWriteRequest( ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="writer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ], ) @@ -700,7 +700,7 @@ options = { body = ClientCheckRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="writer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", context=dict( ViewCount=100 ), @@ -731,12 +731,12 @@ options = { body = [ClientCheckRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", contextual_tuples=[ # optional ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="editor", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ], context=dict( @@ -745,22 +745,22 @@ body = [ClientCheckRequest( ), ClientCheckRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="admin", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", contextual_tuples=[ # optional ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="editor", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ] ), ClientCheckRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="creator", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ClientCheckRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="deleter", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", )] response = await fga_client.batch_check(body, options) @@ -769,11 +769,11 @@ response = await fga_client.batch_check(body, options) # request: { # user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", # relation: "viewer", -# object: "document:roadmap", +# object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", # contextual_tuples: [{ # user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", # relation: "editor", -# object: "document:roadmap" +# object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a" # }], # context=dict( # ViewCount=100 @@ -784,11 +784,11 @@ response = await fga_client.batch_check(body, options) # request: { # user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", # relation: "admin", -# object: "document:roadmap", +# object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", # contextual_tuples: [{ # user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", # relation: "editor", -# object: "document:roadmap" +# object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a" # }] # } # }, { @@ -796,7 +796,7 @@ response = await fga_client.batch_check(body, options) # request: { # user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", # relation: "creator", -# object: "document:roadmap", +# object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", # }, # error: # }, { @@ -804,7 +804,7 @@ response = await fga_client.batch_check(body, options) # request: { # user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", # relation: "deleter", -# object: "document:roadmap", +# object: "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", # }}, # ] ``` @@ -828,11 +828,11 @@ options = { } body = ClientExpandRequest( relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ) 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"]})})})})}) +# response = ExpandResponse({"tree": UsersetTree({"root": Node({"name": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a#viewer", "leaf": Leaf({"users": Users({"users": ["user:81684243-9356-4421-8fbf-a4f8d36aa31b", "user:f52a4f7a-054d-47ff-bb6e-3ac81269988f"]})})})})}) ``` #### List Objects @@ -860,7 +860,7 @@ body = ClientListObjectsRequest( ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="writer", - object="document:budget", + object="document:0192ab2d-d36e-7cb3-a4a8-5d1d67a300c5", ), ], context=dict( @@ -869,7 +869,7 @@ body = ClientListObjectsRequest( ) response = await fga_client.list_objects(body) -# response.objects = ["document:roadmap"] +# response.objects = ["document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"] ``` #### List Relations @@ -889,13 +889,13 @@ options = { } body = ClientListRelationsRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", relations=["can_view", "can_edit", "can_delete", "can_rename"], contextual_tuples=[ # optional ClientTuple( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="writer", - object="document:budget", + object="document:0192ab2d-d36e-7cb3-a4a8-5d1d67a300c5", ), ], context=dict( @@ -946,7 +946,7 @@ async with OpenFgaClient(configuration) as api_client: ClientTuple( user="folder:product", relation="parent", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ], ) @@ -999,7 +999,7 @@ options = { body = [ClientAssertion( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", expectation=True, )] @@ -1064,6 +1064,7 @@ Class | Method | HTTP request | Description - [Any](https://github.com/openfga/python-sdk/blob/main/docs/Any.md) - [Assertion](https://github.com/openfga/python-sdk/blob/main/docs/Assertion.md) - [AssertionTupleKey](https://github.com/openfga/python-sdk/blob/main/docs/AssertionTupleKey.md) + - [AuthErrorCode](https://github.com/openfga/python-sdk/blob/main/docs/AuthErrorCode.md) - [AuthorizationModel](https://github.com/openfga/python-sdk/blob/main/docs/AuthorizationModel.md) - [CheckRequest](https://github.com/openfga/python-sdk/blob/main/docs/CheckRequest.md) - [CheckRequestTupleKey](https://github.com/openfga/python-sdk/blob/main/docs/CheckRequestTupleKey.md) @@ -1082,6 +1083,7 @@ Class | Method | HTTP request | Description - [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) + - [ForbiddenResponse](https://github.com/openfga/python-sdk/blob/main/docs/ForbiddenResponse.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) diff --git a/docs/Assertion.md b/docs/Assertion.md index 036ab9a..2347b30 100644 --- a/docs/Assertion.md +++ b/docs/Assertion.md @@ -6,6 +6,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **tuple_key** | [**AssertionTupleKey**](AssertionTupleKey.md) | | **expectation** | **bool** | | +**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) diff --git a/docs/AuthErrorCode.md b/docs/AuthErrorCode.md new file mode 100644 index 0000000..10a9267 --- /dev/null +++ b/docs/AuthErrorCode.md @@ -0,0 +1,10 @@ +# AuthErrorCode + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/ConsistencyPreference.md b/docs/ConsistencyPreference.md index 410472a..ba98a31 100644 --- a/docs/ConsistencyPreference.md +++ b/docs/ConsistencyPreference.md @@ -1,6 +1,6 @@ # 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. +Controls the consistency preferences when calling the query APIs. - 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 diff --git a/docs/ForbiddenResponse.md b/docs/ForbiddenResponse.md new file mode 100644 index 0000000..970f107 --- /dev/null +++ b/docs/ForbiddenResponse.md @@ -0,0 +1,12 @@ +# ForbiddenResponse + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**code** | [**AuthErrorCode**](AuthErrorCode.md) | | [optional] +**message** | **str** | | [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) + + diff --git a/docs/OpenFgaApi.md b/docs/OpenFgaApi.md index 550687d..578bd18 100644 --- a/docs/OpenFgaApi.md +++ b/docs/OpenFgaApi.md @@ -27,7 +27,7 @@ Method | HTTP request | Description Check whether a user is authorized to access an object -The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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 return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. +The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. ### Requesting higher consistency By default, the Check API caches results for a short time to optimize performance. You may request higher consistency to inform the server that higher consistency should be preferred at the expense of increased latency. Care should be taken when requesting higher consistency due to the increased latency. ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"consistency\": \"HIGHER_CONSISTENCY\" } ``` ### Example @@ -98,6 +98,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -179,6 +180,7 @@ No authorization required **201** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -259,6 +261,7 @@ No authorization required **204** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -342,6 +345,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -423,6 +427,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -435,7 +440,7 @@ No authorization required List all objects of the given type that the user has a relation with -The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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 objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. +The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will contain the related objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. ### Example @@ -506,6 +511,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -588,6 +594,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -600,7 +607,7 @@ No authorization required 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. +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 access 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 @@ -671,6 +678,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -754,6 +762,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -766,7 +775,7 @@ No authorization required Read assertions for an authorization model ID -The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. +The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. ### Example @@ -837,6 +846,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -920,6 +930,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -1005,6 +1016,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -1092,6 +1104,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -1175,6 +1188,7 @@ No authorization required **200** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -1187,7 +1201,7 @@ No authorization required Upsert assertions for an authorization model ID -The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. +The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, the expectation of whether a call to the Check API of that tuple key will return true or false, and optionally a list of contextual tuples. ### Example @@ -1259,6 +1273,7 @@ No authorization required **204** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | @@ -1342,6 +1357,7 @@ No authorization required **201** | A successful response. | - | **400** | Request failed due to invalid input. | - | **401** | Not authenticated. | - | +**403** | Forbidden. | - | **404** | Request failed due to incorrect path. | - | **409** | Request was aborted due a transaction conflict. | - | **422** | Request timed out due to excessive request throttling. | - | diff --git a/example/example1/example1.py b/example/example1/example1.py index f7fdd8f..22fddbf 100644 --- a/example/example1/example1.py +++ b/example/example1/example1.py @@ -180,7 +180,7 @@ async def main(): ClientTuple( user="user:anne", relation="writer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", condition=RelationshipCondition( name="ViewCountLessThan200", context=dict( @@ -246,7 +246,9 @@ async def main(): try: response = await fga_client.check( ClientCheckRequest( - user="user:anne", relation="viewer", object="document:roadmap" + user="user:anne", + relation="viewer", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ) ) print(f"Allowed: {response.allowed}") @@ -260,7 +262,7 @@ async def main(): ClientCheckRequest( user="user:anne", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", context=dict(ViewCount=100), ) ) @@ -286,7 +288,7 @@ async def main(): ClientListRelationsRequest( user="user:anne", relations=["viewer", "writer"], - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ) ) print(f"Relations: {response}") @@ -298,7 +300,7 @@ async def main(): ClientListRelationsRequest( user="user:anne", relations=["viewer", "writer"], - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", context=dict(ViewCount=100), ) ) @@ -331,7 +333,7 @@ async def main(): ClientAssertion( user="user:anne", relation="viewer", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", expectation=False, ), ] diff --git a/openfga_sdk/__init__.py b/openfga_sdk/__init__.py index b04feb6..1eaf1e5 100644 --- a/openfga_sdk/__init__.py +++ b/openfga_sdk/__init__.py @@ -29,6 +29,7 @@ from openfga_sdk.models.any import Any from openfga_sdk.models.assertion import Assertion from openfga_sdk.models.assertion_tuple_key import AssertionTupleKey +from openfga_sdk.models.auth_error_code import AuthErrorCode from openfga_sdk.models.authorization_model import AuthorizationModel from openfga_sdk.models.check_request import CheckRequest from openfga_sdk.models.check_request_tuple_key import CheckRequestTupleKey @@ -47,6 +48,7 @@ from openfga_sdk.models.expand_request_tuple_key import ExpandRequestTupleKey from openfga_sdk.models.expand_response import ExpandResponse from openfga_sdk.models.fga_object import FgaObject +from openfga_sdk.models.forbidden_response import ForbiddenResponse from openfga_sdk.models.get_store_response import GetStoreResponse from openfga_sdk.models.internal_error_code import InternalErrorCode from openfga_sdk.models.internal_error_message_response import ( diff --git a/openfga_sdk/api/open_fga_api.py b/openfga_sdk/api/open_fga_api.py index c3b0ece..c4ddaaa 100644 --- a/openfga_sdk/api/open_fga_api.py +++ b/openfga_sdk/api/open_fga_api.py @@ -51,7 +51,7 @@ async def close(self): async def check(self, body, **kwargs): """Check whether a user is authorized to access an object - The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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 return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. + The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. ### Requesting higher consistency By default, the Check API caches results for a short time to optimize performance. You may request higher consistency to inform the server that higher consistency should be preferred at the expense of increased latency. Care should be taken when requesting higher consistency due to the increased latency. ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"consistency\": \"HIGHER_CONSISTENCY\" } ``` >>> thread = await api.check(body) @@ -78,7 +78,7 @@ async def check(self, body, **kwargs): async def check_with_http_info(self, body, **kwargs): """Check whether a user is authorized to access an object - The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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 return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. + The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. ### Requesting higher consistency By default, the Check API caches results for a short time to optimize performance. You may request higher consistency to inform the server that higher consistency should be preferred at the expense of increased latency. Care should be taken when requesting higher consistency due to the increased latency. ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"consistency\": \"HIGHER_CONSISTENCY\" } ``` >>> thread = api.check_with_http_info(body) @@ -185,6 +185,7 @@ async def check_with_http_info(self, body, **kwargs): 200: "CheckResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -345,6 +346,7 @@ async def create_store_with_http_info(self, body, **kwargs): 201: "CreateStoreResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -660,6 +662,7 @@ async def expand_with_http_info(self, body, **kwargs): 200: "ExpandResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -810,6 +813,7 @@ async def get_store_with_http_info(self, **kwargs): 200: "GetStoreResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -849,7 +853,7 @@ async def get_store_with_http_info(self, **kwargs): async def list_objects(self, body, **kwargs): """List all objects of the given type that the user has a relation with - The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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 objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. + The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will contain the related objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. >>> thread = await api.list_objects(body) @@ -876,7 +880,7 @@ async def list_objects(self, body, **kwargs): async def list_objects_with_http_info(self, body, **kwargs): """List all objects of the given type that the user has a relation with - The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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 objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. + The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will contain the related objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. >>> thread = api.list_objects_with_http_info(body) @@ -984,6 +988,7 @@ async def list_objects_with_http_info(self, body, **kwargs): 200: "ListObjectsResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1142,6 +1147,7 @@ async def list_stores_with_http_info(self, **kwargs): 200: "ListStoresResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1181,7 +1187,7 @@ async def list_stores_with_http_info(self, **kwargs): async def list_users(self, body, **kwargs): """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. + 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 access 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. >>> thread = await api.list_users(body) @@ -1208,7 +1214,7 @@ async def list_users(self, body, **kwargs): async def list_users_with_http_info(self, body, **kwargs): """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. + 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 access 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. >>> thread = api.list_users_with_http_info(body) @@ -1316,6 +1322,7 @@ async def list_users_with_http_info(self, body, **kwargs): 200: "ListUsersResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1489,6 +1496,7 @@ async def read_with_http_info(self, body, **kwargs): 200: "ReadResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1528,7 +1536,7 @@ async def read_with_http_info(self, body, **kwargs): async def read_assertions(self, authorization_model_id, **kwargs): """Read assertions for an authorization model ID - The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. >>> thread = await api.read_assertions(authorization_model_id) @@ -1557,7 +1565,7 @@ async def read_assertions(self, authorization_model_id, **kwargs): async def read_assertions_with_http_info(self, authorization_model_id, **kwargs): """Read assertions for an authorization model ID - The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. >>> thread = api.read_assertions_with_http_info(authorization_model_id) @@ -1658,6 +1666,7 @@ async def read_assertions_with_http_info(self, authorization_model_id, **kwargs) 200: "ReadAssertionsResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1825,6 +1834,7 @@ async def read_authorization_model_with_http_info(self, id, **kwargs): 200: "ReadAuthorizationModelResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1991,6 +2001,7 @@ async def read_authorization_models_with_http_info(self, **kwargs): 200: "ReadAuthorizationModelsResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -2161,6 +2172,7 @@ async def read_changes_with_http_info(self, **kwargs): 200: "ReadChangesResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -2334,6 +2346,7 @@ async def write_with_http_info(self, body, **kwargs): 200: "object", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -2373,7 +2386,7 @@ async def write_with_http_info(self, body, **kwargs): async def write_assertions(self, authorization_model_id, body, **kwargs): """Upsert assertions for an authorization model ID - The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, the expectation of whether a call to the Check API of that tuple key will return true or false, and optionally a list of contextual tuples. >>> thread = await api.write_assertions(authorization_model_id, body) @@ -2406,7 +2419,7 @@ async def write_assertions_with_http_info( ): """Upsert assertions for an authorization model ID - The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, the expectation of whether a call to the Check API of that tuple key will return true or false, and optionally a list of contextual tuples. >>> thread = api.write_assertions_with_http_info(authorization_model_id, body) @@ -2697,6 +2710,7 @@ async def write_authorization_model_with_http_info(self, body, **kwargs): 201: "WriteAuthorizationModelResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", diff --git a/openfga_sdk/models/__init__.py b/openfga_sdk/models/__init__.py index d7c8c92..9c970e7 100644 --- a/openfga_sdk/models/__init__.py +++ b/openfga_sdk/models/__init__.py @@ -14,6 +14,7 @@ from openfga_sdk.models.any import Any from openfga_sdk.models.assertion import Assertion from openfga_sdk.models.assertion_tuple_key import AssertionTupleKey +from openfga_sdk.models.auth_error_code import AuthErrorCode from openfga_sdk.models.authorization_model import AuthorizationModel from openfga_sdk.models.check_request import CheckRequest from openfga_sdk.models.check_request_tuple_key import CheckRequestTupleKey @@ -32,6 +33,7 @@ from openfga_sdk.models.expand_request_tuple_key import ExpandRequestTupleKey from openfga_sdk.models.expand_response import ExpandResponse from openfga_sdk.models.fga_object import FgaObject +from openfga_sdk.models.forbidden_response import ForbiddenResponse from openfga_sdk.models.get_store_response import GetStoreResponse from openfga_sdk.models.internal_error_code import InternalErrorCode from openfga_sdk.models.internal_error_message_response import ( diff --git a/openfga_sdk/models/assertion.py b/openfga_sdk/models/assertion.py index a404928..e7d833d 100644 --- a/openfga_sdk/models/assertion.py +++ b/openfga_sdk/models/assertion.py @@ -33,11 +33,28 @@ class Assertion: attribute_map (dict): The key is attribute name and the value is json key in definition. """ - openapi_types = {"tuple_key": "AssertionTupleKey", "expectation": "bool"} - - attribute_map = {"tuple_key": "tuple_key", "expectation": "expectation"} - - def __init__(self, tuple_key=None, expectation=None, local_vars_configuration=None): + openapi_types = { + "tuple_key": "AssertionTupleKey", + "expectation": "bool", + "contextual_tuples": "list[TupleKey]", + "context": "object", + } + + attribute_map = { + "tuple_key": "tuple_key", + "expectation": "expectation", + "contextual_tuples": "contextual_tuples", + "context": "context", + } + + def __init__( + self, + tuple_key=None, + expectation=None, + contextual_tuples=None, + context=None, + local_vars_configuration=None, + ): """Assertion - a model defined in OpenAPI""" if local_vars_configuration is None: local_vars_configuration = Configuration.get_default_copy() @@ -45,10 +62,16 @@ def __init__(self, tuple_key=None, expectation=None, local_vars_configuration=No self._tuple_key = None self._expectation = None + self._contextual_tuples = None + self._context = None self.discriminator = None self.tuple_key = tuple_key self.expectation = expectation + if contextual_tuples is not None: + self.contextual_tuples = contextual_tuples + if context is not None: + self.context = context @property def tuple_key(self): @@ -96,6 +119,58 @@ def expectation(self, expectation): self._expectation = expectation + @property + def contextual_tuples(self): + """Gets the contextual_tuples of this Assertion. + + + :return: The contextual_tuples of this Assertion. + :rtype: list[TupleKey] + """ + return self._contextual_tuples + + @contextual_tuples.setter + def contextual_tuples(self, contextual_tuples): + """Sets the contextual_tuples of this Assertion. + + + :param contextual_tuples: The contextual_tuples of this Assertion. + :type contextual_tuples: list[TupleKey] + """ + if ( + self.local_vars_configuration.client_side_validation + and contextual_tuples is not None + and len(contextual_tuples) > 20 + ): + raise ValueError( + "Invalid value for `contextual_tuples`, number of items must be less than or equal to `20`" + ) + + self._contextual_tuples = contextual_tuples + + @property + def context(self): + """Gets the context of this Assertion. + + Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. + + :return: The context of this Assertion. + :rtype: object + """ + return self._context + + @context.setter + def context(self, context): + """Sets the context of this Assertion. + + Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. + + :param context: The context of this Assertion. + :type context: object + """ + + self._context = context + def to_dict(self, serialize=False): """Returns the model properties as a dict""" result = {} diff --git a/openfga_sdk/models/auth_error_code.py b/openfga_sdk/models/auth_error_code.py new file mode 100644 index 0000000..64a6f30 --- /dev/null +++ b/openfga_sdk/models/auth_error_code.py @@ -0,0 +1,120 @@ +""" + Python 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/python-sdk/blob/main/LICENSE) + + NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. +""" + +try: + from inspect import getfullargspec +except ImportError: + from inspect import getargspec as getfullargspec +import pprint + +from openfga_sdk.configuration import Configuration + + +class AuthErrorCode: + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + """ + allowed enum values + """ + NO_AUTH_ERROR = "no_auth_error" + AUTH_FAILED_INVALID_SUBJECT = "auth_failed_invalid_subject" + AUTH_FAILED_INVALID_AUDIENCE = "auth_failed_invalid_audience" + AUTH_FAILED_INVALID_ISSUER = "auth_failed_invalid_issuer" + INVALID_CLAIMS = "invalid_claims" + AUTH_FAILED_INVALID_BEARER_TOKEN = "auth_failed_invalid_bearer_token" + BEARER_TOKEN_MISSING = "bearer_token_missing" + UNAUTHENTICATED = "unauthenticated" + FORBIDDEN = "forbidden" + + allowable_values = [ + NO_AUTH_ERROR, + AUTH_FAILED_INVALID_SUBJECT, + AUTH_FAILED_INVALID_AUDIENCE, + AUTH_FAILED_INVALID_ISSUER, + INVALID_CLAIMS, + AUTH_FAILED_INVALID_BEARER_TOKEN, + BEARER_TOKEN_MISSING, + UNAUTHENTICATED, + FORBIDDEN, + ] + + """ + Attributes: + openapi_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + openapi_types = {} + + attribute_map = {} + + def __init__(self, local_vars_configuration=None): + """AuthErrorCode - a model defined in OpenAPI""" + if local_vars_configuration is None: + local_vars_configuration = Configuration.get_default_copy() + self.local_vars_configuration = local_vars_configuration + self.discriminator = None + + def to_dict(self, serialize=False): + """Returns the model properties as a dict""" + result = {} + + def convert(x): + if hasattr(x, "to_dict"): + args = getfullargspec(x.to_dict).args + if len(args) == 1: + return x.to_dict() + else: + return x.to_dict(serialize) + else: + return x + + for attr, _ in self.openapi_types.items(): + value = getattr(self, attr) + attr = self.attribute_map.get(attr, attr) if serialize else attr + if isinstance(value, list): + result[attr] = list(map(lambda x: convert(x), value)) + elif isinstance(value, dict): + result[attr] = dict( + map(lambda item: (item[0], convert(item[1])), value.items()) + ) + else: + result[attr] = convert(value) + + return result + + def to_str(self): + """Returns the string representation of the model""" + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + if not isinstance(other, AuthErrorCode): + return False + + return self.to_dict() == other.to_dict() + + def __ne__(self, other): + """Returns true if both objects are not equal""" + if not isinstance(other, AuthErrorCode): + return True + + return self.to_dict() != other.to_dict() diff --git a/openfga_sdk/models/contextual_tuple_keys.py b/openfga_sdk/models/contextual_tuple_keys.py index ac73088..39759c3 100644 --- a/openfga_sdk/models/contextual_tuple_keys.py +++ b/openfga_sdk/models/contextual_tuple_keys.py @@ -68,6 +68,14 @@ def tuple_keys(self, tuple_keys): """ if self.local_vars_configuration.client_side_validation and tuple_keys is None: raise ValueError("Invalid value for `tuple_keys`, must not be `None`") + if ( + self.local_vars_configuration.client_side_validation + and tuple_keys is not None + and len(tuple_keys) > 100 + ): + raise ValueError( + "Invalid value for `tuple_keys`, number of items must be less than or equal to `100`" + ) self._tuple_keys = tuple_keys diff --git a/openfga_sdk/models/error_code.py b/openfga_sdk/models/error_code.py index aadaf74..45da702 100644 --- a/openfga_sdk/models/error_code.py +++ b/openfga_sdk/models/error_code.py @@ -89,6 +89,7 @@ class ErrorCode: DUPLICATE_CONTEXTUAL_TUPLE = "duplicate_contextual_tuple" INVALID_AUTHORIZATION_MODEL = "invalid_authorization_model" UNSUPPORTED_SCHEMA_VERSION = "unsupported_schema_version" + CANCELLED = "cancelled" allowable_values = [ NO_ERROR, @@ -139,6 +140,7 @@ class ErrorCode: DUPLICATE_CONTEXTUAL_TUPLE, INVALID_AUTHORIZATION_MODEL, UNSUPPORTED_SCHEMA_VERSION, + CANCELLED, ] """ diff --git a/openfga_sdk/models/forbidden_response.py b/openfga_sdk/models/forbidden_response.py new file mode 100644 index 0000000..5cd19ed --- /dev/null +++ b/openfga_sdk/models/forbidden_response.py @@ -0,0 +1,145 @@ +""" + Python 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/python-sdk/blob/main/LICENSE) + + NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. +""" + +try: + from inspect import getfullargspec +except ImportError: + from inspect import getargspec as getfullargspec +import pprint + +from openfga_sdk.configuration import Configuration + + +class ForbiddenResponse: + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + """ + Attributes: + openapi_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + openapi_types = {"code": "AuthErrorCode", "message": "str"} + + attribute_map = {"code": "code", "message": "message"} + + def __init__(self, code=None, message=None, local_vars_configuration=None): + """ForbiddenResponse - a model defined in OpenAPI""" + if local_vars_configuration is None: + local_vars_configuration = Configuration.get_default_copy() + self.local_vars_configuration = local_vars_configuration + + self._code = None + self._message = None + self.discriminator = None + + if code is not None: + self.code = code + if message is not None: + self.message = message + + @property + def code(self): + """Gets the code of this ForbiddenResponse. + + + :return: The code of this ForbiddenResponse. + :rtype: AuthErrorCode + """ + return self._code + + @code.setter + def code(self, code): + """Sets the code of this ForbiddenResponse. + + + :param code: The code of this ForbiddenResponse. + :type code: AuthErrorCode + """ + + self._code = code + + @property + def message(self): + """Gets the message of this ForbiddenResponse. + + + :return: The message of this ForbiddenResponse. + :rtype: str + """ + return self._message + + @message.setter + def message(self, message): + """Sets the message of this ForbiddenResponse. + + + :param message: The message of this ForbiddenResponse. + :type message: str + """ + + self._message = message + + def to_dict(self, serialize=False): + """Returns the model properties as a dict""" + result = {} + + def convert(x): + if hasattr(x, "to_dict"): + args = getfullargspec(x.to_dict).args + if len(args) == 1: + return x.to_dict() + else: + return x.to_dict(serialize) + else: + return x + + for attr, _ in self.openapi_types.items(): + value = getattr(self, attr) + attr = self.attribute_map.get(attr, attr) if serialize else attr + if isinstance(value, list): + result[attr] = list(map(lambda x: convert(x), value)) + elif isinstance(value, dict): + result[attr] = dict( + map(lambda item: (item[0], convert(item[1])), value.items()) + ) + else: + result[attr] = convert(value) + + return result + + def to_str(self): + """Returns the string representation of the model""" + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + if not isinstance(other, ForbiddenResponse): + return False + + return self.to_dict() == other.to_dict() + + def __ne__(self, other): + """Returns true if both objects are not equal""" + if not isinstance(other, ForbiddenResponse): + return True + + return self.to_dict() != other.to_dict() diff --git a/openfga_sdk/models/internal_error_code.py b/openfga_sdk/models/internal_error_code.py index dec0a87..1dd969d 100644 --- a/openfga_sdk/models/internal_error_code.py +++ b/openfga_sdk/models/internal_error_code.py @@ -31,7 +31,6 @@ class InternalErrorCode: """ NO_INTERNAL_ERROR = "no_internal_error" INTERNAL_ERROR = "internal_error" - CANCELLED = "cancelled" DEADLINE_EXCEEDED = "deadline_exceeded" ALREADY_EXISTS = "already_exists" RESOURCE_EXHAUSTED = "resource_exhausted" @@ -44,7 +43,6 @@ class InternalErrorCode: allowable_values = [ NO_INTERNAL_ERROR, INTERNAL_ERROR, - CANCELLED, DEADLINE_EXCEEDED, ALREADY_EXISTS, RESOURCE_EXHAUSTED, diff --git a/openfga_sdk/models/list_users_request.py b/openfga_sdk/models/list_users_request.py index 27422e2..6405fe8 100644 --- a/openfga_sdk/models/list_users_request.py +++ b/openfga_sdk/models/list_users_request.py @@ -182,6 +182,22 @@ def user_filters(self, user_filters): and user_filters is None ): raise ValueError("Invalid value for `user_filters`, must not be `None`") + if ( + self.local_vars_configuration.client_side_validation + and user_filters is not None + and len(user_filters) > 1 + ): + raise ValueError( + "Invalid value for `user_filters`, number of items must be less than or equal to `1`" + ) + if ( + self.local_vars_configuration.client_side_validation + and user_filters is not None + and len(user_filters) < 1 + ): + raise ValueError( + "Invalid value for `user_filters`, number of items must be greater than or equal to `1`" + ) self._user_filters = user_filters @@ -203,6 +219,14 @@ def contextual_tuples(self, contextual_tuples): :param contextual_tuples: The contextual_tuples of this ListUsersRequest. :type contextual_tuples: list[TupleKey] """ + if ( + self.local_vars_configuration.client_side_validation + and contextual_tuples is not None + and len(contextual_tuples) > 100 + ): + raise ValueError( + "Invalid value for `contextual_tuples`, number of items must be less than or equal to `100`" + ) self._contextual_tuples = contextual_tuples diff --git a/openfga_sdk/models/read_request.py b/openfga_sdk/models/read_request.py index 451677d..8158282 100644 --- a/openfga_sdk/models/read_request.py +++ b/openfga_sdk/models/read_request.py @@ -114,6 +114,22 @@ def page_size(self, page_size): :param page_size: The page_size of this ReadRequest. :type page_size: int """ + if ( + self.local_vars_configuration.client_side_validation + and page_size is not None + and page_size > 100 + ): + raise ValueError( + "Invalid value for `page_size`, must be a value less than or equal to `100`" + ) + if ( + self.local_vars_configuration.client_side_validation + and page_size is not None + and page_size < 1 + ): + raise ValueError( + "Invalid value for `page_size`, must be a value greater than or equal to `1`" + ) self._page_size = page_size diff --git a/openfga_sdk/models/write_assertions_request.py b/openfga_sdk/models/write_assertions_request.py index 4fad43c..9d4b043 100644 --- a/openfga_sdk/models/write_assertions_request.py +++ b/openfga_sdk/models/write_assertions_request.py @@ -68,6 +68,14 @@ def assertions(self, assertions): """ if self.local_vars_configuration.client_side_validation and assertions is None: raise ValueError("Invalid value for `assertions`, must not be `None`") + if ( + self.local_vars_configuration.client_side_validation + and assertions is not None + and len(assertions) > 100 + ): + raise ValueError( + "Invalid value for `assertions`, number of items must be less than or equal to `100`" + ) self._assertions = assertions diff --git a/openfga_sdk/models/write_authorization_model_request.py b/openfga_sdk/models/write_authorization_model_request.py index 68c3b0c..7668086 100644 --- a/openfga_sdk/models/write_authorization_model_request.py +++ b/openfga_sdk/models/write_authorization_model_request.py @@ -90,6 +90,14 @@ def type_definitions(self, type_definitions): and type_definitions is None ): raise ValueError("Invalid value for `type_definitions`, must not be `None`") + if ( + self.local_vars_configuration.client_side_validation + and type_definitions is not None + and len(type_definitions) < 1 + ): + raise ValueError( + "Invalid value for `type_definitions`, number of items must be greater than or equal to `1`" + ) self._type_definitions = type_definitions diff --git a/openfga_sdk/models/write_request_deletes.py b/openfga_sdk/models/write_request_deletes.py index 915d5f7..2ea7060 100644 --- a/openfga_sdk/models/write_request_deletes.py +++ b/openfga_sdk/models/write_request_deletes.py @@ -68,6 +68,14 @@ def tuple_keys(self, tuple_keys): """ if self.local_vars_configuration.client_side_validation and tuple_keys is None: raise ValueError("Invalid value for `tuple_keys`, must not be `None`") + if ( + self.local_vars_configuration.client_side_validation + and tuple_keys is not None + and len(tuple_keys) < 1 + ): + raise ValueError( + "Invalid value for `tuple_keys`, number of items must be greater than or equal to `1`" + ) self._tuple_keys = tuple_keys diff --git a/openfga_sdk/models/write_request_writes.py b/openfga_sdk/models/write_request_writes.py index bb044ae..79f50b4 100644 --- a/openfga_sdk/models/write_request_writes.py +++ b/openfga_sdk/models/write_request_writes.py @@ -68,6 +68,14 @@ def tuple_keys(self, tuple_keys): """ if self.local_vars_configuration.client_side_validation and tuple_keys is None: raise ValueError("Invalid value for `tuple_keys`, must not be `None`") + if ( + self.local_vars_configuration.client_side_validation + and tuple_keys is not None + and len(tuple_keys) < 1 + ): + raise ValueError( + "Invalid value for `tuple_keys`, number of items must be greater than or equal to `1`" + ) self._tuple_keys = tuple_keys diff --git a/openfga_sdk/sync/open_fga_api.py b/openfga_sdk/sync/open_fga_api.py index 8c7fb39..b12230d 100644 --- a/openfga_sdk/sync/open_fga_api.py +++ b/openfga_sdk/sync/open_fga_api.py @@ -49,7 +49,7 @@ def close(self): def check(self, body, **kwargs): """Check whether a user is authorized to access an object - The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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 return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. + The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. ### Requesting higher consistency By default, the Check API caches results for a short time to optimize performance. You may request higher consistency to inform the server that higher consistency should be preferred at the expense of increased latency. Care should be taken when requesting higher consistency due to the increased latency. ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"consistency\": \"HIGHER_CONSISTENCY\" } ``` >>> thread = api.check(body) @@ -76,7 +76,7 @@ def check(self, body, **kwargs): def check_with_http_info(self, body, **kwargs): """Check whether a user is authorized to access an object - The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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 return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. + The Check API returns whether a given user has a relationship with a given object in a given store. The `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`. 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`). A `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`. You may also provide an `authorization_model_id` in the body. This will be used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion will be made against the latest authorization model ID. It is strongly recommended to specify authorization model id for better performance. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will return whether the relationship exists in the field `allowed`. Some exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. For example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response. ## Examples ### Querying with contextual tuples In order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple ```json { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ``` the Check API can be used with the following request body: ```json { \"tuple_key\": { \"user\": \"user:anne\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"time_slot:office_hours\" } ] }, \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\" } ``` ### Querying usersets Some Checks will always return `true`, even without any tuples. For example, for the following authorization model ```python model schema 1.1 type user type document relations define reader: [user] ``` the following query ```json { \"tuple_key\": { \"user\": \"document:2021-budget#reader\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" } } ``` will always return `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` will always have the `reader` relation with `document:2021-budget`. ### Querying usersets with difference in the model A Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model ```python model schema 1.1 type user type group relations define member: [user] type document relations define blocked: [user] define reader: [group#member] but not blocked ``` the following query ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"contextual_tuples\": { \"tuple_keys\": [ { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"group:finance\" }, { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, { \"user\": \"user:anne\", \"relation\": \"blocked\", \"object\": \"document:2021-budget\" } ] }, } ``` will return `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object. ### Requesting higher consistency By default, the Check API caches results for a short time to optimize performance. You may request higher consistency to inform the server that higher consistency should be preferred at the expense of increased latency. Care should be taken when requesting higher consistency due to the increased latency. ```json { \"tuple_key\": { \"user\": \"group:finance#member\", \"relation\": \"reader\", \"object\": \"document:2021-budget\" }, \"consistency\": \"HIGHER_CONSISTENCY\" } ``` >>> thread = api.check_with_http_info(body) @@ -183,6 +183,7 @@ def check_with_http_info(self, body, **kwargs): 200: "CheckResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -343,6 +344,7 @@ def create_store_with_http_info(self, body, **kwargs): 201: "CreateStoreResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -658,6 +660,7 @@ def expand_with_http_info(self, body, **kwargs): 200: "ExpandResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -808,6 +811,7 @@ def get_store_with_http_info(self, **kwargs): 200: "GetStoreResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -847,7 +851,7 @@ def get_store_with_http_info(self, **kwargs): def list_objects(self, body, **kwargs): """List all objects of the given type that the user has a relation with - The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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 objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. + The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will contain the related objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. >>> thread = api.list_objects(body) @@ -874,7 +878,7 @@ def list_objects(self, body, **kwargs): def list_objects_with_http_info(self, body, **kwargs): """List all objects of the given type that the user has a relation with - The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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 objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. + The ListObjects API returns a list of all the objects of the given type that the user has a relation with. 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. By default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency. The response will contain the related objects in an array in the \"objects\" field of the response and they will be strings in the object format `:` (e.g. \"document:roadmap\"). The number of objects in the response array will be limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE and by the upper bound specified in the flag OPENFGA_LIST_OBJECTS_MAX_RESULTS, whichever is hit first. The objects given will not be sorted, and therefore two identical calls can give a given different set of objects. >>> thread = api.list_objects_with_http_info(body) @@ -982,6 +986,7 @@ def list_objects_with_http_info(self, body, **kwargs): 200: "ListObjectsResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1140,6 +1145,7 @@ def list_stores_with_http_info(self, **kwargs): 200: "ListStoresResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1179,7 +1185,7 @@ def list_stores_with_http_info(self, **kwargs): def list_users(self, body, **kwargs): """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. + 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 access 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. >>> thread = api.list_users(body) @@ -1206,7 +1212,7 @@ def list_users(self, body, **kwargs): def list_users_with_http_info(self, body, **kwargs): """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. + 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 access 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. >>> thread = api.list_users_with_http_info(body) @@ -1314,6 +1320,7 @@ def list_users_with_http_info(self, body, **kwargs): 200: "ListUsersResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1487,6 +1494,7 @@ def read_with_http_info(self, body, **kwargs): 200: "ReadResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1526,7 +1534,7 @@ def read_with_http_info(self, body, **kwargs): def read_assertions(self, authorization_model_id, **kwargs): """Read assertions for an authorization model ID - The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. >>> thread = api.read_assertions(authorization_model_id) @@ -1553,7 +1561,7 @@ def read_assertions(self, authorization_model_id, **kwargs): def read_assertions_with_http_info(self, authorization_model_id, **kwargs): """Read assertions for an authorization model ID - The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The ReadAssertions API will return, for a given authorization model id, all the assertions stored for it. >>> thread = api.read_assertions_with_http_info(authorization_model_id) @@ -1654,6 +1662,7 @@ def read_assertions_with_http_info(self, authorization_model_id, **kwargs): 200: "ReadAssertionsResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1821,6 +1830,7 @@ def read_authorization_model_with_http_info(self, id, **kwargs): 200: "ReadAuthorizationModelResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -1987,6 +1997,7 @@ def read_authorization_models_with_http_info(self, **kwargs): 200: "ReadAuthorizationModelsResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -2157,6 +2168,7 @@ def read_changes_with_http_info(self, **kwargs): 200: "ReadChangesResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -2330,6 +2342,7 @@ def write_with_http_info(self, body, **kwargs): 200: "object", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", @@ -2369,7 +2382,7 @@ def write_with_http_info(self, body, **kwargs): def write_assertions(self, authorization_model_id, body, **kwargs): """Upsert assertions for an authorization model ID - The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, the expectation of whether a call to the Check API of that tuple key will return true or false, and optionally a list of contextual tuples. >>> thread = api.write_assertions(authorization_model_id, body) @@ -2400,7 +2413,7 @@ def write_assertions(self, authorization_model_id, body, **kwargs): def write_assertions_with_http_info(self, authorization_model_id, body, **kwargs): """Upsert assertions for an authorization model ID - The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, and the expectation of whether a call to the Check API of that tuple key will return true or false. + The WriteAssertions API will upsert new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, the expectation of whether a call to the Check API of that tuple key will return true or false, and optionally a list of contextual tuples. >>> thread = api.write_assertions_with_http_info(authorization_model_id, body) @@ -2691,6 +2704,7 @@ def write_authorization_model_with_http_info(self, body, **kwargs): 201: "WriteAuthorizationModelResponse", 400: "ValidationErrorMessageResponse", 401: "UnauthenticatedResponse", + 403: "ForbiddenResponse", 404: "PathUnknownErrorMessageResponse", 409: "AbortedMessageResponse", 422: "UnprocessableContentMessageResponse", diff --git a/test/api/open_fga_api_test.py b/test/api/open_fga_api_test.py index a873f0f..0dccdc0 100644 --- a/test/api/open_fga_api_test.py +++ b/test/api/open_fga_api_test.py @@ -467,7 +467,6 @@ async def test_list_users(self, mock_request): relation="can_read", user_filters=[ {"type": "user"}, - {"type": "team", "relation": "member"}, ], context={}, contextual_tuples=[ @@ -479,7 +478,7 @@ async def test_list_users(self, mock_request): { "user": "folder:product", "relation": "parent", - "object": "document:roadmap", + "object": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", }, ], ) @@ -522,7 +521,6 @@ async def test_list_users(self, mock_request): "relation": "can_read", "user_filters": [ {"type": "user"}, - {"type": "team", "relation": "member"}, ], "context": {}, "contextual_tuples": [ @@ -534,7 +532,7 @@ async def test_list_users(self, mock_request): { "user": "folder:product", "relation": "parent", - "object": "document:roadmap", + "object": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", }, ], }, diff --git a/test/client/client_test.py b/test/client/client_test.py index 0c027db..48fec42 100644 --- a/test/client/client_test.py +++ b/test/client/client_test.py @@ -2501,7 +2501,7 @@ async def test_list_users(self, mock_request): ClientTuple( user="folder:product", relation="parent", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ], ) @@ -2560,7 +2560,7 @@ async def test_list_users(self, mock_request): { "user": "folder:product", "relation": "parent", - "object": "document:roadmap", + "object": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", }, ], "context": {}, diff --git a/test/sync/client/client_test.py b/test/sync/client/client_test.py index bf05159..c8b8835 100644 --- a/test/sync/client/client_test.py +++ b/test/sync/client/client_test.py @@ -2505,7 +2505,7 @@ def test_list_users(self, mock_request): ClientTuple( user="folder:product", relation="parent", - object="document:roadmap", + object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", ), ] @@ -2563,7 +2563,7 @@ def test_list_users(self, mock_request): { "user": "folder:product", "relation": "parent", - "object": "document:roadmap", + "object": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", }, ], "context": {}, diff --git a/test/sync/open_fga_api_test.py b/test/sync/open_fga_api_test.py index 8ba1115..827370f 100644 --- a/test/sync/open_fga_api_test.py +++ b/test/sync/open_fga_api_test.py @@ -472,7 +472,6 @@ async def test_list_users(self, mock_request): request.relation = "can_read" request.user_filters = [ {"type": "user"}, - {"type": "team", "relation": "member"}, ] request.context = {} request.contextual_tuples = [ @@ -484,7 +483,7 @@ async def test_list_users(self, mock_request): { "user": "folder:product", "relation": "parent", - "object": "document:roadmap", + "object": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", }, ] @@ -526,7 +525,6 @@ async def test_list_users(self, mock_request): "relation": "can_read", "user_filters": [ {"type": "user"}, - {"type": "team", "relation": "member"}, ], "context": {}, "contextual_tuples": [ @@ -538,7 +536,7 @@ async def test_list_users(self, mock_request): { "user": "folder:product", "relation": "parent", - "object": "document:roadmap", + "object": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a", }, ], },