Skip to content

Commit 80e570c

Browse files
committed
Sending X-Client-Version header with auth requests
1 parent 4a5b618 commit 80e570c

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Linq;
1818
using System.Net;
1919
using System.Net.Http;
20+
using System.Net.Http.Headers;
2021
using System.Threading.Tasks;
2122
using FirebaseAdmin.Tests;
2223
using Google.Apis.Auth.OAuth2;
@@ -33,6 +34,8 @@ public class FirebaseUserManagerTest
3334
private static readonly GoogleCredential MockCredential =
3435
GoogleCredential.FromAccessToken("test-token");
3536

37+
private static readonly string ClientVersion = $"DotNet/Admin/{FirebaseApp.GetSdkVersion()}";
38+
3639
private static readonly string CreateUserResponse = @"{""localId"": ""user1""}";
3740
private static readonly string GetUserResponse = @"{""users"": [{""localId"": ""user1""}]}";
3841
private static readonly IList<string> ListUsersResponse = new List<string>()
@@ -81,6 +84,7 @@ public async Task GetUserById()
8184

8285
var request = NewtonsoftJsonSerializer.Instance.Deserialize<Dictionary<string, object>>(handler.LastRequestBody);
8386
Assert.Equal(new JArray("user1"), request["localId"]);
87+
this.AssertClientVersion(handler.LastRequestHeaders);
8488
}
8589

8690
[Fact]
@@ -160,6 +164,8 @@ public async Task GetUserByIdWithProperties()
160164
Assert.NotNull(metadata);
161165
Assert.Equal(UserRecord.UnixEpoch.AddMilliseconds(100), metadata.CreationTimestamp);
162166
Assert.Equal(UserRecord.UnixEpoch.AddMilliseconds(150), metadata.LastSignInTimestamp);
167+
168+
this.AssertClientVersion(handler.LastRequestHeaders);
163169
}
164170

165171
[Fact]
@@ -217,6 +223,7 @@ public async Task GetUserByEmail()
217223

218224
var request = NewtonsoftJsonSerializer.Instance.Deserialize<Dictionary<string, object>>(handler.LastRequestBody);
219225
Assert.Equal(new JArray("[email protected]"), request["email"]);
226+
this.AssertClientVersion(handler.LastRequestHeaders);
220227
}
221228

222229
[Fact]
@@ -274,6 +281,7 @@ public async Task GetUserByPhoneNumber()
274281

275282
var request = NewtonsoftJsonSerializer.Instance.Deserialize<Dictionary<string, object>>(handler.LastRequestBody);
276283
Assert.Equal(new JArray("+1234567890"), request["phoneNumber"]);
284+
this.AssertClientVersion(handler.LastRequestHeaders);
277285
}
278286

279287
[Fact]
@@ -340,6 +348,9 @@ public async Task ListUsers()
340348
Assert.Equal(2, query.Count);
341349
Assert.Equal("1000", query["maxResults"]);
342350
Assert.Equal("token", query["nextPageToken"]);
351+
352+
this.AssertClientVersion(handler.Requests[0].Headers);
353+
this.AssertClientVersion(handler.Requests[1].Headers);
343354
}
344355

345356
[Fact]
@@ -377,6 +388,9 @@ public void ListUsersForEach()
377388
Assert.Equal(2, query.Count);
378389
Assert.Equal("1000", query["maxResults"]);
379390
Assert.Equal("token", query["nextPageToken"]);
391+
392+
this.AssertClientVersion(handler.Requests[0].Headers);
393+
this.AssertClientVersion(handler.Requests[1].Headers);
380394
}
381395

382396
[Fact]
@@ -416,6 +430,9 @@ public void ListUsersCustomOptions()
416430
Assert.Equal(2, query.Count);
417431
Assert.Equal("3", query["maxResults"]);
418432
Assert.Equal("token", query["nextPageToken"]);
433+
434+
this.AssertClientVersion(handler.Requests[0].Headers);
435+
this.AssertClientVersion(handler.Requests[1].Headers);
419436
}
420437

421438
[Fact]
@@ -451,6 +468,9 @@ public async Task ListUsersReadPage()
451468
query = this.ExtractQueryParams(handler.Requests[1]);
452469
Assert.Single(query);
453470
Assert.Equal("3", query["maxResults"]);
471+
472+
this.AssertClientVersion(handler.Requests[0].Headers);
473+
this.AssertClientVersion(handler.Requests[1].Headers);
454474
}
455475

