diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs index 2fe34df7a1..4eb3dd2426 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs @@ -44,6 +44,10 @@ public abstract class DocumentTypeControllerBase : ManagementApiControllerBase .WithTitle("Invalid container name") .WithDetail("One or more container names are invalid") .Build()), + ContentTypeOperationStatus.InvalidContainerType => new BadRequestObjectResult(problemDetailsBuilder + .WithTitle("Invalid container type") + .WithDetail("One or more container types are invalid") + .Build()), ContentTypeOperationStatus.MissingContainer => new BadRequestObjectResult(problemDetailsBuilder .WithTitle("Missing container") .WithDetail("One or more containers or properties are listed as parents to containers that are not defined.") diff --git a/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs b/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs index 0940b693ff..80a574537f 100644 --- a/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs +++ b/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs @@ -343,6 +343,11 @@ internal abstract class ContentTypeEditingServiceBase model, IContentTypeComposition[] allContentTypeCompositions) { + if (model.Containers.Any(container => Enum.TryParse(container.Type, out _) is false)) + { + return ContentTypeOperationStatus.InvalidContainerType; + } + // all property container keys must be present in the model Guid[] modelContainerKeys = model.Containers.Select(c => c.Key).ToArray(); if (model.Properties.Any(p => p.ContainerKey is not null && modelContainerKeys.Contains(p.ContainerKey.Value) is false)) diff --git a/src/Umbraco.Core/Services/OperationStatus/ContentTypeOperationStatus.cs b/src/Umbraco.Core/Services/OperationStatus/ContentTypeOperationStatus.cs index 86a32f7fc8..9f9c46e874 100644 --- a/src/Umbraco.Core/Services/OperationStatus/ContentTypeOperationStatus.cs +++ b/src/Umbraco.Core/Services/OperationStatus/ContentTypeOperationStatus.cs @@ -12,6 +12,7 @@ public enum ContentTypeOperationStatus InvalidComposition, InvalidParent, InvalidContainerName, + InvalidContainerType, MissingContainer, DuplicateContainer, NotFound, diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs index 28dd1f5b0b..2e261015e2 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs @@ -1086,4 +1086,21 @@ public partial class ContentTypeEditingServiceTests Assert.IsFalse(result.Success); Assert.AreEqual(ContentTypeOperationStatus.InvalidComposition, result.Status); } + + [TestCase("something")] + [TestCase("tab")] + [TestCase("group")] + public async Task Cannot_Create_Container_With_Unknown_Type(string containerType) + { + var createModel = ContentTypeCreateModel("Test", "test"); + var container = ContentTypePropertyContainerModel(name: containerType, type: containerType); + createModel.Containers = new[] { container }; + + var propertyType = ContentTypePropertyTypeModel("Test Property", "testProperty", containerKey: container.Key); + createModel.Properties = new[] { propertyType }; + + var result = await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentTypeOperationStatus.InvalidContainerType, result.Status); + } } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Update.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Update.cs index f705f2732f..31be783629 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Update.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Update.cs @@ -802,4 +802,28 @@ public partial class ContentTypeEditingServiceTests Assert.IsFalse(result.Success); Assert.AreEqual(ContentTypeOperationStatus.InvalidInheritance, result.Status); } + + [TestCase("something")] + [TestCase("tab")] + [TestCase("group")] + public async Task Cannot_Update_Container_Types_To_Unknown_Types(string containerType) + { + var createModel = ContentTypeCreateModel("Test", "test"); + var container = ContentTypePropertyContainerModel("One"); + createModel.Containers = new[] { container }; + + var property = ContentTypePropertyTypeModel("Test Property", "testProperty", containerKey: container.Key); + createModel.Properties = new[] { property }; + + var contentType = (await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey)).Result!; + + var updateModel = ContentTypeUpdateModel("Test", "test"); + container.Type = containerType; + updateModel.Containers = new[] { container }; + updateModel.Properties = new[] { property }; + + var result = await ContentTypeEditingService.UpdateAsync(contentType, updateModel, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentTypeOperationStatus.InvalidContainerType, result.Status); + } }