Exemple #1
0
        public void Published_Only()
        {
            var validator = new ContentValueSetValidator(
                true,
                true,
                Mock.Of <IPublicAccessService>(),
                Mock.Of <IScopeProvider>());

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));

            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(new ValueSet(
                                            "555",
                                            IndexTypes.Content,
                                            new Dictionary <string, object>
            {
                ["hello"] = "world",
                ["path"]  = "-1,555",
                [UmbracoExamineFieldNames.PublishedFieldName] = "n"
            }));
            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(new ValueSet(
                                            "555",
                                            IndexTypes.Content,
                                            new Dictionary <string, object>
            {
                ["hello"] = "world",
                ["path"]  = "-1,555",
                [UmbracoExamineFieldNames.PublishedFieldName] = "y"
            }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);
        }
Exemple #2
0
        public void Inclusion_Exclusion_Type_List()
        {
            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"
            });

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555" }));

            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "exclude-content", new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "include-content", new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);
        }
Exemple #3
0
        /// <summary>
        /// Special check for invalid paths
        /// </summary>
        /// <param name="values"></param>
        /// <param name="onComplete"></param>
        protected override void PerformIndexItems(IEnumerable <ValueSet> values, Action <IndexOperationEventArgs> onComplete)
        {
            // We don't want to re-enumerate this list, but we need to split it into 2x enumerables: invalid and valid items.
            // The Invalid items will be deleted, these are items that have invalid paths (i.e. moved to the recycle bin, etc...)
            // Then we'll index the Value group all together.
            var invalidOrValid = values.GroupBy(v =>
            {
                if (!v.Values.TryGetValue("path", out IReadOnlyList <object>?paths) || paths.Count <= 0 || paths[0] == null)
                {
                    return(ValueSetValidationStatus.Failed);
                }

                ValueSetValidationResult validationResult = ValueSetValidator.Validate(v);

                return(validationResult.Status);
            }).ToList();

            var hasDeletes = false;
            var hasUpdates = false;

            // ordering by descending so that Filtered/Failed processes first
            foreach (IGrouping <ValueSetValidationStatus, ValueSet> group in invalidOrValid.OrderByDescending(x => x.Key))
            {
                switch (group.Key)
                {
                case ValueSetValidationStatus.Valid:
                    hasUpdates = true;

                    //these are the valid ones, so just index them all at once
                    base.PerformIndexItems(group.ToList(), onComplete);
                    break;

                case ValueSetValidationStatus.Failed:
                    // don't index anything that is invalid
                    break;

                case ValueSetValidationStatus.Filtered:
                    hasDeletes = true;

                    // these are the invalid/filtered items so we'll delete them
                    // since the path is not valid we need to delete this item in
                    // case it exists in the index already and has now
                    // been moved to an invalid parent.
                    base.PerformDeleteFromIndex(group.Select(x => x.Id), null);
                    break;
                }
            }

            if ((hasDeletes && !hasUpdates) || (!hasDeletes && !hasUpdates))
            {
                //we need to manually call the completed method
                onComplete(new IndexOperationEventArgs(this, 0));
            }
        }
Exemple #4
0
        public void Must_Have_Path()
        {
            var validator = new ContentValueSetValidator(
                false,
                true,
                Mock.Of <IPublicAccessService>(),
                Mock.Of <IScopeProvider>());

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world" }));

            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);
        }
Exemple #5
0
        public void Inclusion_Field_List()
        {
            var validator = new ValueSetValidator(
                null,
                null,
                new[] { "hello", "world" },
                null);

            var valueSet = ValueSet.FromObject("555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555", world = "your oyster" });
            ValueSetValidationResult result = validator.Validate(valueSet);

            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            Assert.IsFalse(result.ValueSet.Values.ContainsKey("path"));
            Assert.IsTrue(result.ValueSet.Values.ContainsKey("hello"));
            Assert.IsTrue(result.ValueSet.Values.ContainsKey("world"));
        }
