Skip to content

Commit d27ef8f

Browse files
authored
feat: support list users (#81)
* feat: support list users # Conflicts: # .github/workflows/main.yaml # .github/workflows/semgrep.yaml * release: v0.3.6 with ListUsers
1 parent d637093 commit d27ef8f

33 files changed

+3428
-30
lines changed

.openapi-generator/FILES

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,22 @@ docs/ErrorCode.md
4242
docs/ExpandRequest.md
4343
docs/ExpandRequestTupleKey.md
4444
docs/ExpandResponse.md
45+
docs/FgaObject.md
4546
docs/GetStoreResponse.md
4647
docs/InternalErrorCode.md
4748
docs/InternalErrorMessageResponse.md
4849
docs/Leaf.md
4950
docs/ListObjectsRequest.md
5051
docs/ListObjectsResponse.md
5152
docs/ListStoresResponse.md
53+
docs/ListUsersRequest.md
54+
docs/ListUsersResponse.md
5255
docs/Metadata.md
5356
docs/Node.md
5457
docs/Nodes.md
5558
docs/NotFoundErrorCode.md
5659
docs/NullValue.md
60+
docs/ObjectOrUserset.md
5761
docs/ObjectRelation.md
5862
docs/OpenFgaApi.md
5963
docs/PathUnknownErrorMessageResponse.md
@@ -78,11 +82,17 @@ docs/TupleOperation.md
7882
docs/TupleToUserset.md
7983
docs/TypeDefinition.md
8084
docs/TypeName.md
85+
docs/TypedWildcard.md
86+
docs/UnprocessableContentErrorCode.md
87+
docs/UnprocessableContentMessageResponse.md
88+
docs/User.md
89+
docs/UserTypeFilter.md
8190
docs/Users.md
8291
docs/Userset.md
8392
docs/UsersetTree.md
8493
docs/UsersetTreeDifference.md
8594
docs/UsersetTreeTupleToUserset.md
95+
docs/UsersetUser.md
8696
docs/Usersets.md
8797
docs/ValidationErrorMessageResponse.md
8898
docs/WriteAssertionsRequest.md
@@ -95,7 +105,6 @@ example/Makefile
95105
example/README.md
96106
example/example1/example1.go
97107
example/example1/go.mod
98-
example/example1/go.sum
99108
git_push.sh
100109
go.mod
101110
go.sum
@@ -122,18 +131,22 @@ model_error_code.go
122131
model_expand_request.go
123132
model_expand_request_tuple_key.go
124133
model_expand_response.go
134+
model_fga_object.go
125135
model_get_store_response.go
126136
model_internal_error_code.go
127137
model_internal_error_message_response.go
128138
model_leaf.go
129139
model_list_objects_request.go
130140
model_list_objects_response.go
131141
model_list_stores_response.go
142+
model_list_users_request.go
143+
model_list_users_response.go
132144
model_metadata.go
133145
model_node.go
134146
model_nodes.go
135147
model_not_found_error_code.go
136148
model_null_value.go
149+
model_object_or_userset.go
137150
model_object_relation.go
138151
model_path_unknown_error_message_response.go
139152
model_read_assertions_response.go
@@ -157,11 +170,17 @@ model_tuple_operation.go
157170
model_tuple_to_userset.go
158171
model_type_definition.go
159172
model_type_name.go
173+
model_typed_wildcard.go
174+
model_unprocessable_content_error_code.go
175+
model_unprocessable_content_message_response.go
176+
model_user.go
177+
model_user_type_filter.go
160178
model_users.go
161179
model_userset.go
162180
model_userset_tree.go
163181
model_userset_tree_difference.go
164182
model_userset_tree_tuple_to_userset.go
183+
model_userset_user.go
165184
model_usersets.go
166185
model_validation_error_message_response.go
167186
model_write_assertions_request.go

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## v0.3.6
4+
5+
### [0.3.6](https://github.com/openfga/go-sdk/compare/v0.3.5...v0.3.6) (2024-04-30)
6+
7+
- feat: support the [ListUsers](https://github.com/openfga/rfcs/blob/main/20231214-listUsers-api.md) endpoint (#81)
8+
- feat: add retries to client credential requests (#51)
9+
310
## v0.3.5
411

512
### [0.3.5](https://github.com/openfga/go-sdk/compare/v0.3.4...v0.3.5) (2024-02-13)
@@ -61,7 +68,7 @@ Some of the changes to expect:
6168
fgaClient, err := NewSdkClient(&ClientConfiguration{
6269
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
6370
StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
64-
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
71+
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production
6572
})
6673
```
6774
- When initializing a client, `AuthorizationModelId` is no longer a pointer, and you can just pass the string directly

README.md

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ This is an autogenerated Go SDK for OpenFGA. It provides a wrapper around the [O
3838
- [Expand](#expand)
3939
- [List Objects](#list-objects)
4040
- [List Relations](#list-relations)
41+
- [List Users](#list-users)
4142
- [Assertions](#assertions)
4243
- [Read Assertions](#read-assertions)
4344
- [Write Assertions](#write-assertions)
@@ -114,7 +115,7 @@ func main() {
114115
fgaClient, err := NewSdkClient(&ClientConfiguration{
115116
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
116117
StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
117-
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
118+
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production
118119
})
119120

120121
if err != nil {
@@ -136,7 +137,7 @@ func main() {
136137
fgaClient, err := NewSdkClient(&ClientConfiguration{
137138
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
138139
StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
139-
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
140+
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production
140141
Credentials: &credentials.Credentials{
141142
Method: credentials.CredentialsMethodApiToken,
142143
Config: &credentials.Config{
@@ -165,7 +166,7 @@ func main() {
165166
fgaClient, err := NewSdkClient(&ClientConfiguration{
166167
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
167168
StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
168-
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
169+
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production
169170
Credentials: &credentials.Credentials{
170171
Method: credentials.CredentialsMethodClientCredentials,
171172
Config: &credentials.Config{
@@ -197,7 +198,7 @@ func main() {
197198
fgaClient, err := NewSdkClient(&ClientConfiguration{
198199
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
199200
StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
200-
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
201+
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production
201202
Credentials: &credentials.Credentials{
202203
Method: credentials.CredentialsMethodClientCredentials,
203204
Config: &credentials.Config{
@@ -762,6 +763,50 @@ data, err := fgaClient.ListRelations(context.Background()).
762763
// data.Relations = ["can_view", "can_edit"]
763764
```
764765

766+
##### List Users
767+
768+
List the users who have a certain relation to a particular type.
769+
770+
[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/ListUsers)
771+
772+
```golang
773+
options := ClientListRelationsOptions{
774+
// You can rely on the model id set in the configuration or override it for this specific request
775+
AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
776+
}
777+
778+
// Only a single filter is allowed by the API for the time being
779+
userFilters := []openfga.UserTypeFilter{{ Type: "user" }}
780+
// user filters can also be of the form
781+
// userFilters := []openfga.UserTypeFilter{{ Type: "team", Relation: openfga.PtrString("member") }}
782+
783+
requestBody := ClientListUsersRequest{
784+
Object: openfga.Object{
785+
Type: "document",
786+
Id: "roadmap",
787+
},
788+
Relation: "can_read",
789+
UserFilters: userFilters,
790+
ContextualTuples: []ClientContextualTupleKey{{
791+
User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
792+
Relation: "editor",
793+
Object: "folder:product",
794+
}, {
795+
User: "folder:product",
796+
Relation: "parent",
797+
Object: "document:roadmap",
798+
}},
799+
Context: &map[string]interface{}{"ViewCount": 100},
800+
}
801+
data, err := fgaClient.ListRelations(context.Background()).
802+
Body(requestBody).
803+
Options(options).
804+
Execute()
805+
806+
// response.users = [{object: {type: "user", id: "81684243-9356-4421-8fbf-a4f8d36aa31b"}}, {userset: { type: "user" }}, ...]
807+
// response.excluded_users = [ {object: {type: "user", id: "4a455e27-d15a-4434-82e0-136f9c2aa4cf"}}, ... ]
808+
```
809+
765810
### Assertions
766811

767812
#### Read Assertions
@@ -826,7 +871,7 @@ func main() {
826871
fgaClient, err := NewSdkClient(&ClientConfiguration{
827872
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
828873
StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
829-
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
874+
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production
830875
RetryParams: &openfga.RetryParams{
831876
MaxRetry: 3, // retry up to 3 times on API requests
832877
MinWaitInMs: 250, // wait a minimum of 250 milliseconds between requests
@@ -849,6 +894,7 @@ Class | Method | HTTP request | Description
849894
*OpenFgaApi* | [**GetStore**](docs/OpenFgaApi.md#getstore) | **Get** /stores/{store_id} | Get a store
850895
*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
851896
*OpenFgaApi* | [**ListStores**](docs/OpenFgaApi.md#liststores) | **Get** /stores | List all stores
897+
*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
852898
*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
853899
*OpenFgaApi* | [**ReadAssertions**](docs/OpenFgaApi.md#readassertions) | **Get** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID
854900
*OpenFgaApi* | [**ReadAuthorizationModel**](docs/OpenFgaApi.md#readauthorizationmodel) | **Get** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model
@@ -881,18 +927,22 @@ Class | Method | HTTP request | Description
881927
- [ExpandRequest](docs/ExpandRequest.md)
882928
- [ExpandRequestTupleKey](docs/ExpandRequestTupleKey.md)
883929
- [ExpandResponse](docs/ExpandResponse.md)
930+
- [FgaObject](docs/FgaObject.md)
884931
- [GetStoreResponse](docs/GetStoreResponse.md)
885932
- [InternalErrorCode](docs/InternalErrorCode.md)
886933
- [InternalErrorMessageResponse](docs/InternalErrorMessageResponse.md)
887934
- [Leaf](docs/Leaf.md)
888935
- [ListObjectsRequest](docs/ListObjectsRequest.md)
889936
- [ListObjectsResponse](docs/ListObjectsResponse.md)
890937
- [ListStoresResponse](docs/ListStoresResponse.md)
938+
- [ListUsersRequest](docs/ListUsersRequest.md)
939+
- [ListUsersResponse](docs/ListUsersResponse.md)
891940
- [Metadata](docs/Metadata.md)
892941
- [Node](docs/Node.md)
893942
- [Nodes](docs/Nodes.md)
894943
- [NotFoundErrorCode](docs/NotFoundErrorCode.md)
895944
- [NullValue](docs/NullValue.md)
945+
- [ObjectOrUserset](docs/ObjectOrUserset.md)
896946
- [ObjectRelation](docs/ObjectRelation.md)
897947
- [PathUnknownErrorMessageResponse](docs/PathUnknownErrorMessageResponse.md)
898948
- [ReadAssertionsResponse](docs/ReadAssertionsResponse.md)
@@ -916,11 +966,17 @@ Class | Method | HTTP request | Description
916966
- [TupleToUserset](docs/TupleToUserset.md)
917967
- [TypeDefinition](docs/TypeDefinition.md)
918968
- [TypeName](docs/TypeName.md)
969+
- [TypedWildcard](docs/TypedWildcard.md)
970+
- [UnprocessableContentErrorCode](docs/UnprocessableContentErrorCode.md)
971+
- [UnprocessableContentMessageResponse](docs/UnprocessableContentMessageResponse.md)
972+
- [User](docs/User.md)
973+
- [UserTypeFilter](docs/UserTypeFilter.md)
919974
- [Users](docs/Users.md)
920975
- [Userset](docs/Userset.md)
921976
- [UsersetTree](docs/UsersetTree.md)
922977
- [UsersetTreeDifference](docs/UsersetTreeDifference.md)
923978
- [UsersetTreeTupleToUserset](docs/UsersetTreeTupleToUserset.md)
979+
- [UsersetUser](docs/UsersetUser.md)
924980
- [Usersets](docs/Usersets.md)
925981
- [ValidationErrorMessageResponse](docs/ValidationErrorMessageResponse.md)
926982
- [WriteAssertionsRequest](docs/WriteAssertionsRequest.md)

0 commit comments

Comments
 (0)