From 38b5e13b2af2d5e5ef91139c966e560216e03e8c Mon Sep 17 00:00:00 2001 From: celestebyte <130874118+celestebyte@users.noreply.github.com> Date: Sat, 13 Jul 2024 12:03:21 -0600 Subject: [PATCH 1/2] Add ban functionality Add properties to set BanDuration on update user and BannedUtil to verify the datetime of the ban applied to the user. Updated the projects from .Net7 to .Net8 (LTS). --- Gotrue/User.cs | 20 ++++++++++++++++++-- GotrueExample/GotrueExample.csproj | 2 +- GotrueTests/GotrueTests.csproj | 2 +- GotrueTests/ServiceRoleTests.cs | 26 +++++++++++++++++++++++++- GotrueTests/TestUtils.cs | 13 ++++++++++++- 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Gotrue/User.cs b/Gotrue/User.cs index 023fd2ca..75f68b02 100644 --- a/Gotrue/User.cs +++ b/Gotrue/User.cs @@ -61,7 +61,10 @@ public class User [JsonProperty("updated_at")] public DateTime? UpdatedAt { get; set; } - [JsonProperty("is_anonymous")] + [JsonProperty("banned_until")] + public DateTime? BannedUntil { get; set; } + + [JsonProperty("is_anonymous")] public bool IsAnonymous { get; set; } [JsonProperty("user_metadata")] @@ -103,7 +106,20 @@ public class AdminUserAttributes : UserAttributes /// [JsonProperty("phone_confirm")] public bool? PhoneConfirm { get; set; } - } + + /// + /// Determines how long a user is banned for. + /// This property is ignored when creating a user. + /// If you want to create a user banned, first create the user then update it sending this property. + /// The format for the ban duration follows a strict sequence of decimal numbers with a unit suffix. + /// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". + /// For example, some possible durations include: '300ms', '2h45m', '1200s'. + /// Setting the ban duration to "none" lifts the ban on the user. + /// Only a service role can modify. + /// + [JsonProperty("ban_duration")] + public string? BanDuration { get; set; } + } /// /// Ref: https://supabase.github.io/gotrue-js/interfaces/UserAttributes.html diff --git a/GotrueExample/GotrueExample.csproj b/GotrueExample/GotrueExample.csproj index 7436345c..b43c349e 100644 --- a/GotrueExample/GotrueExample.csproj +++ b/GotrueExample/GotrueExample.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 diff --git a/GotrueTests/GotrueTests.csproj b/GotrueTests/GotrueTests.csproj index d965618e..381f7049 100644 --- a/GotrueTests/GotrueTests.csproj +++ b/GotrueTests/GotrueTests.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 false diff --git a/GotrueTests/ServiceRoleTests.cs b/GotrueTests/ServiceRoleTests.cs index 6973e49c..3ce8febd 100644 --- a/GotrueTests/ServiceRoleTests.cs +++ b/GotrueTests/ServiceRoleTests.cs @@ -140,7 +140,31 @@ public async Task UpdateUserById() AreNotEqual(createdUser.Email, updatedUser.Email); } - [TestMethod("Service Role: Delete User")] + [TestMethod("Service Role: Ban User by Id")] + public async Task BanUserById() + { + var createdUser = await _client.CreateUser($"{RandomString(12)}@supabase.io", PASSWORD); + + IsNotNull(createdUser); + + int banDurationSeconds = RandomNumber(); + DateTime bannedUntil = DateTime.UtcNow + TimeSpan.FromSeconds(banDurationSeconds); + var updatedUser = await _client.UpdateUserById(createdUser.Id ?? throw new InvalidOperationException(), new AdminUserAttributes { BanDuration = $"{banDurationSeconds}s" }); + + IsNotNull(updatedUser); + + AreEqual(createdUser.Id, updatedUser.Id); + IsNotNull(updatedUser.BannedUntil); + IsTrue((updatedUser.BannedUntil.Value - bannedUntil).Duration().TotalSeconds < 1); + + updatedUser = await _client.UpdateUserById(createdUser.Id ?? throw new InvalidOperationException(), new AdminUserAttributes { BanDuration = "none" }); + IsNotNull(updatedUser); + + AreEqual(createdUser.Id, updatedUser.Id); + IsFalse(updatedUser.BannedUntil.HasValue); + } + + [TestMethod("Service Role: Delete User")] public async Task DeletesUser() { var email = $"{RandomString(12)}@supabase.io"; diff --git a/GotrueTests/TestUtils.cs b/GotrueTests/TestUtils.cs index d155edf1..d396b94a 100644 --- a/GotrueTests/TestUtils.cs +++ b/GotrueTests/TestUtils.cs @@ -35,7 +35,18 @@ public static string GetRandomPhoneNumber() return $"+1{inner}"; } - public static string GenerateServiceRoleToken() + /// + /// Returns a random number within the limits specified via parameters. + /// + /// Minimum value. Default 0. + /// Maximum value. Default 1000. + /// Integer within the range. + public static int RandomNumber(int minValue = 0, int maxValue = 1000) + { + return Random.Next(minValue, maxValue); + } + + public static string GenerateServiceRoleToken() { var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("37c304f8-51aa-419a-a1af-06154e63707a")); // using GOTRUE_JWT_SECRET From eb58ab95a9d441a12e3d56b19cf3aa272bcdb787 Mon Sep 17 00:00:00 2001 From: celestebyte <130874118+celestebyte@users.noreply.github.com> Date: Sat, 13 Jul 2024 12:11:01 -0600 Subject: [PATCH 2/2] Fix indentation type. --- Gotrue/User.cs | 28 +++++++++++++-------------- GotrueTests/ServiceRoleTests.cs | 34 ++++++++++++++++----------------- GotrueTests/TestUtils.cs | 22 ++++++++++----------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Gotrue/User.cs b/Gotrue/User.cs index 75f68b02..a6f24546 100644 --- a/Gotrue/User.cs +++ b/Gotrue/User.cs @@ -61,10 +61,10 @@ public class User [JsonProperty("updated_at")] public DateTime? UpdatedAt { get; set; } - [JsonProperty("banned_until")] - public DateTime? BannedUntil { get; set; } + [JsonProperty("banned_until")] + public DateTime? BannedUntil { get; set; } - [JsonProperty("is_anonymous")] + [JsonProperty("is_anonymous")] public bool IsAnonymous { get; set; } [JsonProperty("user_metadata")] @@ -107,19 +107,19 @@ public class AdminUserAttributes : UserAttributes [JsonProperty("phone_confirm")] public bool? PhoneConfirm { get; set; } - /// - /// Determines how long a user is banned for. + /// + /// Determines how long a user is banned for. /// This property is ignored when creating a user. - /// If you want to create a user banned, first create the user then update it sending this property. - /// The format for the ban duration follows a strict sequence of decimal numbers with a unit suffix. - /// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - /// For example, some possible durations include: '300ms', '2h45m', '1200s'. + /// If you want to create a user banned, first create the user then update it sending this property. + /// The format for the ban duration follows a strict sequence of decimal numbers with a unit suffix. + /// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". + /// For example, some possible durations include: '300ms', '2h45m', '1200s'. /// Setting the ban duration to "none" lifts the ban on the user. - /// Only a service role can modify. - /// - [JsonProperty("ban_duration")] - public string? BanDuration { get; set; } - } + /// Only a service role can modify. + /// + [JsonProperty("ban_duration")] + public string? BanDuration { get; set; } + } /// /// Ref: https://supabase.github.io/gotrue-js/interfaces/UserAttributes.html diff --git a/GotrueTests/ServiceRoleTests.cs b/GotrueTests/ServiceRoleTests.cs index 3ce8febd..4c0b8ca7 100644 --- a/GotrueTests/ServiceRoleTests.cs +++ b/GotrueTests/ServiceRoleTests.cs @@ -140,31 +140,31 @@ public async Task UpdateUserById() AreNotEqual(createdUser.Email, updatedUser.Email); } - [TestMethod("Service Role: Ban User by Id")] - public async Task BanUserById() - { - var createdUser = await _client.CreateUser($"{RandomString(12)}@supabase.io", PASSWORD); + [TestMethod("Service Role: Ban User by Id")] + public async Task BanUserById() + { + var createdUser = await _client.CreateUser($"{RandomString(12)}@supabase.io", PASSWORD); - IsNotNull(createdUser); + IsNotNull(createdUser); - int banDurationSeconds = RandomNumber(); - DateTime bannedUntil = DateTime.UtcNow + TimeSpan.FromSeconds(banDurationSeconds); - var updatedUser = await _client.UpdateUserById(createdUser.Id ?? throw new InvalidOperationException(), new AdminUserAttributes { BanDuration = $"{banDurationSeconds}s" }); + int banDurationSeconds = RandomNumber(); + DateTime bannedUntil = DateTime.UtcNow + TimeSpan.FromSeconds(banDurationSeconds); + var updatedUser = await _client.UpdateUserById(createdUser.Id ?? throw new InvalidOperationException(), new AdminUserAttributes { BanDuration = $"{banDurationSeconds}s" }); - IsNotNull(updatedUser); + IsNotNull(updatedUser); - AreEqual(createdUser.Id, updatedUser.Id); - IsNotNull(updatedUser.BannedUntil); - IsTrue((updatedUser.BannedUntil.Value - bannedUntil).Duration().TotalSeconds < 1); + AreEqual(createdUser.Id, updatedUser.Id); + IsNotNull(updatedUser.BannedUntil); + IsTrue((updatedUser.BannedUntil.Value - bannedUntil).Duration().TotalSeconds < 1); updatedUser = await _client.UpdateUserById(createdUser.Id ?? throw new InvalidOperationException(), new AdminUserAttributes { BanDuration = "none" }); - IsNotNull(updatedUser); + IsNotNull(updatedUser); - AreEqual(createdUser.Id, updatedUser.Id); - IsFalse(updatedUser.BannedUntil.HasValue); - } + AreEqual(createdUser.Id, updatedUser.Id); + IsFalse(updatedUser.BannedUntil.HasValue); + } - [TestMethod("Service Role: Delete User")] + [TestMethod("Service Role: Delete User")] public async Task DeletesUser() { var email = $"{RandomString(12)}@supabase.io"; diff --git a/GotrueTests/TestUtils.cs b/GotrueTests/TestUtils.cs index d396b94a..f1b40dbd 100644 --- a/GotrueTests/TestUtils.cs +++ b/GotrueTests/TestUtils.cs @@ -35,18 +35,18 @@ public static string GetRandomPhoneNumber() return $"+1{inner}"; } - /// - /// Returns a random number within the limits specified via parameters. - /// - /// Minimum value. Default 0. - /// Maximum value. Default 1000. - /// Integer within the range. - public static int RandomNumber(int minValue = 0, int maxValue = 1000) - { - return Random.Next(minValue, maxValue); - } + /// + /// Returns a random number within the limits specified via parameters. + /// + /// Minimum value. Default 0. + /// Maximum value. Default 1000. + /// Integer within the range. + public static int RandomNumber(int minValue = 0, int maxValue = 1000) + { + return Random.Next(minValue, maxValue); + } - public static string GenerateServiceRoleToken() + public static string GenerateServiceRoleToken() { var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("37c304f8-51aa-419a-a1af-06154e63707a")); // using GOTRUE_JWT_SECRET