Exemple #6
0
        public void Recycle_Bin_Media()
        {
            var validator = new ContentValueSetValidator(
                true,
                false,
                Mock.Of <IPublicAccessService>(),
                Mock.Of <IScopeProvider>());

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,-21,555" }));

            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,-21,555,777" }));
            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);
        }
Exemple #7
0
        public void Invalid_Category()
        {
            var validator = new ContentValueSetValidator(
                false,
                true,
                Mock.Of <IPublicAccessService>(),
                Mock.Of <IScopeProvider>());

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));

            Assert.AreEqual(ValueSetValidationResult.Valid, result);

            result = validator.Validate(ValueSet.FromObject("777", IndexTypes.Media, new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationResult.Valid, result);

            result = validator.Validate(ValueSet.FromObject("555", "invalid-category", new { hello = "world", path = "-1,555" }));
            Assert.AreEqual(ValueSetValidationResult.Failed, result);
        }
Exemple #8
0
        public void Non_Protected()
        {
            var publicAccessService = new Mock <IPublicAccessService>();

            publicAccessService.Setup(x => x.IsProtected("-1,555"))
            .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,
                Mock.Of <IScopeProvider>());

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));

            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            result = validator.Validate(ValueSet.FromObject("777", IndexTypes.Content, new { hello = "world", path = "-1,777" }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);
        }
Exemple #9
0
        public void Parent_Id()
        {
            var validator = new ContentValueSetValidator(
                false,
                true,
                Mock.Of <IPublicAccessService>(),
                Mock.Of <IScopeProvider>(),
                555);

            ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" }));

            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,444" }));
            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555,777" }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);

            result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555,777,999" }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);
        }
