From 2bb996620759f34f11d339c0c5588df57b400c1e Mon Sep 17 00:00:00 2001 From: Raghd Hamzeh Date: Mon, 29 Apr 2024 21:07:55 -0400 Subject: [PATCH 1/2] feat: support list users # Conflicts: # .github/workflows/main.yaml # .github/workflows/semgrep.yaml --- .openapi-generator/FILES | 20 + CHANGELOG.md | 2 +- README.md | 66 ++- api_open_fga.go | 458 +++++++++++++++++- api_open_fga_test.go | 89 ++++ client/client.go | 113 +++++ client/client_test.go | 104 ++++ docs/FgaObject.md | 72 +++ docs/ListUsersRequest.md | 171 +++++++ docs/ListUsersResponse.md | 72 +++ docs/ObjectOrUserset.md | 82 ++++ docs/OpenFgaApi.md | 92 ++++ docs/TypedWildcard.md | 51 ++ docs/UnprocessableContentErrorCode.md | 13 + docs/UnprocessableContentMessageResponse.md | 82 ++++ docs/User.md | 108 +++++ docs/UserTypeFilter.md | 77 +++ docs/UsersetUser.md | 93 ++++ example/example1/example1.go | 36 +- example/example1/go.mod | 6 +- example/example1/go.sum | 9 +- model_fga_object.go | 142 ++++++ model_list_users_request.go | 278 +++++++++++ model_list_users_response.go | 142 ++++++ model_object_or_userset.go | 160 ++++++ model_typed_wildcard.go | 115 +++++ model_unprocessable_content_error_code.go | 111 +++++ ..._unprocessable_content_message_response.go | 164 +++++++ model_user.go | 196 ++++++++ model_user_type_filter.go | 151 ++++++ model_userset_user.go | 169 +++++++ 31 files changed, 3419 insertions(+), 25 deletions(-) create mode 100644 docs/FgaObject.md create mode 100644 docs/ListUsersRequest.md create mode 100644 docs/ListUsersResponse.md create mode 100644 docs/ObjectOrUserset.md create mode 100644 docs/TypedWildcard.md create mode 100644 docs/UnprocessableContentErrorCode.md create mode 100644 docs/UnprocessableContentMessageResponse.md create mode 100644 docs/User.md create mode 100644 docs/UserTypeFilter.md create mode 100644 docs/UsersetUser.md create mode 100644 model_fga_object.go create mode 100644 model_list_users_request.go create mode 100644 model_list_users_response.go create mode 100644 model_object_or_userset.go create mode 100644 model_typed_wildcard.go create mode 100644 model_unprocessable_content_error_code.go create mode 100644 model_unprocessable_content_message_response.go create mode 100644 model_user.go create mode 100644 model_user_type_filter.go create mode 100644 model_userset_user.go diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index ba49443..b08e166 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -42,6 +42,7 @@ docs/ErrorCode.md docs/ExpandRequest.md docs/ExpandRequestTupleKey.md docs/ExpandResponse.md +docs/FgaObject.md docs/GetStoreResponse.md docs/InternalErrorCode.md docs/InternalErrorMessageResponse.md @@ -49,11 +50,14 @@ docs/Leaf.md docs/ListObjectsRequest.md docs/ListObjectsResponse.md docs/ListStoresResponse.md +docs/ListUsersRequest.md +docs/ListUsersResponse.md docs/Metadata.md docs/Node.md docs/Nodes.md docs/NotFoundErrorCode.md docs/NullValue.md +docs/ObjectOrUserset.md docs/ObjectRelation.md docs/OpenFgaApi.md docs/PathUnknownErrorMessageResponse.md @@ -78,11 +82,17 @@ docs/TupleOperation.md docs/TupleToUserset.md docs/TypeDefinition.md docs/TypeName.md +docs/TypedWildcard.md +docs/UnprocessableContentErrorCode.md +docs/UnprocessableContentMessageResponse.md +docs/User.md +docs/UserTypeFilter.md docs/Users.md docs/Userset.md docs/UsersetTree.md docs/UsersetTreeDifference.md docs/UsersetTreeTupleToUserset.md +docs/UsersetUser.md docs/Usersets.md docs/ValidationErrorMessageResponse.md docs/WriteAssertionsRequest.md @@ -122,6 +132,7 @@ model_error_code.go model_expand_request.go model_expand_request_tuple_key.go model_expand_response.go +model_fga_object.go model_get_store_response.go model_internal_error_code.go model_internal_error_message_response.go @@ -129,11 +140,14 @@ model_leaf.go model_list_objects_request.go model_list_objects_response.go model_list_stores_response.go +model_list_users_request.go +model_list_users_response.go model_metadata.go model_node.go model_nodes.go model_not_found_error_code.go model_null_value.go +model_object_or_userset.go model_object_relation.go model_path_unknown_error_message_response.go model_read_assertions_response.go @@ -157,11 +171,17 @@ model_tuple_operation.go model_tuple_to_userset.go model_type_definition.go model_type_name.go +model_typed_wildcard.go +model_unprocessable_content_error_code.go +model_unprocessable_content_message_response.go +model_user.go +model_user_type_filter.go model_users.go model_userset.go model_userset_tree.go model_userset_tree_difference.go model_userset_tree_tuple_to_userset.go +model_userset_user.go model_usersets.go model_validation_error_message_response.go model_write_assertions_request.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e0f779..baf78ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,7 +61,7 @@ Some of the changes to expect: fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production }) ``` - When initializing a client, `AuthorizationModelId` is no longer a pointer, and you can just pass the string directly diff --git a/README.md b/README.md index dea8055..f099690 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ This is an autogenerated Go SDK for OpenFGA. It provides a wrapper around the [O - [Expand](#expand) - [List Objects](#list-objects) - [List Relations](#list-relations) + - [List Users](#list-users) - [Assertions](#assertions) - [Read Assertions](#read-assertions) - [Write Assertions](#write-assertions) @@ -114,7 +115,7 @@ func main() { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production }) if err != nil { @@ -136,7 +137,7 @@ func main() { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production Credentials: &credentials.Credentials{ Method: credentials.CredentialsMethodApiToken, Config: &credentials.Config{ @@ -165,7 +166,7 @@ func main() { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production Credentials: &credentials.Credentials{ Method: credentials.CredentialsMethodClientCredentials, Config: &credentials.Config{ @@ -197,7 +198,7 @@ func main() { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production Credentials: &credentials.Credentials{ Method: credentials.CredentialsMethodClientCredentials, Config: &credentials.Config{ @@ -762,6 +763,50 @@ data, err := fgaClient.ListRelations(context.Background()). // data.Relations = ["can_view", "can_edit"] ``` +##### List Users + +List the users who have a certain relation to a particular type. + +[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/ListUsers) + +```golang +options := ClientListRelationsOptions{ + // You can rely on the model id set in the configuration or override it for this specific request + AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"), +} + +// Only a single filter is allowed by the API for the time being +userFilters := []openfga.UserTypeFilter{{ Type: "user" }} +// user filters can also be of the form +// userFilters := []openfga.UserTypeFilter{{ Type: "team", Relation: openfga.PtrString("member") }} + +requestBody := ClientListUsersRequest{ + Object: openfga.Object{ + Type: "document", + Id: "roadmap", + }, + Relation: "can_read", + UserFilters: userFilters, + ContextualTuples: []ClientContextualTupleKey{{ + User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + Relation: "editor", + Object: "folder:product", + }, { + User: "folder:product", + Relation: "parent", + Object: "document:roadmap", + }}, + Context: &map[string]interface{}{"ViewCount": 100}, +} +data, err := fgaClient.ListRelations(context.Background()). + Body(requestBody). + Options(options). + Execute() + +// response.users = [{object: {type: "user", id: "81684243-9356-4421-8fbf-a4f8d36aa31b"}}, {userset: { type: "user" }}, ...] +// response.excluded_users = [ {object: {type: "user", id: "4a455e27-d15a-4434-82e0-136f9c2aa4cf"}}, ... ] +``` + ### Assertions #### Read Assertions @@ -826,7 +871,7 @@ func main() { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production RetryParams: &openfga.RetryParams{ MaxRetry: 3, // retry up to 3 times on API requests MinWaitInMs: 250, // wait a minimum of 250 milliseconds between requests @@ -849,6 +894,7 @@ Class | Method | HTTP request | Description *OpenFgaApi* | [**GetStore**](docs/OpenFgaApi.md#getstore) | **Get** /stores/{store_id} | Get a store *OpenFgaApi* | [**ListObjects**](docs/OpenFgaApi.md#listobjects) | **Post** /stores/{store_id}/list-objects | List all objects of the given type that the user has a relation with *OpenFgaApi* | [**ListStores**](docs/OpenFgaApi.md#liststores) | **Get** /stores | List all stores +*OpenFgaApi* | [**ListUsers**](docs/OpenFgaApi.md#listusers) | **Post** /stores/{store_id}/list-users | List all users of the given type that the object has a relation with *OpenFgaApi* | [**Read**](docs/OpenFgaApi.md#read) | **Post** /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules *OpenFgaApi* | [**ReadAssertions**](docs/OpenFgaApi.md#readassertions) | **Get** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID *OpenFgaApi* | [**ReadAuthorizationModel**](docs/OpenFgaApi.md#readauthorizationmodel) | **Get** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model @@ -881,6 +927,7 @@ Class | Method | HTTP request | Description - [ExpandRequest](docs/ExpandRequest.md) - [ExpandRequestTupleKey](docs/ExpandRequestTupleKey.md) - [ExpandResponse](docs/ExpandResponse.md) + - [FgaObject](docs/FgaObject.md) - [GetStoreResponse](docs/GetStoreResponse.md) - [InternalErrorCode](docs/InternalErrorCode.md) - [InternalErrorMessageResponse](docs/InternalErrorMessageResponse.md) @@ -888,11 +935,14 @@ Class | Method | HTTP request | Description - [ListObjectsRequest](docs/ListObjectsRequest.md) - [ListObjectsResponse](docs/ListObjectsResponse.md) - [ListStoresResponse](docs/ListStoresResponse.md) + - [ListUsersRequest](docs/ListUsersRequest.md) + - [ListUsersResponse](docs/ListUsersResponse.md) - [Metadata](docs/Metadata.md) - [Node](docs/Node.md) - [Nodes](docs/Nodes.md) - [NotFoundErrorCode](docs/NotFoundErrorCode.md) - [NullValue](docs/NullValue.md) + - [ObjectOrUserset](docs/ObjectOrUserset.md) - [ObjectRelation](docs/ObjectRelation.md) - [PathUnknownErrorMessageResponse](docs/PathUnknownErrorMessageResponse.md) - [ReadAssertionsResponse](docs/ReadAssertionsResponse.md) @@ -916,11 +966,17 @@ Class | Method | HTTP request | Description - [TupleToUserset](docs/TupleToUserset.md) - [TypeDefinition](docs/TypeDefinition.md) - [TypeName](docs/TypeName.md) + - [TypedWildcard](docs/TypedWildcard.md) + - [UnprocessableContentErrorCode](docs/UnprocessableContentErrorCode.md) + - [UnprocessableContentMessageResponse](docs/UnprocessableContentMessageResponse.md) + - [User](docs/User.md) + - [UserTypeFilter](docs/UserTypeFilter.md) - [Users](docs/Users.md) - [Userset](docs/Userset.md) - [UsersetTree](docs/UsersetTree.md) - [UsersetTreeDifference](docs/UsersetTreeDifference.md) - [UsersetTreeTupleToUserset](docs/UsersetTreeTupleToUserset.md) + - [UsersetUser](docs/UsersetUser.md) - [Usersets](docs/Usersets.md) - [ValidationErrorMessageResponse](docs/ValidationErrorMessageResponse.md) - [WriteAssertionsRequest](docs/WriteAssertionsRequest.md) diff --git a/api_open_fga.go b/api_open_fga.go index 32c6ee9..a07b014 100644 --- a/api_open_fga.go +++ b/api_open_fga.go @@ -33,13 +33,18 @@ type OpenFgaApi interface { /* * Check Check whether a user is authorized to access an object - * The Check API queries to check if the user has a certain relationship with an object in a certain store. + * 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`. - ## Example + 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 { @@ -68,7 +73,72 @@ type OpenFgaApi interface { "authorization_model_id": "01G50QVV17PECNVAHX1GG4Y5NC" } ``` - OpenFGA's response will include `{ "allowed": true }` if there is a relationship and `{ "allowed": false }` if there isn't. + ### 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 exclusion in the model + A Check for a userset can yield results that must be treated carefully if the model involves exclusion. 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. + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). * @return ApiCheckRequest */ @@ -185,7 +255,8 @@ type OpenFgaApi interface { /* * ListObjects 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 achieve this, both the store tuples and the authorization model are used. + * 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. @@ -219,6 +290,19 @@ type OpenFgaApi interface { */ ListStoresExecute(r ApiListStoresRequest) (ListStoresResponse, *_nethttp.Response, error) + /* + * ListUsers List all users of the given type that the object has a relation with + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @return ApiListUsersRequest + */ + ListUsers(ctx _context.Context) ApiListUsersRequest + + /* + * ListUsersExecute executes the request + * @return ListUsersResponse + */ + ListUsersExecute(r ApiListUsersRequest) (ListUsersResponse, *_nethttp.Response, error) + /* * Read Get tuples from the store that matches a query, without following userset rewrite rules * The Read API will return the tuples for a certain store that match a query filter specified in the body of the request. @@ -471,9 +555,10 @@ type OpenFgaApi interface { /* * Write Add or delete tuples from the store - * The Write API will update the tuples for a certain store. Tuples and type definitions allow OpenFGA to determine whether a relationship exists between an object and an user. + * The Write API will transactionally update the tuples for a certain store. Tuples and type definitions allow OpenFGA to determine whether a relationship exists between an object and an user. In the body, `writes` adds new tuples and `deletes` removes existing tuples. When deleting a tuple, any `condition` specified with it is ignored. The API is not idempotent: if, later on, you try to add the same tuple key (even if the `condition` is different), or if you try to delete a non-existing tuple, it will throw an error. + The API will not allow you to write tuples such as `document:2021-budget#viewer@document:2021-budget#viewer`, because they are implicit. An `authorization_model_id` may be specified in the body. If it is, it will be used to assert that each written tuple (not deleted) is valid for the model specified. If it is not specified, the latest authorization model ID will be used. ## Example ### Adding relationships @@ -611,14 +696,19 @@ func (r ApiCheckRequest) Execute() (CheckResponse, *_nethttp.Response, error) { /* - Check Check whether a user is authorized to access an object - - The Check API queries to check if the user has a certain relationship with an object in a certain store. + - 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`. -## Example +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 @@ -651,7 +741,86 @@ the Check API can be used with the following request body: } ``` -OpenFGA's response will include `{ "allowed": true }` if there is a relationship and `{ "allowed": false }` if there isn't. +### 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 exclusion in the model +A Check for a userset can yield results that must be treated carefully if the model involves exclusion. 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. + - @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiCheckRequest */ @@ -2001,7 +2170,8 @@ func (r ApiListObjectsRequest) Execute() (ListObjectsResponse, *_nethttp.Respons /* - ListObjects 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 achieve this, both the store tuples and the authorization model are used. + - 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`. @@ -2528,6 +2698,273 @@ func (a *OpenFgaApiService) ListStoresExecute(r ApiListStoresRequest) (ListStore return localVarReturnValue, nil, reportError("Error not handled properly") } +type ApiListUsersRequest struct { + ctx _context.Context + ApiService OpenFgaApi + + body *ListUsersRequest +} + +func (r ApiListUsersRequest) Body(body ListUsersRequest) ApiListUsersRequest { + r.body = &body + return r +} + +func (r ApiListUsersRequest) Execute() (ListUsersResponse, *_nethttp.Response, error) { + return r.ApiService.ListUsersExecute(r) +} + +/* + * ListUsers List all users of the given type that the object has a relation with + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @return ApiListUsersRequest + */ +func (a *OpenFgaApiService) ListUsers(ctx _context.Context) ApiListUsersRequest { + return ApiListUsersRequest{ + ApiService: a, + ctx: ctx, + } +} + +/* + * Execute executes the request + * @return ListUsersResponse + */ +func (a *OpenFgaApiService) ListUsersExecute(r ApiListUsersRequest) (ListUsersResponse, *_nethttp.Response, error) { + var maxRetry int + var minWaitInMs int + + if a.RetryParams != nil { + maxRetry = a.RetryParams.MinWaitInMs + minWaitInMs = a.RetryParams.MinWaitInMs + } else { + maxRetry = 0 + minWaitInMs = 0 + } + + for i := 0; i < maxRetry+1; i++ { + var ( + localVarHTTPMethod = _nethttp.MethodPost + localVarPostBody interface{} + localVarReturnValue ListUsersResponse + ) + + if a.client.cfg.StoreId == "" { + return localVarReturnValue, nil, reportError("Configuration.StoreId is required and must be specified to call this method") + } + if a.client.cfg.StoreId != "" && !internalutils.IsWellFormedUlidString(a.client.cfg.StoreId) { + return localVarReturnValue, nil, reportError("Configuration.StoreId is invalid") + } + localVarPath := "/stores/{store_id}/list-users" + localVarPath = strings.Replace(localVarPath, "{"+"store_id"+"}", _neturl.PathEscape(a.client.cfg.StoreId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + if r.body == nil { + return localVarReturnValue, nil, reportError("body is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.body + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = _ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= _nethttp.StatusMultipleChoices { + + if localVarHTTPResponse.StatusCode == _nethttp.StatusBadRequest || localVarHTTPResponse.StatusCode == _nethttp.StatusUnprocessableEntity { + newErr := FgaApiValidationError{ + body: localVarBody, + storeId: a.client.cfg.StoreId, + endpointCategory: "ListUsers", + requestBody: localVarPostBody, + requestMethod: localVarHTTPMethod, + responseStatusCode: localVarHTTPResponse.StatusCode, + responseHeader: localVarHTTPResponse.Header, + } + // Due to CanonicalHeaderKey, header name is case-insensitive. + newErr.requestId = localVarHTTPResponse.Header.Get("Fga-Request-Id") + newErr.error = "ListUsers validation error for " + localVarHTTPMethod + " ListUsers with body " + string(localVarBody) + var v ValidationErrorMessageResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.modelDecodeError = err + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + newErr.responseCode = v.GetCode() + newErr.error += " with error code " + string(v.GetCode()) + " error message: " + v.GetMessage() + + return localVarReturnValue, localVarHTTPResponse, newErr + } + + if localVarHTTPResponse.StatusCode == _nethttp.StatusUnauthorized || localVarHTTPResponse.StatusCode == _nethttp.StatusForbidden { + newErr := FgaApiAuthenticationError{ + body: localVarBody, + + storeId: a.client.cfg.StoreId, + endpointCategory: "ListUsers", + responseStatusCode: localVarHTTPResponse.StatusCode, + responseHeader: localVarHTTPResponse.Header, + } + // Due to CanonicalHeaderKey, header name is case-insensitive. + newErr.requestId = localVarHTTPResponse.Header.Get("Fga-Request-Id") + newErr.error = "ListUsers auth error for " + localVarHTTPMethod + " ListUsers with body " + string(localVarBody) + + return localVarReturnValue, localVarHTTPResponse, newErr + } + + if localVarHTTPResponse.StatusCode == _nethttp.StatusNotFound { + newErr := FgaApiNotFoundError{ + body: localVarBody, + storeId: a.client.cfg.StoreId, + endpointCategory: "ListUsers", + requestBody: localVarPostBody, + requestMethod: localVarHTTPMethod, + responseStatusCode: localVarHTTPResponse.StatusCode, + responseHeader: localVarHTTPResponse.Header, + } + // Due to CanonicalHeaderKey, header name is case-insensitive. + newErr.requestId = localVarHTTPResponse.Header.Get("Fga-Request-Id") + newErr.error = "ListUsers validation error for " + localVarHTTPMethod + " ListUsers with body " + string(localVarBody) + var v PathUnknownErrorMessageResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.modelDecodeError = err + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + newErr.responseCode = v.GetCode() + newErr.error += " with error code " + string(v.GetCode()) + " error message: " + v.GetMessage() + + return localVarReturnValue, localVarHTTPResponse, newErr + } + + if localVarHTTPResponse.StatusCode == _nethttp.StatusTooManyRequests { + if i < maxRetry { + time.Sleep(time.Duration(internalutils.RandomTime(i, minWaitInMs)) * time.Millisecond) + continue + } + // maximum number of retry reached + newErr := FgaApiRateLimitExceededError{ + body: localVarBody, + + storeId: a.client.cfg.StoreId, + endpointCategory: "ListUsers", + requestBody: localVarPostBody, + requestMethod: localVarHTTPMethod, + responseStatusCode: localVarHTTPResponse.StatusCode, + responseHeader: localVarHTTPResponse.Header, + } + newErr.error = "ListUsers rate limit error for " + localVarHTTPMethod + " ListUsers with body " + string(localVarBody) + + // Due to CanonicalHeaderKey, header name is case-insensitive. + newErr.requestId = localVarHTTPResponse.Header.Get("Fga-Request-Id") + return localVarReturnValue, localVarHTTPResponse, newErr + } + + if localVarHTTPResponse.StatusCode >= _nethttp.StatusInternalServerError { + if localVarHTTPResponse.StatusCode != _nethttp.StatusNotImplemented && i < maxRetry { + time.Sleep(time.Duration(internalutils.RandomTime(i, minWaitInMs)) * time.Millisecond) + continue + } + newErr := FgaApiInternalError{ + body: localVarBody, + + storeId: a.client.cfg.StoreId, + endpointCategory: "ListUsers", + requestBody: localVarPostBody, + requestMethod: localVarHTTPMethod, + responseStatusCode: localVarHTTPResponse.StatusCode, + responseHeader: localVarHTTPResponse.Header, + } + newErr.error = "ListUsers internal error for " + localVarHTTPMethod + " ListUsers with body " + string(localVarBody) + newErr.requestId = localVarHTTPResponse.Header.Get("Fga-Request-Id") + + var v InternalErrorMessageResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.modelDecodeError = err + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + newErr.responseCode = v.GetCode() + newErr.error += " with error code " + string(v.GetCode()) + " error message: " + v.GetMessage() + + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr := FgaApiError{ + body: localVarBody, + + storeId: a.client.cfg.StoreId, + endpointCategory: "ListUsers", + requestBody: localVarPostBody, + requestMethod: localVarHTTPMethod, + responseStatusCode: localVarHTTPResponse.StatusCode, + responseHeader: localVarHTTPResponse.Header, + } + newErr.error = "ListUsers error for " + localVarHTTPMethod + " ListUsers with body " + string(localVarBody) + newErr.requestId = localVarHTTPResponse.Header.Get("Fga-Request-Id") + + var v ErrorResponse + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.modelDecodeError = err + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + newErr.responseCode = v.Code + newErr.error += " with error code " + v.Code + " error message: " + v.Message + + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil + } + // should never have reached this + var localVarReturnValue ListUsersResponse + return localVarReturnValue, nil, reportError("Error not handled properly") +} + type ApiReadRequest struct { ctx _context.Context ApiService OpenFgaApi @@ -4092,10 +4529,11 @@ func (r ApiWriteRequest) Execute() (map[string]interface{}, *_nethttp.Response, /* - Write Add or delete tuples from the store - - The Write API will update the tuples for a certain store. Tuples and type definitions allow OpenFGA to determine whether a relationship exists between an object and an user. + - The Write API will transactionally update the tuples for a certain store. Tuples and type definitions allow OpenFGA to determine whether a relationship exists between an object and an user. In the body, `writes` adds new tuples and `deletes` removes existing tuples. When deleting a tuple, any `condition` specified with it is ignored. The API is not idempotent: if, later on, you try to add the same tuple key (even if the `condition` is different), or if you try to delete a non-existing tuple, it will throw an error. +The API will not allow you to write tuples such as `document:2021-budget#viewer@document:2021-budget#viewer`, because they are implicit. An `authorization_model_id` may be specified in the body. If it is, it will be used to assert that each written tuple (not deleted) is valid for the model specified. If it is not specified, the latest authorization model ID will be used. ## Example ### Adding relationships diff --git a/api_open_fga_test.go b/api_open_fga_test.go index 82104eb..6ad63dc 100644 --- a/api_open_fga_test.go +++ b/api_open_fga_test.go @@ -969,6 +969,95 @@ func TestOpenFgaApi(t *testing.T) { } }) + t.Run("ListUsers", func(t *testing.T) { + test := TestDefinition{ + Name: "ListUsers", + // A real API would not return all these for the filter provided, these are just for test purposes + JsonResponse: `{"excluded_users":null,"users":[{"object":{"id":"81684243-9356-4421-8fbf-a4f8d36aa31b","type":"user"}},{"userset":{"id":"fga","relation":"member","type":"team"}},{"wildcard":{"type":"user"}}]}`, + ResponseStatus: http.StatusOK, + Method: http.MethodPost, + RequestPath: "list-users", + } + + requestBody := ListUsersRequest{ + AuthorizationModelId: PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"), + Object: FgaObject{ + Type: "document", + Id: "roadmap", + }, + Relation: "can_read", + // API does not allow sending multiple filters, done here for testing purposes + UserFilters: []UserTypeFilter{{ + Type: "user", + }, { + Type: "team", + Relation: PtrString("member"), + }}, + ContextualTuples: &[]TupleKey{{ + User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + Relation: "editor", + Object: "folder:product", + }, { + User: "folder:product", + Relation: "parent", + Object: "document:roadmap", + }}, + Context: &map[string]interface{}{"ViewCount": 100}, + } + + var expectedResponse ListUsersResponse + if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil { + t.Fatalf("%v", err) + } + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", configuration.ApiUrl, configuration.StoreId, test.RequestPath), + func(req *http.Request) (*http.Response, error) { + resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse) + if err != nil { + return httpmock.NewStringResponse(500, ""), nil + } + return resp, nil + }, + ) + got, response, err := apiClient.OpenFgaApi.ListUsers(context.Background()). + Body(requestBody). + Execute() + if err != nil { + t.Fatalf("%v", err) + } + + if response.StatusCode != test.ResponseStatus { + t.Fatalf("OpenFga%v().Execute() = %v, want %v", test.Name, response.StatusCode, test.ResponseStatus) + } + + _, err = got.MarshalJSON() + if err != nil { + t.Fatalf("%v", err) + } + + if len(got.Users) != len(expectedResponse.Users) { + t.Fatalf("OpenFga%v().Execute() = %v, want %v", test.Name, got.GetUsers(), expectedResponse.GetUsers()) + } + + if got.Users[0].GetObject().Type != expectedResponse.Users[0].GetObject().Type || got.Users[0].GetObject().Id != expectedResponse.Users[0].GetObject().Id { + t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[0], expectedResponse.Users[0], "object: { type: \"user\", id: \"81684243-9356-4421-8fbf-a4f8d36aa31b\" }") + } + + if got.Users[1].GetUserset().Type != expectedResponse.Users[1].GetUserset().Type || got.Users[1].GetUserset().Id != expectedResponse.Users[1].GetUserset().Id || got.Users[1].GetUserset().Relation != expectedResponse.Users[1].GetUserset().Relation { + t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[1], expectedResponse.Users[1], "wildcard: { type: \"team\", id: \"fga\", relation: \"member\" }") + } + + if got.Users[2].GetWildcard().Type != expectedResponse.Users[2].GetWildcard().Type { + t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[2], expectedResponse.Users[2], "wildcard: { type: \"user\" }") + } + + if len(got.ExcludedUsers) != len(expectedResponse.ExcludedUsers) { + t.Fatalf("OpenFga%v().Execute() = %v, want %v", test.Name, got.GetExcludedUsers(), expectedResponse.GetExcludedUsers()) + } + }) + t.Run("Check with 400 error", func(t *testing.T) { test := TestDefinition{ Name: "Check", diff --git a/client/client.go b/client/client.go index 33ebec1..1a99ff7 100644 --- a/client/client.go +++ b/client/client.go @@ -388,6 +388,19 @@ type SdkClient interface { */ ListRelationsExecute(request SdkClientListRelationsRequestInterface) (*ClientListRelationsResponse, error) + /* + * ListUsers List all users of the given type that the object has a relation with + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @return ApiListUsersRequest + */ + ListUsers(ctx _context.Context) SdkClientListUsersRequestInterface + + /* + * ListUsersExecute executes the request + * @return ListUsersResponse + */ + ListUsersExecute(r SdkClientListUsersRequestInterface) (*ClientListUsersResponse, error) + /* Assertions */ /* @@ -2140,6 +2153,106 @@ func (client *OpenFgaClient) ListRelationsExecute(request SdkClientListRelations return &ClientListRelationsResponse{Relations: relations}, nil } +// / ListUsers +type SdkClientListUsersRequest struct { + ctx _context.Context + Client *OpenFgaClient + + body *ClientListUsersRequest + options *ClientListUsersOptions +} + +type SdkClientListUsersRequestInterface interface { + Options(options ClientListUsersOptions) SdkClientListUsersRequestInterface + Body(body ClientListUsersRequest) SdkClientListUsersRequestInterface + Execute() (*ClientListUsersResponse, error) + GetAuthorizationModelIdOverride() *string + + GetContext() _context.Context + GetBody() *ClientListUsersRequest + GetOptions() *ClientListUsersOptions +} + +type ClientListUsersRequest struct { + Object fgaSdk.FgaObject `json:"object"yaml:"object"` + Relation string `json:"relation"yaml:"relation"` + UserFilters []fgaSdk.UserTypeFilter `json:"user_filters"yaml:"user_filters"` + ContextualTuples []ClientContextualTupleKey `json:"contextual_tuples,omitempty"` + // Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. + Context *map[string]interface{} `json:"context,omitempty"yaml:"context,omitempty"` +} + +type ClientListUsersOptions struct { + AuthorizationModelId *string `json:"authorization_model_id,omitempty"` +} + +type ClientListUsersResponse = fgaSdk.ListUsersResponse + +func (client *OpenFgaClient) ListUsers(ctx _context.Context) SdkClientListUsersRequestInterface { + return &SdkClientListUsersRequest{ + Client: client, + ctx: ctx, + } +} + +func (request *SdkClientListUsersRequest) Options(options ClientListUsersOptions) SdkClientListUsersRequestInterface { + request.options = &options + return request +} + +func (request *SdkClientListUsersRequest) GetAuthorizationModelIdOverride() *string { + if request.options == nil { + return nil + } + return request.options.AuthorizationModelId +} + +func (request *SdkClientListUsersRequest) Body(body ClientListUsersRequest) SdkClientListUsersRequestInterface { + request.body = &body + return request +} + +func (request *SdkClientListUsersRequest) Execute() (*ClientListUsersResponse, error) { + return request.Client.ListUsersExecute(request) +} + +func (request *SdkClientListUsersRequest) GetContext() _context.Context { + return request.ctx +} + +func (request *SdkClientListUsersRequest) GetBody() *ClientListUsersRequest { + return request.body +} + +func (request *SdkClientListUsersRequest) GetOptions() *ClientListUsersOptions { + return request.options +} + +func (client *OpenFgaClient) ListUsersExecute(request SdkClientListUsersRequestInterface) (*ClientListUsersResponse, error) { + var contextualTuples []ClientContextualTupleKey + if request.GetBody().ContextualTuples != nil { + for index := 0; index < len(request.GetBody().ContextualTuples); index++ { + contextualTuples = append(contextualTuples, (request.GetBody().ContextualTuples)[index]) + } + } + authorizationModelId, err := client.getAuthorizationModelId(request.GetAuthorizationModelIdOverride()) + if err != nil { + return nil, err + } + data, _, err := client.OpenFgaApi.ListUsers(request.GetContext()).Body(fgaSdk.ListUsersRequest{ + Object: request.GetBody().Object, + Relation: request.GetBody().Relation, + UserFilters: request.GetBody().UserFilters, + ContextualTuples: &fgaSdk.NewContextualTupleKeys(contextualTuples).TupleKeys, + Context: request.GetBody().Context, + AuthorizationModelId: authorizationModelId, + }).Execute() + if err != nil { + return nil, err + } + return &data, nil +} + // / ReadAssertions type SdkClientReadAssertionsRequest struct { ctx _context.Context diff --git a/client/client_test.go b/client/client_test.go index 5446a96..71d92e5 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1869,6 +1869,110 @@ func TestOpenFgaClient(t *testing.T) { } }) + t.Run("ListUsers", func(t *testing.T) { + test := TestDefinition{ + Name: "ListUsers", + // A real API would not return all these for the filter provided, these are just for test purposes + JsonResponse: `{"excluded_users":null,"users":[{"object":{"id":"81684243-9356-4421-8fbf-a4f8d36aa31b","type":"user"}},{"userset":{"id":"fga","relation":"member","type":"team"}},{"wildcard":{"type":"user"}}]}`, + ResponseStatus: http.StatusOK, + Method: http.MethodPost, + RequestPath: "list-users", + } + + requestBody := ClientListUsersRequest{ + Object: openfga.FgaObject{ + Type: "document", + Id: "roadmap", + }, + Relation: "can_read", + // API does not allow sending multiple filters, done here for testing purposes + UserFilters: []openfga.UserTypeFilter{{ + Type: "user", + }, { + Type: "team", + Relation: openfga.PtrString("member"), + }}, + ContextualTuples: []ClientContextualTupleKey{{ + User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + Relation: "editor", + Object: "folder:product", + }, { + User: "folder:product", + Relation: "parent", + Object: "document:roadmap", + }}, + Context: &map[string]interface{}{"ViewCount": 100}, + } + options := ClientListUsersOptions{ + AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"), + } + + var expectedResponse openfga.ListUsersResponse + if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil { + t.Fatalf("%v", err) + } + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, fgaClient.GetConfig().StoreId, test.RequestPath), + func(req *http.Request) (*http.Response, error) { + resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse) + if err != nil { + return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil + } + return resp, nil + }, + ) + + got, err := fgaClient.ListUsers(context.Background()). + Body(requestBody). + Options(options). + Execute() + + _, err = got.MarshalJSON() + if err != nil { + t.Fatalf("%v", err) + } + + if len(got.Users) != len(expectedResponse.Users) { + t.Fatalf("OpenFga%v().Execute() = %v, want %v", test.Name, got.GetUsers(), expectedResponse.GetUsers()) + } + + if got.Users[0].GetObject().Type != expectedResponse.Users[0].GetObject().Type || got.Users[0].GetObject().Id != expectedResponse.Users[0].GetObject().Id { + t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[0], expectedResponse.Users[0], "object: { type: \"user\", id: \"81684243-9356-4421-8fbf-a4f8d36aa31b\" }") + } + + if got.Users[1].GetUserset().Type != expectedResponse.Users[1].GetUserset().Type || got.Users[1].GetUserset().Id != expectedResponse.Users[1].GetUserset().Id || got.Users[1].GetUserset().Relation != expectedResponse.Users[1].GetUserset().Relation { + t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[1], expectedResponse.Users[1], "wildcard: { type: \"team\", id: \"fga\", relation: \"member\" }") + } + + if got.Users[2].GetWildcard().Type != expectedResponse.Users[2].GetWildcard().Type { + t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[2], expectedResponse.Users[2], "wildcard: { type: \"user\" }") + } + + if len(got.ExcludedUsers) != len(expectedResponse.ExcludedUsers) { + t.Fatalf("OpenFga%v().Execute() = %v, want %v", test.Name, got.GetExcludedUsers(), expectedResponse.GetExcludedUsers()) + } + + // ListUsers without options should work + _, err = fgaClient.ListUsers(context.Background()).Body(requestBody).Execute() + if err != nil { + t.Fatalf("%v", err) + } + + // Invalid auth model id should result in error + badOptions := ClientListUsersOptions{ + AuthorizationModelId: openfga.PtrString("INVALID"), + } + _, err = fgaClient.ListUsers(context.Background()). + Body(requestBody). + Options(badOptions). + Execute() + if err == nil { + t.Fatalf("Expect error with invalid auth model id but there is none") + } + }) + /* Assertions */ t.Run("ReadAssertions", func(t *testing.T) { modelId := "01GAHCE4YVKPQEKZQHT2R89MQV" diff --git a/docs/FgaObject.md b/docs/FgaObject.md new file mode 100644 index 0000000..241f2c2 --- /dev/null +++ b/docs/FgaObject.md @@ -0,0 +1,72 @@ +# FgaObject + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Type** | **string** | | +**Id** | **string** | | + +## Methods + +### NewFgaObject + +`func NewFgaObject(type_ string, id string, ) *FgaObject` + +NewFgaObject instantiates a new FgaObject object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewFgaObjectWithDefaults + +`func NewFgaObjectWithDefaults() *FgaObject` + +NewFgaObjectWithDefaults instantiates a new FgaObject object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetType + +`func (o *FgaObject) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *FgaObject) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *FgaObject) SetType(v string)` + +SetType sets Type field to given value. + + +### GetId + +`func (o *FgaObject) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *FgaObject) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *FgaObject) SetId(v string)` + +SetId sets Id field to given value. + + + +[[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/ListUsersRequest.md b/docs/ListUsersRequest.md new file mode 100644 index 0000000..826e255 --- /dev/null +++ b/docs/ListUsersRequest.md @@ -0,0 +1,171 @@ +# ListUsersRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AuthorizationModelId** | Pointer to **string** | | [optional] +**Object** | [**FgaObject**](FgaObject.md) | | +**Relation** | **string** | | +**UserFilters** | [**[]UserTypeFilter**](UserTypeFilter.md) | | +**ContextualTuples** | Pointer to [**[]TupleKey**](TupleKey.md) | | [optional] +**Context** | Pointer to **map[string]interface{}** | Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. | [optional] + +## Methods + +### NewListUsersRequest + +`func NewListUsersRequest(object FgaObject, relation string, userFilters []UserTypeFilter, ) *ListUsersRequest` + +NewListUsersRequest instantiates a new ListUsersRequest object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewListUsersRequestWithDefaults + +`func NewListUsersRequestWithDefaults() *ListUsersRequest` + +NewListUsersRequestWithDefaults instantiates a new ListUsersRequest object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAuthorizationModelId + +`func (o *ListUsersRequest) GetAuthorizationModelId() string` + +GetAuthorizationModelId returns the AuthorizationModelId field if non-nil, zero value otherwise. + +### GetAuthorizationModelIdOk + +`func (o *ListUsersRequest) GetAuthorizationModelIdOk() (*string, bool)` + +GetAuthorizationModelIdOk returns a tuple with the AuthorizationModelId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAuthorizationModelId + +`func (o *ListUsersRequest) SetAuthorizationModelId(v string)` + +SetAuthorizationModelId sets AuthorizationModelId field to given value. + +### HasAuthorizationModelId + +`func (o *ListUsersRequest) HasAuthorizationModelId() bool` + +HasAuthorizationModelId returns a boolean if a field has been set. + +### GetObject + +`func (o *ListUsersRequest) GetObject() FgaObject` + +GetObject returns the Object field if non-nil, zero value otherwise. + +### GetObjectOk + +`func (o *ListUsersRequest) GetObjectOk() (*FgaObject, bool)` + +GetObjectOk returns a tuple with the Object field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetObject + +`func (o *ListUsersRequest) SetObject(v FgaObject)` + +SetObject sets Object field to given value. + + +### GetRelation + +`func (o *ListUsersRequest) GetRelation() string` + +GetRelation returns the Relation field if non-nil, zero value otherwise. + +### GetRelationOk + +`func (o *ListUsersRequest) GetRelationOk() (*string, bool)` + +GetRelationOk returns a tuple with the Relation field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRelation + +`func (o *ListUsersRequest) SetRelation(v string)` + +SetRelation sets Relation field to given value. + + +### GetUserFilters + +`func (o *ListUsersRequest) GetUserFilters() []UserTypeFilter` + +GetUserFilters returns the UserFilters field if non-nil, zero value otherwise. + +### GetUserFiltersOk + +`func (o *ListUsersRequest) GetUserFiltersOk() (*[]UserTypeFilter, bool)` + +GetUserFiltersOk returns a tuple with the UserFilters field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserFilters + +`func (o *ListUsersRequest) SetUserFilters(v []UserTypeFilter)` + +SetUserFilters sets UserFilters field to given value. + + +### GetContextualTuples + +`func (o *ListUsersRequest) GetContextualTuples() []TupleKey` + +GetContextualTuples returns the ContextualTuples field if non-nil, zero value otherwise. + +### GetContextualTuplesOk + +`func (o *ListUsersRequest) GetContextualTuplesOk() (*[]TupleKey, bool)` + +GetContextualTuplesOk returns a tuple with the ContextualTuples field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetContextualTuples + +`func (o *ListUsersRequest) SetContextualTuples(v []TupleKey)` + +SetContextualTuples sets ContextualTuples field to given value. + +### HasContextualTuples + +`func (o *ListUsersRequest) HasContextualTuples() bool` + +HasContextualTuples returns a boolean if a field has been set. + +### GetContext + +`func (o *ListUsersRequest) GetContext() map[string]interface{}` + +GetContext returns the Context field if non-nil, zero value otherwise. + +### GetContextOk + +`func (o *ListUsersRequest) GetContextOk() (*map[string]interface{}, bool)` + +GetContextOk returns a tuple with the Context field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetContext + +`func (o *ListUsersRequest) SetContext(v map[string]interface{})` + +SetContext sets Context field to given value. + +### HasContext + +`func (o *ListUsersRequest) HasContext() bool` + +HasContext returns a boolean if a field has been set. + + +[[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/ListUsersResponse.md b/docs/ListUsersResponse.md new file mode 100644 index 0000000..9da5977 --- /dev/null +++ b/docs/ListUsersResponse.md @@ -0,0 +1,72 @@ +# ListUsersResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Users** | [**[]User**](User.md) | | +**ExcludedUsers** | [**[]ObjectOrUserset**](ObjectOrUserset.md) | | + +## Methods + +### NewListUsersResponse + +`func NewListUsersResponse(users []User, excludedUsers []ObjectOrUserset, ) *ListUsersResponse` + +NewListUsersResponse instantiates a new ListUsersResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewListUsersResponseWithDefaults + +`func NewListUsersResponseWithDefaults() *ListUsersResponse` + +NewListUsersResponseWithDefaults instantiates a new ListUsersResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetUsers + +`func (o *ListUsersResponse) GetUsers() []User` + +GetUsers returns the Users field if non-nil, zero value otherwise. + +### GetUsersOk + +`func (o *ListUsersResponse) GetUsersOk() (*[]User, bool)` + +GetUsersOk returns a tuple with the Users field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUsers + +`func (o *ListUsersResponse) SetUsers(v []User)` + +SetUsers sets Users field to given value. + + +### GetExcludedUsers + +`func (o *ListUsersResponse) GetExcludedUsers() []ObjectOrUserset` + +GetExcludedUsers returns the ExcludedUsers field if non-nil, zero value otherwise. + +### GetExcludedUsersOk + +`func (o *ListUsersResponse) GetExcludedUsersOk() (*[]ObjectOrUserset, bool)` + +GetExcludedUsersOk returns a tuple with the ExcludedUsers field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetExcludedUsers + +`func (o *ListUsersResponse) SetExcludedUsers(v []ObjectOrUserset)` + +SetExcludedUsers sets ExcludedUsers field to given value. + + + +[[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/ObjectOrUserset.md b/docs/ObjectOrUserset.md new file mode 100644 index 0000000..90f4dc0 --- /dev/null +++ b/docs/ObjectOrUserset.md @@ -0,0 +1,82 @@ +# ObjectOrUserset + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Object** | Pointer to [**FgaObject**](FgaObject.md) | | [optional] +**Userset** | Pointer to [**UsersetUser**](UsersetUser.md) | | [optional] + +## Methods + +### NewObjectOrUserset + +`func NewObjectOrUserset() *ObjectOrUserset` + +NewObjectOrUserset instantiates a new ObjectOrUserset object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewObjectOrUsersetWithDefaults + +`func NewObjectOrUsersetWithDefaults() *ObjectOrUserset` + +NewObjectOrUsersetWithDefaults instantiates a new ObjectOrUserset object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetObject + +`func (o *ObjectOrUserset) GetObject() FgaObject` + +GetObject returns the Object field if non-nil, zero value otherwise. + +### GetObjectOk + +`func (o *ObjectOrUserset) GetObjectOk() (*FgaObject, bool)` + +GetObjectOk returns a tuple with the Object field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetObject + +`func (o *ObjectOrUserset) SetObject(v FgaObject)` + +SetObject sets Object field to given value. + +### HasObject + +`func (o *ObjectOrUserset) HasObject() bool` + +HasObject returns a boolean if a field has been set. + +### GetUserset + +`func (o *ObjectOrUserset) GetUserset() UsersetUser` + +GetUserset returns the Userset field if non-nil, zero value otherwise. + +### GetUsersetOk + +`func (o *ObjectOrUserset) GetUsersetOk() (*UsersetUser, bool)` + +GetUsersetOk returns a tuple with the Userset field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserset + +`func (o *ObjectOrUserset) SetUserset(v UsersetUser)` + +SetUserset sets Userset field to given value. + +### HasUserset + +`func (o *ObjectOrUserset) HasUserset() bool` + +HasUserset returns a boolean if a field has been set. + + +[[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 5adc01e..dcb3fb3 100644 --- a/docs/OpenFgaApi.md +++ b/docs/OpenFgaApi.md @@ -11,6 +11,7 @@ Method | HTTP request | Description [**GetStore**](OpenFgaApi.md#GetStore) | **Get** /stores/{store_id} | Get a store [**ListObjects**](OpenFgaApi.md#ListObjects) | **Post** /stores/{store_id}/list-objects | List all objects of the given type that the user has a relation with [**ListStores**](OpenFgaApi.md#ListStores) | **Get** /stores | List all stores +[**ListUsers**](OpenFgaApi.md#ListUsers) | **Post** /stores/{store_id}/list-users | List all users of the given type that the object has a relation with [**Read**](OpenFgaApi.md#Read) | **Post** /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules [**ReadAssertions**](OpenFgaApi.md#ReadAssertions) | **Get** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID [**ReadAuthorizationModel**](OpenFgaApi.md#ReadAuthorizationModel) | **Get** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model @@ -661,6 +662,97 @@ No authorization required [[Back to README]](../README.md) +## ListUsers + +> ListUsersResponse ListUsers(ctx).Body(body).Execute() + +List all users of the given type that the object has a relation with + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openfga "github.com/openfga/go-sdk" +) + +func main() { + + body := *openapiclient.NewListUsersRequest(*openapiclient.NewFgaObject("document", "Id_example"), "reader", []openapiclient.UserTypeFilter{*openapiclient.NewUserTypeFilter("group")}) // ListUsersRequest | + + configuration, err := openfga.NewConfiguration(openfga.Configuration{ + ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example + StoreId: os.Getenv("OPENFGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` + }) + + if err != nil { + // .. Handle error + } + + apiClient := openfga.NewAPIClient(configuration) + + resp, r, err := apiClient.OpenFgaApi.ListUsers(context.Background()).Body(body).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `OpenFgaApi.ListUsers``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + switch v := err.(type) { + case FgaApiAuthenticationError: + // Handle authentication error + case FgaApiValidationError: + // Handle parameter validation error + case FgaApiNotFoundError: + // Handle not found error + case FgaApiInternalError: + // Handle API internal error + case FgaApiRateLimitError: + // Exponential backoff in handling rate limit error + default: + // Handle unknown/undefined error + } + } + // response from `ListUsers`: ListUsersResponse + fmt.Fprintf(os.Stdout, "Response from `OpenFgaApi.ListUsers`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + +### Other Parameters + +Other parameters are passed through a pointer to a apiListUsersRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**body** | [**ListUsersRequest**](ListUsersRequest.md) | | + +### Return type + +[**ListUsersResponse**](ListUsersResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## Read > ReadResponse Read(ctx).Body(body).Execute() diff --git a/docs/TypedWildcard.md b/docs/TypedWildcard.md new file mode 100644 index 0000000..39b0485 --- /dev/null +++ b/docs/TypedWildcard.md @@ -0,0 +1,51 @@ +# TypedWildcard + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Type** | **string** | | + +## Methods + +### NewTypedWildcard + +`func NewTypedWildcard(type_ string, ) *TypedWildcard` + +NewTypedWildcard instantiates a new TypedWildcard object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewTypedWildcardWithDefaults + +`func NewTypedWildcardWithDefaults() *TypedWildcard` + +NewTypedWildcardWithDefaults instantiates a new TypedWildcard object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetType + +`func (o *TypedWildcard) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *TypedWildcard) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *TypedWildcard) SetType(v string)` + +SetType sets Type field to given value. + + + +[[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/UnprocessableContentErrorCode.md b/docs/UnprocessableContentErrorCode.md new file mode 100644 index 0000000..1a828e0 --- /dev/null +++ b/docs/UnprocessableContentErrorCode.md @@ -0,0 +1,13 @@ +# UnprocessableContentErrorCode + +## Enum + + +* `NO_THROTTLED_ERROR_CODE` (value: `"no_throttled_error_code"`) + +* `THROTTLED_TIMEOUT_ERROR` (value: `"throttled_timeout_error"`) + + +[[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/UnprocessableContentMessageResponse.md b/docs/UnprocessableContentMessageResponse.md new file mode 100644 index 0000000..3129044 --- /dev/null +++ b/docs/UnprocessableContentMessageResponse.md @@ -0,0 +1,82 @@ +# UnprocessableContentMessageResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Code** | Pointer to [**UnprocessableContentErrorCode**](UnprocessableContentErrorCode.md) | | [optional] [default to NO_THROTTLED_ERROR_CODE] +**Message** | Pointer to **string** | | [optional] + +## Methods + +### NewUnprocessableContentMessageResponse + +`func NewUnprocessableContentMessageResponse() *UnprocessableContentMessageResponse` + +NewUnprocessableContentMessageResponse instantiates a new UnprocessableContentMessageResponse object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUnprocessableContentMessageResponseWithDefaults + +`func NewUnprocessableContentMessageResponseWithDefaults() *UnprocessableContentMessageResponse` + +NewUnprocessableContentMessageResponseWithDefaults instantiates a new UnprocessableContentMessageResponse object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetCode + +`func (o *UnprocessableContentMessageResponse) GetCode() UnprocessableContentErrorCode` + +GetCode returns the Code field if non-nil, zero value otherwise. + +### GetCodeOk + +`func (o *UnprocessableContentMessageResponse) GetCodeOk() (*UnprocessableContentErrorCode, bool)` + +GetCodeOk returns a tuple with the Code field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCode + +`func (o *UnprocessableContentMessageResponse) SetCode(v UnprocessableContentErrorCode)` + +SetCode sets Code field to given value. + +### HasCode + +`func (o *UnprocessableContentMessageResponse) HasCode() bool` + +HasCode returns a boolean if a field has been set. + +### GetMessage + +`func (o *UnprocessableContentMessageResponse) GetMessage() string` + +GetMessage returns the Message field if non-nil, zero value otherwise. + +### GetMessageOk + +`func (o *UnprocessableContentMessageResponse) GetMessageOk() (*string, bool)` + +GetMessageOk returns a tuple with the Message field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMessage + +`func (o *UnprocessableContentMessageResponse) SetMessage(v string)` + +SetMessage sets Message field to given value. + +### HasMessage + +`func (o *UnprocessableContentMessageResponse) HasMessage() bool` + +HasMessage returns a boolean if a field has been set. + + +[[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/User.md b/docs/User.md new file mode 100644 index 0000000..e3bc82b --- /dev/null +++ b/docs/User.md @@ -0,0 +1,108 @@ +# User + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Object** | Pointer to [**FgaObject**](FgaObject.md) | | [optional] +**Userset** | Pointer to [**UsersetUser**](UsersetUser.md) | | [optional] +**Wildcard** | Pointer to [**TypedWildcard**](TypedWildcard.md) | | [optional] + +## Methods + +### NewUser + +`func NewUser() *User` + +NewUser instantiates a new User object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUserWithDefaults + +`func NewUserWithDefaults() *User` + +NewUserWithDefaults instantiates a new User object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetObject + +`func (o *User) GetObject() FgaObject` + +GetObject returns the Object field if non-nil, zero value otherwise. + +### GetObjectOk + +`func (o *User) GetObjectOk() (*FgaObject, bool)` + +GetObjectOk returns a tuple with the Object field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetObject + +`func (o *User) SetObject(v FgaObject)` + +SetObject sets Object field to given value. + +### HasObject + +`func (o *User) HasObject() bool` + +HasObject returns a boolean if a field has been set. + +### GetUserset + +`func (o *User) GetUserset() UsersetUser` + +GetUserset returns the Userset field if non-nil, zero value otherwise. + +### GetUsersetOk + +`func (o *User) GetUsersetOk() (*UsersetUser, bool)` + +GetUsersetOk returns a tuple with the Userset field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUserset + +`func (o *User) SetUserset(v UsersetUser)` + +SetUserset sets Userset field to given value. + +### HasUserset + +`func (o *User) HasUserset() bool` + +HasUserset returns a boolean if a field has been set. + +### GetWildcard + +`func (o *User) GetWildcard() TypedWildcard` + +GetWildcard returns the Wildcard field if non-nil, zero value otherwise. + +### GetWildcardOk + +`func (o *User) GetWildcardOk() (*TypedWildcard, bool)` + +GetWildcardOk returns a tuple with the Wildcard field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetWildcard + +`func (o *User) SetWildcard(v TypedWildcard)` + +SetWildcard sets Wildcard field to given value. + +### HasWildcard + +`func (o *User) HasWildcard() bool` + +HasWildcard returns a boolean if a field has been set. + + +[[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/UserTypeFilter.md b/docs/UserTypeFilter.md new file mode 100644 index 0000000..7a42098 --- /dev/null +++ b/docs/UserTypeFilter.md @@ -0,0 +1,77 @@ +# UserTypeFilter + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Type** | **string** | | +**Relation** | Pointer to **string** | | [optional] + +## Methods + +### NewUserTypeFilter + +`func NewUserTypeFilter(type_ string, ) *UserTypeFilter` + +NewUserTypeFilter instantiates a new UserTypeFilter object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUserTypeFilterWithDefaults + +`func NewUserTypeFilterWithDefaults() *UserTypeFilter` + +NewUserTypeFilterWithDefaults instantiates a new UserTypeFilter object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetType + +`func (o *UserTypeFilter) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *UserTypeFilter) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *UserTypeFilter) SetType(v string)` + +SetType sets Type field to given value. + + +### GetRelation + +`func (o *UserTypeFilter) GetRelation() string` + +GetRelation returns the Relation field if non-nil, zero value otherwise. + +### GetRelationOk + +`func (o *UserTypeFilter) GetRelationOk() (*string, bool)` + +GetRelationOk returns a tuple with the Relation field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRelation + +`func (o *UserTypeFilter) SetRelation(v string)` + +SetRelation sets Relation field to given value. + +### HasRelation + +`func (o *UserTypeFilter) HasRelation() bool` + +HasRelation returns a boolean if a field has been set. + + +[[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/UsersetUser.md b/docs/UsersetUser.md new file mode 100644 index 0000000..04d2d73 --- /dev/null +++ b/docs/UsersetUser.md @@ -0,0 +1,93 @@ +# UsersetUser + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Type** | **string** | | +**Id** | **string** | | +**Relation** | **string** | | + +## Methods + +### NewUsersetUser + +`func NewUsersetUser(type_ string, id string, relation string, ) *UsersetUser` + +NewUsersetUser instantiates a new UsersetUser object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUsersetUserWithDefaults + +`func NewUsersetUserWithDefaults() *UsersetUser` + +NewUsersetUserWithDefaults instantiates a new UsersetUser object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetType + +`func (o *UsersetUser) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *UsersetUser) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *UsersetUser) SetType(v string)` + +SetType sets Type field to given value. + + +### GetId + +`func (o *UsersetUser) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *UsersetUser) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *UsersetUser) SetId(v string)` + +SetId sets Id field to given value. + + +### GetRelation + +`func (o *UsersetUser) GetRelation() string` + +GetRelation returns the Relation field if non-nil, zero value otherwise. + +### GetRelationOk + +`func (o *UsersetUser) GetRelationOk() (*string, bool)` + +GetRelationOk returns a tuple with the Relation field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRelation + +`func (o *UsersetUser) SetRelation(v string)` + +SetRelation sets Relation field to given value. + + + +[[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/example/example1/example1.go b/example/example1/example1.go index 3b42858..97b0617 100644 --- a/example/example1/example1.go +++ b/example/example1/example1.go @@ -31,8 +31,8 @@ func mainInner() error { } fgaClient, err := client.NewSdkClient(&client.ClientConfiguration{ ApiUrl: apiUrl, - StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` - AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production + StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production Credentials: &creds, }) @@ -243,6 +243,38 @@ func mainInner() error { } fmt.Printf("Allowed: %v\n", checkResponse.Allowed) + // ListObjects + fmt.Println("Listing objects user has access to") + listObjectsResponse, err := fgaClient.ListObjects(ctx).Body(client.ClientListObjectsRequest{ + User: "user:anne", + Relation: "viewer", + Type: "document", + }).Execute() + fmt.Printf("Response: Objects = %v\n", listObjectsResponse.Objects) + + // ListRelations + fmt.Println("Listing relations user has with object") + listRelationsResponse, err := fgaClient.ListRelations(ctx).Body(client.ClientListRelationsRequest{ + User: "user:anne", + Object: "document:roadmap", + Relations: []string{"viewer"}, + }).Execute() + fmt.Printf("Response: Relations = %v\n", listRelationsResponse.Relations) + + // ListUsers + fmt.Println("Listing user who have access to object") + listUsersResponse, err := fgaClient.ListUsers(ctx).Body(client.ClientListUsersRequest{ + Relation: "viewer", + Object: openfga.Object{ + Type: "document", + Id: "roadmap", + }, + UserFilters: []openfga.ListUsersFilter{{ + Type: "user", + }}, + }).Execute() + fmt.Printf("Response: Users = %v\n", listUsersResponse.Users) + // WriteAssertions _, err = fgaClient.WriteAssertions(ctx).Body([]client.ClientAssertion{ { diff --git a/example/example1/go.mod b/example/example1/go.mod index 25626a6..187b3eb 100644 --- a/example/example1/go.mod +++ b/example/example1/go.mod @@ -1,10 +1,10 @@ module example1 -go 1.21 +go 1.21.9 require github.com/openfga/go-sdk v0.3.5 -require golang.org/x/sync v0.6.0 // indirect +require golang.org/x/sync v0.7.0 // indirect // To reference local build, uncomment below and run `go mod tidy` -//replace github.com/openfga/go-sdk v0.3.5 => ../../ \ No newline at end of file +//replace github.com/openfga/go-sdk v0.3.5 => ../../ diff --git a/example/example1/go.sum b/example/example1/go.sum index b026a82..e8778b2 100644 --- a/example/example1/go.sum +++ b/example/example1/go.sum @@ -1,5 +1,6 @@ github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= -github.com/openfga/go-sdk v0.3.3 h1:eMZGCEDW/sz9S3gNxbpO5rNpDezz7cjT+zwjpDgqTt0= -github.com/openfga/go-sdk v0.3.3/go.mod h1:W4SNYMSxptGOtA9aGYxsYUmSC7LaZYP7y9qbT36ouCc= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/openfga/go-sdk v0.3.5 h1:KQXhMREh+g/K7HNuZ/YmXuHkREkq0VMKteua4bYr3Uw= +github.com/openfga/go-sdk v0.3.5/go.mod h1:u1iErzj5E9/bhe+8nsMv0gigcYbJtImcdgcE5DmpbBg= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= diff --git a/model_fga_object.go b/model_fga_object.go new file mode 100644 index 0000000..577a67e --- /dev/null +++ b/model_fga_object.go @@ -0,0 +1,142 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// FgaObject Object represents an OpenFGA Object. An Object is composed of a type and identifier (e.g. 'document:1') See https://openfga.dev/docs/concepts#what-is-an-object +type FgaObject struct { + Type string `json:"type"yaml:"type"` + Id string `json:"id"yaml:"id"` +} + +// NewFgaObject instantiates a new FgaObject object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewFgaObject(type_ string, id string) *FgaObject { + this := FgaObject{} + this.Type = type_ + this.Id = id + return &this +} + +// NewFgaObjectWithDefaults instantiates a new FgaObject object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewFgaObjectWithDefaults() *FgaObject { + this := FgaObject{} + return &this +} + +// GetType returns the Type field value +func (o *FgaObject) GetType() string { + if o == nil { + var ret string + return ret + } + + return o.Type +} + +// GetTypeOk returns a tuple with the Type field value +// and a boolean to check if the value has been set. +func (o *FgaObject) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Type, true +} + +// SetType sets field value +func (o *FgaObject) SetType(v string) { + o.Type = v +} + +// GetId returns the Id field value +func (o *FgaObject) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *FgaObject) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *FgaObject) SetId(v string) { + o.Id = v +} + +func (o FgaObject) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + toSerialize["type"] = o.Type + toSerialize["id"] = o.Id + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableFgaObject struct { + value *FgaObject + isSet bool +} + +func (v NullableFgaObject) Get() *FgaObject { + return v.value +} + +func (v *NullableFgaObject) Set(val *FgaObject) { + v.value = val + v.isSet = true +} + +func (v NullableFgaObject) IsSet() bool { + return v.isSet +} + +func (v *NullableFgaObject) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFgaObject(val *FgaObject) *NullableFgaObject { + return &NullableFgaObject{value: val, isSet: true} +} + +func (v NullableFgaObject) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFgaObject) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_list_users_request.go b/model_list_users_request.go new file mode 100644 index 0000000..989aacd --- /dev/null +++ b/model_list_users_request.go @@ -0,0 +1,278 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// ListUsersRequest struct for ListUsersRequest +type ListUsersRequest struct { + AuthorizationModelId *string `json:"authorization_model_id,omitempty"yaml:"authorization_model_id,omitempty"` + Object FgaObject `json:"object"yaml:"object"` + Relation string `json:"relation"yaml:"relation"` + UserFilters []UserTypeFilter `json:"user_filters"yaml:"user_filters"` + ContextualTuples *[]TupleKey `json:"contextual_tuples,omitempty"yaml:"contextual_tuples,omitempty"` + // Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation. + Context *map[string]interface{} `json:"context,omitempty"yaml:"context,omitempty"` +} + +// NewListUsersRequest instantiates a new ListUsersRequest object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewListUsersRequest(object FgaObject, relation string, userFilters []UserTypeFilter) *ListUsersRequest { + this := ListUsersRequest{} + this.Object = object + this.Relation = relation + this.UserFilters = userFilters + return &this +} + +// NewListUsersRequestWithDefaults instantiates a new ListUsersRequest object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewListUsersRequestWithDefaults() *ListUsersRequest { + this := ListUsersRequest{} + return &this +} + +// GetAuthorizationModelId returns the AuthorizationModelId field value if set, zero value otherwise. +func (o *ListUsersRequest) GetAuthorizationModelId() string { + if o == nil || o.AuthorizationModelId == nil { + var ret string + return ret + } + return *o.AuthorizationModelId +} + +// GetAuthorizationModelIdOk returns a tuple with the AuthorizationModelId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ListUsersRequest) GetAuthorizationModelIdOk() (*string, bool) { + if o == nil || o.AuthorizationModelId == nil { + return nil, false + } + return o.AuthorizationModelId, true +} + +// HasAuthorizationModelId returns a boolean if a field has been set. +func (o *ListUsersRequest) HasAuthorizationModelId() bool { + if o != nil && o.AuthorizationModelId != nil { + return true + } + + return false +} + +// SetAuthorizationModelId gets a reference to the given string and assigns it to the AuthorizationModelId field. +func (o *ListUsersRequest) SetAuthorizationModelId(v string) { + o.AuthorizationModelId = &v +} + +// GetObject returns the Object field value +func (o *ListUsersRequest) GetObject() FgaObject { + if o == nil { + var ret FgaObject + return ret + } + + return o.Object +} + +// GetObjectOk returns a tuple with the Object field value +// and a boolean to check if the value has been set. +func (o *ListUsersRequest) GetObjectOk() (*FgaObject, bool) { + if o == nil { + return nil, false + } + return &o.Object, true +} + +// SetObject sets field value +func (o *ListUsersRequest) SetObject(v FgaObject) { + o.Object = v +} + +// GetRelation returns the Relation field value +func (o *ListUsersRequest) GetRelation() string { + if o == nil { + var ret string + return ret + } + + return o.Relation +} + +// GetRelationOk returns a tuple with the Relation field value +// and a boolean to check if the value has been set. +func (o *ListUsersRequest) GetRelationOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Relation, true +} + +// SetRelation sets field value +func (o *ListUsersRequest) SetRelation(v string) { + o.Relation = v +} + +// GetUserFilters returns the UserFilters field value +func (o *ListUsersRequest) GetUserFilters() []UserTypeFilter { + if o == nil { + var ret []UserTypeFilter + return ret + } + + return o.UserFilters +} + +// GetUserFiltersOk returns a tuple with the UserFilters field value +// and a boolean to check if the value has been set. +func (o *ListUsersRequest) GetUserFiltersOk() (*[]UserTypeFilter, bool) { + if o == nil { + return nil, false + } + return &o.UserFilters, true +} + +// SetUserFilters sets field value +func (o *ListUsersRequest) SetUserFilters(v []UserTypeFilter) { + o.UserFilters = v +} + +// GetContextualTuples returns the ContextualTuples field value if set, zero value otherwise. +func (o *ListUsersRequest) GetContextualTuples() []TupleKey { + if o == nil || o.ContextualTuples == nil { + var ret []TupleKey + return ret + } + return *o.ContextualTuples +} + +// GetContextualTuplesOk returns a tuple with the ContextualTuples field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ListUsersRequest) GetContextualTuplesOk() (*[]TupleKey, bool) { + if o == nil || o.ContextualTuples == nil { + return nil, false + } + return o.ContextualTuples, true +} + +// HasContextualTuples returns a boolean if a field has been set. +func (o *ListUsersRequest) HasContextualTuples() bool { + if o != nil && o.ContextualTuples != nil { + return true + } + + return false +} + +// SetContextualTuples gets a reference to the given []TupleKey and assigns it to the ContextualTuples field. +func (o *ListUsersRequest) SetContextualTuples(v []TupleKey) { + o.ContextualTuples = &v +} + +// GetContext returns the Context field value if set, zero value otherwise. +func (o *ListUsersRequest) GetContext() map[string]interface{} { + if o == nil || o.Context == nil { + var ret map[string]interface{} + return ret + } + return *o.Context +} + +// GetContextOk returns a tuple with the Context field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ListUsersRequest) GetContextOk() (*map[string]interface{}, bool) { + if o == nil || o.Context == nil { + return nil, false + } + return o.Context, true +} + +// HasContext returns a boolean if a field has been set. +func (o *ListUsersRequest) HasContext() bool { + if o != nil && o.Context != nil { + return true + } + + return false +} + +// SetContext gets a reference to the given map[string]interface{} and assigns it to the Context field. +func (o *ListUsersRequest) SetContext(v map[string]interface{}) { + o.Context = &v +} + +func (o ListUsersRequest) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if o.AuthorizationModelId != nil { + toSerialize["authorization_model_id"] = o.AuthorizationModelId + } + toSerialize["object"] = o.Object + toSerialize["relation"] = o.Relation + toSerialize["user_filters"] = o.UserFilters + if o.ContextualTuples != nil { + toSerialize["contextual_tuples"] = o.ContextualTuples + } + if o.Context != nil { + toSerialize["context"] = o.Context + } + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableListUsersRequest struct { + value *ListUsersRequest + isSet bool +} + +func (v NullableListUsersRequest) Get() *ListUsersRequest { + return v.value +} + +func (v *NullableListUsersRequest) Set(val *ListUsersRequest) { + v.value = val + v.isSet = true +} + +func (v NullableListUsersRequest) IsSet() bool { + return v.isSet +} + +func (v *NullableListUsersRequest) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableListUsersRequest(val *ListUsersRequest) *NullableListUsersRequest { + return &NullableListUsersRequest{value: val, isSet: true} +} + +func (v NullableListUsersRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableListUsersRequest) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_list_users_response.go b/model_list_users_response.go new file mode 100644 index 0000000..211a26c --- /dev/null +++ b/model_list_users_response.go @@ -0,0 +1,142 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// ListUsersResponse struct for ListUsersResponse +type ListUsersResponse struct { + Users []User `json:"users"yaml:"users"` + ExcludedUsers []ObjectOrUserset `json:"excluded_users"yaml:"excluded_users"` +} + +// NewListUsersResponse instantiates a new ListUsersResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewListUsersResponse(users []User, excludedUsers []ObjectOrUserset) *ListUsersResponse { + this := ListUsersResponse{} + this.Users = users + this.ExcludedUsers = excludedUsers + return &this +} + +// NewListUsersResponseWithDefaults instantiates a new ListUsersResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewListUsersResponseWithDefaults() *ListUsersResponse { + this := ListUsersResponse{} + return &this +} + +// GetUsers returns the Users field value +func (o *ListUsersResponse) GetUsers() []User { + if o == nil { + var ret []User + return ret + } + + return o.Users +} + +// GetUsersOk returns a tuple with the Users field value +// and a boolean to check if the value has been set. +func (o *ListUsersResponse) GetUsersOk() (*[]User, bool) { + if o == nil { + return nil, false + } + return &o.Users, true +} + +// SetUsers sets field value +func (o *ListUsersResponse) SetUsers(v []User) { + o.Users = v +} + +// GetExcludedUsers returns the ExcludedUsers field value +func (o *ListUsersResponse) GetExcludedUsers() []ObjectOrUserset { + if o == nil { + var ret []ObjectOrUserset + return ret + } + + return o.ExcludedUsers +} + +// GetExcludedUsersOk returns a tuple with the ExcludedUsers field value +// and a boolean to check if the value has been set. +func (o *ListUsersResponse) GetExcludedUsersOk() (*[]ObjectOrUserset, bool) { + if o == nil { + return nil, false + } + return &o.ExcludedUsers, true +} + +// SetExcludedUsers sets field value +func (o *ListUsersResponse) SetExcludedUsers(v []ObjectOrUserset) { + o.ExcludedUsers = v +} + +func (o ListUsersResponse) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + toSerialize["users"] = o.Users + toSerialize["excluded_users"] = o.ExcludedUsers + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableListUsersResponse struct { + value *ListUsersResponse + isSet bool +} + +func (v NullableListUsersResponse) Get() *ListUsersResponse { + return v.value +} + +func (v *NullableListUsersResponse) Set(val *ListUsersResponse) { + v.value = val + v.isSet = true +} + +func (v NullableListUsersResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableListUsersResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableListUsersResponse(val *ListUsersResponse) *NullableListUsersResponse { + return &NullableListUsersResponse{value: val, isSet: true} +} + +func (v NullableListUsersResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableListUsersResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_object_or_userset.go b/model_object_or_userset.go new file mode 100644 index 0000000..e6daefb --- /dev/null +++ b/model_object_or_userset.go @@ -0,0 +1,160 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// ObjectOrUserset struct for ObjectOrUserset +type ObjectOrUserset struct { + Object *FgaObject `json:"object,omitempty"yaml:"object,omitempty"` + Userset *UsersetUser `json:"userset,omitempty"yaml:"userset,omitempty"` +} + +// NewObjectOrUserset instantiates a new ObjectOrUserset object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewObjectOrUserset() *ObjectOrUserset { + this := ObjectOrUserset{} + return &this +} + +// NewObjectOrUsersetWithDefaults instantiates a new ObjectOrUserset object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewObjectOrUsersetWithDefaults() *ObjectOrUserset { + this := ObjectOrUserset{} + return &this +} + +// GetObject returns the Object field value if set, zero value otherwise. +func (o *ObjectOrUserset) GetObject() FgaObject { + if o == nil || o.Object == nil { + var ret FgaObject + return ret + } + return *o.Object +} + +// GetObjectOk returns a tuple with the Object field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ObjectOrUserset) GetObjectOk() (*FgaObject, bool) { + if o == nil || o.Object == nil { + return nil, false + } + return o.Object, true +} + +// HasObject returns a boolean if a field has been set. +func (o *ObjectOrUserset) HasObject() bool { + if o != nil && o.Object != nil { + return true + } + + return false +} + +// SetObject gets a reference to the given FgaObject and assigns it to the Object field. +func (o *ObjectOrUserset) SetObject(v FgaObject) { + o.Object = &v +} + +// GetUserset returns the Userset field value if set, zero value otherwise. +func (o *ObjectOrUserset) GetUserset() UsersetUser { + if o == nil || o.Userset == nil { + var ret UsersetUser + return ret + } + return *o.Userset +} + +// GetUsersetOk returns a tuple with the Userset field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ObjectOrUserset) GetUsersetOk() (*UsersetUser, bool) { + if o == nil || o.Userset == nil { + return nil, false + } + return o.Userset, true +} + +// HasUserset returns a boolean if a field has been set. +func (o *ObjectOrUserset) HasUserset() bool { + if o != nil && o.Userset != nil { + return true + } + + return false +} + +// SetUserset gets a reference to the given UsersetUser and assigns it to the Userset field. +func (o *ObjectOrUserset) SetUserset(v UsersetUser) { + o.Userset = &v +} + +func (o ObjectOrUserset) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if o.Object != nil { + toSerialize["object"] = o.Object + } + if o.Userset != nil { + toSerialize["userset"] = o.Userset + } + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableObjectOrUserset struct { + value *ObjectOrUserset + isSet bool +} + +func (v NullableObjectOrUserset) Get() *ObjectOrUserset { + return v.value +} + +func (v *NullableObjectOrUserset) Set(val *ObjectOrUserset) { + v.value = val + v.isSet = true +} + +func (v NullableObjectOrUserset) IsSet() bool { + return v.isSet +} + +func (v *NullableObjectOrUserset) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableObjectOrUserset(val *ObjectOrUserset) *NullableObjectOrUserset { + return &NullableObjectOrUserset{value: val, isSet: true} +} + +func (v NullableObjectOrUserset) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableObjectOrUserset) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_typed_wildcard.go b/model_typed_wildcard.go new file mode 100644 index 0000000..ee07324 --- /dev/null +++ b/model_typed_wildcard.go @@ -0,0 +1,115 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// TypedWildcard struct for TypedWildcard +type TypedWildcard struct { + Type string `json:"type"yaml:"type"` +} + +// NewTypedWildcard instantiates a new TypedWildcard object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewTypedWildcard(type_ string) *TypedWildcard { + this := TypedWildcard{} + this.Type = type_ + return &this +} + +// NewTypedWildcardWithDefaults instantiates a new TypedWildcard object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewTypedWildcardWithDefaults() *TypedWildcard { + this := TypedWildcard{} + return &this +} + +// GetType returns the Type field value +func (o *TypedWildcard) GetType() string { + if o == nil { + var ret string + return ret + } + + return o.Type +} + +// GetTypeOk returns a tuple with the Type field value +// and a boolean to check if the value has been set. +func (o *TypedWildcard) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Type, true +} + +// SetType sets field value +func (o *TypedWildcard) SetType(v string) { + o.Type = v +} + +func (o TypedWildcard) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + toSerialize["type"] = o.Type + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableTypedWildcard struct { + value *TypedWildcard + isSet bool +} + +func (v NullableTypedWildcard) Get() *TypedWildcard { + return v.value +} + +func (v *NullableTypedWildcard) Set(val *TypedWildcard) { + v.value = val + v.isSet = true +} + +func (v NullableTypedWildcard) IsSet() bool { + return v.isSet +} + +func (v *NullableTypedWildcard) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTypedWildcard(val *TypedWildcard) *NullableTypedWildcard { + return &NullableTypedWildcard{value: val, isSet: true} +} + +func (v NullableTypedWildcard) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableTypedWildcard) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_unprocessable_content_error_code.go b/model_unprocessable_content_error_code.go new file mode 100644 index 0000000..7b98ba9 --- /dev/null +++ b/model_unprocessable_content_error_code.go @@ -0,0 +1,111 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "encoding/json" + "fmt" +) + +// UnprocessableContentErrorCode the model 'UnprocessableContentErrorCode' +type UnprocessableContentErrorCode string + +// List of UnprocessableContentErrorCode +const ( + NO_THROTTLED_ERROR_CODE UnprocessableContentErrorCode = "no_throttled_error_code" + THROTTLED_TIMEOUT_ERROR UnprocessableContentErrorCode = "throttled_timeout_error" +) + +var allowedUnprocessableContentErrorCodeEnumValues = []UnprocessableContentErrorCode{ + "no_throttled_error_code", + "throttled_timeout_error", +} + +func (v *UnprocessableContentErrorCode) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := UnprocessableContentErrorCode(value) + for _, existing := range allowedUnprocessableContentErrorCodeEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid UnprocessableContentErrorCode", value) +} + +// NewUnprocessableContentErrorCodeFromValue returns a pointer to a valid UnprocessableContentErrorCode +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewUnprocessableContentErrorCodeFromValue(v string) (*UnprocessableContentErrorCode, error) { + ev := UnprocessableContentErrorCode(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for UnprocessableContentErrorCode: valid values are %v", v, allowedUnprocessableContentErrorCodeEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v UnprocessableContentErrorCode) IsValid() bool { + for _, existing := range allowedUnprocessableContentErrorCodeEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to UnprocessableContentErrorCode value +func (v UnprocessableContentErrorCode) Ptr() *UnprocessableContentErrorCode { + return &v +} + +type NullableUnprocessableContentErrorCode struct { + value *UnprocessableContentErrorCode + isSet bool +} + +func (v NullableUnprocessableContentErrorCode) Get() *UnprocessableContentErrorCode { + return v.value +} + +func (v *NullableUnprocessableContentErrorCode) Set(val *UnprocessableContentErrorCode) { + v.value = val + v.isSet = true +} + +func (v NullableUnprocessableContentErrorCode) IsSet() bool { + return v.isSet +} + +func (v *NullableUnprocessableContentErrorCode) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUnprocessableContentErrorCode(val *UnprocessableContentErrorCode) *NullableUnprocessableContentErrorCode { + return &NullableUnprocessableContentErrorCode{value: val, isSet: true} +} + +func (v NullableUnprocessableContentErrorCode) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUnprocessableContentErrorCode) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_unprocessable_content_message_response.go b/model_unprocessable_content_message_response.go new file mode 100644 index 0000000..5c565a7 --- /dev/null +++ b/model_unprocessable_content_message_response.go @@ -0,0 +1,164 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// UnprocessableContentMessageResponse struct for UnprocessableContentMessageResponse +type UnprocessableContentMessageResponse struct { + Code *UnprocessableContentErrorCode `json:"code,omitempty"yaml:"code,omitempty"` + Message *string `json:"message,omitempty"yaml:"message,omitempty"` +} + +// NewUnprocessableContentMessageResponse instantiates a new UnprocessableContentMessageResponse object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUnprocessableContentMessageResponse() *UnprocessableContentMessageResponse { + this := UnprocessableContentMessageResponse{} + var code UnprocessableContentErrorCode = NO_THROTTLED_ERROR_CODE + this.Code = &code + return &this +} + +// NewUnprocessableContentMessageResponseWithDefaults instantiates a new UnprocessableContentMessageResponse object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUnprocessableContentMessageResponseWithDefaults() *UnprocessableContentMessageResponse { + this := UnprocessableContentMessageResponse{} + var code UnprocessableContentErrorCode = NO_THROTTLED_ERROR_CODE + this.Code = &code + return &this +} + +// GetCode returns the Code field value if set, zero value otherwise. +func (o *UnprocessableContentMessageResponse) GetCode() UnprocessableContentErrorCode { + if o == nil || o.Code == nil { + var ret UnprocessableContentErrorCode + return ret + } + return *o.Code +} + +// GetCodeOk returns a tuple with the Code field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UnprocessableContentMessageResponse) GetCodeOk() (*UnprocessableContentErrorCode, bool) { + if o == nil || o.Code == nil { + return nil, false + } + return o.Code, true +} + +// HasCode returns a boolean if a field has been set. +func (o *UnprocessableContentMessageResponse) HasCode() bool { + if o != nil && o.Code != nil { + return true + } + + return false +} + +// SetCode gets a reference to the given UnprocessableContentErrorCode and assigns it to the Code field. +func (o *UnprocessableContentMessageResponse) SetCode(v UnprocessableContentErrorCode) { + o.Code = &v +} + +// GetMessage returns the Message field value if set, zero value otherwise. +func (o *UnprocessableContentMessageResponse) GetMessage() string { + if o == nil || o.Message == nil { + var ret string + return ret + } + return *o.Message +} + +// GetMessageOk returns a tuple with the Message field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UnprocessableContentMessageResponse) GetMessageOk() (*string, bool) { + if o == nil || o.Message == nil { + return nil, false + } + return o.Message, true +} + +// HasMessage returns a boolean if a field has been set. +func (o *UnprocessableContentMessageResponse) HasMessage() bool { + if o != nil && o.Message != nil { + return true + } + + return false +} + +// SetMessage gets a reference to the given string and assigns it to the Message field. +func (o *UnprocessableContentMessageResponse) SetMessage(v string) { + o.Message = &v +} + +func (o UnprocessableContentMessageResponse) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if o.Code != nil { + toSerialize["code"] = o.Code + } + if o.Message != nil { + toSerialize["message"] = o.Message + } + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableUnprocessableContentMessageResponse struct { + value *UnprocessableContentMessageResponse + isSet bool +} + +func (v NullableUnprocessableContentMessageResponse) Get() *UnprocessableContentMessageResponse { + return v.value +} + +func (v *NullableUnprocessableContentMessageResponse) Set(val *UnprocessableContentMessageResponse) { + v.value = val + v.isSet = true +} + +func (v NullableUnprocessableContentMessageResponse) IsSet() bool { + return v.isSet +} + +func (v *NullableUnprocessableContentMessageResponse) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUnprocessableContentMessageResponse(val *UnprocessableContentMessageResponse) *NullableUnprocessableContentMessageResponse { + return &NullableUnprocessableContentMessageResponse{value: val, isSet: true} +} + +func (v NullableUnprocessableContentMessageResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUnprocessableContentMessageResponse) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_user.go b/model_user.go new file mode 100644 index 0000000..42784d0 --- /dev/null +++ b/model_user.go @@ -0,0 +1,196 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// User struct for User +type User struct { + Object *FgaObject `json:"object,omitempty"yaml:"object,omitempty"` + Userset *UsersetUser `json:"userset,omitempty"yaml:"userset,omitempty"` + Wildcard *TypedWildcard `json:"wildcard,omitempty"yaml:"wildcard,omitempty"` +} + +// NewUser instantiates a new User object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUser() *User { + this := User{} + return &this +} + +// NewUserWithDefaults instantiates a new User object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUserWithDefaults() *User { + this := User{} + return &this +} + +// GetObject returns the Object field value if set, zero value otherwise. +func (o *User) GetObject() FgaObject { + if o == nil || o.Object == nil { + var ret FgaObject + return ret + } + return *o.Object +} + +// GetObjectOk returns a tuple with the Object field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *User) GetObjectOk() (*FgaObject, bool) { + if o == nil || o.Object == nil { + return nil, false + } + return o.Object, true +} + +// HasObject returns a boolean if a field has been set. +func (o *User) HasObject() bool { + if o != nil && o.Object != nil { + return true + } + + return false +} + +// SetObject gets a reference to the given FgaObject and assigns it to the Object field. +func (o *User) SetObject(v FgaObject) { + o.Object = &v +} + +// GetUserset returns the Userset field value if set, zero value otherwise. +func (o *User) GetUserset() UsersetUser { + if o == nil || o.Userset == nil { + var ret UsersetUser + return ret + } + return *o.Userset +} + +// GetUsersetOk returns a tuple with the Userset field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *User) GetUsersetOk() (*UsersetUser, bool) { + if o == nil || o.Userset == nil { + return nil, false + } + return o.Userset, true +} + +// HasUserset returns a boolean if a field has been set. +func (o *User) HasUserset() bool { + if o != nil && o.Userset != nil { + return true + } + + return false +} + +// SetUserset gets a reference to the given UsersetUser and assigns it to the Userset field. +func (o *User) SetUserset(v UsersetUser) { + o.Userset = &v +} + +// GetWildcard returns the Wildcard field value if set, zero value otherwise. +func (o *User) GetWildcard() TypedWildcard { + if o == nil || o.Wildcard == nil { + var ret TypedWildcard + return ret + } + return *o.Wildcard +} + +// GetWildcardOk returns a tuple with the Wildcard field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *User) GetWildcardOk() (*TypedWildcard, bool) { + if o == nil || o.Wildcard == nil { + return nil, false + } + return o.Wildcard, true +} + +// HasWildcard returns a boolean if a field has been set. +func (o *User) HasWildcard() bool { + if o != nil && o.Wildcard != nil { + return true + } + + return false +} + +// SetWildcard gets a reference to the given TypedWildcard and assigns it to the Wildcard field. +func (o *User) SetWildcard(v TypedWildcard) { + o.Wildcard = &v +} + +func (o User) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if o.Object != nil { + toSerialize["object"] = o.Object + } + if o.Userset != nil { + toSerialize["userset"] = o.Userset + } + if o.Wildcard != nil { + toSerialize["wildcard"] = o.Wildcard + } + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableUser struct { + value *User + isSet bool +} + +func (v NullableUser) Get() *User { + return v.value +} + +func (v *NullableUser) Set(val *User) { + v.value = val + v.isSet = true +} + +func (v NullableUser) IsSet() bool { + return v.isSet +} + +func (v *NullableUser) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUser(val *User) *NullableUser { + return &NullableUser{value: val, isSet: true} +} + +func (v NullableUser) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUser) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_user_type_filter.go b/model_user_type_filter.go new file mode 100644 index 0000000..38c02e2 --- /dev/null +++ b/model_user_type_filter.go @@ -0,0 +1,151 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// UserTypeFilter struct for UserTypeFilter +type UserTypeFilter struct { + Type string `json:"type"yaml:"type"` + Relation *string `json:"relation,omitempty"yaml:"relation,omitempty"` +} + +// NewUserTypeFilter instantiates a new UserTypeFilter object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUserTypeFilter(type_ string) *UserTypeFilter { + this := UserTypeFilter{} + this.Type = type_ + return &this +} + +// NewUserTypeFilterWithDefaults instantiates a new UserTypeFilter object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUserTypeFilterWithDefaults() *UserTypeFilter { + this := UserTypeFilter{} + return &this +} + +// GetType returns the Type field value +func (o *UserTypeFilter) GetType() string { + if o == nil { + var ret string + return ret + } + + return o.Type +} + +// GetTypeOk returns a tuple with the Type field value +// and a boolean to check if the value has been set. +func (o *UserTypeFilter) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Type, true +} + +// SetType sets field value +func (o *UserTypeFilter) SetType(v string) { + o.Type = v +} + +// GetRelation returns the Relation field value if set, zero value otherwise. +func (o *UserTypeFilter) GetRelation() string { + if o == nil || o.Relation == nil { + var ret string + return ret + } + return *o.Relation +} + +// GetRelationOk returns a tuple with the Relation field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UserTypeFilter) GetRelationOk() (*string, bool) { + if o == nil || o.Relation == nil { + return nil, false + } + return o.Relation, true +} + +// HasRelation returns a boolean if a field has been set. +func (o *UserTypeFilter) HasRelation() bool { + if o != nil && o.Relation != nil { + return true + } + + return false +} + +// SetRelation gets a reference to the given string and assigns it to the Relation field. +func (o *UserTypeFilter) SetRelation(v string) { + o.Relation = &v +} + +func (o UserTypeFilter) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + toSerialize["type"] = o.Type + if o.Relation != nil { + toSerialize["relation"] = o.Relation + } + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableUserTypeFilter struct { + value *UserTypeFilter + isSet bool +} + +func (v NullableUserTypeFilter) Get() *UserTypeFilter { + return v.value +} + +func (v *NullableUserTypeFilter) Set(val *UserTypeFilter) { + v.value = val + v.isSet = true +} + +func (v NullableUserTypeFilter) IsSet() bool { + return v.isSet +} + +func (v *NullableUserTypeFilter) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUserTypeFilter(val *UserTypeFilter) *NullableUserTypeFilter { + return &NullableUserTypeFilter{value: val, isSet: true} +} + +func (v NullableUserTypeFilter) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUserTypeFilter) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/model_userset_user.go b/model_userset_user.go new file mode 100644 index 0000000..981aef0 --- /dev/null +++ b/model_userset_user.go @@ -0,0 +1,169 @@ +/** + * Go SDK for OpenFGA + * + * API version: 0.1 + * Website: https://openfga.dev + * Documentation: https://openfga.dev/docs + * Support: https://openfga.dev/community + * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE) + * + * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. + */ + +package openfga + +import ( + "bytes" + + "encoding/json" +) + +// UsersetUser struct for UsersetUser +type UsersetUser struct { + Type string `json:"type"yaml:"type"` + Id string `json:"id"yaml:"id"` + Relation string `json:"relation"yaml:"relation"` +} + +// NewUsersetUser instantiates a new UsersetUser object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUsersetUser(type_ string, id string, relation string) *UsersetUser { + this := UsersetUser{} + this.Type = type_ + this.Id = id + this.Relation = relation + return &this +} + +// NewUsersetUserWithDefaults instantiates a new UsersetUser object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUsersetUserWithDefaults() *UsersetUser { + this := UsersetUser{} + return &this +} + +// GetType returns the Type field value +func (o *UsersetUser) GetType() string { + if o == nil { + var ret string + return ret + } + + return o.Type +} + +// GetTypeOk returns a tuple with the Type field value +// and a boolean to check if the value has been set. +func (o *UsersetUser) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Type, true +} + +// SetType sets field value +func (o *UsersetUser) SetType(v string) { + o.Type = v +} + +// GetId returns the Id field value +func (o *UsersetUser) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *UsersetUser) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *UsersetUser) SetId(v string) { + o.Id = v +} + +// GetRelation returns the Relation field value +func (o *UsersetUser) GetRelation() string { + if o == nil { + var ret string + return ret + } + + return o.Relation +} + +// GetRelationOk returns a tuple with the Relation field value +// and a boolean to check if the value has been set. +func (o *UsersetUser) GetRelationOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Relation, true +} + +// SetRelation sets field value +func (o *UsersetUser) SetRelation(v string) { + o.Relation = v +} + +func (o UsersetUser) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + toSerialize["type"] = o.Type + toSerialize["id"] = o.Id + toSerialize["relation"] = o.Relation + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + err := enc.Encode(toSerialize) + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + +type NullableUsersetUser struct { + value *UsersetUser + isSet bool +} + +func (v NullableUsersetUser) Get() *UsersetUser { + return v.value +} + +func (v *NullableUsersetUser) Set(val *UsersetUser) { + v.value = val + v.isSet = true +} + +func (v NullableUsersetUser) IsSet() bool { + return v.isSet +} + +func (v *NullableUsersetUser) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUsersetUser(val *UsersetUser) *NullableUsersetUser { + return &NullableUsersetUser{value: val, isSet: true} +} + +func (v NullableUsersetUser) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUsersetUser) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} From 17c79daab16fed7c62c6bcac6c74166b301ec7f9 Mon Sep 17 00:00:00 2001 From: Raghd Hamzeh Date: Mon, 29 Apr 2024 23:11:18 -0400 Subject: [PATCH 2/2] release: v0.3.6 with ListUsers --- .openapi-generator/FILES | 1 - CHANGELOG.md | 7 +++++++ configuration.go | 4 ++-- example/example1/go.mod | 6 +++--- example/example1/go.sum | 2 -- go.mod | 2 +- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index b08e166..46c0ff2 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -105,7 +105,6 @@ example/Makefile example/README.md example/example1/example1.go example/example1/go.mod -example/example1/go.sum git_push.sh go.mod go.sum diff --git a/CHANGELOG.md b/CHANGELOG.md index baf78ea..e231f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## v0.3.6 + +### [0.3.6](https://github.com/openfga/go-sdk/compare/v0.3.5...v0.3.6) (2024-04-30) + +- feat: support the [ListUsers](https://github.com/openfga/rfcs/blob/main/20231214-listUsers-api.md) endpoint (#81) +- feat: add retries to client credential requests (#51) + ## v0.3.5 ### [0.3.5](https://github.com/openfga/go-sdk/compare/v0.3.4...v0.3.5) (2024-02-13) diff --git a/configuration.go b/configuration.go index b05bf9a..04a9580 100644 --- a/configuration.go +++ b/configuration.go @@ -20,9 +20,9 @@ import ( ) const ( - SdkVersion = "0.3.5" + SdkVersion = "0.3.6" - defaultUserAgent = "openfga-sdk go/0.3.5" + defaultUserAgent = "openfga-sdk go/0.3.6" ) // RetryParams configures configuration for retry in case of HTTP too many request diff --git a/example/example1/go.mod b/example/example1/go.mod index 187b3eb..c7d0c66 100644 --- a/example/example1/go.mod +++ b/example/example1/go.mod @@ -1,10 +1,10 @@ module example1 -go 1.21.9 +go 1.22.2 -require github.com/openfga/go-sdk v0.3.5 +require github.com/openfga/go-sdk v0.3.6 require golang.org/x/sync v0.7.0 // indirect // To reference local build, uncomment below and run `go mod tidy` -//replace github.com/openfga/go-sdk v0.3.5 => ../../ +replace github.com/openfga/go-sdk v0.3.6 => ../../ diff --git a/example/example1/go.sum b/example/example1/go.sum index e8778b2..623e552 100644 --- a/example/example1/go.sum +++ b/example/example1/go.sum @@ -1,6 +1,4 @@ github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= -github.com/openfga/go-sdk v0.3.5 h1:KQXhMREh+g/K7HNuZ/YmXuHkREkq0VMKteua4bYr3Uw= -github.com/openfga/go-sdk v0.3.5/go.mod h1:u1iErzj5E9/bhe+8nsMv0gigcYbJtImcdgcE5DmpbBg= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= diff --git a/go.mod b/go.mod index cb13d39..236c08b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/openfga/go-sdk -go 1.21 +go 1.21.9 require ( github.com/jarcoal/httpmock v1.3.1