Merge branch 'v8/8.7' into v8/8.8

This commit is contained in:
Sebastiaan Janssen
2021-03-01 16:02:37 +01:00
4 changed files with 145 additions and 56 deletions

View File

@@ -62,12 +62,10 @@ namespace Umbraco.Core.Services.Implement
//start with the deepest id
ids.Reverse();
using (var scope = ScopeProvider.CreateScope())
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
//This will retrieve from cache!
var entries = _publicAccessRepository.GetMany().ToArray();
scope.Complete();
var entries = _publicAccessRepository.GetMany().ToList();
foreach (var id in ids)
{
var found = entries.FirstOrDefault(x => x.ProtectedNodeId == id);

View File

@@ -4,7 +4,9 @@ using System.Linq;
using Examine;
using Examine.LuceneEngine.Providers;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
namespace Umbraco.Examine
@@ -15,9 +17,9 @@ namespace Umbraco.Examine
public class ContentValueSetValidator : ValueSetValidator, IContentValueSetValidator
{
private readonly IPublicAccessService _publicAccessService;
private readonly IScopeProvider _scopeProvider;
private const string PathKey = "path";
private static readonly IEnumerable<string> ValidCategories = new[] {IndexTypes.Content, IndexTypes.Media};
private static readonly IEnumerable<string> ValidCategories = new[] { IndexTypes.Content, IndexTypes.Media };
protected override IEnumerable<string> ValidIndexCategories => ValidCategories;
public bool PublishedValuesOnly { get; }
@@ -53,25 +55,38 @@ namespace Umbraco.Examine
public bool ValidateProtectedContent(string path, string category)
{
if (category == IndexTypes.Content
&& !SupportProtectedContent
//if the service is null we can't look this up so we'll return false
&& (_publicAccessService == null || _publicAccessService.IsProtected(path)))
if (category == IndexTypes.Content && !SupportProtectedContent)
{
return false;
//if the service is null we can't look this up so we'll return false
if (_publicAccessService == null || _scopeProvider == null)
{
return false;
}
// explicit scope since we may be in a background thread
using (_scopeProvider.CreateScope(autoComplete: true))
{
if (_publicAccessService.IsProtected(path))
{
return false;
}
}
}
return true;
}
// used for tests
public ContentValueSetValidator(bool publishedValuesOnly, int? parentId = null,
IEnumerable<string> includeItemTypes = null, IEnumerable<string> excludeItemTypes = null)
: this(publishedValuesOnly, true, null, parentId, includeItemTypes, excludeItemTypes)
: this(publishedValuesOnly, true, null, null, parentId, includeItemTypes, excludeItemTypes)
{
}
public ContentValueSetValidator(bool publishedValuesOnly, bool supportProtectedContent,
IPublicAccessService publicAccessService, int? parentId = null,
IPublicAccessService publicAccessService,
IScopeProvider scopeProvider,
int? parentId = null,
IEnumerable<string> includeItemTypes = null, IEnumerable<string> excludeItemTypes = null)
: base(includeItemTypes, excludeItemTypes, null, null)
{
@@ -79,6 +94,16 @@ namespace Umbraco.Examine
SupportProtectedContent = supportProtectedContent;
ParentId = parentId;
_publicAccessService = publicAccessService;
_scopeProvider = scopeProvider;
}
[Obsolete("Use the ctor with all parameters instead")]
public ContentValueSetValidator(bool publishedValuesOnly, bool supportProtectedContent,
IPublicAccessService publicAccessService, int? parentId = null,
IEnumerable<string> includeItemTypes = null, IEnumerable<string> excludeItemTypes = null)
: this(publishedValuesOnly, supportProtectedContent, publicAccessService, Current.ScopeProvider,
parentId, includeItemTypes, excludeItemTypes)
{
}
public override ValueSetValidationResult Validate(ValueSet valueSet)
@@ -103,7 +128,7 @@ namespace Umbraco.Examine
&& variesByCulture.Count > 0 && variesByCulture[0].Equals("y"))
{
//so this valueset is for a content that varies by culture, now check for non-published cultures and remove those values
foreach(var publishField in valueSet.Values.Where(x => x.Key.StartsWith($"{UmbracoExamineIndex.PublishedFieldName}_")).ToList())
foreach (var publishField in valueSet.Values.Where(x => x.Key.StartsWith($"{UmbracoExamineIndex.PublishedFieldName}_")).ToList())
{
if (publishField.Value.Count <= 0 || !publishField.Value[0].Equals("y"))
{
@@ -134,7 +159,7 @@ namespace Umbraco.Examine
|| !ValidateProtectedContent(path, valueSet.Category))
return ValueSetValidationResult.Filtered;
return isFiltered ? ValueSetValidationResult.Filtered: ValueSetValidationResult.Valid;
return isFiltered ? ValueSetValidationResult.Filtered : ValueSetValidationResult.Valid;
}
}
}