Exemple #10
0
        public void Published_Only_With_Variants()
        {
            var validator = new ContentValueSetValidator(true,
                                                         true,
                                                         Mock.Of <IPublicAccessService>(),
                                                         Mock.Of <IScopeProvider>());

            ValueSetValidationResult result = validator.Validate(new ValueSet(
                                                                     "555",
                                                                     IndexTypes.Content,
                                                                     new Dictionary <string, object>
            {
                ["hello"] = "world",
                ["path"]  = "-1,555",
                [UmbracoExamineFieldNames.VariesByCultureFieldName] = "y",
                [UmbracoExamineFieldNames.PublishedFieldName]       = "n"
            }));

            Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status);

            result = validator.Validate(new ValueSet(
                                            "555",
                                            IndexTypes.Content,
                                            new Dictionary <string, object>
            {
                ["hello"] = "world",
                ["path"]  = "-1,555",
                [UmbracoExamineFieldNames.VariesByCultureFieldName] = "y",
                [UmbracoExamineFieldNames.PublishedFieldName]       = "y"
            }));
            Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status);

            var valueSet = new ValueSet(
                "555",
                IndexTypes.Content,
                new Dictionary <string, object>
            {
                ["hello"] = "world",
                ["path"]  = "-1,555",
                [UmbracoExamineFieldNames.VariesByCultureFieldName]      = "y",
                [$"{UmbracoExamineFieldNames.PublishedFieldName}_en-us"] = "y",
                ["hello_en-us"] = "world",
                ["title_en-us"] = "my title",
                [$"{UmbracoExamineFieldNames.PublishedFieldName}_es-es"] = "n",
                ["hello_es-ES"] = "world",
                ["title_es-ES"] = "my title",
                [UmbracoExamineFieldNames.PublishedFieldName] = "y"
            });

            Assert.AreEqual(10, valueSet.Values.Count());
            Assert.IsTrue(valueSet.Values.ContainsKey($"{UmbracoExamineFieldNames.PublishedFieldName}_es-es"));
            Assert.IsTrue(valueSet.Values.ContainsKey("hello_es-ES"));
            Assert.IsTrue(valueSet.Values.ContainsKey("title_es-ES"));

            result = validator.Validate(valueSet);
            Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status);

            Assert.AreEqual(7, result.ValueSet.Values.Count()); // filtered to 7 values (removes es-es values)
            Assert.IsFalse(result.ValueSet.Values.ContainsKey($"{UmbracoExamineFieldNames.PublishedFieldName}_es-es"));
            Assert.IsFalse(result.ValueSet.Values.ContainsKey("hello_es-ES"));
            Assert.IsFalse(result.ValueSet.Values.ContainsKey("title_es-ES"));
        }
    public override ValueSetValidationResult Validate(ValueSet valueSet)
    {
        ValueSetValidationResult baseValidate = base.Validate(valueSet);

        valueSet = baseValidate.ValueSet;
        if (baseValidate.Status == ValueSetValidationStatus.Failed)
        {
            return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
        }

        var isFiltered = baseValidate.Status == ValueSetValidationStatus.Filtered;

        var filteredValues = valueSet.Values.ToDictionary(x => x.Key, x => x.Value.ToList());

        //check for published content
        if (valueSet.Category == IndexTypes.Content && PublishedValuesOnly)
        {
            if (!valueSet.Values.TryGetValue(UmbracoExamineFieldNames.PublishedFieldName, out IReadOnlyList <object>?published))
            {
                return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
            }

            if (!published[0].Equals("y"))
            {
                return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
            }

            //deal with variants, if there are unpublished variants than we need to remove them from the value set
            if (valueSet.Values.TryGetValue(UmbracoExamineFieldNames.VariesByCultureFieldName, out IReadOnlyList <object>?variesByCulture) &&
                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 (KeyValuePair <string, IReadOnlyList <object> > publishField in valueSet.Values
                         .Where(x => x.Key.StartsWith($"{UmbracoExamineFieldNames.PublishedFieldName}_")).ToList())
                {
                    if (publishField.Value.Count <= 0 || !publishField.Value[0].Equals("y"))
                    {
                        //this culture is not published, so remove all of these culture values
                        var cultureSuffix = publishField.Key.Substring(publishField.Key.LastIndexOf('_'));
                        foreach (KeyValuePair <string, IReadOnlyList <object> > cultureField in valueSet.Values
                                 .Where(x => x.Key.InvariantEndsWith(cultureSuffix)).ToList())
                        {
                            filteredValues.Remove(cultureField.Key);
                            isFiltered = true;
                        }
                    }
                }
            }
        }

        //must have a 'path'
        if (!valueSet.Values.TryGetValue(PathKey, out IReadOnlyList <object>?pathValues))
        {
            return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
        }

        if (pathValues.Count == 0)
        {
            return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
        }

        if (pathValues[0] == null)
        {
            return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
        }

        if (pathValues[0].ToString().IsNullOrWhiteSpace())
        {
            return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet));
        }

        var path = pathValues[0].ToString();

        var filteredValueSet = new ValueSet(valueSet.Id, valueSet.Category, valueSet.ItemType, filteredValues.ToDictionary(x => x.Key, x => (IEnumerable <object>)x.Value));

        // We need to validate the path of the content based on ParentId, protected content and recycle bin rules.
        // We cannot return FAILED here because we need the value set to get into the indexer and then deal with it from there
        // because we need to remove anything that doesn't pass by protected content in the cases that umbraco data is moved to an illegal parent.
        if (!ValidatePath(path !, valueSet.Category) ||
            !ValidateRecycleBin(path !, valueSet.Category) ||
            !ValidateProtectedContent(path !, valueSet.Category))
        {
            return(new ValueSetValidationResult(ValueSetValidationStatus.Filtered, filteredValueSet));
        }

        return(new ValueSetValidationResult(
                   isFiltered ? ValueSetValidationStatus.Filtered : ValueSetValidationStatus.Valid, filteredValueSet));
    }