Skip to content

Commit

Permalink
Handle invalid recipe files from breaking the harvester (OrchardCMS#1…
Browse files Browse the repository at this point in the history
…6490)

---------

Co-authored-by: Zoltán Lehóczky <[email protected]>
  • Loading branch information
2 people authored and hyzx86 committed Jul 30, 2024
1 parent 912616c commit de11ba8
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public RecipeHarvester(

/// <inheritdoc/>
public virtual Task<IEnumerable<RecipeDescriptor>> HarvestRecipesAsync()
=> _extensionManager.GetExtensions().InvokeAsync(HarvestRecipes, _logger);
=> _extensionManager.GetExtensions().InvokeAsync(GetRecipesAsync, _logger);

/// <summary>
/// Returns a list of recipes for a content path.
Expand All @@ -50,13 +50,18 @@ protected async Task<IEnumerable<RecipeDescriptor>> HarvestRecipesAsync(string p
{
var recipeDescriptor = await _recipeReader.GetRecipeDescriptorAsync(path, recipeFile, _hostingEnvironment.ContentRootFileProvider);

if (recipeDescriptor == null)
{
continue;
}

recipeDescriptors.Add(recipeDescriptor);
}

return recipeDescriptors;
}

private Task<IEnumerable<RecipeDescriptor>> HarvestRecipes(IExtensionInfo extension)
private Task<IEnumerable<RecipeDescriptor>> GetRecipesAsync(IExtensionInfo extension)
{
var folderSubPath = PathExtensions.Combine(extension.SubPath, RecipesConstants.RecipesFolderName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,23 @@ public async Task<string> ExecuteAsync(string recipeFileName, IDataMigration mig
var recipeFilePath = Path.Combine(recipeBasePath, recipeFileName).Replace('\\', '/');
var recipeFileInfo = _hostingEnvironment.ContentRootFileProvider.GetFileInfo(recipeFilePath);
var recipeDescriptor = await _recipeReader.GetRecipeDescriptorAsync(recipeBasePath, recipeFileInfo, _hostingEnvironment.ContentRootFileProvider);

if (recipeDescriptor == null)
{
return null;
}

recipeDescriptor.RequireNewScope = false;

var environment = new Dictionary<string, object>();

await _environmentProviders.OrderBy(x => x.Order).InvokeAsync((provider, env) => provider.PopulateEnvironmentAsync(env), environment, _logger);
await _environmentProviders.OrderBy(x => x.Order)
.InvokeAsync((provider, env) => provider.PopulateEnvironmentAsync(env), environment, _logger);

var executionId = Guid.NewGuid().ToString("n");

return await _recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, environment, CancellationToken.None);
}
}
}

27 changes: 23 additions & 4 deletions src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using OrchardCore.Recipes.Models;

namespace OrchardCore.Recipes.Services
{
public class RecipeReader : IRecipeReader
{
private readonly ILogger _logger;

public RecipeReader(ILogger<RecipeReader> logger)
{
_logger = logger;
}

public async Task<RecipeDescriptor> GetRecipeDescriptorAsync(string recipeBasePath, IFileInfo recipeFileInfo, IFileProvider recipeFileProvider)
{
// TODO: Try to optimize by only reading the required metadata instead of the whole file.
using var stream = recipeFileInfo.CreateReadStream();

var recipeDescriptor = await JsonSerializer.DeserializeAsync<RecipeDescriptor>(stream, JOptions.Default);
RecipeDescriptor recipeDescriptor = null;

try
{
recipeDescriptor = await JsonSerializer.DeserializeAsync<RecipeDescriptor>(stream, JOptions.Default);

recipeDescriptor.FileProvider = recipeFileProvider;
recipeDescriptor.BasePath = recipeBasePath;
recipeDescriptor.RecipeFileInfo = recipeFileInfo;

recipeDescriptor.FileProvider = recipeFileProvider;
recipeDescriptor.BasePath = recipeBasePath;
recipeDescriptor.RecipeFileInfo = recipeFileInfo;
}
catch (Exception ex)
{
_logger.LogError(ex, "Unable to deserialize the recipe file: '{FileName}'.", recipeFileInfo.Name);
}

return recipeDescriptor;
}
Expand Down
6 changes: 6 additions & 0 deletions test/OrchardCore.Tests/Apis/Context/TestRecipeHarvester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ private async Task<IEnumerable<RecipeDescriptor>> HarvestRecipesAsync(string[] p
foreach (var fileInfo in fileInfos)
{
var descriptor = await _recipeReader.GetRecipeDescriptorAsync(fileInfo.PhysicalPath, fileInfo, testAssemblyFileProvider);

if (descriptor == null)
{
continue;
}

recipeDescriptors.Add(descriptor);
}

Expand Down

0 comments on commit de11ba8

Please sign in to comment.