Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release(v0.3.0): with conditions support and several breaking changes #61

Merged
merged 2 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ configuration.go
credentials/credentials.go
docs/Any.md
docs/Assertion.md
docs/AssertionTupleKey.md
docs/AuthorizationModel.md
docs/CheckRequest.md
docs/CheckRequestTupleKey.md
Expand Down Expand Up @@ -93,6 +94,7 @@ internal/utils/ulid.go
internal/utils/ulid_test.go
model_any.go
model_assertion.go
model_assertion_tuple_key.go
model_authorization_model.go
model_check_request.go
model_check_request_tuple_key.go
Expand Down
44 changes: 43 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,51 @@

## v0.3.0

### [0.3.0](https://github.com/openfga/go-sdk/compare/v0.2.3...v0.3.0) (2023-11-02)
### [0.3.0](https://github.com/openfga/go-sdk/compare/v0.2.3...v0.3.0) (2023-12-11)

- feat!: initial support for conditions
- feat: support specifying a port and path for the API (You can now set the `ApiUrl` to something like: `https://api.fga.exampleL8080/some_path`)
- fix: resolve a bug in `NewCredentials` (#60) - thanks @harper
- chore!: use latest API interfaces
- chore: dependency updates


BREAKING CHANGES:
Note: This release comes with substantial breaking changes, especially to the interfaces due to the protobuf changes in the last release.

While the http interfaces did not break (you can still use `v0.2.3` SDK with a `v1.3.8+` server),
the grpc interface did and this caused a few changes in the interfaces of the SDK.

You will have to modify some parts of your code, but we hope this will be to the better as a lot of the parameters are now correctly marked as required,
and so the Pointer-to-String conversion is no longer needed.

Some of the changes to expect:

* When initializing a client, please use `ApiUrl`. The separate `ApiScheme` and `ApiHost` fields have been deprecated
```go
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
})
```
- When initializing a client, `AuthorizationModelId` is no longer a pointer, and you can just pass the string directly
- The `OpenFgaClient` now has methods to get and set the model ID `GetAuthorizationModelId` and `SetAuthorizationModelId`
- The following request interfaces changed:
- `CheckRequest`: the `TupleKey` field is now of interface `CheckRequestTupleKey`, you can also now pass in `Context`
- `ExpandRequest`: the `TupleKey` field is now of interface `ExpandRequestTupleKey`
- `ReadRequest`: the `TupleKey` field is now of interface `ReadRequestTupleKey`
- `WriteRequest`: now takes `WriteRequestWrites` and `WriteRequestDeletes`
- And more
- The following interfaces had fields that were pointers are are now the direct value:
- `CreateStoreResponse`
- `GetStoreResponse`
- `ListStoresResponse`
- `ListObjectsResponse`
- `ReadChangesResponse`
- `ReadResponse`
- `AuthorizationModel` and several interfaces under it
- And more

## v0.2.3

Expand Down
7 changes: 5 additions & 2 deletions README.md
adriantam marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,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
})

