diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs index e7a785cf88..c1a4e41a75 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs @@ -2,9 +2,12 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.ViewModels.DocumentType; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Features; using Umbraco.Cms.Web.Common.Authorization; @@ -14,18 +17,31 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType; [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public class ConfigurationDocumentTypeController : DocumentTypeControllerBase { - private readonly UmbracoFeatures _umbracoFeatures; - private readonly DataTypesSettings _dataTypesSettings; - private readonly SegmentSettings _segmentSettings; + private readonly IConfigurationPresentationFactory _configurationPresentationFactory; + [ActivatorUtilitiesConstructor] + public ConfigurationDocumentTypeController(IConfigurationPresentationFactory configurationPresentationFactory) + { + _configurationPresentationFactory = configurationPresentationFactory; + } + + [Obsolete("Use the constructor that only accepts IConfigurationPresentationFactory, scheduled for removal in V16")] + public ConfigurationDocumentTypeController( + UmbracoFeatures umbracoFeatures, + IOptionsSnapshot dataTypesSettings, + IOptionsSnapshot segmentSettings, + IConfigurationPresentationFactory configurationPresentationFactory) + : this(configurationPresentationFactory) + { + } + + [Obsolete("Use the constructor that only accepts IConfigurationPresentationFactory, scheduled for removal in V16")] public ConfigurationDocumentTypeController( UmbracoFeatures umbracoFeatures, IOptionsSnapshot dataTypesSettings, IOptionsSnapshot segmentSettings) + : this(StaticServiceProvider.Instance.GetRequiredService()) { - _umbracoFeatures = umbracoFeatures; - _dataTypesSettings = dataTypesSettings.Value; - _segmentSettings = segmentSettings.Value; } [HttpGet("configuration")] @@ -33,12 +49,7 @@ public class ConfigurationDocumentTypeController : DocumentTypeControllerBase [ProducesResponseType(typeof(DocumentTypeConfigurationResponseModel), StatusCodes.Status200OK)] public Task Configuration(CancellationToken cancellationToken) { - var responseModel = new DocumentTypeConfigurationResponseModel - { - DataTypesCanBeChanged = _dataTypesSettings.CanBeChanged, - DisableTemplates = _umbracoFeatures.Disabled.DisableTemplates, - UseSegments = _segmentSettings.Enabled, - }; + DocumentTypeConfigurationResponseModel responseModel = _configurationPresentationFactory.CreateDocumentTypeConfigurationResponseModel(); return Task.FromResult(Ok(responseModel)); } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ConfigurationMediaTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ConfigurationMediaTypeController.cs new file mode 100644 index 0000000000..25447c60a1 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/ConfigurationMediaTypeController.cs @@ -0,0 +1,31 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.ViewModels.MediaType; +using Umbraco.Cms.Web.Common.Authorization; + +namespace Umbraco.Cms.Api.Management.Controllers.MediaType; + +[ApiVersion("1.0")] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] +public class ConfigurationMediaTypeController : MediaTypeControllerBase +{ + private readonly IConfigurationPresentationFactory _configurationPresentationFactory; + + public ConfigurationMediaTypeController(IConfigurationPresentationFactory configurationPresentationFactory) + { + _configurationPresentationFactory = configurationPresentationFactory; + } + + [HttpGet("configuration")] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(MediaTypeConfigurationResponseModel), StatusCodes.Status200OK)] + public Task Configuration(CancellationToken cancellationToken) + { + MediaTypeConfigurationResponseModel responseModel = _configurationPresentationFactory.CreateMediaTypeConfigurationResponseModel(); + + return Task.FromResult(Ok(responseModel)); + } +} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/ConfigurationMemberTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/ConfigurationMemberTypeController.cs new file mode 100644 index 0000000000..141dbd80ee --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/ConfigurationMemberTypeController.cs @@ -0,0 +1,30 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.ViewModels.MemberType; +using Umbraco.Cms.Web.Common.Authorization; + +namespace Umbraco.Cms.Api.Management.Controllers.MemberType; + +[ApiVersion("1.0")] +public class ConfigurationMemberTypeController : MemberTypeControllerBase +{ + private readonly IConfigurationPresentationFactory _configurationPresentationFactory; + + public ConfigurationMemberTypeController(IConfigurationPresentationFactory configurationPresentationFactory) + { + _configurationPresentationFactory = configurationPresentationFactory; + } + + [HttpGet("configuration")] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(MemberTypeConfigurationResponseModel), StatusCodes.Status200OK)] + public Task Configuration(CancellationToken cancellationToken) + { + MemberTypeConfigurationResponseModel responseModel = _configurationPresentationFactory.CreateMemberTypeConfigurationResponseModel(); + + return Task.FromResult(Ok(responseModel)); + } +} diff --git a/src/Umbraco.Cms.Api.Management/Factories/ConfigurationPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/ConfigurationPresentationFactory.cs index b8580083c5..7efc4ff90f 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/ConfigurationPresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/ConfigurationPresentationFactory.cs @@ -1,8 +1,14 @@ -using Microsoft.Extensions.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Umbraco.Cms.Api.Management.ViewModels.Document; +using Umbraco.Cms.Api.Management.ViewModels.DocumentType; using Umbraco.Cms.Api.Management.ViewModels.Media; +using Umbraco.Cms.Api.Management.ViewModels.MediaType; using Umbraco.Cms.Api.Management.ViewModels.Member; +using Umbraco.Cms.Api.Management.ViewModels.MemberType; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Features; using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Factories; @@ -10,19 +16,40 @@ namespace Umbraco.Cms.Api.Management.Factories; public class ConfigurationPresentationFactory : IConfigurationPresentationFactory { private readonly IReservedFieldNamesService _reservedFieldNamesService; + private readonly UmbracoFeatures _umbracoFeatures; + private readonly DataTypesSettings _dataTypesSettings; private readonly ContentSettings _contentSettings; private readonly SegmentSettings _segmentSettings; public ConfigurationPresentationFactory( IReservedFieldNamesService reservedFieldNamesService, IOptions contentSettings, - IOptions segmentSettings) + IOptions segmentSettings, + IOptions dataTypesSettings, + UmbracoFeatures umbracoFeatures) { _reservedFieldNamesService = reservedFieldNamesService; + _umbracoFeatures = umbracoFeatures; + _dataTypesSettings = dataTypesSettings.Value; _contentSettings = contentSettings.Value; _segmentSettings = segmentSettings.Value; } + [Obsolete("Use the constructor with all dependencies")] + public ConfigurationPresentationFactory( + IReservedFieldNamesService reservedFieldNamesService, + IOptions contentSettings, + IOptions segmentSettings) + : this( + reservedFieldNamesService, + contentSettings, + segmentSettings, + StaticServiceProvider.Instance.GetRequiredService>(), + StaticServiceProvider.Instance.GetRequiredService() + ) + { + } + public DocumentConfigurationResponseModel CreateDocumentConfigurationResponseModel() => new() { @@ -33,12 +60,27 @@ public class ConfigurationPresentationFactory : IConfigurationPresentationFactor ReservedFieldNames = _reservedFieldNamesService.GetDocumentReservedFieldNames(), }; + public DocumentTypeConfigurationResponseModel CreateDocumentTypeConfigurationResponseModel() => + new() + { + DataTypesCanBeChanged = _dataTypesSettings.CanBeChanged, + DisableTemplates = _umbracoFeatures.Disabled.DisableTemplates, + UseSegments = _segmentSettings.Enabled, + ReservedFieldNames = _reservedFieldNamesService.GetDocumentReservedFieldNames(), + }; + public MemberConfigurationResponseModel CreateMemberConfigurationResponseModel() => new() { ReservedFieldNames = _reservedFieldNamesService.GetMemberReservedFieldNames(), }; + public MemberTypeConfigurationResponseModel CreateMemberTypeConfigurationResponseModel() => + new() + { + ReservedFieldNames = _reservedFieldNamesService.GetMemberReservedFieldNames(), + }; + public MediaConfigurationResponseModel CreateMediaConfigurationResponseModel() => new() { @@ -46,4 +88,10 @@ public class ConfigurationPresentationFactory : IConfigurationPresentationFactor DisableUnpublishWhenReferenced = _contentSettings.DisableUnpublishWhenReferenced, ReservedFieldNames = _reservedFieldNamesService.GetMediaReservedFieldNames(), }; + + public MediaTypeConfigurationResponseModel CreateMediaTypeConfigurationResponseModel() => + new() + { + ReservedFieldNames = _reservedFieldNamesService.GetMediaReservedFieldNames(), + }; } diff --git a/src/Umbraco.Cms.Api.Management/Factories/IConfigurationPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/IConfigurationPresentationFactory.cs index 920a7fd7b8..3914a0e058 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/IConfigurationPresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/IConfigurationPresentationFactory.cs @@ -1,6 +1,9 @@ using Umbraco.Cms.Api.Management.ViewModels.Document; +using Umbraco.Cms.Api.Management.ViewModels.DocumentType; using Umbraco.Cms.Api.Management.ViewModels.Media; +using Umbraco.Cms.Api.Management.ViewModels.MediaType; using Umbraco.Cms.Api.Management.ViewModels.Member; +using Umbraco.Cms.Api.Management.ViewModels.MemberType; namespace Umbraco.Cms.Api.Management.Factories; @@ -8,7 +11,16 @@ public interface IConfigurationPresentationFactory { DocumentConfigurationResponseModel CreateDocumentConfigurationResponseModel(); + DocumentTypeConfigurationResponseModel CreateDocumentTypeConfigurationResponseModel() + => throw new NotImplementedException(); + MemberConfigurationResponseModel CreateMemberConfigurationResponseModel(); + MemberTypeConfigurationResponseModel CreateMemberTypeConfigurationResponseModel() + => throw new NotImplementedException(); + MediaConfigurationResponseModel CreateMediaConfigurationResponseModel(); + + MediaTypeConfigurationResponseModel CreateMediaTypeConfigurationResponseModel() + => throw new NotImplementedException(); } diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json index 2799d1bd61..77e006ffaa 100644 --- a/src/Umbraco.Cms.Api.Management/OpenApi.json +++ b/src/Umbraco.Cms.Api.Management/OpenApi.json @@ -14526,6 +14526,41 @@ ] } }, + "/umbraco/management/api/v1/media-type/configuration": { + "get": { + "tags": [ + "Media Type" + ], + "operationId": "GetMediaTypeConfiguration", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/MediaTypeConfigurationResponseModel" + } + ] + } + } + } + }, + "401": { + "description": "The resource is protected and requires an authentication token" + }, + "403": { + "description": "The authenticated user do not have access to this resource" + } + }, + "security": [ + { + "Backoffice User": [] + } + ] + } + }, "/umbraco/management/api/v1/media-type/folder": { "post": { "tags": [ @@ -19094,6 +19129,41 @@ ] } }, + "/umbraco/management/api/v1/member-type/configuration": { + "get": { + "tags": [ + "Member Type" + ], + "operationId": "GetMemberTypeConfiguration", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/MemberTypeConfigurationResponseModel" + } + ] + } + } + } + }, + "401": { + "description": "The resource is protected and requires an authentication token" + }, + "403": { + "description": "The authenticated user do not have access to this resource" + } + }, + "security": [ + { + "Backoffice User": [] + } + ] + } + }, "/umbraco/management/api/v1/tree/member-type/root": { "get": { "tags": [ @@ -36124,7 +36194,8 @@ "type": "array", "items": { "type": "string" - } + }, + "deprecated": true } }, "additionalProperties": false @@ -36551,6 +36622,7 @@ "required": [ "dataTypesCanBeChanged", "disableTemplates", + "reservedFieldNames", "useSegments" ], "type": "object", @@ -36563,6 +36635,13 @@ }, "useSegments": { "type": "boolean" + }, + "reservedFieldNames": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } } }, "additionalProperties": false @@ -37540,7 +37619,7 @@ }, "actionParameters": { "type": "object", - "additionalProperties": {}, + "additionalProperties": { }, "nullable": true } }, @@ -37827,7 +37906,7 @@ }, "providerProperties": { "type": "object", - "additionalProperties": {}, + "additionalProperties": { }, "nullable": true } }, @@ -38162,7 +38241,7 @@ }, "extensions": { "type": "array", - "items": {} + "items": { } } }, "additionalProperties": false @@ -38238,7 +38317,8 @@ "type": "array", "items": { "type": "string" - } + }, + "deprecated": true } }, "additionalProperties": false @@ -38548,6 +38628,22 @@ }, "additionalProperties": false }, + "MediaTypeConfigurationResponseModel": { + "required": [ + "reservedFieldNames" + ], + "type": "object", + "properties": { + "reservedFieldNames": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, "MediaTypeItemResponseModel": { "required": [ "id", @@ -38999,7 +39095,8 @@ "type": "array", "items": { "type": "string" - } + }, + "deprecated": true } }, "additionalProperties": false @@ -39230,6 +39327,22 @@ }, "additionalProperties": false }, + "MemberTypeConfigurationResponseModel": { + "required": [ + "reservedFieldNames" + ], + "type": "object", + "properties": { + "reservedFieldNames": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, "MemberTypeItemResponseModel": { "required": [ "id", @@ -41591,7 +41704,7 @@ "nullable": true } }, - "additionalProperties": {} + "additionalProperties": { } }, "ProblemDetailsBuilderModel": { "type": "object", @@ -45151,7 +45264,7 @@ "authorizationCode": { "authorizationUrl": "/umbraco/management/api/v1/security/back-office/authorize", "tokenUrl": "/umbraco/management/api/v1/security/back-office/token", - "scopes": {} + "scopes": { } } } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs index 100f3ec3c9..f6673bcd5b 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs @@ -10,5 +10,6 @@ public class DocumentConfigurationResponseModel public required bool AllowNonExistingSegmentsCreation { get; set; } + [Obsolete("Use DocumentTypeConfigurationResponseModel.ReservedFieldNames from the ConfigurationDocumentTypeController endpoint instead.")] public required ISet ReservedFieldNames { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs index c575cc7bc1..802519851a 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs @@ -9,4 +9,6 @@ public class DocumentTypeConfigurationResponseModel public required bool DisableTemplates { get; set; } public required bool UseSegments { get; set; } + + public required ISet ReservedFieldNames { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaConfigurationResponseModel.cs index e1a15250a6..ff723b658f 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaConfigurationResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaConfigurationResponseModel.cs @@ -6,5 +6,6 @@ public class MediaConfigurationResponseModel public required bool DisableUnpublishWhenReferenced { get; set; } + [Obsolete("Use MediaTypeConfigurationResponseModel.ReservedFieldNames from the ConfigurationMediaTypeController endpoint instead.")] public required ISet ReservedFieldNames { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/MediaTypeConfigurationModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/MediaTypeConfigurationModel.cs new file mode 100644 index 0000000000..313dc7643e --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/MediaTypeConfigurationModel.cs @@ -0,0 +1,6 @@ +namespace Umbraco.Cms.Api.Management.ViewModels.MediaType; + +public class MediaTypeConfigurationResponseModel +{ + public required ISet ReservedFieldNames { get; set; } +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Member/MemberConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Member/MemberConfigurationResponseModel.cs index 5faeed7fd8..a3434583bd 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Member/MemberConfigurationResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Member/MemberConfigurationResponseModel.cs @@ -2,5 +2,6 @@ public class MemberConfigurationResponseModel { + [Obsolete("Use MemberTypeConfigurationResponseModel.ReservedFieldNames from the ConfigurationMemberTypeController endpoint instead.")] public required ISet ReservedFieldNames { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/MemberType/MemberTypeConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/MemberType/MemberTypeConfigurationResponseModel.cs new file mode 100644 index 0000000000..85e44e93b7 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/MemberType/MemberTypeConfigurationResponseModel.cs @@ -0,0 +1,6 @@ +namespace Umbraco.Cms.Api.Management.ViewModels.MemberType; + +public class MemberTypeConfigurationResponseModel +{ + public required ISet ReservedFieldNames { get; set; } +}