mirror of
https://github.com/bitwarden/server
synced 2025-12-14 15:23:42 +00:00
Stricter scene and query types
SeederAPI only serves Scenes, Recipes are inteded to be used locally only.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using Bit.SeederApi.Models.Requests;
|
using Bit.SeederApi.Models.Requests;
|
||||||
using Bit.SeederApi.Models.Response;
|
using Bit.SeederApi.Models.Response;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@@ -40,11 +40,12 @@ public class SeedControllerTests : IClassFixture<SeederApiApplicationFactory>, I
|
|||||||
});
|
});
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
var result = await response.Content.ReadFromJsonAsync<SeedResponseModel>();
|
var result = await response.Content.ReadFromJsonAsync<SceneResponseModel>();
|
||||||
|
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.NotEqual(Guid.Empty, result.SeedId);
|
Assert.NotEqual(Guid.Empty, result.SeedId);
|
||||||
Assert.NotNull(result.Result);
|
Assert.NotNull(result.MangleMap);
|
||||||
|
Assert.Null(result.Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -83,7 +84,7 @@ public class SeedControllerTests : IClassFixture<SeederApiApplicationFactory>, I
|
|||||||
});
|
});
|
||||||
|
|
||||||
seedResponse.EnsureSuccessStatusCode();
|
seedResponse.EnsureSuccessStatusCode();
|
||||||
var seedResult = await seedResponse.Content.ReadFromJsonAsync<SeedResponseModel>();
|
var seedResult = await seedResponse.Content.ReadFromJsonAsync<SceneResponseModel>();
|
||||||
Assert.NotNull(seedResult);
|
Assert.NotNull(seedResult);
|
||||||
|
|
||||||
var deleteResponse = await _client.DeleteAsync($"/seed/{seedResult.SeedId}");
|
var deleteResponse = await _client.DeleteAsync($"/seed/{seedResult.SeedId}");
|
||||||
@@ -117,7 +118,7 @@ public class SeedControllerTests : IClassFixture<SeederApiApplicationFactory>, I
|
|||||||
});
|
});
|
||||||
|
|
||||||
seedResponse.EnsureSuccessStatusCode();
|
seedResponse.EnsureSuccessStatusCode();
|
||||||
var seedResult = await seedResponse.Content.ReadFromJsonAsync<SeedResponseModel>();
|
var seedResult = await seedResponse.Content.ReadFromJsonAsync<SceneResponseModel>();
|
||||||
Assert.NotNull(seedResult);
|
Assert.NotNull(seedResult);
|
||||||
Assert.NotNull(seedResult.SeedId);
|
Assert.NotNull(seedResult.SeedId);
|
||||||
seedIds.Add(seedResult.SeedId.Value);
|
seedIds.Add(seedResult.SeedId.Value);
|
||||||
@@ -149,7 +150,7 @@ public class SeedControllerTests : IClassFixture<SeederApiApplicationFactory>, I
|
|||||||
});
|
});
|
||||||
|
|
||||||
seedResponse.EnsureSuccessStatusCode();
|
seedResponse.EnsureSuccessStatusCode();
|
||||||
var seedResult = await seedResponse.Content.ReadFromJsonAsync<SeedResponseModel>();
|
var seedResult = await seedResponse.Content.ReadFromJsonAsync<SceneResponseModel>();
|
||||||
Assert.NotNull(seedResult);
|
Assert.NotNull(seedResult);
|
||||||
|
|
||||||
// Try to delete with mix of valid and invalid IDs
|
// Try to delete with mix of valid and invalid IDs
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Bit.Seeder;
|
namespace Bit.Seeder;
|
||||||
|
|
||||||
public interface IQuery
|
public interface IQuery
|
||||||
{
|
{
|
||||||
@@ -6,9 +6,9 @@ public interface IQuery
|
|||||||
object Execute(object request);
|
object Execute(object request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IQuery<TRequest> : IQuery where TRequest : class
|
public interface IQuery<TRequest, TResult> : IQuery where TRequest : class where TResult : class
|
||||||
{
|
{
|
||||||
object Execute(TRequest request);
|
TResult Execute(TRequest request);
|
||||||
|
|
||||||
Type IQuery.GetRequestType() => typeof(TRequest);
|
Type IQuery.GetRequestType() => typeof(TRequest);
|
||||||
object IQuery.Execute(object request) => Execute((TRequest)request);
|
object IQuery.Execute(object request) => Execute((TRequest)request);
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
namespace Bit.Seeder;
|
namespace Bit.Seeder;
|
||||||
|
|
||||||
public interface IScene
|
public interface IScene
|
||||||
{
|
{
|
||||||
Type GetRequestType();
|
Type GetRequestType();
|
||||||
SceneResult Seed(object request);
|
SceneResult<object?> Seed(object request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generic scene interface for seeding operations with a specific request type. Does not return a value beyond tracking entities and a mangle map.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TRequest"></typeparam>
|
||||||
public interface IScene<TRequest> : IScene where TRequest : class
|
public interface IScene<TRequest> : IScene where TRequest : class
|
||||||
{
|
{
|
||||||
SceneResult Seed(TRequest request);
|
SceneResult Seed(TRequest request);
|
||||||
|
Type IScene.GetRequestType() => typeof(TRequest);
|
||||||
|
SceneResult<object?> IScene.Seed(object request)
|
||||||
|
{
|
||||||
|
var result = Seed((TRequest)request);
|
||||||
|
return new SceneResult(mangleMap: result.MangleMap, trackedEntities: result.TrackedEntities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IScene<TRequest, TResult> : IScene where TRequest : class where TResult : class
|
||||||
|
{
|
||||||
|
SceneResult<TResult> Seed(TRequest request);
|
||||||
|
|
||||||
Type IScene.GetRequestType() => typeof(TRequest);
|
Type IScene.GetRequestType() => typeof(TRequest);
|
||||||
SceneResult IScene.Seed(object request) => Seed((TRequest)request);
|
SceneResult<object?> IScene.Seed(object request) => (SceneResult<object?>)Seed((TRequest)request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Auth.Enums;
|
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Tokens;
|
using Bit.Core.Tokens;
|
||||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||||
@@ -9,7 +8,7 @@ namespace Bit.Seeder.Queries;
|
|||||||
public class EmergencyAccessInviteQuery(
|
public class EmergencyAccessInviteQuery(
|
||||||
DatabaseContext db,
|
DatabaseContext db,
|
||||||
IDataProtectorTokenFactory<EmergencyAccessInviteTokenable> dataProtectorTokenizer)
|
IDataProtectorTokenFactory<EmergencyAccessInviteTokenable> dataProtectorTokenizer)
|
||||||
: IQuery<EmergencyAccessInviteQuery.Request>
|
: IQuery<EmergencyAccessInviteQuery.Request, IEnumerable<string>>
|
||||||
{
|
{
|
||||||
public class Request
|
public class Request
|
||||||
{
|
{
|
||||||
@@ -17,7 +16,7 @@ public class EmergencyAccessInviteQuery(
|
|||||||
public required string Email { get; set; }
|
public required string Email { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Execute(Request request)
|
public IEnumerable<string> Execute(Request request)
|
||||||
{
|
{
|
||||||
var invites = db.EmergencyAccesses
|
var invites = db.EmergencyAccesses
|
||||||
.Where(ea => ea.Email == request.Email).ToList().Select(ea =>
|
.Where(ea => ea.Email == request.Email).ToList().Select(ea =>
|
||||||
|
|||||||
6
util/Seeder/RecipeResult.cs
Normal file
6
util/Seeder/RecipeResult.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Bit.Seeder;
|
||||||
|
|
||||||
|
public class RecipeResult
|
||||||
|
{
|
||||||
|
public Dictionary<string, List<Guid>> TrackedEntities { get; init; } = new();
|
||||||
|
}
|
||||||
@@ -1,7 +1,35 @@
|
|||||||
namespace Bit.Seeder;
|
namespace Bit.Seeder;
|
||||||
|
|
||||||
public class SceneResult
|
public class SceneResult : SceneResult<object?>
|
||||||
{
|
{
|
||||||
public required object Result { get; init; }
|
public SceneResult(Dictionary<string, string?> mangleMap, Dictionary<string, List<Guid>> trackedEntities)
|
||||||
public Dictionary<string, List<Guid>> TrackedEntities { get; init; } = new();
|
: base(result: null, mangleMap: mangleMap, trackedEntities: trackedEntities) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SceneResult<TResult>
|
||||||
|
{
|
||||||
|
public TResult Result { get; init; }
|
||||||
|
public Dictionary<string, string?> MangleMap { get; init; }
|
||||||
|
public Dictionary<string, List<Guid>> TrackedEntities { get; init; }
|
||||||
|
|
||||||
|
public SceneResult(TResult result, Dictionary<string, string?> mangleMap, Dictionary<string, List<Guid>> trackedEntities)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
MangleMap = mangleMap;
|
||||||
|
TrackedEntities = trackedEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator SceneResult<object?>(SceneResult<TResult> v)
|
||||||
|
{
|
||||||
|
var result = v.Result;
|
||||||
|
|
||||||
|
if (result is null)
|
||||||
|
{
|
||||||
|
return new SceneResult<object?>(result: null, mangleMap: v.MangleMap, trackedEntities: v.TrackedEntities);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new SceneResult<object?>(result: result, mangleMap: v.MangleMap, trackedEntities: v.TrackedEntities);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Enums;
|
|
||||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||||
using Bit.Seeder.Factories;
|
using Bit.Seeder.Factories;
|
||||||
|
|
||||||
@@ -22,23 +21,19 @@ public class SingleUserScene(DatabaseContext db, UserSeeder userSeeder) : IScene
|
|||||||
db.Add(user);
|
db.Add(user);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
|
||||||
return new SceneResult
|
return new SceneResult(mangleMap: userSeeder.GetMangleMap(user, new UserData
|
||||||
{
|
|
||||||
Result = userSeeder.GetMangleMap(user, new UserData
|
|
||||||
{
|
{
|
||||||
Email = request.Email,
|
Email = request.Email,
|
||||||
Id = Guid.Parse("00000000-0000-0000-0000-000000000001"),
|
Id = user.Id,
|
||||||
Key = "seeded_key",
|
Key = user.Key,
|
||||||
PublicKey = "seeded_public_key",
|
PublicKey = user.PublicKey,
|
||||||
PrivateKey = "seeded_private_key",
|
PrivateKey = user.PrivateKey,
|
||||||
ApiKey = "seeded_api_key",
|
ApiKey = user.ApiKey,
|
||||||
Kdf = KdfType.PBKDF2_SHA256,
|
Kdf = user.Kdf,
|
||||||
KdfIterations = 600_000,
|
KdfIterations = user.KdfIterations,
|
||||||
}),
|
}), trackedEntities: new Dictionary<string, List<Guid>>
|
||||||
TrackedEntities = new Dictionary<string, List<Guid>>
|
|
||||||
{
|
{
|
||||||
["User"] = [user.Id]
|
["User"] = [user.Id]
|
||||||
}
|
});
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
using Bit.SeederApi.Models.Requests;
|
using Bit.SeederApi.Models.Requests;
|
||||||
using Bit.SeederApi.Services;
|
using Bit.SeederApi.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Bit.SeederApi.Controllers
|
namespace Bit.SeederApi.Controllers;
|
||||||
{
|
|
||||||
[Route("query")]
|
[Route("query")]
|
||||||
public class QueryController(ILogger<QueryController> logger, IRecipeService recipeService)
|
public class QueryController(ILogger<QueryController> logger, ISeedService recipeService)
|
||||||
: Controller
|
: Controller
|
||||||
{
|
{
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Query([FromBody] QueryRequestModel request)
|
public IActionResult Query([FromBody] QueryRequestModel request)
|
||||||
{
|
{
|
||||||
@@ -33,5 +33,4 @@ namespace Bit.SeederApi.Controllers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using Bit.SeederApi.Models.Requests;
|
using Bit.SeederApi.Models.Requests;
|
||||||
using Bit.SeederApi.Models.Response;
|
|
||||||
using Bit.SeederApi.Services;
|
using Bit.SeederApi.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Bit.SeederApi.Controllers
|
namespace Bit.SeederApi.Controllers;
|
||||||
{
|
|
||||||
[Route("seed")]
|
[Route("seed")]
|
||||||
public class SeedController(ILogger<SeedController> logger, IRecipeService recipeService)
|
public class SeedController(ILogger<SeedController> logger, ISeedService recipeService)
|
||||||
: Controller
|
: Controller
|
||||||
{
|
{
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Seed([FromBody] SeedRequestModel request)
|
public IActionResult Seed([FromBody] SeedRequestModel request)
|
||||||
{
|
{
|
||||||
@@ -16,13 +15,9 @@ namespace Bit.SeederApi.Controllers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (result, seedId) = recipeService.ExecuteRecipe(request.Template, request.Arguments);
|
var response = recipeService.ExecuteScene(request.Template, request.Arguments);
|
||||||
|
|
||||||
return Json(new SeedResponseModel
|
return Json(response);
|
||||||
{
|
|
||||||
SeedId = seedId,
|
|
||||||
Result = result,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (RecipeNotFoundException ex)
|
catch (RecipeNotFoundException ex)
|
||||||
{
|
{
|
||||||
@@ -135,5 +130,4 @@ namespace Bit.SeederApi.Controllers
|
|||||||
}
|
}
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Bit.Seeder;
|
using Bit.Seeder;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
@@ -12,11 +12,15 @@ public static class ServiceCollectionExtensions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static IServiceCollection AddScenes(this IServiceCollection services)
|
public static IServiceCollection AddScenes(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
var iSceneType1 = typeof(IScene<>);
|
||||||
|
var iSceneType2 = typeof(IScene<,>);
|
||||||
|
var isIScene = (Type t) => t == iSceneType1 || t == iSceneType2;
|
||||||
|
|
||||||
var seederAssembly = Assembly.Load("Seeder");
|
var seederAssembly = Assembly.Load("Seeder");
|
||||||
var sceneTypes = seederAssembly.GetTypes()
|
var sceneTypes = seederAssembly.GetTypes()
|
||||||
.Where(t => t is { IsClass: true, IsAbstract: false } &&
|
.Where(t => t is { IsClass: true, IsAbstract: false } &&
|
||||||
t.GetInterfaces().Any(i => i.IsGenericType &&
|
t.GetInterfaces().Any(i => i.IsGenericType &&
|
||||||
i.GetGenericTypeDefinition().Name == "IScene`1"));
|
isIScene(i.GetGenericTypeDefinition())));
|
||||||
|
|
||||||
foreach (var sceneType in sceneTypes)
|
foreach (var sceneType in sceneTypes)
|
||||||
{
|
{
|
||||||
@@ -33,11 +37,12 @@ public static class ServiceCollectionExtensions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static IServiceCollection AddQueries(this IServiceCollection services)
|
public static IServiceCollection AddQueries(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
var iQueryType = typeof(IQuery<,>);
|
||||||
var seederAssembly = Assembly.Load("Seeder");
|
var seederAssembly = Assembly.Load("Seeder");
|
||||||
var queryTypes = seederAssembly.GetTypes()
|
var queryTypes = seederAssembly.GetTypes()
|
||||||
.Where(t => t is { IsClass: true, IsAbstract: false } &&
|
.Where(t => t is { IsClass: true, IsAbstract: false } &&
|
||||||
t.GetInterfaces().Any(i => i.IsGenericType &&
|
t.GetInterfaces().Any(i => i.IsGenericType &&
|
||||||
i.GetGenericTypeDefinition().Name == "IQuery`1"));
|
i.GetGenericTypeDefinition() == iQueryType));
|
||||||
|
|
||||||
foreach (var queryType in queryTypes)
|
foreach (var queryType in queryTypes)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,20 @@
|
|||||||
namespace Bit.SeederApi.Models.Response;
|
using Bit.Seeder;
|
||||||
|
|
||||||
public class SeedResponseModel
|
namespace Bit.SeederApi.Models.Response;
|
||||||
|
|
||||||
|
public class SceneResponseModel
|
||||||
{
|
{
|
||||||
public Guid? SeedId { get; set; }
|
public required Guid? SeedId { get; init; }
|
||||||
public object? Result { get; set; }
|
public required Dictionary<string, string?>? MangleMap { get; init; }
|
||||||
|
public required object? Result { get; init; }
|
||||||
|
|
||||||
|
public static SceneResponseModel FromSceneResult<T>(SceneResult<T> sceneResult, Guid? seedId)
|
||||||
|
{
|
||||||
|
return new SceneResponseModel
|
||||||
|
{
|
||||||
|
Result = sceneResult.Result,
|
||||||
|
MangleMap = sceneResult.MangleMap,
|
||||||
|
SeedId = seedId
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ builder.Services.AddScoped<Microsoft.AspNetCore.Identity.IPasswordHasher<Bit.Cor
|
|||||||
// Seeder services
|
// Seeder services
|
||||||
builder.Services.AddSingleton<Bit.RustSDK.RustSdkService>();
|
builder.Services.AddSingleton<Bit.RustSDK.RustSdkService>();
|
||||||
builder.Services.AddScoped<Bit.Seeder.Factories.UserSeeder>();
|
builder.Services.AddScoped<Bit.Seeder.Factories.UserSeeder>();
|
||||||
builder.Services.AddScoped<IRecipeService, RecipeService>();
|
builder.Services.AddScoped<ISeedService, SeedService>();
|
||||||
builder.Services.AddScoped<MangleId>(_ => new MangleId());
|
builder.Services.AddScoped<MangleId>(_ => new MangleId());
|
||||||
builder.Services.AddScenes();
|
builder.Services.AddScenes();
|
||||||
builder.Services.AddQueries();
|
builder.Services.AddQueries();
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Infrastructure.EntityFramework.Models;
|
using Bit.Infrastructure.EntityFramework.Models;
|
||||||
|
using Bit.SeederApi.Models.Response;
|
||||||
|
|
||||||
namespace Bit.SeederApi.Services;
|
namespace Bit.SeederApi.Services;
|
||||||
|
|
||||||
public interface IRecipeService
|
public interface ISeedService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes a scene with the given template name and arguments.
|
/// Executes a scene with the given template name and arguments.
|
||||||
@@ -13,7 +14,7 @@ public interface IRecipeService
|
|||||||
/// <returns>A tuple containing the result and optional seed ID for tracked entities</returns>
|
/// <returns>A tuple containing the result and optional seed ID for tracked entities</returns>
|
||||||
/// <exception cref="RecipeNotFoundException">Thrown when the scene template is not found</exception>
|
/// <exception cref="RecipeNotFoundException">Thrown when the scene template is not found</exception>
|
||||||
/// <exception cref="RecipeExecutionException">Thrown when there's an error executing the scene</exception>
|
/// <exception cref="RecipeExecutionException">Thrown when there's an error executing the scene</exception>
|
||||||
(object? Result, Guid? SeedId) ExecuteRecipe(string templateName, JsonElement? arguments);
|
SceneResponseModel ExecuteScene(string templateName, JsonElement? arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Destroys data created by a scene using the seeded data ID.
|
/// Destroys data created by a scene using the seeded data ID.
|
||||||
|
|||||||
@@ -3,16 +3,17 @@ using Bit.Core.Repositories;
|
|||||||
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 Bit.SeederApi.Models.Response;
|
||||||
|
|
||||||
namespace Bit.SeederApi.Services;
|
namespace Bit.SeederApi.Services;
|
||||||
|
|
||||||
public class RecipeService(
|
public class SeedService(
|
||||||
DatabaseContext databaseContext,
|
DatabaseContext databaseContext,
|
||||||
ILogger<RecipeService> logger,
|
ILogger<SeedService> logger,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IOrganizationRepository organizationRepository)
|
IOrganizationRepository organizationRepository)
|
||||||
: IRecipeService
|
: ISeedService
|
||||||
{
|
{
|
||||||
private static readonly JsonSerializerOptions _jsonOptions = new()
|
private static readonly JsonSerializerOptions _jsonOptions = new()
|
||||||
{
|
{
|
||||||
@@ -25,13 +26,13 @@ public class RecipeService(
|
|||||||
return databaseContext.SeededData.ToList();
|
return databaseContext.SeededData.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public (object? Result, Guid? SeedId) ExecuteRecipe(string templateName, JsonElement? arguments)
|
public SceneResponseModel ExecuteScene(string templateName, JsonElement? arguments)
|
||||||
{
|
{
|
||||||
var result = ExecuteRecipeMethod(templateName, arguments, "Seed");
|
var result = ExecuteSceneMethod(templateName, arguments, "Seed");
|
||||||
|
|
||||||
if (result.TrackedEntities.Count == 0)
|
if (result.TrackedEntities.Count == 0)
|
||||||
{
|
{
|
||||||
return (Result: result.Result, SeedId: null);
|
return SceneResponseModel.FromSceneResult(result, seedId: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var seededData = new SeededData
|
var seededData = new SeededData
|
||||||
@@ -48,7 +49,7 @@ public class RecipeService(
|
|||||||
logger.LogInformation("Saved seeded data with ID {SeedId} for scene {RecipeName}",
|
logger.LogInformation("Saved seeded data with ID {SeedId} for scene {RecipeName}",
|
||||||
seededData.Id, templateName);
|
seededData.Id, templateName);
|
||||||
|
|
||||||
return (Result: result.Result, SeedId: seededData.Id);
|
return SceneResponseModel.FromSceneResult(result, seededData.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object ExecuteQuery(string queryName, JsonElement? arguments)
|
public object ExecuteQuery(string queryName, JsonElement? arguments)
|
||||||
@@ -166,7 +167,7 @@ public class RecipeService(
|
|||||||
return new { SeedId = seedId, RecipeName = seededData.RecipeName };
|
return new { SeedId = seedId, RecipeName = seededData.RecipeName };
|
||||||
}
|
}
|
||||||
|
|
||||||
private SceneResult ExecuteRecipeMethod(string templateName, JsonElement? arguments, string methodName)
|
private SceneResult<object?> ExecuteSceneMethod(string templateName, JsonElement? arguments, string methodName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user