View File

@@ -8,6 +8,7 @@ using Umbraco.Core;
using Umbraco.Core.Models;
using System;
using System.Linq;
using Umbraco.Core.Scoping;
namespace Umbraco.Tests.UmbracoExamine
{
@@ -17,10 +18,14 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Invalid_Category()
{
var validator = new ContentValueSetValidator(false, true, Mock.Of<IPublicAccessService>());
var validator = new ContentValueSetValidator(
false,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>());
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
Assert.AreEqual(ValueSetValidationResult.Valid, result);
result = validator.Validate(ValueSet.FromObject("777", IndexTypes.Media, new { hello = "world", path = "-1,555" }));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
@@ -33,7 +38,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Must_Have_Path()
{
var validator = new ContentValueSetValidator(false, true, Mock.Of<IPublicAccessService>());
var validator = new ContentValueSetValidator(
false,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>());
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world" }));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -45,7 +54,12 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Parent_Id()
{
var validator = new ContentValueSetValidator(false, true, Mock.Of<IPublicAccessService>(), 555);
var validator = new ContentValueSetValidator(
false,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>(),
555);
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));
Assert.AreEqual(ValueSetValidationResult.Filtered, result);
@@ -63,7 +77,9 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Inclusion_Field_List()
{
var validator = new ValueSetValidator(null, null,
var validator = new ValueSetValidator(
null,
null,
new[] { "hello", "world" },
null);
@@ -79,7 +95,9 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Exclusion_Field_List()
{
var validator = new ValueSetValidator(null, null,
var validator = new ValueSetValidator(
null,
null,
null,
new[] { "hello", "world" });
@@ -95,7 +113,9 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Inclusion_Exclusion_Field_List()
{
var validator = new ValueSetValidator(null, null,
var validator = new ValueSetValidator(
null,
null,
new[] { "hello", "world" },
new[] { "world" });
@@ -111,7 +131,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Inclusion_Type_List()
{
var validator = new ContentValueSetValidator(false, true, Mock.Of<IPublicAccessService>(),
var validator = new ContentValueSetValidator(
false,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>(),
includeItemTypes: new List<string> { "include-content" });
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555" }));
@@ -127,7 +151,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Exclusion_Type_List()
{
var validator = new ContentValueSetValidator(false, true, Mock.Of<IPublicAccessService>(),
var validator = new ContentValueSetValidator(
false,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>(),
excludeItemTypes: new List<string> { "exclude-content" });
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555" }));
@@ -143,7 +171,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Inclusion_Exclusion_Type_List()
{
var validator = new ContentValueSetValidator(false, true, Mock.Of<IPublicAccessService>(),
var validator = new ContentValueSetValidator(
false,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>(),
includeItemTypes: new List<string> { "include-content", "exclude-content" },
excludeItemTypes: new List<string> { "exclude-content" });
@@ -163,7 +195,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Recycle_Bin_Content()
{
var validator = new ContentValueSetValidator(true, false, Mock.Of<IPublicAccessService>());
var validator = new ContentValueSetValidator(
true,
false,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>());
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,-20,555" }));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -187,7 +223,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Recycle_Bin_Media()
{
var validator = new ContentValueSetValidator(true, false, Mock.Of<IPublicAccessService>());
var validator = new ContentValueSetValidator(
true,
false,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>());
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,-21,555" }));
Assert.AreEqual(ValueSetValidationResult.Filtered, result);
@@ -203,7 +243,11 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Published_Only()
{
var validator = new ContentValueSetValidator(true, true, Mock.Of<IPublicAccessService>());
var validator = new ContentValueSetValidator(
true,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>());
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -230,7 +274,10 @@ namespace Umbraco.Tests.UmbracoExamine
[Test]
public void Published_Only_With_Variants()
{
var validator = new ContentValueSetValidator(true, true, Mock.Of<IPublicAccessService>());
var validator = new ContentValueSetValidator(true,
true,
Mock.Of<IPublicAccessService>(),
Mock.Of<IScopeProvider>());
var result = validator.Validate(new ValueSet("555", IndexTypes.Content,
new Dictionary<string, object>
@@ -288,7 +335,11 @@ namespace Umbraco.Tests.UmbracoExamine
.Returns(Attempt.Succeed(new PublicAccessEntry(Guid.NewGuid(), 555, 444, 333, Enumerable.Empty<PublicAccessRule>())));
publicAccessService.Setup(x => x.IsProtected("-1,777"))
.Returns(Attempt.Fail<PublicAccessEntry>());
var validator = new ContentValueSetValidator(false, false, publicAccessService.Object);
var validator = new ContentValueSetValidator(
false,
false,
publicAccessService.Object,
Mock.Of<IScopeProvider>());
var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));
Assert.AreEqual(ValueSetValidationResult.Filtered, result);

View File

@@ -629,22 +629,27 @@ namespace Umbraco.Web.Search
// perform the ValueSet lookup on a background thread
examineComponent._indexItemTaskRunner.Add(new SimpleTask(() =>
{
// for content we have a different builder for published vs unpublished
// we don't want to build more value sets than is needed so we'll lazily build 2 one for published one for non-published
var builders = new Dictionary<bool, Lazy<List<ValueSet>>>
// Background thread, wrap the whole thing in an explicit scope since we know
// DB services are used within this logic.
using (examineComponent._scopeProvider.CreateScope(autoComplete: true))
{
[true] = new Lazy<List<ValueSet>>(() => examineComponent._publishedContentValueSetBuilder.GetValueSets(content).ToList()),
[false] = new Lazy<List<ValueSet>>(() => examineComponent._contentValueSetBuilder.GetValueSets(content).ToList())
};
// for content we have a different builder for published vs unpublished
// we don't want to build more value sets than is needed so we'll lazily build 2 one for published one for non-published
var builders = new Dictionary<bool, Lazy<List<ValueSet>>>
{
[true] = new Lazy<List<ValueSet>>(() => examineComponent._publishedContentValueSetBuilder.GetValueSets(content).ToList()),
[false] = new Lazy<List<ValueSet>>(() => examineComponent._contentValueSetBuilder.GetValueSets(content).ToList())
};
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
//filter the indexers
.Where(x => isPublished || !x.PublishedValuesOnly)
.Where(x => x.EnableDefaultEventHandler))
{
var valueSet = builders[index.PublishedValuesOnly].Value;
index.IndexItems(valueSet);
}
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
//filter the indexers
.Where(x => isPublished || !x.PublishedValuesOnly)
.Where(x => x.EnableDefaultEventHandler))
{
var valueSet = builders[index.PublishedValuesOnly].Value;
index.IndexItems(valueSet);
}
}
}));
}
}
@@ -675,14 +680,19 @@ namespace Umbraco.Web.Search
// perform the ValueSet lookup on a background thread
examineComponent._indexItemTaskRunner.Add(new SimpleTask(() =>
{
var valueSet = examineComponent._mediaValueSetBuilder.GetValueSets(media).ToList();
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
//filter the indexers
.Where(x => isPublished || !x.PublishedValuesOnly)
.Where(x => x.EnableDefaultEventHandler))
// Background thread, wrap the whole thing in an explicit scope since we know
// DB services are used within this logic.
using (examineComponent._scopeProvider.CreateScope(autoComplete: true))
{
index.IndexItems(valueSet);
var valueSet = examineComponent._mediaValueSetBuilder.GetValueSets(media).ToList();
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
//filter the indexers
.Where(x => isPublished || !x.PublishedValuesOnly)
.Where(x => x.EnableDefaultEventHandler))
{
index.IndexItems(valueSet);
}
}
}));
}
@@ -712,12 +722,17 @@ namespace Umbraco.Web.Search
// perform the ValueSet lookup on a background thread
examineComponent._indexItemTaskRunner.Add(new SimpleTask(() =>
{
var valueSet = examineComponent._memberValueSetBuilder.GetValueSets(member).ToList();
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
//filter the indexers
.Where(x => x.EnableDefaultEventHandler))
// Background thread, wrap the whole thing in an explicit scope since we know
// DB services are used within this logic.
using (examineComponent._scopeProvider.CreateScope(autoComplete: true))
{
index.IndexItems(valueSet);
var valueSet = examineComponent._memberValueSetBuilder.GetValueSets(member).ToList();
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
//filter the indexers
.Where(x => x.EnableDefaultEventHandler))
{
index.IndexItems(valueSet);
}
}
}));
}