Skip to content

Commit

Permalink
release(v0.3.0)!: support for conditions and some breaking changes (#36)
Browse files Browse the repository at this point in the history
<!-- Thanks for opening a PR! Here are some quick tips:
If this is your first time contributing, [read our Contributing
Guidelines](https://github.com/openfga/.github/blob/main/CONTRIBUTING.md)
to learn how to create an acceptable PR for this repo.
By submitting a PR to this repository, you agree to the terms within the
[OpenFGA Code of
Conduct](https://github.com/openfga/.github/blob/main/CODE_OF_CONDUCT.md)

If your PR is under active development, please submit it as a "draft".
Once it's ready, open it up for review.
-->

<!-- Provide a brief summary of the changes -->

## Description
<!-- Provide a detailed description of the changes -->

## References
<!-- Provide a list of any applicable references here (Github Issue,
[OpenFGA RFC](https://github.com/openfga/rfcs), other PRs, etc..) -->
- closes #23
- closes #26
- closes #33

## Review Checklist
- [ ] I have clicked on ["allow edits by
maintainers"](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork).
- [ ] I have added documentation for new/changed functionality in this
PR or in a PR to [openfga.dev](https://github.com/openfga/openfga.dev)
[Provide a link to any relevant PRs in the references section above]
- [ ] The correct base branch is being used, if not `main`
- [ ] I have added tests to validate that the change in functionality is
working as expected
  • Loading branch information
rhamzeh authored Dec 20, 2023
2 parents 45e06db + 8c77f04 commit 27514de
Show file tree
Hide file tree
Showing 125 changed files with 3,801 additions and 613 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ By submitting an issue to this repository, you agree to the terms within the [Op
> A clear and concise description of what you expected to happen.
### Additional context
> Add any other context about the problem here.
> Add any other context about the problem here.
18 changes: 18 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "monthly"
groups:
dependencies:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
dependencies:
patterns:
- "*"
36 changes: 34 additions & 2 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.github/CODEOWNERS
.github/ISSUE_TEMPLATE/bug_report.md
.github/ISSUE_TEMPLATE/feature_request.md
.github/dependabot.yaml
.github/workflows/main.yaml
.github/workflows/semgrep.yaml
.gitignore
Expand All @@ -14,18 +15,24 @@ OpenFga.Sdk.sln
README.md
VERSION.txt
assets/FGAIcon.png
docs/AbortedMessageResponse.md
docs/Any.md
docs/Assertion.md
docs/AssertionTupleKey.md
docs/AuthorizationModel.md
docs/CheckRequest.md
docs/CheckRequestTupleKey.md
docs/CheckResponse.md
docs/Computed.md
docs/Condition.md
docs/ConditionParamTypeRef.md
docs/ContextualTupleKeys.md
docs/CreateStoreRequest.md
docs/CreateStoreResponse.md
docs/Difference.md
docs/ErrorCode.md
docs/ExpandRequest.md
docs/ExpandRequestTupleKey.md
docs/ExpandResponse.md
docs/GetStoreResponse.md
docs/InternalErrorCode.md
Expand All @@ -38,6 +45,7 @@ docs/Metadata.md
docs/Node.md
docs/Nodes.md
docs/NotFoundErrorCode.md
docs/NullValue.md
docs/ObjectRelation.md
docs/OpenFgaApi.md
docs/PathUnknownErrorMessageResponse.md
Expand All @@ -46,18 +54,21 @@ docs/ReadAuthorizationModelResponse.md
docs/ReadAuthorizationModelsResponse.md
docs/ReadChangesResponse.md
docs/ReadRequest.md
docs/ReadRequestTupleKey.md
docs/ReadResponse.md
docs/RelationMetadata.md
docs/RelationReference.md
docs/RelationshipCondition.md
docs/Status.md
docs/Store.md
docs/Tuple.md
docs/TupleChange.md
docs/TupleKey.md
docs/TupleKeys.md
docs/TupleKeyWithoutCondition.md
docs/TupleOperation.md
docs/TupleToUserset.md
docs/TypeDefinition.md
docs/TypeName.md
docs/Users.md
docs/Userset.md
docs/UsersetTree.md
Expand All @@ -69,6 +80,12 @@ docs/WriteAssertionsRequest.md
docs/WriteAuthorizationModelRequest.md
docs/WriteAuthorizationModelResponse.md
docs/WriteRequest.md
docs/WriteRequestDeletes.md
docs/WriteRequestWrites.md
example/Example1/Example1.cs
example/Example1/Example1.csproj
example/Makefile
example/README.md
src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs
src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs
src/OpenFga.Sdk.Test/Models/ModelTests.cs
Expand Down Expand Up @@ -105,7 +122,9 @@ src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs
src/OpenFga.Sdk/Client/Model/ClientReadRequest.cs
src/OpenFga.Sdk/Client/Model/ClientRequestOptions.cs
src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithAuthZModelId.cs
src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithStoreId.cs
src/OpenFga.Sdk/Client/Model/ClientTupleKey.cs
src/OpenFga.Sdk/Client/Model/ClientTupleKeyWithoutCondition.cs
src/OpenFga.Sdk/Client/Model/ClientWriteAssertionsOptions.cs
src/OpenFga.Sdk/Client/Model/ClientWriteAssertionsRequest.cs
src/OpenFga.Sdk/Client/Model/ClientWriteAuthorizationModelRequest.cs
Expand All @@ -114,6 +133,7 @@ src/OpenFga.Sdk/Client/Model/ClientWriteRequest.cs
src/OpenFga.Sdk/Client/Model/ClientWriteResponse.cs
src/OpenFga.Sdk/Client/Model/ClientWriteStatus.cs
src/OpenFga.Sdk/Client/Model/RetryParams.cs
src/OpenFga.Sdk/Client/Model/StoreIdOptions.cs
src/OpenFga.Sdk/Configuration/Configuration.cs
src/OpenFga.Sdk/Configuration/Credentials.cs
src/OpenFga.Sdk/Exceptions/ApiAuthenticationError.cs
Expand All @@ -128,19 +148,25 @@ src/OpenFga.Sdk/Exceptions/Parsers/RateLimitParser.cs
src/OpenFga.Sdk/Exceptions/RateLimitExceededError.cs
src/OpenFga.Sdk/Exceptions/RequiredParamError.cs
src/OpenFga.Sdk/Exceptions/ValidationError.cs
src/OpenFga.Sdk/Model/AbortedMessageResponse.cs
src/OpenFga.Sdk/Model/AbstractOpenAPISchema.cs
src/OpenFga.Sdk/Model/Any.cs
src/OpenFga.Sdk/Model/Assertion.cs
src/OpenFga.Sdk/Model/AssertionTupleKey.cs
src/OpenFga.Sdk/Model/AuthorizationModel.cs
src/OpenFga.Sdk/Model/CheckRequest.cs
src/OpenFga.Sdk/Model/CheckRequestTupleKey.cs
src/OpenFga.Sdk/Model/CheckResponse.cs
src/OpenFga.Sdk/Model/Computed.cs
src/OpenFga.Sdk/Model/Condition.cs
src/OpenFga.Sdk/Model/ConditionParamTypeRef.cs
src/OpenFga.Sdk/Model/ContextualTupleKeys.cs
src/OpenFga.Sdk/Model/CreateStoreRequest.cs
src/OpenFga.Sdk/Model/CreateStoreResponse.cs
src/OpenFga.Sdk/Model/Difference.cs
src/OpenFga.Sdk/Model/ErrorCode.cs
src/OpenFga.Sdk/Model/ExpandRequest.cs
src/OpenFga.Sdk/Model/ExpandRequestTupleKey.cs
src/OpenFga.Sdk/Model/ExpandResponse.cs
src/OpenFga.Sdk/Model/GetStoreResponse.cs
src/OpenFga.Sdk/Model/InternalErrorCode.cs
Expand All @@ -154,25 +180,29 @@ src/OpenFga.Sdk/Model/Metadata.cs
src/OpenFga.Sdk/Model/Node.cs
src/OpenFga.Sdk/Model/Nodes.cs
src/OpenFga.Sdk/Model/NotFoundErrorCode.cs
src/OpenFga.Sdk/Model/NullValue.cs
src/OpenFga.Sdk/Model/ObjectRelation.cs
src/OpenFga.Sdk/Model/PathUnknownErrorMessageResponse.cs
src/OpenFga.Sdk/Model/ReadAssertionsResponse.cs
src/OpenFga.Sdk/Model/ReadAuthorizationModelResponse.cs
src/OpenFga.Sdk/Model/ReadAuthorizationModelsResponse.cs
src/OpenFga.Sdk/Model/ReadChangesResponse.cs
src/OpenFga.Sdk/Model/ReadRequest.cs
src/OpenFga.Sdk/Model/ReadRequestTupleKey.cs
src/OpenFga.Sdk/Model/ReadResponse.cs
src/OpenFga.Sdk/Model/RelationMetadata.cs
src/OpenFga.Sdk/Model/RelationReference.cs
src/OpenFga.Sdk/Model/RelationshipCondition.cs
src/OpenFga.Sdk/Model/Status.cs
src/OpenFga.Sdk/Model/Store.cs
src/OpenFga.Sdk/Model/Tuple.cs
src/OpenFga.Sdk/Model/TupleChange.cs
src/OpenFga.Sdk/Model/TupleKey.cs
src/OpenFga.Sdk/Model/TupleKeys.cs
src/OpenFga.Sdk/Model/TupleKeyWithoutCondition.cs
src/OpenFga.Sdk/Model/TupleOperation.cs
src/OpenFga.Sdk/Model/TupleToUserset.cs
src/OpenFga.Sdk/Model/TypeDefinition.cs
src/OpenFga.Sdk/Model/TypeName.cs
src/OpenFga.Sdk/Model/Users.cs
src/OpenFga.Sdk/Model/Userset.cs
src/OpenFga.Sdk/Model/UsersetTree.cs
Expand All @@ -184,4 +214,6 @@ src/OpenFga.Sdk/Model/WriteAssertionsRequest.cs
src/OpenFga.Sdk/Model/WriteAuthorizationModelRequest.cs
src/OpenFga.Sdk/Model/WriteAuthorizationModelResponse.cs
src/OpenFga.Sdk/Model/WriteRequest.cs
src/OpenFga.Sdk/Model/WriteRequestDeletes.cs
src/OpenFga.Sdk/Model/WriteRequestWrites.cs
src/OpenFga.Sdk/OpenFga.Sdk.csproj
55 changes: 55 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
# Changelog

## v0.3.0

### [0.3.0](https://github.com/openfga/dotnet-sdk/compare/v0.2.5...v0.3.0) (2023-12-20)
- feat!: initial support for conditions
- feat!: allow overriding storeId per request (#33)
- 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`)
- feat: validate that store id and auth model id in ulid format (#23)
- fix: exception when using the same configuration with multiple clients (#26)
- fix: `OpenFgaClient.ReadLatestAuthorizationModel` can now return a null if no model has ever been created in that store
- fix: `OpenFgaClient.Read` and `OpenFgaClient.ReadChanges` now allow a null body
- 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.5` SDK with a `v1.3.8+` server),
the grpc interface did and this caused a few changes in the interfaces of the SDK.

If you are using `OpenFgaClient`, the changes required should be smaller, if you are using `OpenFgaApi` a bit more changes will be needed.

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
```csharp
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
};
var fgaClient = new OpenFgaClient(configuration);
```
- `OpenFgaApi` now requires `storeId` as first param when needed
- `Configuration` no longer accepts `storeId` (`ClientConfiguration` is not affected)
- 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`, the latter of which accepts `TupleKeyWithoutCondition`
- And more
- The following interfaces had fields that were pointers are are now the direct value:
- `CreateStoreResponse`
- `GetStoreResponse`
- `ListStoresResponse`
- `ListObjectsResponse`
- `ReadChangesResponse`
- `ReadResponse`
- `AuthorizationModel`
- And more

Take a look at https://github.com/openfga/dotnet-sdk/commit/fa43463ded102df3f660bae6d741e1a8c1dea090 for more model changes.

## v0.2.5

### [0.2.5](https://github.com/openfga/dotnet-sdk/compare/v0.2.4...v0.2.5) (2023-12-01)
Expand Down
49 changes: 29 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,9 @@ namespace Example {
public static async Task Main() {
try {
var configuration = new ClientConfiguration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"), // optional, defaults to "https"
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId = Environment.GetEnvironmentVariable("OPENFGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("OPENFGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
};
var fgaClient = new OpenFgaClient(configuration);
var response = await fgaClient.ReadAuthorizationModels();
Expand All @@ -135,14 +134,13 @@ namespace Example {
public static async Task Main() {
try {
var configuration = new ClientConfiguration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"), // optional, defaults to "https"
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId = Environment.GetEnvironmentVariable("OPENFGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("OPENFGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
Credentials = new Credentials() {
Method = CredentialsMethod.ApiToken,
Config = new CredentialsConfig() {
ApiToken = Environment.GetEnvironmentVariable("OPENFGA_API_TOKEN"), // will be passed as the "Authorization: Bearer ${ApiToken}" request header
ApiToken = Environment.GetEnvironmentVariable("FGA_API_TOKEN"), // will be passed as the "Authorization: Bearer ${ApiToken}" request header
}
}
};
Expand All @@ -168,17 +166,16 @@ namespace Example {
public static async Task Main() {
try {
var configuration = new ClientConfiguration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"), // optional, defaults to "https"
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId = Environment.GetEnvironmentVariable("OPENFGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("OPENFGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_AUTHORIZATION_MODEL_ID"), // Optional, can be overridden per request
Credentials = new Credentials() {
Method = CredentialsMethod.ClientCredentials,
Config = new CredentialsConfig() {
ApiTokenIssuer = Environment.GetEnvironmentVariable("OPENFGA_API_TOKEN_ISSUER"),
ApiAudience = Environment.GetEnvironmentVariable("OPENFGA_API_AUDIENCE"),
ClientId = Environment.GetEnvironmentVariable("OPENFGA_CLIENT_ID"),
ClientSecret = Environment.GetEnvironmentVariable("OPENFGA_CLIENT_SECRET"),
ApiTokenIssuer = Environment.GetEnvironmentVariable("FGA_API_TOKEN_ISSUER"),
ApiAudience = Environment.GetEnvironmentVariable("FGA_API_AUDIENCE"),
ClientId = Environment.GetEnvironmentVariable("FGA_CLIENT_ID"),
ClientSecret = Environment.GetEnvironmentVariable("FGA_CLIENT_SECRET"),
}
}
};
Expand Down Expand Up @@ -465,7 +462,7 @@ var body = new ClientWriteRequest() {
Object = "document:budget",
}
},
Deletes = new List<ClientTupleKey> {
Deletes = new List<ClientTupleKeyWithoutCondition> {
new() {
User = "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
Relation = "writer",
Expand Down Expand Up @@ -500,7 +497,7 @@ var body = new ClientWriteRequest() {
Object = "document:budget",
}
},
Deletes = new List<ClientTupleKey> {
Deletes = new List<ClientTupleKeyWithoutCondition> {
new() {
User = "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
Relation = "writer",
Expand Down Expand Up @@ -768,18 +765,24 @@ await fgaClient.WriteAssertions(body, options);

### Models

- [Model.AbortedMessageResponse](docs/AbortedMessageResponse.md)
- [Model.Any](docs/Any.md)
- [Model.Assertion](docs/Assertion.md)
- [Model.AssertionTupleKey](docs/AssertionTupleKey.md)
- [Model.AuthorizationModel](docs/AuthorizationModel.md)
- [Model.CheckRequest](docs/CheckRequest.md)
- [Model.CheckRequestTupleKey](docs/CheckRequestTupleKey.md)
- [Model.CheckResponse](docs/CheckResponse.md)
- [Model.Computed](docs/Computed.md)
- [Model.Condition](docs/Condition.md)
- [Model.ConditionParamTypeRef](docs/ConditionParamTypeRef.md)
- [Model.ContextualTupleKeys](docs/ContextualTupleKeys.md)
- [Model.CreateStoreRequest](docs/CreateStoreRequest.md)
- [Model.CreateStoreResponse](docs/CreateStoreResponse.md)
- [Model.Difference](docs/Difference.md)
- [Model.ErrorCode](docs/ErrorCode.md)
- [Model.ExpandRequest](docs/ExpandRequest.md)
- [Model.ExpandRequestTupleKey](docs/ExpandRequestTupleKey.md)
- [Model.ExpandResponse](docs/ExpandResponse.md)
- [Model.GetStoreResponse](docs/GetStoreResponse.md)
- [Model.InternalErrorCode](docs/InternalErrorCode.md)
Expand All @@ -792,25 +795,29 @@ await fgaClient.WriteAssertions(body, options);
- [Model.Node](docs/Node.md)
- [Model.Nodes](docs/Nodes.md)
- [Model.NotFoundErrorCode](docs/NotFoundErrorCode.md)
- [Model.NullValue](docs/NullValue.md)
- [Model.ObjectRelation](docs/ObjectRelation.md)
- [Model.PathUnknownErrorMessageResponse](docs/PathUnknownErrorMessageResponse.md)
- [Model.ReadAssertionsResponse](docs/ReadAssertionsResponse.md)
- [Model.ReadAuthorizationModelResponse](docs/ReadAuthorizationModelResponse.md)
- [Model.ReadAuthorizationModelsResponse](docs/ReadAuthorizationModelsResponse.md)
- [Model.ReadChangesResponse](docs/ReadChangesResponse.md)
- [Model.ReadRequest](docs/ReadRequest.md)
- [Model.ReadRequestTupleKey](docs/ReadRequestTupleKey.md)
- [Model.ReadResponse](docs/ReadResponse.md)
- [Model.RelationMetadata](docs/RelationMetadata.md)
- [Model.RelationReference](docs/RelationReference.md)
- [Model.RelationshipCondition](docs/RelationshipCondition.md)
- [Model.Status](docs/Status.md)
- [Model.Store](docs/Store.md)
- [Model.Tuple](docs/Tuple.md)
- [Model.TupleChange](docs/TupleChange.md)
- [Model.TupleKey](docs/TupleKey.md)
- [Model.TupleKeys](docs/TupleKeys.md)
- [Model.TupleKeyWithoutCondition](docs/TupleKeyWithoutCondition.md)
- [Model.TupleOperation](docs/TupleOperation.md)
- [Model.TupleToUserset](docs/TupleToUserset.md)
- [Model.TypeDefinition](docs/TypeDefinition.md)
- [Model.TypeName](docs/TypeName.md)
- [Model.Users](docs/Users.md)
- [Model.Userset](docs/Userset.md)
- [Model.UsersetTree](docs/UsersetTree.md)
Expand All @@ -822,6 +829,8 @@ await fgaClient.WriteAssertions(body, options);
- [Model.WriteAuthorizationModelRequest](docs/WriteAuthorizationModelRequest.md)
- [Model.WriteAuthorizationModelResponse](docs/WriteAuthorizationModelResponse.md)
- [Model.WriteRequest](docs/WriteRequest.md)
- [Model.WriteRequestDeletes](docs/WriteRequestDeletes.md)
- [Model.WriteRequestWrites](docs/WriteRequestWrites.md)



Expand Down
11 changes: 11 additions & 0 deletions docs/AbortedMessageResponse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# OpenFga.Sdk.Model.AbortedMessageResponse

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Code** | **string** | | [optional]
**Message** | **string** | | [optional]

[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)

Loading

0 comments on commit 27514de

Please sign in to comment.