if err != nil {
Expand All @@ -134,6 +135,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
Credentials: &credentials.Credentials{
Method: credentials.CredentialsMethodApiToken,
Config: &credentials.Config{
Expand Down Expand Up @@ -162,7 +164,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: openfga.PtrString("OPENFGA_AUTHORIZATION_MODEL_ID"),
AuthorizationModelId: os.Getenv("FGA_AUTHORIZATION_MODEL_ID"), // optional, recommended to be set for production
Credentials: &credentials.Credentials{
Method: credentials.CredentialsMethodClientCredentials,
Config: &credentials.Config{
Expand Down Expand Up @@ -224,7 +226,7 @@ if err != nil {

// store store.Id in database
// update the storeId of the current instance
fgaClient.SetStoreId(*store.Id)
fgaClient.SetStoreId(store.Id)
// continue calling the API normally, scoped to this store
```

Expand Down Expand Up @@ -796,6 +798,7 @@ Class | Method | HTTP request | Description

- [Any](docs/Any.md)
- [Assertion](docs/Assertion.md)
- [AssertionTupleKey](docs/AssertionTupleKey.md)
- [AuthorizationModel](docs/AuthorizationModel.md)
- [CheckRequest](docs/CheckRequest.md)
- [CheckRequestTupleKey](docs/CheckRequestTupleKey.md)
Expand Down
47 changes: 33 additions & 14 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ type ClientConfiguration struct {
fgaSdk.Configuration
// ApiScheme - defines the scheme for the API: http or https
// Deprecated: use ApiUrl instead of ApiScheme and ApiHost
ApiScheme string `json:"api_scheme,omitempty"`
ApiScheme string `json:"api_scheme"`
// ApiHost - defines the host for the API without the scheme e.g. (api.fga.example)
// Deprecated: use ApiUrl instead of ApiScheme and ApiHost
ApiHost string `json:"api_host,omitempty"`
ApiUrl string `json:"api_url,omitempty"`
StoreId string `json:"store_id,omitempty"`
AuthorizationModelId *string `json:"authorization_model_id,omitempty"`
Credentials *credentials.Credentials `json:"credentials,omitempty"`
DefaultHeaders map[string]string `json:"default_headers,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
Debug bool `json:"debug,omitempty"`
ApiHost string `json:"api_host"`
ApiUrl string `json:"api_url"`
StoreId string `json:"store_id"`
AuthorizationModelId string `json:"authorization_model_id"`
Credentials *credentials.Credentials `json:"credentials"`
DefaultHeaders map[string]string `json:"default_headers"`
UserAgent string `json:"user_agent"`
Debug bool `json:"debug"`
HTTPClient *_nethttp.Client
RetryParams *fgaSdk.RetryParams
}
Expand Down Expand Up @@ -94,7 +94,7 @@ func NewSdkClient(cfg *ClientConfiguration) (*OpenFgaClient, error) {

// store id is already validate as part of configuration validation

if cfg.AuthorizationModelId != nil && *cfg.AuthorizationModelId != "" && !internalutils.IsWellFormedUlidString(*cfg.AuthorizationModelId) {
if cfg.AuthorizationModelId != "" && !internalutils.IsWellFormedUlidString(cfg.AuthorizationModelId) {
return nil, FgaInvalidError{param: "AuthorizationModelId", description: "ULID"}
}

Expand Down Expand Up @@ -417,16 +417,35 @@ type SdkClient interface {
WriteAssertionsExecute(request SdkClientWriteAssertionsRequestInterface) (*ClientWriteAssertionsResponse, error)
}

func (client *OpenFgaClient) SetAuthorizationModelId(authorizationModelId string) error {
if authorizationModelId != "" && !internalutils.IsWellFormedUlidString(authorizationModelId) {
return FgaInvalidError{param: "AuthorizationModelId", description: "ULID"}
}

client.config.AuthorizationModelId = authorizationModelId

return nil
}

func (client *OpenFgaClient) GetAuthorizationModelId() (string, error) {
modelId := client.config.AuthorizationModelId
if modelId != "" && !internalutils.IsWellFormedUlidString(modelId) {
return "", FgaInvalidError{param: "AuthorizationModelId", description: "ULID"}
}

return modelId, nil
}

func (client *OpenFgaClient) getAuthorizationModelId(authorizationModelId *string) (*string, error) {
modelId := client.config.AuthorizationModelId
if authorizationModelId != nil && *authorizationModelId != "" {
modelId = authorizationModelId
modelId = *authorizationModelId
}

if modelId != nil && *modelId != "" && !internalutils.IsWellFormedUlidString(*modelId) {
if modelId != "" && !internalutils.IsWellFormedUlidString(modelId) {
return nil, FgaInvalidError{param: "AuthorizationModelId", description: "ULID"}
}
return modelId, nil
return &modelId, nil
}

// helper function to validate the connection (i.e., get token)
Expand Down Expand Up @@ -2226,7 +2245,7 @@ type ClientWriteAssertionsRequest = []ClientAssertion

func (clientAssertion ClientAssertion) ToAssertion() fgaSdk.Assertion {
return fgaSdk.Assertion{
TupleKey: fgaSdk.CheckRequestTupleKey{
TupleKey: fgaSdk.AssertionTupleKey{
User: clientAssertion.User,
Relation: clientAssertion.Relation,
Object: clientAssertion.Object,
Expand Down
9 changes: 4 additions & 5 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func TestOpenFgaClient(t *testing.T) {
_, err := NewSdkClient(&ClientConfiguration{
ApiHost: "api.fga.example",
StoreId: "01GXSB9YR785C4FYS3C0RTG7B2",
AuthorizationModelId: openfga.PtrString("BadAuthID"),
AuthorizationModelId: "BadAuthID",
})
if err == nil {
t.Fatalf("Expect invalid auth mode ID to result in error but there is none")
Expand All @@ -117,7 +117,7 @@ func TestOpenFgaClient(t *testing.T) {
_, err := NewSdkClient(&ClientConfiguration{
ApiHost: "api.fga.example",
StoreId: "01GXSB9YR785C4FYS3C0RTG7B2",
AuthorizationModelId: openfga.PtrString(""),
AuthorizationModelId: "",
})
if err != nil {
t.Fatalf("Expect no error when auth model id is empty but has %v", err)
Expand All @@ -126,9 +126,8 @@ func TestOpenFgaClient(t *testing.T) {

t.Run("Allow specifying an ApiUrl with a port and a base path", func(t *testing.T) {
_, err := NewSdkClient(&ClientConfiguration{
ApiUrl: "https://api.fga.example:8080/fga",
StoreId: "01GXSB9YR785C4FYS3C0RTG7B2",
AuthorizationModelId: openfga.PtrString(""),
ApiUrl: "https://api.fga.example:8080/fga",
StoreId: "01GXSB9YR785C4FYS3C0RTG7B2",
})
if err != nil {
t.Fatalf("Expect no error when auth model id is empty but has %v", err)
Expand Down
4 changes: 2 additions & 2 deletions configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import (
)

const (
SdkVersion = "0.3.0-beta.1"
SdkVersion = "0.3.0"

defaultUserAgent = "openfga-sdk go/0.3.0-beta.1"
defaultUserAgent = "openfga-sdk go/0.3.0"
)

// RetryParams configures configuration for retry in case of HTTP too many request
Expand Down
10 changes: 5 additions & 5 deletions docs/Assertion.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**TupleKey** | [**CheckRequestTupleKey**](CheckRequestTupleKey.md) | |
**TupleKey** | [**AssertionTupleKey**](AssertionTupleKey.md) | |
**Expectation** | **bool** | |

## Methods

### NewAssertion

`func NewAssertion(tupleKey CheckRequestTupleKey, expectation bool, ) *Assertion`
`func NewAssertion(tupleKey AssertionTupleKey, expectation bool, ) *Assertion`

NewAssertion instantiates a new Assertion object
This constructor will assign default values to properties that have it defined,
Expand All @@ -28,20 +28,20 @@ but it doesn't guarantee that properties required by API are set

### GetTupleKey

`func (o *Assertion) GetTupleKey() CheckRequestTupleKey`
`func (o *Assertion) GetTupleKey() AssertionTupleKey`

GetTupleKey returns the TupleKey field if non-nil, zero value otherwise.

### GetTupleKeyOk

`func (o *Assertion) GetTupleKeyOk() (*CheckRequestTupleKey, bool)`
`func (o *Assertion) GetTupleKeyOk() (*AssertionTupleKey, bool)`

GetTupleKeyOk returns a tuple with the TupleKey field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.

### SetTupleKey

`func (o *Assertion) SetTupleKey(v CheckRequestTupleKey)`
`func (o *Assertion) SetTupleKey(v AssertionTupleKey)`

SetTupleKey sets TupleKey field to given value.

Expand Down
93 changes: 93 additions & 0 deletions docs/AssertionTupleKey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# AssertionTupleKey

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Object** | **string** | |
**Relation** | **string** | |
**User** | **string** | |

## Methods

### NewAssertionTupleKey

`func NewAssertionTupleKey(object string, relation string, user string, ) *AssertionTupleKey`

NewAssertionTupleKey instantiates a new AssertionTupleKey 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

### NewAssertionTupleKeyWithDefaults

`func NewAssertionTupleKeyWithDefaults() *AssertionTupleKey`

NewAssertionTupleKeyWithDefaults instantiates a new AssertionTupleKey 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 *AssertionTupleKey) GetObject() string`

GetObject returns the Object field if non-nil, zero value otherwise.

### GetObjectOk

`func (o *AssertionTupleKey) GetObjectOk() (*string, 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 *AssertionTupleKey) SetObject(v string)`

SetObject sets Object field to given value.


### GetRelation

`func (o *AssertionTupleKey) GetRelation() string`

GetRelation returns the Relation field if non-nil, zero value otherwise.

### GetRelationOk

`func (o *AssertionTupleKey) 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 *AssertionTupleKey) SetRelation(v string)`

SetRelation sets Relation field to given value.


### GetUser

`func (o *AssertionTupleKey) GetUser() string`

GetUser returns the User field if non-nil, zero value otherwise.

### GetUserOk

`func (o *AssertionTupleKey) GetUserOk() (*string, bool)`

GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.

### SetUser

`func (o *AssertionTupleKey) SetUser(v string)`

SetUser sets User 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)


2 changes: 1 addition & 1 deletion docs/OpenFgaApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,7 @@ import (
func main() {

authorizationModelId := "authorizationModelId_example" // string |
body := *openapiclient.NewWriteAssertionsRequest([]openapiclient.Assertion{*openapiclient.NewAssertion(*openapiclient.NewCheckRequestTupleKey("user:anne", "reader", "document:2021-budget"), false)}) // WriteAssertionsRequest |
body := *openapiclient.NewWriteAssertionsRequest([]openapiclient.Assertion{*openapiclient.NewAssertion(*openapiclient.NewAssertionTupleKey("document:2021-budget", "reader", "user:anne"), false)}) // WriteAssertionsRequest |

configuration, err := openfga.NewConfiguration(openfga.Configuration{
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/openfga/go-sdk

go 1.21.4
go 1.21.5

require (
github.com/jarcoal/httpmock v1.3.1
Expand Down
Loading
Loading