From 902be7dfb814503e6962a828c9116dd4d304a147 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 10 Feb 2026 19:01:50 +0000 Subject: [PATCH] Require password when seeding a new user (#6978) --- .../SeedControllerTests.cs | 15 ++++++++------- util/Seeder/Factories/UserSeeder.cs | 5 +++-- util/Seeder/Scenes/SingleUserScene.cs | 5 ++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/test/SeederApi.IntegrationTest/SeedControllerTests.cs b/test/SeederApi.IntegrationTest/SeedControllerTests.cs index 39139903d8..41324be221 100644 --- a/test/SeederApi.IntegrationTest/SeedControllerTests.cs +++ b/test/SeederApi.IntegrationTest/SeedControllerTests.cs @@ -1,4 +1,5 @@ using System.Net; +using Bit.Seeder.Scenes; using Bit.SeederApi.Models.Request; using Bit.SeederApi.Models.Response; using Xunit; @@ -37,7 +38,7 @@ public class SeedControllerTests : IClassFixture, I var response = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "SingleUserScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = testEmail }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = testEmail, Password = "asdfasdfasdf" }) }, playId); response.EnsureSuccessStatusCode(); @@ -54,7 +55,7 @@ public class SeedControllerTests : IClassFixture, I var response = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "NonExistentScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = "test@example.com" }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = "test@example.com", Password = "asdfasdfasdf" }) }); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -82,7 +83,7 @@ public class SeedControllerTests : IClassFixture, I var seedResponse = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "SingleUserScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = testEmail }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = testEmail, Password = "asdfasdfasdf" }) }, playId); seedResponse.EnsureSuccessStatusCode(); @@ -119,7 +120,7 @@ public class SeedControllerTests : IClassFixture, I var seedResponse = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "SingleUserScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = testEmail }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = testEmail, Password = "asdfasdfasdf" }) }, playId); seedResponse.EnsureSuccessStatusCode(); @@ -151,7 +152,7 @@ public class SeedControllerTests : IClassFixture, I var seedResponse = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "SingleUserScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = testEmail }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = testEmail, Password = "asdfasdfasdf" }) }, validPlayId); seedResponse.EnsureSuccessStatusCode(); @@ -184,7 +185,7 @@ public class SeedControllerTests : IClassFixture, I var seedResponse = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "SingleUserScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = testEmail }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = testEmail, Password = "asdfasdfasdf" }) }, playId); seedResponse.EnsureSuccessStatusCode(); @@ -204,7 +205,7 @@ public class SeedControllerTests : IClassFixture, I var response = await _client.PostAsJsonAsync("/seed", new SeedRequestModel { Template = "SingleUserScene", - Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new { email = testEmail }) + Arguments = System.Text.Json.JsonSerializer.SerializeToElement(new SingleUserScene.Request() { Email = testEmail, Password = "asdfasdfasdf" }) }, playId); response.EnsureSuccessStatusCode(); diff --git a/util/Seeder/Factories/UserSeeder.cs b/util/Seeder/Factories/UserSeeder.cs index 9afca627c8..a615b665a0 100644 --- a/util/Seeder/Factories/UserSeeder.cs +++ b/util/Seeder/Factories/UserSeeder.cs @@ -17,12 +17,13 @@ internal static class UserSeeder IManglerService manglerService, bool emailVerified = true, bool premium = false, - UserKeys? keys = null) + UserKeys? keys = null, + string? password = null) { // When keys are provided, caller owns email/key consistency - don't mangle var mangledEmail = keys == null ? manglerService.Mangle(email) : email; - keys ??= RustSdkService.GenerateUserKeys(mangledEmail, DefaultPassword); + keys ??= RustSdkService.GenerateUserKeys(mangledEmail, password ?? DefaultPassword); var user = new User { diff --git a/util/Seeder/Scenes/SingleUserScene.cs b/util/Seeder/Scenes/SingleUserScene.cs index 9e6fe7b6c6..a2122974bb 100644 --- a/util/Seeder/Scenes/SingleUserScene.cs +++ b/util/Seeder/Scenes/SingleUserScene.cs @@ -30,6 +30,8 @@ public class SingleUserScene( { [Required] public required string Email { get; set; } + [Required] + public required string Password { get; set; } public bool EmailVerified { get; set; } = false; public bool Premium { get; set; } = false; } @@ -42,7 +44,8 @@ public class SingleUserScene( passwordHasher, manglerService, request.EmailVerified, - request.Premium); + request.Premium, + password: request.Password); await userRepository.CreateAsync(user);