1
0
mirror of https://github.com/bitwarden/server synced 2025-12-17 16:53:23 +00:00

Delete all seeded data

Fixup single user recipe to inform of seeded entities
This commit is contained in:
Matt Gibson
2025-10-09 15:36:29 -07:00
parent d93cd50818
commit 431a708914
5 changed files with 72 additions and 18 deletions

View File

@@ -1,7 +1,7 @@
namespace Bit.Seeder; namespace Bit.Seeder;
public class RecipeResult public class RecipeResult
{ {
public required object Result { get; init; } public required object Result { get; init; }
public Dictionary<string, List<Guid>> TrackedEntities { get; init; } = new(); public Dictionary<string, List<Guid>> TrackedEntities { get; init; } = new();
} }

View File

@@ -6,7 +6,7 @@ namespace Bit.Seeder.Recipes;
public class SingleUserRecipe(DatabaseContext db) public class SingleUserRecipe(DatabaseContext db)
{ {
public Dictionary<string, string?> Seed(string email) public RecipeResult Seed(string email)
{ {
var userSeeder = new UserSeeder(Guid.NewGuid()); var userSeeder = new UserSeeder(Guid.NewGuid());
var user = userSeeder.CreateUser(email); var user = userSeeder.CreateUser(email);
@@ -14,16 +14,23 @@ public class SingleUserRecipe(DatabaseContext db)
db.Add(user); db.Add(user);
db.SaveChanges(); db.SaveChanges();
return userSeeder.GetMangleMap(user, new UserData return new RecipeResult
{ {
Email = email, Result = userSeeder.GetMangleMap(user, new UserData
Id = Guid.Parse("00000000-0000-0000-0000-000000000001"), {
Key = "seeded_key", Email = email,
PublicKey = "seeded_public_key", Id = Guid.Parse("00000000-0000-0000-0000-000000000001"),
PrivateKey = "seeded_private_key", Key = "seeded_key",
ApiKey = "seeded_api_key", PublicKey = "seeded_public_key",
Kdf = KdfType.PBKDF2_SHA256, PrivateKey = "seeded_private_key",
KdfIterations = 600_000, ApiKey = "seeded_api_key",
}); Kdf = KdfType.PBKDF2_SHA256,
KdfIterations = 600_000,
}),
TrackedEntities = new Dictionary<string, List<Guid>>
{
["User"] = [user.Id]
}
};
} }
} }

View File

@@ -1,7 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Bit.SeederApi.Services; using Bit.SeederApi.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace Bit.SeederApi.Controllers; namespace Bit.SeederApi.Controllers;
@@ -99,4 +99,44 @@ public class SeedController : Controller
}); });
} }
} }
[HttpDelete("/seed")]
public async Task<IActionResult> DeleteAll()
{
_logger.LogInformation("Deleting all seeded data");
// Pull all Seeded Data ids
var seededData = _recipeService.GetAllSeededData();
var aggregateException = new AggregateException();
await Task.Run(() =>
{
foreach (var sd in seededData)
{
try
{
_recipeService.DestroyRecipe(sd.Id);
}
catch (Exception ex)
{
aggregateException = new AggregateException(aggregateException, ex);
_logger.LogError(ex, "Error deleting seeded data: {SeedId}", sd.Id);
}
}
});
if (aggregateException.InnerExceptions.Count > 0)
{
return BadRequest(new
{
Error = "One or more errors occurred while deleting seeded data",
Details = aggregateException.InnerExceptions.Select(e => e.Message).ToList()
});
}
return Ok(new
{
Message = "All seeded data deleted successfully"
});
}
} }

View File

@@ -1,4 +1,5 @@
using System.Text.Json; using System.Text.Json;
using Bit.Infrastructure.EntityFramework.Models;
namespace Bit.SeederApi.Services; namespace Bit.SeederApi.Services;
@@ -21,4 +22,5 @@ public interface IRecipeService
/// <returns>The result of the destroy operation</returns> /// <returns>The result of the destroy operation</returns>
/// <exception cref="RecipeExecutionException">Thrown when there's an error destroying the seeded data</exception> /// <exception cref="RecipeExecutionException">Thrown when there's an error destroying the seeded data</exception>
object? DestroyRecipe(Guid seedId); object? DestroyRecipe(Guid seedId);
List<SeededData> GetAllSeededData();
} }

View File

@@ -1,8 +1,8 @@
using System.Reflection;
using System.Text.Json;
using Bit.Infrastructure.EntityFramework.Models; using Bit.Infrastructure.EntityFramework.Models;
using Bit.Infrastructure.EntityFramework.Repositories; using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Seeder; using Bit.Seeder;
using System.Reflection;
using System.Text.Json;
namespace Bit.SeederApi.Services; namespace Bit.SeederApi.Services;
@@ -17,6 +17,11 @@ public class RecipeService : IRecipeService
_logger = logger; _logger = logger;
} }
public List<SeededData> GetAllSeededData()
{
return _databaseContext.SeededData.ToList();
}
public (object? Result, Guid? SeedId) ExecuteRecipe(string templateName, JsonElement? arguments) public (object? Result, Guid? SeedId) ExecuteRecipe(string templateName, JsonElement? arguments)
{ {
var result = ExecuteRecipeMethod(templateName, arguments, "Seed"); var result = ExecuteRecipeMethod(templateName, arguments, "Seed");