456476
[Fact]
@@ -496,6 +516,9 @@ public async Task ListUsersByPages()
496516
{
497517
Assert.Equal($"user{i + 1}", users[i].Uid);
498518
}
519+
520+
this.AssertClientVersion(handler.Requests[0].Headers);
521+
this.AssertClientVersion(handler.Requests[1].Headers);
499522
}
500523

501524
[Fact]
@@ -521,6 +544,9 @@ public async Task ListUsersReadLargePageSize()
521544
Assert.Equal(2, query.Count);
522545
Assert.Equal("7", query["maxResults"]);
523546
Assert.Equal("token", query["nextPageToken"]);
547+
548+
this.AssertClientVersion(handler.Requests[0].Headers);
549+
this.AssertClientVersion(handler.Requests[1].Headers);
524550
}
525551

526552
[Fact]
@@ -562,6 +588,9 @@ public async Task ListUsersAsRawResponses()
562588
Assert.Equal(2, query.Count);
563589
Assert.Equal("1000", query["maxResults"]);
564590
Assert.Equal("token", query["nextPageToken"]);
591+
592+
this.AssertClientVersion(handler.Requests[0].Headers);
593+
this.AssertClientVersion(handler.Requests[1].Headers);
565594
}
566595

567596
[Fact]
@@ -698,6 +727,9 @@ public async Task CreateUser()
698727
Assert.Equal(2, handler.Requests.Count);
699728
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Requests[0].Body);
700729
Assert.Empty(request);
730+
731+
this.AssertClientVersion(handler.Requests[0].Headers);
732+
this.AssertClientVersion(handler.Requests[1].Headers);
701733
}
702734

703735
[Fact]
@@ -731,6 +763,9 @@ public async Task CreateUserWithArgs()
731763
Assert.Equal("secret", request["password"]);
732764
Assert.Equal("+1234567890", request["phoneNumber"]);
733765
Assert.Equal("https://example.com/user.png", request["photoUrl"]);
766+
767+
this.AssertClientVersion(handler.Requests[0].Headers);
768+
this.AssertClientVersion(handler.Requests[1].Headers);
734769
}
735770

736771
[Fact]
@@ -759,6 +794,9 @@ public async Task CreateUserWithExplicitDefaults()
759794
Assert.Equal(2, request.Count);
760795
Assert.False((bool)request["disabled"]);
761796
Assert.False((bool)request["emailVerified"]);
797+
798+
this.AssertClientVersion(handler.Requests[0].Headers);
799+
this.AssertClientVersion(handler.Requests[1].Headers);
762800
}
763801

764802
[Fact]
@@ -956,6 +994,9 @@ public async Task UpdateUser()
956994
Assert.True((bool)claims["admin"]);
957995
Assert.Equal(4L, claims["level"]);
958996
Assert.Equal("gold", claims["package"]);
997+
998+
this.AssertClientVersion(handler.Requests[0].Headers);
999+
this.AssertClientVersion(handler.Requests[1].Headers);
9591000
}
9601001

9611002
[Fact]
@@ -979,6 +1020,9 @@ public async Task UpdateUserPartial()
9791020
Assert.Equal(2, request.Count);
9801021
Assert.Equal("user1", request["localId"]);
9811022
Assert.True((bool)request["emailVerified"]);
1023+
1024+
this.AssertClientVersion(handler.Requests[0].Headers);
1025+
this.AssertClientVersion(handler.Requests[1].Headers);
9821026
}
9831027

9841028
[Fact]
@@ -1005,6 +1049,9 @@ public async Task UpdateUserRemoveAttributes()
10051049
Assert.Equal(
10061050
new JArray() { "DISPLAY_NAME", "PHOTO_URL" },
10071051
request["deleteAttribute"]);
1052+
1053+
this.AssertClientVersion(handler.Requests[0].Headers);
1054+
this.AssertClientVersion(handler.Requests[1].Headers);
10081055
}
10091056

10101057
[Fact]
@@ -1030,6 +1077,9 @@ public async Task UpdateUserRemoveProviders()
10301077
Assert.Equal(
10311078
new JArray() { "phone" },
10321079
request["deleteProvider"]);
1080+
1081+
this.AssertClientVersion(handler.Requests[0].Headers);
1082+
this.AssertClientVersion(handler.Requests[1].Headers);
10331083
}
10341084

