Skip to content

Commit 3a8a2de

Browse files
authored
chore(dotnet-sdk): fixes and sync back sdk changes (#526)
2 parents 2f71825 + 42bdbbe commit 3a8a2de

13 files changed

Lines changed: 423 additions & 55 deletions

.github/workflows/main.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ jobs:
9393

9494
- name: Run All Tests
9595
run: make test-client-dotnet
96+
env:
97+
OPEN_API_REF: f9709139a3693f6624efda12a001e242c5d506b6
9698

9799
- name: Check for SDK changes
98100
run: |

config/clients/dotnet/CHANGELOG.md.mustache

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
## [Unreleased](https://github.com/openfga/dotnet-sdk/compare/v{{packageVersion}}...HEAD)
44

55
- feat: add support for `start_time` parameter in `ReadChanges` endpoint
6+
- feat: update API definitions
7+
- feat: support assertions context and contextual tuples
8+
- feat: support contextual tuples in `Expand`
9+
- feat!: support passing in name to filter in `ListStores`
10+
- fix: remove dependency on OpenTelemetry.Api (#100) - thanks @m4tchl0ck
11+
- fix: limit default retries to `3` from `15` (https://github.com/openfga/sdk-generator/pull/420) - thanks @ovindu-a
12+
- fix: `ListRelations` should not swallow errors
13+
- chore(docs): replace readable names with uuid to discourage storing PII in OpenFGA (https://github.com/openfga/sdk-generator/pull/433) - thanks @sccalabr
14+
15+
[!WARNING]
16+
BREAKING CHANGES:
17+
- The `ListStores` method now accepts a body parameter with an optional `Name` to filter the stores. This is a breaking change as it changes the method contract to allow passing in a body with the name.
618

719
## v0.5.1
820

config/clients/dotnet/config.overrides.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@
7979
"destinationFilename": "src/OpenFga.Sdk/Client/Model/ClientBatchCheckResponse.cs",
8080
"templateType": "SupportingFiles"
8181
},
82+
"Client/Model/ClientBatchCheckResponseTest.mustache": {
83+
"destinationFilename": "src/OpenFga.Sdk.Test/Models/Client/ClientBatchCheckResponseTest.cs",
84+
"templateType": "SupportingFiles"
85+
},
8286
"Client/Model/ClientCheckOptions.mustache": {
8387
"destinationFilename": "src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs",
8488
"templateType": "SupportingFiles"
@@ -131,6 +135,10 @@
131135
"destinationFilename": "src/OpenFga.Sdk/Client/Model/ClientListStoresOptions.cs",
132136
"templateType": "SupportingFiles"
133137
},
138+
"Client/Model/ClientListStoresRequest.mustache": {
139+
"destinationFilename": "src/OpenFga.Sdk/Client/Model/ClientListStoresRequest.cs",
140+
"templateType": "SupportingFiles"
141+
},
134142
"Client/Model/ClientListUsersOptions.mustache": {
135143
"destinationFilename": "src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs",
136144
"templateType": "SupportingFiles"

config/clients/dotnet/template/Client/Client.mustache

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ public class {{appShortName}}Client : IDisposable {
7272
/**
7373
* ListStores - Get a paginated list of stores.
7474
*/
75-
public async Task<ListStoresResponse> ListStores(IClientListStoresOptions? options = default,
75+
public async Task<ListStoresResponse> ListStores(IClientListStoresRequest? body, IClientListStoresOptions? options = default,
7676
CancellationToken cancellationToken = default) =>
77-
await api.ListStores(options?.PageSize, options?.ContinuationToken, cancellationToken);
77+
await api.ListStores(options?.PageSize, options?.ContinuationToken, body?.Name, cancellationToken);
7878

7979
/**
8080
* CreateStore - Initialize a store
@@ -334,6 +334,11 @@ public class {{appShortName}}Client : IDisposable {
334334
GetStoreId(options),
335335
new ExpandRequest {
336336
TupleKey = new ExpandRequestTupleKey {Relation = body.Relation, Object = body.Object},
337+
ContextualTuples =
338+
new ContextualTupleKeys {
339+
TupleKeys = body.ContextualTuples?.ConvertAll(tupleKey => tupleKey.ToTupleKey()) ??
340+
new List<TupleKey>()
341+
},
337342
AuthorizationModelId = GetAuthorizationModelId(options),
338343
Consistency = options?.Consistency
339344
}, cancellationToken);
@@ -384,8 +389,12 @@ public class {{appShortName}}Client : IDisposable {
384389

385390
var batchCheckResponse = await BatchCheck(batchCheckRequests, options, cancellationToken);
386391

387-
for (var index = 0; index < batchCheckResponse.Responses.Count; index++) {
388-
var batchCheckSingleResponse = batchCheckResponse.Responses[index];
392+
393+
foreach (var batchCheckSingleResponse in batchCheckResponse.Responses) {
394+
if (batchCheckSingleResponse.Error != null) {
395+
throw batchCheckSingleResponse.Error;
396+
}
397+
389398
if (batchCheckSingleResponse.Allowed && batchCheckSingleResponse.Request?.Relation != null) {
390399
responses.AddRelation(batchCheckSingleResponse.Request.Relation);
391400
}

config/clients/dotnet/template/Client/Model/ClientBatchCheckResponse.mustache

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,26 @@ public class BatchCheckSingleResponse : IEquatable<BatchCheckSingleResponse>, IV
4343
[JsonPropertyName("error")]
4444
public Exception? Error { get; set; }
4545

46-
public bool Equals(BatchCheckSingleResponse? other) => throw new NotImplementedException();
46+
/// <inheritdoc />
47+
public bool Equals(BatchCheckSingleResponse? other)
48+
{
49+
if (other == null) return false;
50+
if (ReferenceEquals(this, other)) return true;
51+
52+
return Allowed == other.Allowed &&
53+
EqualityComparer<ClientCheckRequest>.Default.Equals(Request, other.Request) &&
54+
EqualityComparer<Exception>.Default.Equals(Error, other.Error);
55+
}
56+
57+
/// <inheritdoc />
58+
public override bool Equals(object obj)
59+
{
60+
if (obj is BatchCheckSingleResponse other)
61+
{
62+
return Equals(other);
63+
}
64+
return false;
65+
}
4766

4867
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) =>
4968
throw new NotImplementedException();
@@ -72,7 +91,24 @@ public class ClientBatchCheckClientResponse : IEquatable<ClientBatchCheckClientR
7291
[JsonPropertyName("responses")]
7392
public List<BatchCheckSingleResponse> Responses { get; set; }
7493

75-
public bool Equals(ClientBatchCheckClientResponse? other) => throw new NotImplementedException();
94+
/// <inheritdoc />
95+
public bool Equals(ClientBatchCheckClientResponse? other)
96+
{
97+
if (other == null) return false;
98+
if (ReferenceEquals(this, other)) return true;
99+
100+
return Responses.SequenceEqual(other.Responses);
101+
}
102+
103+
/// <inheritdoc />
104+
public override bool Equals(object obj)
105+
{
106+
if (obj is ClientBatchCheckClientResponse other)
107+
{
108+
return Equals(other);
109+
}
110+
return false;
111+
}
76112

77113
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) =>
78114
throw new NotImplementedException();
@@ -82,4 +118,4 @@ public class ClientBatchCheckClientResponse : IEquatable<ClientBatchCheckClientR
82118
/// </summary>
83119
/// <param name="response"></param>
84120
public void AppendResponse(BatchCheckSingleResponse response) => Responses.Add(response);
85-
}
121+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{{>partial_header}}
2+
3+
using {{packageName}}.Client.Model;
4+
using System.Collections.Generic;
5+
using Xunit;
6+
7+
public class ClientBatchCheckClientResponseTests
8+
{
9+
[Fact]
10+
public void Equals_ReturnsTrue_WhenResponsesAreEqual()
11+
{
12+
var response1 = new BatchCheckSingleResponse(true, new ClientCheckRequest(), null);
13+
var response2 = new BatchCheckSingleResponse(true, new ClientCheckRequest(), null);
14+
var clientResponse1 = new ClientBatchCheckClientResponse(new List<BatchCheckSingleResponse> { response1 });
15+
var clientResponse2 = new ClientBatchCheckClientResponse(new List<BatchCheckSingleResponse> { response2 });
16+
17+
Assert.True(clientResponse1.Equals(clientResponse2));
18+
}
19+
20+
[Fact]
21+
public void Equals_ReturnsFalse_WhenResponsesAreNotEqual()
22+
{
23+
var response1 = new BatchCheckSingleResponse(true, new ClientCheckRequest(), null);
24+
var response2 = new BatchCheckSingleResponse(false, new ClientCheckRequest(), null);
25+
var clientResponse1 = new ClientBatchCheckClientResponse(new List<BatchCheckSingleResponse> { response1 });
26+
var clientResponse2 = new ClientBatchCheckClientResponse(new List<BatchCheckSingleResponse> { response2 });
27+
28+
Assert.False(clientResponse1.Equals(clientResponse2));
29+
}
30+
31+
[Fact]
32+
public void AppendResponse_AddsResponseToList()
33+
{
34+
var clientResponse = new ClientBatchCheckClientResponse();
35+
var response = new BatchCheckSingleResponse(true, new ClientCheckRequest(), null);
36+
37+
clientResponse.AppendResponse(response);
38+
39+
Assert.Contains(response, clientResponse.Responses);
40+
}
41+
}

config/clients/dotnet/template/Client/Model/ClientExpandRequest.mustache

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{{>partial_header}}
22

3+
using {{packageName}}.Model;
34
using System.ComponentModel.DataAnnotations;
45
using System.Runtime.Serialization;
56
using System.Text.Json;
@@ -20,6 +21,8 @@ public interface IClientExpandRequest {
2021
/// Object
2122
/// </summary>
2223
public string Object { get; set; }
24+
25+
public List<ClientTupleKey>? ContextualTuples { get; set; }
2326
}
2427

2528
/// <inheritdoc />
@@ -35,6 +38,13 @@ public class ClientExpandRequest : IClientExpandRequest, IEquatable<ClientExpand
3538

3639
public string Object { get; set; }
3740

41+
/// <summary>
42+
/// Gets or Sets Contextual Tuples
43+
/// </summary>
44+
[DataMember(Name = "contextual_tuples", EmitDefaultValue = false)]
45+
[JsonPropertyName("contextual_tuples")]
46+
public List<ClientTupleKey>? ContextualTuples { get; set; }
47+
3848
public bool Equals(ClientExpandRequest input) {
3949
if (input == null) {
4050
return false;
@@ -50,6 +60,11 @@ public class ClientExpandRequest : IClientExpandRequest, IEquatable<ClientExpand
5060
Object == input.Object ||
5161
(Object != null &&
5262
Object.Equals(input.Object))
63+
) &&
64+
(
65+
ContextualTuples == input.ContextualTuples ||
66+
(ContextualTuples != null &&
67+
ContextualTuples.Equals(input.ContextualTuples))
5368
);
5469
}
5570

@@ -76,7 +91,11 @@ public class ClientExpandRequest : IClientExpandRequest, IEquatable<ClientExpand
7691
hashCode = (hashCode * {{hashCodeMultiplierPrimeNumber}}) + Object.GetHashCode();
7792
}
7893

94+
if (ContextualTuples != null) {
95+
hashCode = (hashCode * {{hashCodeMultiplierPrimeNumber}}) + ContextualTuples.GetHashCode();
96+
}
97+
7998
return hashCode;
8099
}
81100
}
82-
}
101+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{{>partial_header}}
2+
3+
using System.ComponentModel.DataAnnotations;
4+
using System.Runtime.Serialization;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
8+
namespace {{packageName}}.Client.Model;
9+
10+
public interface IClientListStoresRequest {
11+
public string? Name { get; set; }
12+
}
13+
14+
/// <summary>
15+
/// ClientListStoresRequest
16+
/// </summary>
17+
public class ClientListStoresRequest : IClientListStoresRequest, IEquatable<ClientListStoresRequest>,
18+
IValidatableObject {
19+
/// <summary>
20+
/// Gets or Sets Name
21+
/// </summary>
22+
[DataMember(Name = "name", EmitDefaultValue = false)]
23+
[JsonPropertyName("name")]
24+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
25+
public string? Name { get; set; }
26+
27+
public bool Equals(ClientListStoresRequest input) {
28+
if (input == null) {
29+
return false;
30+
}
31+
32+
return
33+
(
34+
Name == input.Name ||
35+
(Name != null &&
36+
Name.Equals(input.Name))
37+
);
38+
}
39+
40+
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
41+
yield break;
42+
}
43+
44+
public virtual string ToJson() => JsonSerializer.Serialize(this);
45+
46+
public static ClientListStoresRequest FromJson(string jsonString) =>
47+
JsonSerializer.Deserialize<ClientListStoresRequest>(jsonString) ?? throw new InvalidOperationException();
48+
49+
public override bool Equals(object input) => Equals(input as ClientListStoresRequest);
50+
51+
public override int GetHashCode() {
52+
unchecked // Overflow is fine, just wrap
53+
{
54+
var hashCode = 9661;
55+
if (Name != null) {
56+
hashCode = (hashCode * 9923) + Name.GetHashCode();
57+
}
58+
59+
return hashCode;
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)