10351085
[Fact]
@@ -1053,6 +1103,8 @@ public async Task UpdateUserSetCustomClaims()
10531103
Assert.True((bool)claims["admin"]);
10541104
Assert.Equal(4L, claims["level"]);
10551105
Assert.Equal("gold", claims["package"]);
1106+
1107+
this.AssertClientVersion(handler.LastRequestHeaders);
10561108
}
10571109

10581110
[Fact]
@@ -1066,6 +1118,7 @@ public async Task LargeClaimsUnderLimit()
10661118
};
10671119

10681120
await auth.SetCustomUserClaimsAsync("user1", customClaims);
1121+
this.AssertClientVersion(handler.LastRequestHeaders);
10691122
}
10701123

10711124
[Fact]
@@ -1079,6 +1132,8 @@ public async Task EmptyClaims()
10791132
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.LastRequestBody);
10801133
Assert.Equal("user1", request["localId"]);
10811134
Assert.Equal("{}", request["customAttributes"]);
1135+
1136+
this.AssertClientVersion(handler.LastRequestHeaders);
10821137
}
10831138

10841139
[Fact]
@@ -1092,6 +1147,8 @@ public async Task NullClaims()
10921147
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.LastRequestBody);
10931148
Assert.Equal("user1", request["localId"]);
10941149
Assert.Equal("{}", request["customAttributes"]);
1150+
1151+
this.AssertClientVersion(handler.LastRequestHeaders);
10951152
}
10961153

10971154
[Fact]
@@ -1354,6 +1411,7 @@ public async Task DeleteUser()
13541411
var auth = this.CreateFirebaseAuth(handler);
13551412

13561413
await auth.DeleteUserAsync("user1");
1414+
this.AssertClientVersion(handler.LastRequestHeaders);
13571415
}
13581416

13591417
[Fact]
@@ -1390,5 +1448,12 @@ private IDictionary<string, string> ExtractQueryParams(MockMessageHandler.Incomi
13901448
return req.Url.Query.Substring(1).Split('&').ToDictionary(
13911449
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
13921450
}
1451+
1452+
private void AssertClientVersion(HttpRequestHeaders header)
1453+
{
1454+
Assert.Equal(
1455+
FirebaseUserManager.ClientVersion,
1456+
header.GetValues(FirebaseUserManager.ClientVersionHeader).First());
1457+
}
13931458
}
13941459
}

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ namespace FirebaseAdmin.Auth
3434
/// </summary>
3535
internal class FirebaseUserManager : IDisposable
3636
{
37+
internal const string ClientVersionHeader = "X-Client-Version";
38+
39+
internal static readonly string ClientVersion = $"DotNet/Admin/{FirebaseApp.GetSdkVersion()}";
40+
3741
private const string IdTooklitUrl = "https://identitytoolkit.googleapis.com/v1/projects/{0}";
3842

3943
private readonly ConfigurableHttpClient httpClient;
@@ -265,6 +269,7 @@ private async Task<string> PostAsync(
265269
private async Task<string> SendAsync(
266270
HttpRequestMessage request, CancellationToken cancellationToken)
267271
{
272+
request.Headers.Add(ClientVersionHeader, ClientVersion);
268273
try
269274
{
270275
var response = await this.httpClient.SendAsync(request, cancellationToken)

FirebaseAdmin/FirebaseAdmin/Auth/ListUsersRequest.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ public HttpRequestMessage CreateRequest(bool? overrideGZipEnabled = null)
6161
{
6262
var queryParameters = string.Join("&", this.RequestParameters.Select(
6363
kvp => $"{kvp.Key}={kvp.Value.DefaultValue}"));
64-
return new HttpRequestMessage()
64+
var request = new HttpRequestMessage()
6565
{
6666
Method = System.Net.Http.HttpMethod.Get,
6767
RequestUri = new Uri($"{this.baseUrl}/{this.RestPath}?{queryParameters}"),
6868
};
69+
request.Headers.Add(FirebaseUserManager.ClientVersionHeader, FirebaseUserManager.ClientVersion);
70+
return request;
6971
}
7072

7173
public Task<Stream> ExecuteAsStreamAsync()

0 commit comments

Comments
 (0)