diff --git a/Directory.Packages.props b/Directory.Packages.props index 976f971f46..fe1b24d22d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,7 +12,6 @@ - @@ -56,7 +55,6 @@ - diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs index 76d14b8f68..8f389b67b9 100644 --- a/src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs +++ b/src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs @@ -1,6 +1,6 @@ -using Microsoft.AspNetCore.Mvc; using System.Net; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Common.Attributes; using Umbraco.Cms.Api.Common.Filters; using Umbraco.Cms.Api.Delivery.Configuration; @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Api.Delivery.Controllers; [ApiController] [JsonOptionsName(Constants.JsonOptionsNames.DeliveryApi)] [MapToApi(DeliveryApiConfiguration.ApiName)] -[Authorize(Policy = "New" + AuthorizationPolicies.UmbracoFeatureEnabled)] +[Authorize(Policy = AuthorizationPolicies.UmbracoFeatureEnabled)] public abstract class DeliveryApiControllerBase : Controller, IUmbracoFeature { protected string DecodePath(string path) diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs index dcf3c82614..d1c58971c8 100644 --- a/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs +++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs @@ -15,13 +15,12 @@ using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Web.Common.Security; using Umbraco.Extensions; -using SignInResult = Microsoft.AspNetCore.Mvc.SignInResult; using IdentitySignInResult = Microsoft.AspNetCore.Identity.SignInResult; +using SignInResult = Microsoft.AspNetCore.Mvc.SignInResult; namespace Umbraco.Cms.Api.Delivery.Controllers.Security; [ApiVersion("1.0")] -[ApiController] [VersionedDeliveryApiRoute(Common.Security.Paths.MemberApi.EndpointTemplate)] [ApiExplorerSettings(IgnoreApi = true)] public class MemberController : DeliveryApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/AuditLogControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/AuditLogControllerBase.cs index f7e29b4682..08d6b36d4c 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/AuditLogControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/AuditLogControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.AuditLog; -[ApiController] [VersionedApiBackOfficeRoute("audit-log")] [ApiExplorerSettings(GroupName = "Audit Log")] public class AuditLogControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/ByKeyAuditLogController.cs b/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/ByKeyAuditLogController.cs index 7875ad0d84..5fd59656ab 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/ByKeyAuditLogController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/AuditLog/ByKeyAuditLogController.cs @@ -13,7 +13,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.AuditLog; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContentOrMedia)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContentOrMedia)] public class ByKeyAuditLogController : AuditLogControllerBase { private readonly IAuditService _auditService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs index 67c738e83b..42398145bd 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Api.Management.ViewModels.Content; using Umbraco.Cms.Core.Models.ContentEditing; using Umbraco.Cms.Core.Models.ContentEditing.Validation; using Umbraco.Cms.Core.Services.OperationStatus; @@ -61,6 +60,14 @@ public class ContentControllerBase : ManagementApiControllerBase .WithTitle("Invalid sorting options") .WithDetail("The supplied sorting operations were invalid. Additional details can be found in the log.") .Build()), + ContentEditingOperationStatus.InvalidCulture => BadRequest(problemDetailsBuilder + .WithTitle("Invalid culture") + .WithDetail("One or more of the supplied culture codes did not match the configured languages.") + .Build()), + ContentEditingOperationStatus.DuplicateKey => BadRequest(problemDetailsBuilder + .WithTitle("Invalid Id") + .WithDetail("The supplied id is already in use.") + .Build()), ContentEditingOperationStatus.Unknown => StatusCode( StatusCodes.Status500InternalServerError, problemDetailsBuilder diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Culture/CultureControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Culture/CultureControllerBase.cs index 3aec530319..08d1cddef0 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Culture/CultureControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Culture/CultureControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Culture; -[ApiController] [VersionedApiBackOfficeRoute("culture")] [ApiExplorerSettings(GroupName = "Culture")] public abstract class CultureControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/DataTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/DataTypeControllerBase.cs index 9ee0fbb237..01e5d67dcc 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/DataTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/DataTypeControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DataType; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.DataType)] [ApiExplorerSettings(GroupName = "Data Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] public abstract class DataTypeControllerBase : ManagementApiControllerBase { protected IActionResult DataTypeOperationStatusResult(DataTypeOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Filter/DataTypeFilterControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Filter/DataTypeFilterControllerBase.cs new file mode 100644 index 0000000000..edb41a6996 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Filter/DataTypeFilterControllerBase.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Core; +using Umbraco.Cms.Web.Common.Authorization; + +namespace Umbraco.Cms.Api.Management.Controllers.DataType.Filter; + +[ApiExplorerSettings(GroupName = "Data Type")] +[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Filter}/{Constants.UdiEntityType.DataType}")] +// This auth policy might become problematic, as when getting DataTypes on Media types, you don't need access to the document tree. +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] +public abstract class DataTypeFilterControllerBase : ManagementApiControllerBase +{ +} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Filter/FilterDataTypeFilterController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Filter/FilterDataTypeFilterController.cs new file mode 100644 index 0000000000..7248028a2e --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Filter/FilterDataTypeFilterController.cs @@ -0,0 +1,45 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.ViewModels.DataType.Item; +using Umbraco.Cms.Api.Management.ViewModels.Language; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Api.Management.Controllers.DataType.Filter; + +[ApiVersion("1.0")] +public class FilterDataTypeFilterController : DataTypeFilterControllerBase +{ + private readonly IDataTypeService _dataTypeService; + private readonly IUmbracoMapper _mapper; + + public FilterDataTypeFilterController(IDataTypeService dataTypeService, IUmbracoMapper mapper) + { + _dataTypeService = dataTypeService; + _mapper = mapper; + } + + [HttpGet] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] + public async Task Filter( + int skip = 0, + int take = 100, + string name = "", + string? editorUiAlias = null, + string? editorAlias = null) + { + PagedModel dataTypes = await _dataTypeService.FilterAsync(name, editorUiAlias, editorAlias, skip, take); + List responseModels = _mapper.MapEnumerable(dataTypes.Items); + var viewModel = new PagedViewModel + { + Total = dataTypes.Total, + Items = responseModels, + }; + return Ok(viewModel); + } +} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Folder/DataTypeFolderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Folder/DataTypeFolderControllerBase.cs index 80194b97d1..c710ebbe31 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Folder/DataTypeFolderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Folder/DataTypeFolderControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DataType}/folder")] [ApiExplorerSettings(GroupName = "Data Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public abstract class DataTypeFolderControllerBase : FolderManagementControllerBase { protected DataTypeFolderControllerBase( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/ByEditorUiAliasController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/ByEditorUiAliasController.cs deleted file mode 100644 index 7394580cdb..0000000000 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/ByEditorUiAliasController.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Asp.Versioning; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Api.Management.ViewModels.DataType.Item; -using Umbraco.Cms.Core.Mapping; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Services; - -namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item; - -[ApiVersion("1.0")] -public class ByEditorUiAliasController : DatatypeItemControllerBase -{ - private readonly IDataTypeService _dataTypeService; - private readonly IUmbracoMapper _mapper; - - public ByEditorUiAliasController( - IDataTypeService dataTypeService, - IUmbracoMapper mapper) - { - _dataTypeService = dataTypeService; - _mapper = mapper; - } - - [HttpGet("{*alias}")] - [MapToApiVersion("1.0")] - [ProducesResponseType(typeof(DataTypeItemResponseModel), StatusCodes.Status200OK)] - public async Task ByEditorUiAlias(string alias) - { - IEnumerable dataTypes = await _dataTypeService.GetByEditorUiAlias(alias); - List responseModels = _mapper.MapEnumerable(dataTypes); - return Ok(responseModels); - } -} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/DatatypeItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/DatatypeItemControllerBase.cs index 5d1496cf0c..ab7881f7a4 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/DatatypeItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Item/DatatypeItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.DataType}")] [ApiExplorerSettings(GroupName = "Data Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] public class DatatypeItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs index ab9bcf2041..452a321d9b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs @@ -1,21 +1,20 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Web.Common.Authorization; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.DataType}")] [ApiExplorerSettings(GroupName = "Data Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDataTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)] public class DataTypeTreeControllerBase : FolderTreeControllerBase { private readonly IDataTypeService _dataTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/DictionaryControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/DictionaryControllerBase.cs index c527e96281..d59310df12 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/DictionaryControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/DictionaryControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Dictionary; -[ApiController] [VersionedApiBackOfficeRoute("dictionary")] [ApiExplorerSettings(GroupName = "Dictionary")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDictionary)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDictionary)] public abstract class DictionaryControllerBase : ManagementApiControllerBase { protected IActionResult DictionaryItemOperationStatusResult(DictionaryItemOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Item/DictionaryItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Item/DictionaryItemControllerBase.cs index b83525ae7b..c64f67572b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Item/DictionaryItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Item/DictionaryItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/dictionary")] [ApiExplorerSettings(GroupName = "Dictionary")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDictionary)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDictionary)] public class DictionaryItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs index 2113804361..d2e5b10a64 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs @@ -1,20 +1,19 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/dictionary")] [ApiExplorerSettings(GroupName = "Dictionary")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDictionaryOrTemplates)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDictionaryOrTemplates)] // NOTE: at the moment dictionary items (renamed to dictionary tree) aren't supported by EntityService, so we have little use of the // tree controller base. We'll keep it though, in the hope that we can mend EntityService. public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs index 20b1553d8d..71dfc75fb1 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs @@ -12,10 +12,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Document.Collection; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Collection}/{Constants.UdiEntityType.Document}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)] public abstract class DocumentCollectionControllerBase : ContentCollectionControllerBase { protected DocumentCollectionControllerBase(IUmbracoMapper mapper) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/ConfigurationDocumentController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/ConfigurationDocumentController.cs index 4008498e56..a900477296 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/ConfigurationDocumentController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/ConfigurationDocumentController.cs @@ -12,11 +12,16 @@ public class ConfigurationDocumentController : DocumentControllerBase { private readonly GlobalSettings _globalSettings; private readonly ContentSettings _contentSettings; + private readonly SegmentSettings _segmentSettings; - public ConfigurationDocumentController(IOptionsSnapshot globalSettings, IOptionsSnapshot contentSettings) + public ConfigurationDocumentController( + IOptionsSnapshot globalSettings, + IOptionsSnapshot contentSettings, + IOptionsSnapshot segmentSettings) { _contentSettings = contentSettings.Value; _globalSettings = globalSettings.Value; + _segmentSettings = segmentSettings.Value; } [HttpGet("configuration")] @@ -30,7 +35,9 @@ public class ConfigurationDocumentController : DocumentControllerBase DisableUnpublishWhenReferenced = _contentSettings.DisableUnpublishWhenReferenced, SanitizeTinyMce = _globalSettings.SanitizeTinyMce, AllowEditInvariantFromNonDefault = _contentSettings.AllowEditInvariantFromNonDefault, + AllowNonExistingSegmentsCreation = _segmentSettings.AllowCreation, }; + return Task.FromResult(Ok(responseModel)); } } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/DeleteDocumentController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/DeleteDocumentController.cs index 74e2a7463c..7eb02498b2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/DeleteDocumentController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/DeleteDocumentController.cs @@ -39,7 +39,7 @@ public class DeleteDocumentController : DocumentControllerBase [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] public async Task Delete(Guid id) { - AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( + AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, ContentPermissionResource.WithKeys(ActionDelete.ActionLetter, id), AuthorizationPolicies.ContentPermissionByResource); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs index 4c7b58d884..63e987e474 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Management.Controllers.Content; using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels.Content; using Umbraco.Cms.Api.Management.ViewModels.Document; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models.ContentEditing; @@ -13,10 +12,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Document; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.Document)] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)] public abstract class DocumentControllerBase : ContentControllerBase { protected IActionResult DocumentNotFound() diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/DocumentItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/DocumentItemControllerBase.cs index 406fdde38c..700a0d4734 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/DocumentItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/DocumentItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Document.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Document}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)] public class DocumentItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DeleteDocumentRecycleBinController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DeleteDocumentRecycleBinController.cs index 22beb9e93c..cb8085e769 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DeleteDocumentRecycleBinController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DeleteDocumentRecycleBinController.cs @@ -43,7 +43,7 @@ public class DeleteDocumentRecycleBinController : DocumentRecycleBinControllerBa [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] public async Task Delete(Guid id) { - AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( + AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, ContentPermissionResource.RecycleBin(ActionDelete.ActionLetter), AuthorizationPolicies.ContentPermissionByResource); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DocumentRecycleBinControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DocumentRecycleBinControllerBase.cs index 5f73af8a99..ce2340cca6 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DocumentRecycleBinControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/RecycleBin/DocumentRecycleBinControllerBase.cs @@ -1,23 +1,22 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.Entities; -using Umbraco.Cms.Core.Services; using Umbraco.Cms.Api.Management.Controllers.RecycleBin; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Filters; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Api.Management.ViewModels.Document.RecycleBin; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Entities; +using Umbraco.Cms.Core.Services; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.RecycleBin}/{Constants.UdiEntityType.Document}")] [RequireDocumentTreeRootAccess] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)] public class DocumentRecycleBinControllerBase : RecycleBinControllerBase { private readonly IDocumentPresentationFactory _documentPresentationFactory; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs index 9aa4bd48aa..805bd933bb 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs @@ -1,24 +1,23 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.Factories; -using Umbraco.Cms.Api.Management.Services.Entities; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Document}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessForContentTree)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessForContentTree)] public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBase { private readonly IPublicAccessService _publicAccessService; @@ -63,23 +62,17 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa return responseModel; } - // TODO: delete these (faking start node setup for unlimited editor) - protected override int[] GetUserStartNodeIds() => new[] { -1 }; + protected override int[] GetUserStartNodeIds() + => _backofficeSecurityAccessor + .BackOfficeSecurity? + .CurrentUser? + .CalculateContentStartNodeIds(EntityService, _appCaches) + ?? Array.Empty(); - protected override string[] GetUserStartNodePaths() => Array.Empty(); - - // TODO: use these implementations instead of the dummy ones above once we have backoffice auth in place - // protected override int[] GetUserStartNodeIds() - // => _backofficeSecurityAccessor - // .BackOfficeSecurity? - // .CurrentUser? - // .CalculateContentStartNodeIds(EntityService, _appCaches) - // ?? Array.Empty(); - // - // protected override string[] GetUserStartNodePaths() - // => _backofficeSecurityAccessor - // .BackOfficeSecurity? - // .CurrentUser? - // .GetContentStartNodePaths(EntityService, _appCaches) - // ?? Array.Empty(); + protected override string[] GetUserStartNodePaths() + => _backofficeSecurityAccessor + .BackOfficeSecurity? + .CurrentUser? + .GetContentStartNodePaths(EntityService, _appCaches) + ?? Array.Empty(); } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/DocumentBlueprintItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/DocumentBlueprintItemControllerBase.cs index 8c2bd7efe3..4e204aa918 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/DocumentBlueprintItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Item/DocumentBlueprintItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.DocumentBlueprint}")] [ApiExplorerSettings(GroupName = "Document Blueprint")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContent)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)] public class DocumentBlueprintItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs index 85865b83b9..17da28f06b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs @@ -1,21 +1,20 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.Factories; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.DocumentBlueprint}")] [ApiExplorerSettings(GroupName = "Document Blueprint")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContent)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)] public class DocumentBlueprintTreeControllerBase : NamedEntityTreeControllerBase { private readonly IDocumentPresentationFactory _documentPresentationFactory; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedAtRootDocumentTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedAtRootDocumentTypeController.cs index 82c2d1a0c8..d5f5a338bf 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedAtRootDocumentTypeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedAtRootDocumentTypeController.cs @@ -12,7 +12,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] public class AllowedAtRootDocumentTypeController : DocumentTypeControllerBase { private readonly IContentTypeService _contentTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs index ab59c55ff4..254bfdc680 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/AllowedChildrenDocumentTypeController.cs @@ -14,7 +14,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] public class AllowedChildrenDocumentTypeController : DocumentTypeControllerBase { private readonly IContentTypeService _contentTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs index 8ca204017b..ee04389885 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ConfigurationDocumentTypeController.cs @@ -13,11 +13,16 @@ public class ConfigurationDocumentTypeController : DocumentTypeControllerBase { private readonly UmbracoFeatures _umbracoFeatures; private readonly DataTypesSettings _dataTypesSettings; + private readonly SegmentSettings _segmentSettings; - public ConfigurationDocumentTypeController(UmbracoFeatures umbracoFeatures, IOptionsSnapshot dataTypesSettings) + public ConfigurationDocumentTypeController( + UmbracoFeatures umbracoFeatures, + IOptionsSnapshot dataTypesSettings, + IOptionsSnapshot segmentSettings) { _umbracoFeatures = umbracoFeatures; _dataTypesSettings = dataTypesSettings.Value; + _segmentSettings = segmentSettings.Value; } [HttpGet("configuration")] @@ -29,7 +34,9 @@ public class ConfigurationDocumentTypeController : DocumentTypeControllerBase { DataTypesCanBeChanged = _dataTypesSettings.CanBeChanged, DisableTemplates = _umbracoFeatures.Disabled.DisableTemplates, + UseSegments = _segmentSettings.Enabled, }; + return Task.FromResult(Ok(responseModel)); } } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs index 9b624a3c45..83b9fc5714 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.DocumentType)] [ApiExplorerSettings(GroupName = "Document Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public abstract class DocumentTypeControllerBase : ManagementApiControllerBase { protected IActionResult OperationStatusResult(ContentTypeOperationStatus status) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Folder/DocumentTypeFolderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Folder/DocumentTypeFolderControllerBase.cs index cbe7ceb4e2..0502397fe2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Folder/DocumentTypeFolderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Folder/DocumentTypeFolderControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Folder; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DocumentType}/folder")] [ApiExplorerSettings(GroupName = "Document Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public abstract class DocumentTypeFolderControllerBase : FolderManagementControllerBase { protected DocumentTypeFolderControllerBase( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/DocumentTypeItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/DocumentTypeItemControllerBase.cs index 46545bced5..16e2a3af9b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/DocumentTypeItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Item/DocumentTypeItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Item; -[ApiController] [VersionedApiBackOfficeRoute( $"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.DocumentType}")] [ApiExplorerSettings(GroupName = "Document Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public class DocumentTypeItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs index 6d6607ff15..91c7af1c2e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs @@ -1,20 +1,19 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.DocumentType}")] [ApiExplorerSettings(GroupName = "Document Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public class DocumentTypeTreeControllerBase : FolderTreeControllerBase { private readonly IContentTypeService _contentTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/DynamicRootControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/DynamicRootControllerBase.cs index 149d62ced7..6d1ed45d21 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/DynamicRootControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/DynamicRootControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.DynamicRoot; -[ApiController] [VersionedApiBackOfficeRoute("dynamic-root")] [ApiExplorerSettings(GroupName = "Dynamic Root")] public abstract class DynamicRootControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetDynamicRootController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetDynamicRootController.cs index 37a1d681f2..3f887dd08c 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetDynamicRootController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetDynamicRootController.cs @@ -10,7 +10,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DynamicRoot; -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContent)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)] [ApiVersion("1.0")] public class GetRootsController : DynamicRootControllerBase { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs index 9b97a29b96..0e9b7803e2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DynamicRoot/GetQueryStepsController.cs @@ -7,7 +7,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.DynamicRoot; -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] [ApiVersion("1.0")] public class GetQueryStepsController : DynamicRootControllerBase { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/FolderManagementControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/FolderManagementControllerBase.cs index 5366ceed27..8f1957d550 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/FolderManagementControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/FolderManagementControllerBase.cs @@ -1,7 +1,6 @@ using System.Linq.Expressions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.Folder; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; @@ -36,14 +35,11 @@ public abstract class FolderManagementControllerBase : ManagementAp .Build())); } - EntityContainer? parentContainer = await _treeEntityTypeContainerService.GetParentAsync(container); - // we could implement a mapper for this but it seems rather overkill at this point return Ok(new FolderResponseModel { Name = container.Name!, - Id = container.Key, - Parent = ReferenceByIdModel.ReferenceOrNull(parentContainer?.Key) + Id = container.Key }); } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/HealthCheckGroupControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/HealthCheckGroupControllerBase.cs index 2eda4b7939..3393f671f0 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/HealthCheckGroupControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/Group/HealthCheckGroupControllerBase.cs @@ -7,10 +7,9 @@ using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Cms.Api.Management.Controllers.HealthCheck.Group; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.HealthChecks.RoutePath.HealthCheck}-group")] [ApiExplorerSettings(GroupName = "Health Check")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] public abstract class HealthCheckGroupControllerBase : ManagementApiControllerBase { protected IActionResult HealthCheckGroupNotFound() => NotFound(new ProblemDetailsBuilder() diff --git a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/HealthCheckControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/HealthCheckControllerBase.cs index 42e721db1d..5f4922e718 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/HealthCheckControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/HealthCheck/HealthCheckControllerBase.cs @@ -6,10 +6,9 @@ using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Cms.Api.Management.Controllers.HealthCheck; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.HealthChecks.RoutePath.HealthCheck}")] [ApiExplorerSettings(GroupName = "Health Check")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] public abstract class HealthCheckControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Help/HelpControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Help/HelpControllerBase.cs index 779dbfc743..4fce426926 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Help/HelpControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Help/HelpControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Help; -[ApiController] [VersionedApiBackOfficeRoute("help")] [ApiExplorerSettings(GroupName = "Help")] public abstract class HelpControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/IndexerControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/IndexerControllerBase.cs index 7d41b6c2ef..b992afe42d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/IndexerControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/IndexerControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Indexer; -[ApiController] [VersionedApiBackOfficeRoute("indexer")] [ApiExplorerSettings(GroupName = "Indexer")] public class IndexerControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Install/InstallControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Install/InstallControllerBase.cs index db19e73768..8881a3bfba 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Install/InstallControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Install/InstallControllerBase.cs @@ -1,16 +1,15 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core; using Umbraco.Cms.Api.Management.Filters; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models.Installer; using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.Install; [AllowAnonymous] -[ApiController] [VersionedApiBackOfficeRoute("install")] [ApiExplorerSettings(GroupName = "Install")] [RequireRuntimeLevel(RuntimeLevel.Install)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Language/CreateLanguageController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Language/CreateLanguageController.cs index 680e6543a7..ae62476597 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Language/CreateLanguageController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Language/CreateLanguageController.cs @@ -14,7 +14,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Language; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessLanguages)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] public class CreateLanguageController : LanguageControllerBase { private readonly ILanguageService _languageService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Language/DeleteLanguageController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Language/DeleteLanguageController.cs index f14256c567..a11f7a7bde 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Language/DeleteLanguageController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Language/DeleteLanguageController.cs @@ -12,7 +12,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Language; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessLanguages)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] public class DeleteLanguageController : LanguageControllerBase { private readonly ILanguageService _languageService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Language/Item/LanguageEntityControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Language/Item/LanguageEntityControllerBase.cs index dabaec4f85..0a06573b62 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Language/Item/LanguageEntityControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Language/Item/LanguageEntityControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Language.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Language}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Language))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessLanguages)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] public class LanguageEntityControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Language/LanguageControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Language/LanguageControllerBase.cs index c92f48469f..ea48f80bd6 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Language/LanguageControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Language/LanguageControllerBase.cs @@ -7,7 +7,6 @@ using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.Language; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.Language)] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Language))] public abstract class LanguageControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Language/UpdateLanguageController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Language/UpdateLanguageController.cs index e040ee8a1d..6238898d79 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Language/UpdateLanguageController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Language/UpdateLanguageController.cs @@ -14,7 +14,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Language; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessLanguages)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] public class UpdateLanguageController : LanguageControllerBase { private readonly ILanguageService _languageService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/LogViewerControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/LogViewerControllerBase.cs index 3f6ed71952..8613ff0396 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/LogViewerControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/LogViewerControllerBase.cs @@ -7,10 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.LogViewer; -[ApiController] [VersionedApiBackOfficeRoute("log-viewer")] [ApiExplorerSettings(GroupName = "Log Viewer")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] public abstract class LogViewerControllerBase : ManagementApiControllerBase { protected IActionResult LogViewerOperationStatusResult(LogViewerOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/SavedSearch/SavedSearchLogViewerControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/SavedSearch/SavedSearchLogViewerControllerBase.cs index 163dd3d4ff..fce6a6e0c9 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/SavedSearch/SavedSearchLogViewerControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/LogViewer/SavedSearch/SavedSearchLogViewerControllerBase.cs @@ -4,12 +4,10 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.LogViewer.SavedSearch; -[ApiController] [VersionedApiBackOfficeRoute("log-viewer/saved-search")] [ApiExplorerSettings(GroupName = "Log Viewer")] public class SavedSearchLogViewerControllerBase : LogViewerControllerBase { - protected IActionResult SavedSearchNotFound() => NotFound(new ProblemDetailsBuilder() .WithTitle("The saved search could not be found") .Build()); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs index fc25ab5c16..9a9048ccb9 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs @@ -16,8 +16,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers; -[Authorize(Policy = "New" + AuthorizationPolicies.BackOfficeAccess)] -[Authorize(Policy = "New" + AuthorizationPolicies.UmbracoFeatureEnabled)] +[ApiController] +[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] +[Authorize(Policy = AuthorizationPolicies.UmbracoFeatureEnabled)] [MapToApi(ManagementApiConfiguration.ApiName)] [JsonOptionsName(Constants.JsonOptionsNames.BackOffice)] [AppendEventMessages] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs index f96ea545ed..c6bf7eadda 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs @@ -12,10 +12,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Media.Collection; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Collection}/{Constants.UdiEntityType.Media}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Media))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessMedia)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessMedia)] public abstract class MediaCollectionControllerBase : ContentCollectionControllerBase { protected MediaCollectionControllerBase(IUmbracoMapper mapper) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/DeleteMediaController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/DeleteMediaController.cs index 8d1a670034..9e1095ab8f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/DeleteMediaController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/DeleteMediaController.cs @@ -38,7 +38,7 @@ public class DeleteMediaController : MediaControllerBase [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] public async Task Delete(Guid id) { - AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( + AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, MediaPermissionResource.RecycleBin(), AuthorizationPolicies.MediaPermissionByResource); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/MediaItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/MediaItemControllerBase.cs index c35f234115..ad77315675 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/MediaItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/MediaItemControllerBase.cs @@ -7,11 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Media.Item; -[ApiVersion("1.0")] -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Media}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Media))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessForMediaTree)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessForMediaTree)] public class MediaItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaControllerBase.cs index 96b2a62029..0e2577ce62 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/MediaControllerBase.cs @@ -1,22 +1,18 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Api.Common.Builders; using Umbraco.Cms.Api.Management.Controllers.Content; using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels.Content; using Umbraco.Cms.Api.Management.ViewModels.Media; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models.ContentEditing; -using Umbraco.Cms.Core.Models.ContentEditing.Validation; using Umbraco.Cms.Core.Services.OperationStatus; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Media; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.Media)] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Media))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessMedia)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessMedia)] public class MediaControllerBase : ContentControllerBase { protected IActionResult MediaNotFound() diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/DeleteMediaRecycleBinController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/DeleteMediaRecycleBinController.cs index bd6c02fc33..97d2d84ee4 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/DeleteMediaRecycleBinController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/DeleteMediaRecycleBinController.cs @@ -42,7 +42,7 @@ public class DeleteMediaRecycleBinController : MediaRecycleBinControllerBase [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] public async Task Delete(Guid id) { - AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( + AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, MediaPermissionResource.WithKeys(id), AuthorizationPolicies.MediaPermissionByResource); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/MediaRecycleBinControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/MediaRecycleBinControllerBase.cs index d7971c2115..e4a80ad624 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/MediaRecycleBinControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/RecycleBin/MediaRecycleBinControllerBase.cs @@ -1,23 +1,22 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.Entities; -using Umbraco.Cms.Core.Services; using Umbraco.Cms.Api.Management.Controllers.RecycleBin; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Filters; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Api.Management.ViewModels.Media.RecycleBin; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Entities; +using Umbraco.Cms.Core.Services; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Media.RecycleBin; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.RecycleBin}/{Constants.UdiEntityType.Media}")] [RequireMediaTreeRootAccess] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Media))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessMedia)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessMedia)] public class MediaRecycleBinControllerBase : RecycleBinControllerBase { private readonly IMediaPresentationFactory _mediaPresentationFactory; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs index 3d1799468e..93da6c8820 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs @@ -1,24 +1,23 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.Factories; -using Umbraco.Cms.Api.Management.Services.Entities; -using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Media.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Media}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Media))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessForMediaTree)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessForMediaTree)] public class MediaTreeControllerBase : UserStartNodeTreeControllerBase { private readonly AppCaches _appCaches; @@ -59,23 +58,17 @@ public class MediaTreeControllerBase : UserStartNodeTreeControllerBase new[] { -1 }; + protected override int[] GetUserStartNodeIds() + => _backofficeSecurityAccessor + .BackOfficeSecurity? + .CurrentUser? + .CalculateMediaStartNodeIds(EntityService, _appCaches) + ?? Array.Empty(); - protected override string[] GetUserStartNodePaths() => Array.Empty(); - - // TODO: use these implementations instead of the dummy ones above once we have backoffice auth in place - // protected override int[] GetUserStartNodeIds() - // => _backofficeSecurityAccessor - // .BackOfficeSecurity? - // .CurrentUser? - // .CalculateMediaStartNodeIds(EntityService, _appCaches) - // ?? Array.Empty(); - // - // protected override string[] GetUserStartNodePaths() - // => _backofficeSecurityAccessor - // .BackOfficeSecurity? - // .CurrentUser? - // .GetMediaStartNodePaths(EntityService, _appCaches) - // ?? Array.Empty(); + protected override string[] GetUserStartNodePaths() + => _backofficeSecurityAccessor + .BackOfficeSecurity? + .CurrentUser? + .GetMediaStartNodePaths(EntityService, _appCaches) + ?? Array.Empty(); } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedAtRootMediaTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedAtRootMediaTypeController.cs index 9862412830..122510762a 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedAtRootMediaTypeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedAtRootMediaTypeController.cs @@ -12,7 +12,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MediaType; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] public class AllowedAtRootMediaTypeController : MediaTypeControllerBase { private readonly IMediaTypeService _mediaTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs index a3f217a2af..8ca59590bf 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/AllowedChildrenMediaTypeController.cs @@ -15,7 +15,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MediaType; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] public class AllowedChildrenMediaTypeController : MediaTypeControllerBase { private readonly IMediaTypeService _mediaTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Folder/MediaTypeFolderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Folder/MediaTypeFolderControllerBase.cs index f1e3be8be7..a3e26a1c1f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Folder/MediaTypeFolderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Folder/MediaTypeFolderControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Folder; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.MediaType}/folder")] [ApiExplorerSettings(GroupName = "Media Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMediaTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] public abstract class MediaTypeFolderControllerBase : FolderManagementControllerBase { protected MediaTypeFolderControllerBase( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/MediaTypeItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/MediaTypeItemControllerBase.cs index 2285eb0090..3ed737b932 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/MediaTypeItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Item/MediaTypeItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.MediaType}")] [ApiExplorerSettings(GroupName = "Media Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMediaTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] public class MediaTypeItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/MediaTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/MediaTypeControllerBase.cs index a5d9fc56cd..dd3cec55ad 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/MediaTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/MediaTypeControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MediaType; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.MediaType)] [ApiExplorerSettings(GroupName = "Media Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMediaTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] public abstract class MediaTypeControllerBase : ManagementApiControllerBase { protected IActionResult OperationStatusResult(ContentTypeOperationStatus status) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs index d5af2b21b2..87d1c7d201 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs @@ -1,20 +1,19 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.MediaType}")] [ApiExplorerSettings(GroupName = "Media Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMediaTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] public class MediaTypeTreeControllerBase : FolderTreeControllerBase { private readonly IMediaTypeService _mediaTypeService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/Filter/MemberFilterControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/Filter/MemberFilterControllerBase.cs index 80b1def4c6..13a165579e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Member/Filter/MemberFilterControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/Filter/MemberFilterControllerBase.cs @@ -7,10 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Member.Filter; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Filter}/{Constants.UdiEntityType.Member}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Member))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessForMemberTree)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessForMemberTree)] public abstract class MemberFilterControllerBase : ManagementApiControllerBase { protected IActionResult MemberTypeNotFound() diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/MemberItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/MemberItemControllerBase.cs index 639a104ef2..fba91bd72e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/MemberItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/Item/MemberItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Member.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Member}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Member))] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessForMemberTree)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessForMemberTree)] public class MemberItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/MemberControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/MemberControllerBase.cs index 7b7a906a1a..2fd929e992 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Member/MemberControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/MemberControllerBase.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Common.Builders; using Umbraco.Cms.Api.Management.Controllers.Content; using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels.Content; using Umbraco.Cms.Api.Management.ViewModels.Member; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models.ContentEditing; @@ -11,11 +10,10 @@ using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.Member; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.Member)] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Member))] // FIXME: implement authorization -// [Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessMembers)] +// [Authorize(Policy = AuthorizationPolicies.SectionAccessMembers)] public class MemberControllerBase : ContentControllerBase { protected IActionResult MemberNotFound() => OperationStatusResult(MemberEditingOperationStatus.MemberNotFound, MemberNotFound); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/ByKeyMemberGroupController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/ByKeyMemberGroupController.cs new file mode 100644 index 0000000000..5d2c6de087 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/ByKeyMemberGroupController.cs @@ -0,0 +1,39 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.ViewModels.MemberGroup; +using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup; + +[ApiVersion("1.0")] +public class ByKeyMemberGroupController : MemberGroupControllerBase +{ + private readonly IMemberGroupService _memberGroupService; + private readonly IUmbracoMapper _mapper; + + public ByKeyMemberGroupController(IMemberGroupService memberGroupService, IUmbracoMapper mapper) + { + _memberGroupService = memberGroupService; + _mapper = mapper; + } + + [HttpGet("{id:guid}")] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(MemberGroupResponseModel), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task ByKey(Guid id) + { + IMemberGroup? memberGroup = await _memberGroupService.GetAsync(id); + if (memberGroup is null) + { + return MemberGroupNotFound(); + } + + MemberGroupResponseModel responseModel = _mapper.Map(memberGroup)!; + + return Ok(responseModel); + } +} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/DeleteMemberGroupController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/DeleteMemberGroupController.cs index a3c9d86501..f798a31bbd 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/DeleteMemberGroupController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/DeleteMemberGroupController.cs @@ -15,14 +15,14 @@ public class DeleteMemberGroupController : MemberGroupControllerBase public DeleteMemberGroupController(IMemberGroupService memberGroupService) => _memberGroupService = memberGroupService; - [HttpDelete("{key:guid}")] + [HttpDelete("{id:guid}")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task Delete(Guid key) + public async Task Delete(Guid id) { - Attempt result = await _memberGroupService.DeleteAsync(key); + Attempt result = await _memberGroupService.DeleteAsync(id); return result.Success ? Ok() : MemberGroupOperationStatusResult(result.Status); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Item/MemberGroupItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Item/MemberGroupItemControllerBase.cs index 9ee8a40c5b..926677156c 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Item/MemberGroupItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Item/MemberGroupItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.MemberGroup}")] [ApiExplorerSettings(GroupName = "Member Group")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMemberGroups)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberGroups)] public class MemberGroupItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/MemberGroupControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/MemberGroupControllerBase.cs index c1759cdb7f..16d297b6a4 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/MemberGroupControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/MemberGroupControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.MemberGroup}")] [ApiExplorerSettings(GroupName = "Member Group")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessMembers)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessMembers)] public class MemberGroupControllerBase : ManagementApiControllerBase { protected IActionResult MemberGroupOperationStatusResult(MemberGroupOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs index 29010e5a34..2066e79768 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs @@ -1,19 +1,18 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.MemberGroup}")] [ApiExplorerSettings(GroupName = "Member Group")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMemberGroups)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberGroups)] public class MemberGroupTreeControllerBase : NamedEntityTreeControllerBase { public MemberGroupTreeControllerBase(IEntityService entityService) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Item/MemberTypeItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Item/MemberTypeItemControllerBase.cs index 977e0d732a..d1aafba4e3 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Item/MemberTypeItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Item/MemberTypeItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.MemberType}")] [ApiExplorerSettings(GroupName = "Member Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMemberTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)] public class MemberTypeItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/MemberTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/MemberTypeControllerBase.cs index a672f23ab8..73ad7b6374 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/MemberTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/MemberTypeControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MemberType; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.MemberType)] [ApiExplorerSettings(GroupName = "Member Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMemberTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)] public abstract class MemberTypeControllerBase : ManagementApiControllerBase { protected IActionResult OperationStatusResult(ContentTypeOperationStatus status) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs index 5e44e8dcf3..295be479dd 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs @@ -1,19 +1,18 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.MemberType}")] [ApiExplorerSettings(GroupName = "Member Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessMemberTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)] public class MemberTypeTreeControllerBase : NamedEntityTreeControllerBase { public MemberTypeTreeControllerBase(IEntityService entityService) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/ModelsBuilderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/ModelsBuilderControllerBase.cs index 114015361e..5afc2e7424 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/ModelsBuilderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/ModelsBuilderControllerBase.cs @@ -5,10 +5,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.ModelsBuilder; -[ApiController] [VersionedApiBackOfficeRoute("models-builder")] [ApiExplorerSettings(GroupName = "Models Builder")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] public class ModelsBuilderControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/ObjectTypes/ObjectTypesControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/ObjectTypes/ObjectTypesControllerBase.cs index d932acd146..5cf4b60305 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/ObjectTypes/ObjectTypesControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/ObjectTypes/ObjectTypesControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.ObjectTypes; -[ApiController] [VersionedApiBackOfficeRoute("object-types")] [ApiExplorerSettings(GroupName = "Object Types")] public class ObjectTypesControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Package/Created/CreatedPackageControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Package/Created/CreatedPackageControllerBase.cs index 310842b9be..c191e4de91 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Package/Created/CreatedPackageControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Package/Created/CreatedPackageControllerBase.cs @@ -4,7 +4,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Package.Created; -[ApiController] [VersionedApiBackOfficeRoute("package/created")] [ApiExplorerSettings(GroupName = "Package")] public class CreatedPackageControllerBase : PackageControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Package/PackageControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Package/PackageControllerBase.cs index 007613be2c..87a4290f69 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Package/PackageControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Package/PackageControllerBase.cs @@ -7,10 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Package; -[ApiController] [VersionedApiBackOfficeRoute("package")] [ApiExplorerSettings(GroupName = "Package")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessPackages)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessPackages)] public abstract class PackageControllerBase : ManagementApiControllerBase { protected IActionResult PackageOperationStatusResult(PackageOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Folder/PartialViewFolderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Folder/PartialViewFolderControllerBase.cs index 868c69033b..be38b679f7 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Folder/PartialViewFolderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Folder/PartialViewFolderControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.PartialView.Folder; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.PartialView}/folder")] [ApiExplorerSettings(GroupName = "Partial View")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessPartialViews)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessPartialViews)] public class PartialViewFolderControllerBase : FileSystemManagementControllerBase { protected IActionResult OperationStatusResult(PartialViewFolderOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Item/PartialViewItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Item/PartialViewItemControllerBase.cs index 9cc03353e2..1276370095 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Item/PartialViewItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Item/PartialViewItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.PartialView.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.PartialView}")] [ApiExplorerSettings(GroupName = "Partial View")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessPartialViews)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessPartialViews)] public class PartialViewItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/PartialViewControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/PartialViewControllerBase.cs index b7676bd3c2..57af2377ba 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/PartialViewControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/PartialViewControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.PartialView; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.PartialView}")] [ApiExplorerSettings(GroupName = "Partial View")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessPartialViews)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessPartialViews)] public class PartialViewControllerBase : FileSystemManagementControllerBase { protected IActionResult PartialViewOperationStatusResult(PartialViewOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Tree/PartialViewTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Tree/PartialViewTreeControllerBase.cs index 0627302535..3ed515bc19 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Tree/PartialViewTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/PartialView/Tree/PartialViewTreeControllerBase.cs @@ -1,17 +1,16 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core; -using Umbraco.Cms.Core.IO; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.IO; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.PartialView.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.PartialView}")] [ApiExplorerSettings(GroupName = "Partial View")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessPartialViews)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessPartialViews)] public class PartialViewTreeControllerBase : FileSystemTreeControllerBase { public PartialViewTreeControllerBase(FileSystems fileSystems) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Preview/PreviewControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Preview/PreviewControllerBase.cs index 0534624bd6..54f8e73c71 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Preview/PreviewControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Preview/PreviewControllerBase.cs @@ -1,11 +1,8 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Preview; -[ApiController] [VersionedApiBackOfficeRoute("preview")] [ApiExplorerSettings(GroupName = "Preview")] public class PreviewControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Profiling/ProfilingControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Profiling/ProfilingControllerBase.cs index 113f7600ae..648de60298 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Profiling/ProfilingControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Profiling/ProfilingControllerBase.cs @@ -7,10 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Profiling; -[ApiController] [VersionedApiBackOfficeRoute("profiling")] [ApiExplorerSettings(GroupName = "Profiling")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] public class ProfilingControllerBase : ManagementApiControllerBase { protected IActionResult WebProfilerOperationStatusResult(WebProfilerOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/PropertyType/PropertyTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/PropertyType/PropertyTypeControllerBase.cs index 787970ddbe..8b9ba15dca 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/PropertyType/PropertyTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/PropertyType/PropertyTypeControllerBase.cs @@ -7,10 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.PropertyType; -[ApiController] [VersionedApiBackOfficeRoute("property-type")] [ApiExplorerSettings(GroupName = "Property Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public abstract class PropertyTypeControllerBase : ManagementApiControllerBase { protected IActionResult PropertyTypeOperationStatusResult(PropertyTypeOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/PublishedCache/PublishedCacheControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/PublishedCache/PublishedCacheControllerBase.cs index 717fee6f55..09a36a7411 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/PublishedCache/PublishedCacheControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/PublishedCache/PublishedCacheControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.PublishedCache; -[ApiController] [VersionedApiBackOfficeRoute("published-cache")] [ApiExplorerSettings(GroupName = "Published Cache")] public class PublishedCacheControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/RedirectUrlManagement/RedirectUrlManagementControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/RedirectUrlManagement/RedirectUrlManagementControllerBase.cs index f1636b1830..866afb3844 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/RedirectUrlManagement/RedirectUrlManagementControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/RedirectUrlManagement/RedirectUrlManagementControllerBase.cs @@ -5,11 +5,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.RedirectUrlManagement; -[ApiController] [VersionedApiBackOfficeRoute("redirect-management")] [ApiExplorerSettings(GroupName = "Redirect Management")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContent)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)] public class RedirectUrlManagementControllerBase : ManagementApiControllerBase { - } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Relation/RelationControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Relation/RelationControllerBase.cs index f916a6072e..6974231663 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Relation/RelationControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Relation/RelationControllerBase.cs @@ -7,10 +7,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Relation; -[ApiController] [VersionedApiBackOfficeRoute("relation")] [ApiExplorerSettings(GroupName = "Relation")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContent)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)] public abstract class RelationControllerBase : ManagementApiControllerBase { protected IActionResult RelationOperationStatusResult(RelationOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Item/RelationTypeItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Item/RelationTypeItemControllerBase.cs index b6efa387b0..9daa3ac10e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Item/RelationTypeItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Item/RelationTypeItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.RelationType.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.RelationType}")] [ApiExplorerSettings(GroupName = "Relation Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessRelationTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessRelationTypes)] public class RelationTypeItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Query/RelationTypeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Query/RelationTypeControllerBase.cs index 3ecd3d51e8..cda171f7b7 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Query/RelationTypeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Query/RelationTypeControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.RelationType.Query; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.RelationType}")] [ApiExplorerSettings(GroupName = "Relation Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessRelationTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessRelationTypes)] public class RelationTypeControllerBase : ManagementApiControllerBase { protected IActionResult RelationTypeOperationStatusResult(RelationTypeOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Tree/RelationTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Tree/RelationTypeTreeControllerBase.cs index 8311ed6234..dba61adc60 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Tree/RelationTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/RelationType/Tree/RelationTypeTreeControllerBase.cs @@ -1,20 +1,19 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; -using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.RelationType.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.RelationType}")] [ApiExplorerSettings(GroupName = "Relation Type")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessRelationTypes)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessRelationTypes)] // NOTE: at the moment relation types aren't supported by EntityService, so we have little use of the // tree controller base. We'll keep it though, in the hope that we can mend EntityService. public class RelationTypeTreeControllerBase : NamedEntityTreeControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Script/Folder/ScriptFolderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Script/Folder/ScriptFolderControllerBase.cs index 9d088cb0da..598292397d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Script/Folder/ScriptFolderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Script/Folder/ScriptFolderControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Script.Folder; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Script}/folder")] [ApiExplorerSettings(GroupName = "Script")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessScripts)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessScripts)] public class ScriptFolderControllerBase : FileSystemManagementControllerBase { protected IActionResult OperationStatusResult(ScriptFolderOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Script/Item/ScriptItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Script/Item/ScriptItemControllerBase.cs index 5797e33e24..9da3dea411 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Script/Item/ScriptItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Script/Item/ScriptItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Script.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Script}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Script))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessScripts)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessScripts)] public class ScriptItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Script/ScriptControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Script/ScriptControllerBase.cs index 324c767d90..98055f5f1b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Script/ScriptControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Script/ScriptControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Script; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Script}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Script))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessScripts)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessScripts)] public class ScriptControllerBase : FileSystemManagementControllerBase { protected IActionResult ScriptOperationStatusResult(ScriptOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Script/Tree/ScriptTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Script/Tree/ScriptTreeControllerBase.cs index ea86b67b3b..70f13269c3 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Script/Tree/ScriptTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Script/Tree/ScriptTreeControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Script.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Script}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Script))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessScripts)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessScripts)] public class ScriptTreeControllerBase : FileSystemTreeControllerBase { public ScriptTreeControllerBase(FileSystems fileSystems) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Searcher/SearcherControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Searcher/SearcherControllerBase.cs index d27fe28826..81bacd016d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Searcher/SearcherControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Searcher/SearcherControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Searcher; -[ApiController] [VersionedApiBackOfficeRoute("searcher")] [ApiExplorerSettings(GroupName = "Searcher")] public class SearcherControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs index d58bdc148a..1336805045 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs @@ -2,7 +2,6 @@ using Asp.Versioning; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -14,17 +13,16 @@ using Umbraco.Cms.Api.Common.Builders; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Security; +using Umbraco.Cms.Web.Common.Security; using Umbraco.Extensions; using IdentitySignInResult = Microsoft.AspNetCore.Identity.SignInResult; using SignInResult = Microsoft.AspNetCore.Mvc.SignInResult; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Web.Common.Security; namespace Umbraco.Cms.Api.Management.Controllers.Security; [ApiVersion("1.0")] -[ApiController] [VersionedApiBackOfficeRoute(Common.Security.Paths.BackOfficeApi.EndpointTemplate)] [ApiExplorerSettings(IgnoreApi = true)] public class BackOfficeController : SecurityControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Security/ConfigurationSecurityController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Security/ConfigurationSecurityController.cs index b60e5b085d..92823e5dc6 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Security/ConfigurationSecurityController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Security/ConfigurationSecurityController.cs @@ -9,7 +9,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Security; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.DenyLocalLoginIfConfigured)] +[Authorize(Policy = AuthorizationPolicies.DenyLocalLoginIfConfigured)] // FIXME: Add requiring password reset token policy when its implemented public class ConfigurationSecurityController : SecurityControllerBase { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Security/SecurityControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Security/SecurityControllerBase.cs index 8fcdb13561..5e447a424a 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Security/SecurityControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Security/SecurityControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Security; -[ApiController] [VersionedApiBackOfficeRoute("security")] [ApiExplorerSettings(GroupName = "Security")] -[Authorize(Policy = "New" + AuthorizationPolicies.DenyLocalLoginIfConfigured)] +[Authorize(Policy = AuthorizationPolicies.DenyLocalLoginIfConfigured)] public abstract class SecurityControllerBase : ManagementApiControllerBase { protected IActionResult UserOperationStatusResult(UserOperationStatus status, ErrorMessageResult? errorMessageResult = null) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Server/ServerControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Server/ServerControllerBase.cs index 646f1f6996..8b476651eb 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Server/ServerControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Server/ServerControllerBase.cs @@ -3,10 +3,8 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Server; -[ApiController] [VersionedApiBackOfficeRoute("server")] [ApiExplorerSettings(GroupName = "Server")] public abstract class ServerControllerBase : ManagementApiControllerBase { - } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Item/StaticFileItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Item/StaticFileItemControllerBase.cs index 6255da9183..884ec7f8b8 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Item/StaticFileItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Item/StaticFileItemControllerBase.cs @@ -4,7 +4,6 @@ using Umbraco.Cms.Core; namespace Umbraco.Cms.Api.Management.Controllers.StaticFile.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/static-file")] [ApiExplorerSettings(GroupName = "Static File")] public class StaticFileItemControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Tree/StaticFileTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Tree/StaticFileTreeControllerBase.cs index a6907b6d23..21d58bfc1f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Tree/StaticFileTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/StaticFile/Tree/StaticFileTreeControllerBase.cs @@ -6,7 +6,6 @@ using Umbraco.Cms.Core.IO; namespace Umbraco.Cms.Api.Management.Controllers.StaticFile.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/static-file")] [ApiExplorerSettings(GroupName = "Static File")] public class StaticFileTreeControllerBase : FileSystemTreeControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Folder/StylesheetFolderControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Folder/StylesheetFolderControllerBase.cs index cf52ea6f77..5430cc7ab5 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Folder/StylesheetFolderControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Folder/StylesheetFolderControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Stylesheet.Folder; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Stylesheet}/folder")] [ApiExplorerSettings(GroupName = "Stylesheet")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessStylesheets)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessStylesheets)] public class StylesheetFolderControllerBase : FileSystemManagementControllerBase { protected IActionResult OperationStatusResult(StylesheetFolderOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Item/StylesheetItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Item/StylesheetItemControllerBase.cs index d528852513..17a7f01125 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Item/StylesheetItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Item/StylesheetItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Stylesheet.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Stylesheet}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Stylesheet))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessStylesheets)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessStylesheets)] public class StylesheetItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/StylesheetControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/StylesheetControllerBase.cs index 6556212f10..f36b707424 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/StylesheetControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/StylesheetControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Stylesheet; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Stylesheet}")] [ApiExplorerSettings(GroupName = "Stylesheet")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessStylesheets)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessStylesheets)] public class StylesheetControllerBase : FileSystemManagementControllerBase { protected IActionResult StylesheetOperationStatusResult(StylesheetOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Tree/StylesheetTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Tree/StylesheetTreeControllerBase.cs index 9b58647c16..b03e547fc2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Tree/StylesheetTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Stylesheet/Tree/StylesheetTreeControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Stylesheet.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Stylesheet}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Stylesheet))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessStylesheets)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessStylesheets)] public class StylesheetTreeControllerBase : FileSystemTreeControllerBase { public StylesheetTreeControllerBase(FileSystems fileSystems) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tag/TagControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tag/TagControllerBase.cs index 209bc85558..6257e00187 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tag/TagControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tag/TagControllerBase.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.Tag; -[ApiController] [VersionedApiBackOfficeRoute("tag")] [ApiExplorerSettings(GroupName = "Tag")] public class TagControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Telemetry/TelemetryControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Telemetry/TelemetryControllerBase.cs index 4530e284c4..adb11cc3ef 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Telemetry/TelemetryControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Telemetry/TelemetryControllerBase.cs @@ -5,10 +5,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Telemetry; -[ApiController] [VersionedApiBackOfficeRoute("telemetry")] [ApiExplorerSettings(GroupName = "Telemetry")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessSettings)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessSettings)] public abstract class TelemetryControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Item/TemplateItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Item/TemplateItemControllerBase.cs index c67181381b..19941bd6d7 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Item/TemplateItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Item/TemplateItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Template.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Template}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Template))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessTemplates)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessTemplates)] public class TemplateItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/TemplateControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/TemplateControllerBase.cs index f771236ec5..568143c80f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/TemplateControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/TemplateControllerBase.cs @@ -9,10 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Template; -[ApiController] [VersionedApiBackOfficeRoute(Constants.UdiEntityType.Template)] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Template))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessTemplates)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessTemplates)] public class TemplateControllerBase : ManagementApiControllerBase { protected IActionResult TemplateOperationStatusResult(TemplateOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs index 95b69ca395..2ab19a1ee5 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs @@ -1,19 +1,18 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Management.Controllers.Tree; +using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Controllers.Tree; -using Umbraco.Cms.Api.Management.ViewModels.Tree; -using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Template.Tree; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Template}")] [ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Template))] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessTemplates)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessTemplates)] public class TemplateTreeControllerBase : NamedEntityTreeControllerBase { public TemplateTreeControllerBase(IEntityService entityService) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/TemporaryFile/TemporaryFileControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/TemporaryFile/TemporaryFileControllerBase.cs index a0d848b711..b33f63d7ac 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/TemporaryFile/TemporaryFileControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/TemporaryFile/TemporaryFileControllerBase.cs @@ -6,7 +6,6 @@ using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.TemporaryFile; -[ApiController] [VersionedApiBackOfficeRoute("temporary-file")] [ApiExplorerSettings(GroupName = "Temporary File")] public abstract class TemporaryFileControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tour/TourControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tour/TourControllerBase.cs index 4e4cc3846e..fafb01ed17 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tour/TourControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tour/TourControllerBase.cs @@ -5,7 +5,6 @@ using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.Tour; -[ApiController] [VersionedApiBackOfficeRoute("tour")] [ApiExplorerSettings(GroupName = "Tour")] public class TourControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/Controllers/TrackedReference/TrackedReferencesControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/TrackedReference/TrackedReferencesControllerBase.cs index 1d8212637b..2af92ee696 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/TrackedReference/TrackedReferencesControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/TrackedReference/TrackedReferencesControllerBase.cs @@ -5,10 +5,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.TrackedReference; -[ApiController] [VersionedApiBackOfficeRoute("tracked-reference")] [ApiExplorerSettings(GroupName = "Tracked Reference")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContentOrMedia)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessContentOrMedia)] public abstract class TrackedReferenceControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/FileSystemTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/FileSystemTreeControllerBase.cs index 604e5a82be..fecad5b85b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/FileSystemTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/FileSystemTreeControllerBase.cs @@ -1,10 +1,10 @@ using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.IO; -using Umbraco.Cms.Api.Management.Services.Paging; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Extensions; +using Umbraco.Cms.Api.Management.Services.Paging; using Umbraco.Cms.Api.Management.ViewModels.FileSystem; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.IO; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Controllers.Tree; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs index 435f98088f..11d2fc420e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs @@ -1,8 +1,8 @@ -using Umbraco.Cms.Core; +using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.ViewModels.Tree; namespace Umbraco.Cms.Api.Management.Controllers.Tree; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs index c631569da1..f72eff814b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs @@ -1,9 +1,9 @@ -using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Models.Entities; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Models.Entities; +using Umbraco.Cms.Api.Management.Models.Entities; using Umbraco.Cms.Api.Management.Services.Entities; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models.Entities; +using Umbraco.Cms.Core.Services; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Controllers.Tree; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Upgrade/UpgradeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Upgrade/UpgradeControllerBase.cs index 219e17aa2e..bf720a4e44 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Upgrade/UpgradeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Upgrade/UpgradeControllerBase.cs @@ -1,20 +1,19 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core; using Umbraco.Cms.Api.Management.Filters; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models.Installer; using Umbraco.Cms.Core.Services.OperationStatus; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Upgrade; -[ApiController] [RequireRuntimeLevel(RuntimeLevel.Upgrade)] [VersionedApiBackOfficeRoute("upgrade")] [ApiExplorerSettings(GroupName = "Upgrade")] -[Authorize(Policy = "New" + AuthorizationPolicies.RequireAdminAccess)] +[Authorize(Policy = AuthorizationPolicies.RequireAdminAccess)] public abstract class UpgradeControllerBase : ManagementApiControllerBase { protected IActionResult UpgradeOperationResult(UpgradeOperationStatus status, InstallationResult? result = null) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/BulkDeleteUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/BulkDeleteUserController.cs index 8a10c6deea..e330dc6a58 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/BulkDeleteUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/BulkDeleteUserController.cs @@ -39,7 +39,7 @@ public class BulkDeleteUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(model.UserIds), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ByKeyUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ByKeyUserController.cs index 8012386030..05c5a8fa96 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/ByKeyUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ByKeyUserController.cs @@ -40,7 +40,7 @@ public class ByKeyUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ChangePasswordUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ChangePasswordUserController.cs index 734a9ed714..614bde7f19 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/ChangePasswordUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ChangePasswordUserController.cs @@ -42,7 +42,7 @@ public class ChangePasswordUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ClearAvatarUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ClearAvatarUserController.cs index 12fe4325f8..5cc15fe35e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/ClearAvatarUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ClearAvatarUserController.cs @@ -33,7 +33,7 @@ public class ClearAvatarUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ConfigurationUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ConfigurationUserController.cs index 46b2a3a328..9cc9298613 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/ConfigurationUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ConfigurationUserController.cs @@ -9,7 +9,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.RequireAdminAccess)] +[Authorize(Policy = AuthorizationPolicies.RequireAdminAccess)] public class ConfigurationUserController : UserControllerBase { private readonly IUserPresentationFactory _userPresentationFactory; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/CreateInitialPasswordUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/CreateInitialPasswordUserController.cs index 8753c327b8..e017b0c6a3 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/CreateInitialPasswordUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/CreateInitialPasswordUserController.cs @@ -12,7 +12,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.DenyLocalLoginIfConfigured)] +[Authorize(Policy = AuthorizationPolicies.DenyLocalLoginIfConfigured)] public class CreateInitialPasswordUserController : UserControllerBase { private readonly IUserService _userService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/ConfigurationCurrentUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/ConfigurationCurrentUserController.cs index 9e29b10801..92d2dcd02d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/ConfigurationCurrentUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/ConfigurationCurrentUserController.cs @@ -9,7 +9,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User.Current; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.BackOfficeAccess)] +[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] public class ConfigurationCurrentUserController : CurrentUserControllerBase { private readonly IUserPresentationFactory _userPresentationFactory; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/CurrentUserControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/CurrentUserControllerBase.cs index b8802fa0c1..b6d4f0e920 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/CurrentUserControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/CurrentUserControllerBase.cs @@ -1,12 +1,9 @@ -using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Routing; namespace Umbraco.Cms.Api.Management.Controllers.User.Current; -[ApiController] [VersionedApiBackOfficeRoute("user/current")] public abstract class CurrentUserControllerBase : UserOrCurrentUserControllerBase { - } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetCurrentUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetCurrentUserController.cs index 2d4752cac1..c0a7d26470 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetCurrentUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetCurrentUserController.cs @@ -44,7 +44,7 @@ public class GetCurrentUserController : CurrentUserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(currentUserKey), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/SetAvatarCurrentUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/SetAvatarCurrentUserController.cs index 3558a903e1..be714f9b3e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/SetAvatarCurrentUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/SetAvatarCurrentUserController.cs @@ -41,7 +41,7 @@ public class SetAvatarCurrentUserController : CurrentUserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(userKey), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/DeleteUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/DeleteUserController.cs index bf4de77f6f..8043dbae5d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/DeleteUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/DeleteUserController.cs @@ -39,7 +39,7 @@ public class DeleteUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/DisableTwoFactorProviderUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/DisableTwoFactorProviderUserController.cs index 5f2a0f5955..99ce5d62d8 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/DisableTwoFactorProviderUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/DisableTwoFactorProviderUserController.cs @@ -36,7 +36,7 @@ public class DisableTwoFactorProviderUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/DisableUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/DisableUserController.cs index a3f0facf5d..5b3eb98623 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/DisableUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/DisableUserController.cs @@ -40,7 +40,7 @@ public class DisableUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(model.UserIds), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/EnableUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/EnableUserController.cs index 0490724959..8817626b9f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/EnableUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/EnableUserController.cs @@ -40,7 +40,7 @@ public class EnableUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(model.UserIds), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Filter/UserFilterControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Filter/UserFilterControllerBase.cs index 9b58d64567..177159c95f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Filter/UserFilterControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/Filter/UserFilterControllerBase.cs @@ -1,14 +1,12 @@ using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Core; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User.Filter; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Filter}/user")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessUsers)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessUsers)] public abstract class UserFilterControllerBase : UserOrCurrentUserControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Item/UserItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Item/UserItemControllerBase.cs index 8954621f9a..97853aa722 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Item/UserItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/Item/UserItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/user")] [ApiExplorerSettings(GroupName = "User")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessUsers)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessUsers)] public class UserItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ListTwoFactorProvidersUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ListTwoFactorProvidersUserController.cs index 299ebd325a..6a5fe786f0 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/ListTwoFactorProvidersUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ListTwoFactorProvidersUserController.cs @@ -36,7 +36,7 @@ public class ListTwoFactorProvidersUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ResetPasswordUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ResetPasswordUserController.cs index b793eb76fd..2be4d9a6b5 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/ResetPasswordUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ResetPasswordUserController.cs @@ -45,7 +45,7 @@ public class ResetPasswordUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/SetAvatarUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/SetAvatarUserController.cs index 5086cc6b44..4bd92b9d0c 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/SetAvatarUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/SetAvatarUserController.cs @@ -34,7 +34,7 @@ public class SetAvatarUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/UnlockUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/UnlockUserController.cs index d39718b894..8ebd3fe7bc 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/UnlockUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/UnlockUserController.cs @@ -41,7 +41,7 @@ public class UnlockUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(model.UserIds), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserController.cs index a5622f1bce..28c77a7ab1 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserController.cs @@ -46,7 +46,7 @@ public class UpdateUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(id), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserGroupsUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserGroupsUserController.cs index 013a663e0b..a9227d28e3 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserGroupsUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/UpdateUserGroupsUserController.cs @@ -31,7 +31,7 @@ public class UpdateUserGroupsUserController : UserControllerBase AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync( User, UserPermissionResource.WithKeys(requestModel.UserIds), - AuthorizationPolicies.AdminUserEditsRequireAdmin); + AuthorizationPolicies.UserPermissionByResource); if (!authorizationResult.Succeeded) { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/UserControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/UserControllerBase.cs index 619cd812ef..3b0986f579 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/UserControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/UserControllerBase.cs @@ -1,13 +1,11 @@ using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User; -[ApiController] [VersionedApiBackOfficeRoute("user")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessUsers)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessUsers)] public abstract class UserControllerBase : UserOrCurrentUserControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs index 90ba76eec1..6b9f20ea1e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs @@ -5,7 +5,6 @@ using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.User; -[ApiController] [ApiExplorerSettings(GroupName = "User")] public abstract class UserOrCurrentUserControllerBase : ManagementApiControllerBase { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/VerifyInviteUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/VerifyInviteUserController.cs index 1c193e1780..0252712f4c 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/VerifyInviteUserController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/VerifyInviteUserController.cs @@ -11,7 +11,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.User; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.DenyLocalLoginIfConfigured)] +[Authorize(Policy = AuthorizationPolicies.DenyLocalLoginIfConfigured)] public class VerifyInviteUserController : UserControllerBase { private readonly IUserService _userService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/Item/UserGroupItemControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/Item/UserGroupItemControllerBase.cs index 898524619a..70664a5d19 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/Item/UserGroupItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/Item/UserGroupItemControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.UserGroup.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/user-group")] [ApiExplorerSettings(GroupName = "User Group")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessUsers)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessUsers)] public class UserGroupItemControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/UserGroupsControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/UserGroupsControllerBase.cs index 6627e7f8e0..93daff8c3b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/UserGroupsControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/UserGroup/UserGroupsControllerBase.cs @@ -8,10 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.UserGroup; -[ApiController] [VersionedApiBackOfficeRoute("user-group")] [ApiExplorerSettings(GroupName = "User Group")] -[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessUsers)] +[Authorize(Policy = AuthorizationPolicies.SectionAccessUsers)] public class UserGroupControllerBase : ManagementApiControllerBase { protected IActionResult UserGroupOperationStatusResult(UserGroupOperationStatus status) => diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/CreateWebhookController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/CreateWebhookController.cs index 80c5418ff7..4dd8330272 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/CreateWebhookController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/CreateWebhookController.cs @@ -13,7 +13,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Webhook; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessWebhooks)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessWebhooks)] public class CreateWebhookController : WebhookControllerBase { private readonly IWebhookService _webhookService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/DeleteWebhookController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/DeleteWebhookController.cs index 103bfe645c..d1475cde98 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/DeleteWebhookController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/DeleteWebhookController.cs @@ -12,7 +12,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Webhook; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessWebhooks)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessWebhooks)] public class DeleteWebhookController : WebhookControllerBase { private readonly IWebhookService _webhookService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/Item/WebhookEntityControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/Item/WebhookEntityControllerBase.cs index 1982cd898d..b28cb6c062 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/Item/WebhookEntityControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/Item/WebhookEntityControllerBase.cs @@ -6,10 +6,9 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Webhook.Item; -[ApiController] [VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Webhook}")] [ApiExplorerSettings(GroupName = "Webhook")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessWebhooks)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessWebhooks)] public class WebhookEntityControllerBase : ManagementApiControllerBase { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/UpdateWebhookController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/UpdateWebhookController.cs index a74a4eb27a..3731dcadc0 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/UpdateWebhookController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/UpdateWebhookController.cs @@ -15,7 +15,7 @@ using Umbraco.Cms.Web.Common.Authorization; namespace Umbraco.Cms.Api.Management.Controllers.Webhook; [ApiVersion("1.0")] -[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessWebhooks)] +[Authorize(Policy = AuthorizationPolicies.TreeAccessWebhooks)] public class UpdateWebhookController : WebhookControllerBase { private readonly IWebhookService _webhookService; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/WebhookControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/WebhookControllerBase.cs index 30f9bcb5fd..98c3868c65 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Webhook/WebhookControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Webhook/WebhookControllerBase.cs @@ -6,7 +6,6 @@ using Umbraco.Cms.Core.Services.OperationStatus; namespace Umbraco.Cms.Api.Management.Controllers.Webhook; -[ApiController] [VersionedApiBackOfficeRoute("webhook")] [ApiExplorerSettings(GroupName = "Webhook")] public abstract class WebhookControllerBase : ManagementApiControllerBase diff --git a/src/Umbraco.Cms.Api.Management/DependencyInjection/BackOfficeAuthPolicyBuilderExtensions.cs b/src/Umbraco.Cms.Api.Management/DependencyInjection/BackOfficeAuthPolicyBuilderExtensions.cs index bffdb43db1..4714c54c74 100644 --- a/src/Umbraco.Cms.Api.Management/DependencyInjection/BackOfficeAuthPolicyBuilderExtensions.cs +++ b/src/Umbraco.Cms.Api.Management/DependencyInjection/BackOfficeAuthPolicyBuilderExtensions.cs @@ -1,11 +1,9 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using OpenIddict.Validation.AspNetCore; -using Umbraco.Cms.Api.Management.Security.Authorization; using Umbraco.Cms.Api.Management.Security.Authorization.Content; using Umbraco.Cms.Api.Management.Security.Authorization.DenyLocalLogin; using Umbraco.Cms.Api.Management.Security.Authorization.Dictionary; -using Umbraco.Cms.Api.Management.Security.Authorization.Feature; using Umbraco.Cms.Api.Management.Security.Authorization.Media; using Umbraco.Cms.Api.Management.Security.Authorization.User; using Umbraco.Cms.Api.Management.Security.Authorization.UserGroup; @@ -25,11 +23,11 @@ internal static class BackOfficeAuthPolicyBuilderExtensions // any auth defining a matching requirement and scheme. builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); - builder.Services.AddSingleton(); builder.Services.AddAuthorization(CreatePolicies); return builder; @@ -39,20 +37,20 @@ internal static class BackOfficeAuthPolicyBuilderExtensions { void AddPolicy(string policyName, string claimType, params string[] allowedClaimValues) { - options.AddPolicy($"New{policyName}", policy => + options.AddPolicy(policyName, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.RequireClaim(claimType, allowedClaimValues); }); } - options.AddPolicy($"New{AuthorizationPolicies.BackOfficeAccess}", policy => + options.AddPolicy(AuthorizationPolicies.BackOfficeAccess, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.RequireAuthenticatedUser(); }); - options.AddPolicy($"New{AuthorizationPolicies.RequireAdminAccess}", policy => + options.AddPolicy(AuthorizationPolicies.RequireAdminAccess, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.RequireRole(Constants.Security.AdminGroupAlias); @@ -93,47 +91,46 @@ internal static class BackOfficeAuthPolicyBuilderExtensions AddPolicy(AuthorizationPolicies.TreeAccessWebhooks, Constants.Security.AllowedApplicationsClaimType, Constants.Applications.Settings); // Contextual permissions - // TODO: Rename policies once we have the old ones removed - options.AddPolicy($"New{AuthorizationPolicies.AdminUserEditsRequireAdmin}", policy => - { - policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); - policy.Requirements.Add(new UserPermissionRequirement()); - }); - - options.AddPolicy($"New{AuthorizationPolicies.ContentPermissionByResource}", policy => + options.AddPolicy(AuthorizationPolicies.ContentPermissionByResource, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.Requirements.Add(new ContentPermissionRequirement()); }); - options.AddPolicy($"New{AuthorizationPolicies.DenyLocalLoginIfConfigured}", policy => + options.AddPolicy(AuthorizationPolicies.DenyLocalLoginIfConfigured, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.Requirements.Add(new DenyLocalLoginRequirement()); }); - options.AddPolicy($"New{AuthorizationPolicies.MediaPermissionByResource}", policy => + options.AddPolicy(AuthorizationPolicies.DictionaryPermissionByResource, policy => + { + policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); + policy.Requirements.Add(new DictionaryPermissionRequirement()); + }); + + options.AddPolicy(AuthorizationPolicies.MediaPermissionByResource, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.Requirements.Add(new MediaPermissionRequirement()); }); - options.AddPolicy($"New{AuthorizationPolicies.UmbracoFeatureEnabled}", policy => + options.AddPolicy(AuthorizationPolicies.UmbracoFeatureEnabled, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.Requirements.Add(new FeatureAuthorizeRequirement()); }); - options.AddPolicy($"New{AuthorizationPolicies.UserBelongsToUserGroupInRequest}", policy => + options.AddPolicy(AuthorizationPolicies.UserBelongsToUserGroupInRequest, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); policy.Requirements.Add(new UserGroupPermissionRequirement()); }); - options.AddPolicy($"New{AuthorizationPolicies.DictionaryPermissionByResource}", policy => + options.AddPolicy(AuthorizationPolicies.UserPermissionByResource, policy => { policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); - policy.Requirements.Add(new DictionaryPermissionRequirement()); + policy.Requirements.Add(new UserPermissionRequirement()); }); } } diff --git a/src/Umbraco.Cms.Api.Management/Factories/DocumentTypeEditingPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/DocumentTypeEditingPresentationFactory.cs index de6ed6ebf6..d0fbc93172 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/DocumentTypeEditingPresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/DocumentTypeEditingPresentationFactory.cs @@ -25,7 +25,7 @@ internal sealed class DocumentTypeEditingPresentationFactory : ContentTypeEditin MapCleanup(createModel, requestModel.Cleanup); createModel.Key = requestModel.Id; - createModel.ContainerKey = requestModel.Folder?.Id; + createModel.ContainerKey = requestModel.Parent?.Id; createModel.AllowedTemplateKeys = requestModel.AllowedTemplates.Select(reference => reference.Id).ToArray(); createModel.DefaultTemplateKey = requestModel.DefaultTemplate?.Id; createModel.ListView = requestModel.Collection?.Id; diff --git a/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs index b2e9aa6132..11b2d18134 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs @@ -24,7 +24,7 @@ internal sealed class MediaTypeEditingPresentationFactory : ContentTypeEditingPr >(requestModel); createModel.Key = requestModel.Id; - createModel.ContainerKey = requestModel.Folder?.Id; + createModel.ContainerKey = requestModel.Parent?.Id; createModel.AllowedContentTypes = MapAllowedContentTypes(requestModel.AllowedMediaTypes); createModel.Compositions = MapCompositions(requestModel.Compositions); createModel.ListView = requestModel.Collection?.Id; diff --git a/src/Umbraco.Cms.Api.Management/Mapping/DataType/DataTypeViewModelMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/DataType/DataTypeViewModelMapDefinition.cs index 32959224f6..380400fc00 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/DataType/DataTypeViewModelMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/DataType/DataTypeViewModelMapDefinition.cs @@ -1,20 +1,13 @@ -using Umbraco.Cms.Api.Management.ViewModels; -using Umbraco.Cms.Api.Management.ViewModels.DataType; +using Umbraco.Cms.Api.Management.ViewModels.DataType; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PropertyEditors; -using Umbraco.Cms.Core.Services; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Mapping.DataType; public class DataTypeViewModelMapDefinition : IMapDefinition { - private readonly IDataTypeService _dataTypeService; - - public DataTypeViewModelMapDefinition(IDataTypeService dataTypeService) - => _dataTypeService = dataTypeService; - public void DefineMaps(IUmbracoMapper mapper) => mapper.Define((_, _) => new DataTypeResponseModel(), Map); @@ -22,8 +15,6 @@ public class DataTypeViewModelMapDefinition : IMapDefinition private void Map(IDataType source, DataTypeResponseModel target, MapperContext context) { target.Id = source.Key; - Guid? parentId = _dataTypeService.GetContainer(source.ParentId)?.Key; - target.Parent = ReferenceByIdModel.ReferenceOrNull(parentId); target.Name = source.Name ?? string.Empty; target.EditorAlias = source.EditorAlias; target.EditorUiAlias = source.EditorUiAlias; diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json index 40367c29f7..4043d085fc 100644 --- a/src/Umbraco.Cms.Api.Management/OpenApi.json +++ b/src/Umbraco.Cms.Api.Management/OpenApi.json @@ -1665,6 +1665,86 @@ ] } }, + "/umbraco/management/api/v1/filter/data-type": { + "get": { + "tags": [ + "Data Type" + ], + "operationId": "GetFilterDataType", + "parameters": [ + { + "name": "skip", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "take", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 100 + } + }, + { + "name": "name", + "in": "query", + "schema": { + "type": "string", + "default": "" + } + }, + { + "name": "editorUiAlias", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "editorAlias", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PagedDataTypeItemResponseModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/PagedDataTypeItemResponseModel" + } + }, + "text/plain": { + "schema": { + "$ref": "#/components/schemas/PagedDataTypeItemResponseModel" + } + } + } + }, + "401": { + "description": "The resource is protected and requires an authentication token" + } + }, + "security": [ + { + "Backoffice User": [ ] + } + ] + } + }, "/umbraco/management/api/v1/item/data-type": { "get": { "tags": [ @@ -1738,66 +1818,6 @@ ] } }, - "/umbraco/management/api/v1/item/data-type/{alias}": { - "get": { - "tags": [ - "Data Type" - ], - "operationId": "GetItemDataTypeByAlias", - "parameters": [ - { - "name": "alias", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/DataTypeItemResponseModel" - } - ] - } - }, - "text/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/DataTypeItemResponseModel" - } - ] - } - }, - "text/plain": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/DataTypeItemResponseModel" - } - ] - } - } - } - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - } - }, "/umbraco/management/api/v1/tree/data-type/children": { "get": { "tags": [ @@ -15307,6 +15327,174 @@ } }, "/umbraco/management/api/v1/member-group/{id}": { + "get": { + "tags": [ + "Member Group" + ], + "operationId": "GetMemberGroupById", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/MemberGroupResponseModel" + } + ] + } + }, + "text/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/MemberGroupResponseModel" + } + ] + } + }, + "text/plain": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/MemberGroupResponseModel" + } + ] + } + } + } + }, + "404": { + "description": "Not Found" + }, + "401": { + "description": "The resource is protected and requires an authentication token" + } + }, + "security": [ + { + "Backoffice User": [ ] + } + ] + }, + "delete": { + "tags": [ + "Member Group" + ], + "operationId": "DeleteMemberGroupById", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "400": { + "description": "Bad Request", + "headers": { + "Umb-Notifications": { + "description": "The list of notifications produced during the request.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationHeaderModel" + }, + "nullable": true + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "404": { + "description": "Not Found", + "headers": { + "Umb-Notifications": { + "description": "The list of notifications produced during the request.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationHeaderModel" + }, + "nullable": true + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "200": { + "description": "Success", + "headers": { + "Umb-Notifications": { + "description": "The list of notifications produced during the request.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationHeaderModel" + }, + "nullable": true + } + } + } + }, + "401": { + "description": "The resource is protected and requires an authentication token" + } + }, + "security": [ + { + "Backoffice User": [ ] + } + ] + }, "put": { "tags": [ "Member Group" @@ -15474,114 +15662,6 @@ ] } }, - "/umbraco/management/api/v1/member-group/{key}": { - "delete": { - "tags": [ - "Member Group" - ], - "operationId": "DeleteMemberGroupByKey", - "parameters": [ - { - "name": "key", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "responses": { - "400": { - "description": "Bad Request", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "404": { - "description": "Not Found", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/json": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - }, - "text/plain": { - "schema": { - "$ref": "#/components/schemas/ProblemDetails" - } - } - } - }, - "200": { - "description": "Success", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - } - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - } - }, "/umbraco/management/api/v1/tree/member-group/root": { "get": { "tags": [ @@ -32822,7 +32902,7 @@ "format": "uuid", "nullable": true }, - "folder": { + "parent": { "oneOf": [ { "$ref": "#/components/schemas/ReferenceByIdModel" @@ -32908,7 +32988,7 @@ "format": "uuid", "nullable": true }, - "folder": { + "parent": { "oneOf": [ { "$ref": "#/components/schemas/ReferenceByIdModel" @@ -33836,14 +33916,6 @@ "type": "string", "format": "uuid" }, - "parent": { - "oneOf": [ - { - "$ref": "#/components/schemas/ReferenceByIdModel" - } - ], - "nullable": true - }, "isDeletable": { "type": "boolean" }, @@ -34216,6 +34288,7 @@ "DocumentConfigurationResponseModel": { "required": [ "allowEditInvariantFromNonDefault", + "allowNonExistingSegmentsCreation", "disableDeleteWhenReferenced", "disableUnpublishWhenReferenced", "sanitizeTinyMce" @@ -34233,6 +34306,9 @@ }, "allowEditInvariantFromNonDefault": { "type": "boolean" + }, + "allowNonExistingSegmentsCreation": { + "type": "boolean" } }, "additionalProperties": false @@ -34506,7 +34582,8 @@ "DocumentTypeConfigurationResponseModel": { "required": [ "dataTypesCanBeChanged", - "disableTemplates" + "disableTemplates", + "useSegments" ], "type": "object", "properties": { @@ -34515,6 +34592,9 @@ }, "disableTemplates": { "type": "boolean" + }, + "useSegments": { + "type": "boolean" } }, "additionalProperties": false @@ -35244,14 +35324,6 @@ "id": { "type": "string", "format": "uuid" - }, - "parent": { - "oneOf": [ - { - "$ref": "#/components/schemas/ReferenceByIdModel" - } - ], - "nullable": true } }, "additionalProperties": false @@ -37090,6 +37162,30 @@ }, "additionalProperties": false }, + "PagedDataTypeItemResponseModel": { + "required": [ + "items", + "total" + ], + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int64" + }, + "items": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/DataTypeItemResponseModel" + } + ] + } + } + }, + "additionalProperties": false + }, "PagedDataTypeTreeItemResponseModel": { "required": [ "items", @@ -41113,4 +41209,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Cms.Api.Management/Security/Authorization/AuthorizationServiceExtensions.cs b/src/Umbraco.Cms.Api.Management/Security/Authorization/AuthorizationServiceExtensions.cs index 4011bf4234..bfb370d332 100644 --- a/src/Umbraco.Cms.Api.Management/Security/Authorization/AuthorizationServiceExtensions.cs +++ b/src/Umbraco.Cms.Api.Management/Security/Authorization/AuthorizationServiceExtensions.cs @@ -1,6 +1,5 @@ using System.Security.Claims; using Microsoft.AspNetCore.Authorization; -using Umbraco.Cms.Api.Management.Security.Authorization; using Umbraco.Cms.Core.Security.Authorization; namespace Umbraco.Extensions; @@ -8,5 +7,5 @@ namespace Umbraco.Extensions; public static class AuthorizationServiceExtensions { public static Task AuthorizeResourceAsync(this IAuthorizationService authorizationService, ClaimsPrincipal user, IPermissionResource resource, string policyName) - => authorizationService.AuthorizeAsync(user, resource, $"New{policyName}"); + => authorizationService.AuthorizeAsync(user, resource, policyName); } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/CreateContentTypeInFolderRequestModelBase.cs b/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/CreateContentTypeWithParentRequestModelBase.cs similarity index 62% rename from src/Umbraco.Cms.Api.Management/ViewModels/ContentType/CreateContentTypeInFolderRequestModelBase.cs rename to src/Umbraco.Cms.Api.Management/ViewModels/ContentType/CreateContentTypeWithParentRequestModelBase.cs index 0ebc930038..d1dedd8cbd 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/CreateContentTypeInFolderRequestModelBase.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/CreateContentTypeWithParentRequestModelBase.cs @@ -1,9 +1,9 @@ namespace Umbraco.Cms.Api.Management.ViewModels.ContentType; -public abstract class CreateContentTypeInFolderRequestModelBase +public abstract class CreateContentTypeWithParentRequestModelBase : CreateContentTypeRequestModelBase where TPropertyType : PropertyTypeModelBase where TPropertyTypeContainer : PropertyTypeContainerModelBase { - public ReferenceByIdModel? Folder { get; set; } + public ReferenceByIdModel? Parent { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/DataType/DataTypeResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/DataType/DataTypeResponseModel.cs index 0cf51ab1a6..209f8f368a 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/DataType/DataTypeResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/DataType/DataTypeResponseModel.cs @@ -4,8 +4,6 @@ public class DataTypeResponseModel : DataTypeModelBase { public Guid Id { get; set; } - public ReferenceByIdModel? Parent { get; set; } - public bool IsDeletable { get; set; } public bool CanIgnoreStartNodes { get; set; } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs index e6bd12e476..626a294eb3 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentConfigurationResponseModel.cs @@ -9,4 +9,6 @@ public class DocumentConfigurationResponseModel public required bool DisableUnpublishWhenReferenced { get; set; } public required bool AllowEditInvariantFromNonDefault { get; set; } + + public required bool AllowNonExistingSegmentsCreation { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/CreateDocumentTypeRequestModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/CreateDocumentTypeRequestModel.cs index 6bd3fc34c8..8b450b15a6 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/CreateDocumentTypeRequestModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/CreateDocumentTypeRequestModel.cs @@ -5,7 +5,7 @@ namespace Umbraco.Cms.Api.Management.ViewModels.DocumentType; [ShortGenericSchemaName("CreateContentTypeForDocumentTypeRequestModel")] public class CreateDocumentTypeRequestModel - : CreateContentTypeInFolderRequestModelBase + : CreateContentTypeWithParentRequestModelBase { public IEnumerable AllowedTemplates { get; set; } = Enumerable.Empty(); diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs index d4cd9e1c49..c575cc7bc1 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/DocumentType/DocumentTypeConfigurationResponseModel.cs @@ -7,4 +7,6 @@ public class DocumentTypeConfigurationResponseModel public required DataTypeChangeMode DataTypesCanBeChanged { get; set; } public required bool DisableTemplates { get; set; } + + public required bool UseSegments { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Folder/FolderResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Folder/FolderResponseModel.cs index 217251ca6c..c645c7feb3 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Folder/FolderResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Folder/FolderResponseModel.cs @@ -3,6 +3,4 @@ public class FolderResponseModel : FolderModelBase { public Guid Id { get; set; } - - public ReferenceByIdModel? Parent { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/CreateMediaTypeRequestModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/CreateMediaTypeRequestModel.cs index 24abc8be9b..cae2e515d0 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/CreateMediaTypeRequestModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/MediaType/CreateMediaTypeRequestModel.cs @@ -5,7 +5,7 @@ namespace Umbraco.Cms.Api.Management.ViewModels.MediaType; [ShortGenericSchemaName("CreateContentTypeForMediaTypeRequestModel")] public class CreateMediaTypeRequestModel - : CreateContentTypeInFolderRequestModelBase + : CreateContentTypeWithParentRequestModelBase { public IEnumerable AllowedMediaTypes { get; set; } = Enumerable.Empty(); diff --git a/src/Umbraco.Core/Cache/Refreshers/Implement/MemberCacheRefresher.cs b/src/Umbraco.Core/Cache/Refreshers/Implement/MemberCacheRefresher.cs index ac9dac5a09..18809a6bbe 100644 --- a/src/Umbraco.Core/Cache/Refreshers/Implement/MemberCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/Refreshers/Implement/MemberCacheRefresher.cs @@ -1,5 +1,3 @@ -// using Newtonsoft.Json; - using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Notifications; diff --git a/src/Umbraco.Core/Configuration/Models/SegmentSettings.cs b/src/Umbraco.Core/Configuration/Models/SegmentSettings.cs new file mode 100644 index 0000000000..e6fc90995a --- /dev/null +++ b/src/Umbraco.Core/Configuration/Models/SegmentSettings.cs @@ -0,0 +1,23 @@ +using System.ComponentModel; + +namespace Umbraco.Cms.Core.Configuration.Models; + +/// +/// Typed configuration options for segment settings. +/// +public class SegmentSettings +{ + private const bool StaticEnabled = false; + private const bool StaticAllowCreation = true; + + /// + /// Gets or sets a value indicating whether the usage of segments is enabled. + /// + [DefaultValue(StaticEnabled)] + public bool Enabled { get; set; } = StaticEnabled; + + /// + /// Gets or sets a value indicating whether the creation of non-existing segments is allowed. + /// + public bool AllowCreation { get; set; } = StaticAllowCreation; +} diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs index a3e2dbc4c5..d25a34e166 100644 --- a/src/Umbraco.Core/Constants-DataTypes.cs +++ b/src/Umbraco.Core/Constants-DataTypes.cs @@ -54,16 +54,6 @@ public static partial class Constants /// public const string MemberPicker = "1EA2E01F-EBD8-4CE1-8D71-6B1149E63548"; - /// - /// Guid for Media Picker as string - /// - public const string MediaPicker = "135D60E0-64D9-49ED-AB08-893C9BA44AE5"; - - /// - /// Guid for Multiple Media Picker as string - /// - public const string MultipleMediaPicker = "9DBBCBBB-2327-434A-B355-AF1B84E5010A"; - /// /// Guid for Media Picker v3 as string /// @@ -244,16 +234,6 @@ public static partial class Constants /// public static readonly Guid MemberPickerGuid = new(MemberPicker); - /// - /// Guid for Media Picker - /// - public static readonly Guid MediaPickerGuid = new(MediaPicker); - - /// - /// Guid for Multiple Media Picker - /// - public static readonly Guid MultipleMediaPickerGuid = new(MultipleMediaPicker); - /// /// Guid for Media Picker v3 /// diff --git a/src/Umbraco.Core/Models/DataTypeExtensions.cs b/src/Umbraco.Core/Models/DataTypeExtensions.cs index 5dd314f241..568dede982 100644 --- a/src/Umbraco.Core/Models/DataTypeExtensions.cs +++ b/src/Umbraco.Core/Models/DataTypeExtensions.cs @@ -12,8 +12,6 @@ public static class DataTypeExtensions { Constants.DataTypes.Guids.ContentPickerGuid, Constants.DataTypes.Guids.MemberPickerGuid, - Constants.DataTypes.Guids.MediaPickerGuid, - Constants.DataTypes.Guids.MultipleMediaPickerGuid, Constants.DataTypes.Guids.RelatedLinksGuid, Constants.DataTypes.Guids.MemberGuid, Constants.DataTypes.Guids.ImageCropperGuid, diff --git a/src/Umbraco.Core/Persistence/Repositories/IDataTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IDataTypeRepository.cs index 3a8a120bcd..ad113533d8 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IDataTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IDataTypeRepository.cs @@ -5,7 +5,7 @@ namespace Umbraco.Cms.Core.Persistence.Repositories; public interface IDataTypeRepository : IReadWriteQueryRepository { - + IDataType? Get(Guid key); IEnumerable> Move(IDataType toMove, EntityContainer? container); diff --git a/src/Umbraco.Core/Services/ContentEditingService.cs b/src/Umbraco.Core/Services/ContentEditingService.cs index 755e0994d6..2ad8365bcf 100644 --- a/src/Umbraco.Core/Services/ContentEditingService.cs +++ b/src/Umbraco.Core/Services/ContentEditingService.cs @@ -40,15 +40,20 @@ internal sealed class ContentEditingService { IContent? content = ContentService.GetById(key); return content is not null - ? await ValidatePropertiesAsync(updateModel, content.ContentType.Key) + ? await ValidateCulturesAndPropertiesAsync(updateModel, content.ContentType.Key) : Attempt.FailWithStatus(ContentEditingOperationStatus.NotFound, new ContentValidationResult()); } public async Task> ValidateCreateAsync(ContentCreateModel createModel) - => await ValidatePropertiesAsync(createModel, createModel.ContentTypeKey); + => await ValidateCulturesAndPropertiesAsync(createModel, createModel.ContentTypeKey); public async Task> CreateAsync(ContentCreateModel createModel, Guid userKey) { + if (await ValidateCulturesAsync(createModel) is false) + { + return Attempt.FailWithStatus(ContentEditingOperationStatus.InvalidCulture, new ContentCreateResult()); + } + Attempt result = await MapCreate(createModel); if (result.Success == false) { @@ -81,6 +86,11 @@ internal sealed class ContentEditingService return Attempt.FailWithStatus(ContentEditingOperationStatus.NotFound, new ContentUpdateResult()); } + if (await ValidateCulturesAsync(updateModel) is false) + { + return Attempt.FailWithStatus(ContentEditingOperationStatus.InvalidCulture, new ContentUpdateResult { Content = content }); + } + Attempt result = await MapUpdate(content, updateModel); if (result.Success == false) { @@ -125,6 +135,13 @@ internal sealed class ContentEditingService public async Task SortAsync(Guid? parentKey, IEnumerable sortingModels, Guid userKey) => await HandleSortAsync(parentKey, sortingModels, userKey); + private async Task> ValidateCulturesAndPropertiesAsync( + ContentEditingModelBase contentEditingModelBase, + Guid contentTypeKey) + => await ValidateCulturesAsync(contentEditingModelBase) is false + ? Attempt.FailWithStatus(ContentEditingOperationStatus.InvalidCulture, new ContentValidationResult()) + : await ValidatePropertiesAsync(contentEditingModelBase, contentTypeKey); + private async Task UpdateTemplateAsync(IContent content, Guid? templateKey) { if (templateKey == null) diff --git a/src/Umbraco.Core/Services/ContentEditingServiceBase.cs b/src/Umbraco.Core/Services/ContentEditingServiceBase.cs index cbb8ddbc89..4d441ac569 100644 --- a/src/Umbraco.Core/Services/ContentEditingServiceBase.cs +++ b/src/Umbraco.Core/Services/ContentEditingServiceBase.cs @@ -108,6 +108,9 @@ internal abstract class ContentEditingServiceBase ValidateCulturesAsync(ContentEditingModelBase contentEditingModelBase) + => await _validationService.ValidateCulturesAsync(contentEditingModelBase); + protected async Task> ValidatePropertiesAsync( ContentEditingModelBase contentEditingModelBase, Guid contentTypeKey) diff --git a/src/Umbraco.Core/Services/ContentPublishingService.cs b/src/Umbraco.Core/Services/ContentPublishingService.cs index 5792d0b6c9..61592ee021 100644 --- a/src/Umbraco.Core/Services/ContentPublishingService.cs +++ b/src/Umbraco.Core/Services/ContentPublishingService.cs @@ -61,7 +61,7 @@ internal sealed class ContentPublishingService : IContentPublishingService } var validCultures = (await _languageService.GetAllAsync()).Select(x => x.IsoCode); - if (cultures.Any(x => x == "*") || cultures.All(x=> validCultures.Contains(x, StringComparer.InvariantCultureIgnoreCase) is false)) + if (cultures.Any(x => x == "*") || cultures.All(x=> validCultures.Contains(x) is false)) { scope.Complete(); return Attempt.FailWithStatus(ContentPublishingOperationStatus.InvalidCulture, new ContentPublishingResult()); @@ -277,7 +277,7 @@ internal sealed class ContentPublishingService : IContentPublishingService foreach (var culture in cultures) { - if (validCultures.Contains(culture, StringComparer.InvariantCultureIgnoreCase) is false) + if (validCultures.Contains(culture) is false) { scope.Complete(); return Attempt.Fail(ContentPublishingOperationStatus.InvalidCulture); diff --git a/src/Umbraco.Core/Services/ContentValidationServiceBase.cs b/src/Umbraco.Core/Services/ContentValidationServiceBase.cs index 09c4649a33..b4cc9f2e51 100644 --- a/src/Umbraco.Core/Services/ContentValidationServiceBase.cs +++ b/src/Umbraco.Core/Services/ContentValidationServiceBase.cs @@ -43,7 +43,7 @@ internal abstract class ContentValidationServiceBase return new ContentValidationResult { ValidationErrors = validationErrors }; } - var cultures = (await _languageService.GetAllAsync()).Select(language => language.IsoCode).ToArray(); + var cultures = await GetCultureCodes(); // we don't have any managed segments, so we have to make do with the ones passed in the model var segments = contentEditingModelBase.Variants.DistinctBy(variant => variant.Segment).Select(variant => variant.Segment).ToArray(); @@ -59,7 +59,20 @@ internal abstract class ContentValidationServiceBase } return new ContentValidationResult { ValidationErrors = validationErrors }; - } + } + + public async Task ValidateCulturesAsync(ContentEditingModelBase contentEditingModelBase) + { + var cultures = await GetCultureCodes(); + var invalidCultures = contentEditingModelBase + .Variants + .Select(variant => variant.Culture) + .WhereNotNull().Except(cultures).ToArray(); + + return invalidCultures.IsCollectionEmpty(); + } + + private async Task GetCultureCodes() => (await _languageService.GetAllAsync()).Select(language => language.IsoCode).ToArray(); private IEnumerable ValidateProperty(ContentEditingModelBase contentEditingModelBase, IPropertyType propertyType, string? culture, string? segment) { diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index 45b3f362dc..83a9f033d1 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Umbraco.Cms.Core.DependencyInjection; @@ -13,6 +14,7 @@ using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Services.OperationStatus; using Umbraco.Extensions; +using DataType = Umbraco.Cms.Core.Models.DataType; namespace Umbraco.Cms.Core.Services.Implement { @@ -246,6 +248,35 @@ namespace Umbraco.Cms.Core.Services.Implement return Task.FromResult>(dataTypes); } + /// + public Task> FilterAsync(string? name = null, string? editorUiAlias = null, string? editorAlias = null, int skip = 0, int take = 100) + { + IEnumerable query = GetAll(); + + if (name is not null) + { + query = query.Where(datatype => datatype.Name?.InvariantContains(name) ?? false); + } + + if (editorUiAlias != null) + { + query = query.Where(datatype => datatype.EditorUiAlias?.InvariantContains(editorUiAlias) ?? false); + } + + if (editorAlias != null) + { + query = query.Where(datatype => datatype.EditorAlias.InvariantContains(editorAlias)); + } + + IDataType[] result = query.ToArray(); + + return Task.FromResult(new PagedModel + { + Total = result.Length, + Items = result.Skip(skip).Take(take), + }); + } + /// /// Gets a by its Id /// diff --git a/src/Umbraco.Core/Services/IContentValidationServiceBase.cs b/src/Umbraco.Core/Services/IContentValidationServiceBase.cs index 0ce4f77b16..4218881766 100644 --- a/src/Umbraco.Core/Services/IContentValidationServiceBase.cs +++ b/src/Umbraco.Core/Services/IContentValidationServiceBase.cs @@ -7,4 +7,6 @@ internal interface IContentValidationServiceBase where TContentType : IContentTypeComposition { Task ValidatePropertiesAsync(ContentEditingModelBase contentEditingModelBase, TContentType contentType); + + Task ValidateCulturesAsync(ContentEditingModelBase contentEditingModelBase); } diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 60b5c34af0..8aefd3b93f 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -17,6 +17,7 @@ public interface IDataTypeService : IService /// [Obsolete("Please use GetReferencesAsync. Will be deleted in V15.")] IReadOnlyDictionary> GetReferences(int id); + IReadOnlyDictionary> GetListViewReferences(int id) => throw new NotImplementedException(); /// @@ -27,7 +28,8 @@ public interface IDataTypeService : IService Task>, DataTypeOperationStatus>> GetReferencesAsync(Guid id); [Obsolete("Please use IDataTypeContainerService for all data type container operations. Will be removed in V15.")] - Attempt?> CreateContainer(int parentId, Guid key, string name, int userId = Constants.Security.SuperUserId); + Attempt?> CreateContainer(int parentId, Guid key, string name, + int userId = Constants.Security.SuperUserId); [Obsolete("Please use IDataTypeContainerService for all data type container operations. Will be removed in V15.")] Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId); @@ -51,7 +53,8 @@ public interface IDataTypeService : IService Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId); [Obsolete("Please use IDataTypeContainerService for all data type container operations. Will be removed in V15.")] - Attempt?> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId); + Attempt?> RenameContainer(int id, string name, + int userId = Constants.Security.SuperUserId); /// /// Gets a by its Name @@ -108,6 +111,17 @@ public interface IDataTypeService : IService /// An attempt with the requested data types. Task> GetAllAsync(params Guid[] keys); + /// + /// Gets multiple objects by their unique keys. + /// + /// Name to filter by. + /// Editor ui alias to filter by. + /// Editor alias to filter by. + /// Number of items to skip. + /// Number of items to take. + /// An attempt with the requested data types. + Task> FilterAsync(string? name = null, string? editorUiAlias = null, string? editorAlias = null, int skip = 0, int take = 100); + /// /// Gets all objects or those with the ids passed in /// @@ -204,10 +218,12 @@ public interface IDataTypeService : IService Task> MoveAsync(IDataType toMove, Guid? containerKey, Guid userKey); [Obsolete("Please use CopyASync instead. Will be removed in V15")] - Attempt?> Copy(IDataType copying, int containerId) => Copy(copying, containerId, Constants.Security.SuperUserId); + Attempt?> Copy(IDataType copying, int containerId) => + Copy(copying, containerId, Constants.Security.SuperUserId); [Obsolete("Please use CopyASync instead. Will be removed in V15")] - Attempt?> Copy(IDataType copying, int containerId, int userId = Constants.Security.SuperUserId) => throw new NotImplementedException(); + Attempt?> Copy(IDataType copying, int containerId, + int userId = Constants.Security.SuperUserId) => throw new NotImplementedException(); /// /// Copies a to a given container diff --git a/src/Umbraco.Core/Services/MediaEditingService.cs b/src/Umbraco.Core/Services/MediaEditingService.cs index 90eddcef22..f771dd3460 100644 --- a/src/Umbraco.Core/Services/MediaEditingService.cs +++ b/src/Umbraco.Core/Services/MediaEditingService.cs @@ -144,6 +144,7 @@ internal sealed class MediaEditingService // these are the only result states currently expected from Save OperationResultType.Success => ContentEditingOperationStatus.Success, OperationResultType.FailedCancelledByEvent => ContentEditingOperationStatus.CancelledByNotification, + OperationResultType.FailedDuplicateKey => ContentEditingOperationStatus.DuplicateKey, // for any other state we'll return "unknown" so we know that we need to amend this _ => ContentEditingOperationStatus.Unknown diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 63aace15d4..755b36ae82 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -756,6 +756,13 @@ namespace Umbraco.Cms.Core.Services scope.WriteLock(Constants.Locks.MediaTree); if (media.HasIdentity == false) { + if (_entityRepository.Get(media.Key, UmbracoObjectTypes.Media.GetGuid()) is not null) + { + scope.Complete(); + return Attempt.Fail( + new OperationResult(OperationResultType.FailedDuplicateKey, eventMessages)); + } + media.CreatorId = userId; } diff --git a/src/Umbraco.Core/Services/OperationResultType.cs b/src/Umbraco.Core/Services/OperationResultType.cs index c87b70c2a2..8db80fe61c 100644 --- a/src/Umbraco.Core/Services/OperationResultType.cs +++ b/src/Umbraco.Core/Services/OperationResultType.cs @@ -40,5 +40,10 @@ public enum OperationResultType : byte /// NoOperation = Failed | 6, // TODO: shouldn't it be a success? + /// + /// The operation could not complete due to duplicate key detection + /// + FailedDuplicateKey = Failed | 7 + // TODO: In the future, we might need to add more operations statuses, potentially like 'FailedByPermissions', etc... } diff --git a/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs b/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs index 76ae8a21e5..6288104af5 100644 --- a/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs +++ b/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs @@ -17,5 +17,7 @@ public enum ContentEditingOperationStatus NotInTrash, SortingInvalid, PropertyValidationError, - Unknown + InvalidCulture, + DuplicateKey, + Unknown, } diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs index 4cd7df61a0..91413064f5 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Examine.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Umbraco.Cms.Core.DeliveryApi; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; @@ -41,7 +42,9 @@ public static partial class UmbracoBuilderExtensions factory.GetRequiredService(), factory.GetRequiredService(), true, - factory.GetRequiredService())); + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService>())); builder.Services.AddUnique(factory => new ContentValueSetBuilder( factory.GetRequiredService(), @@ -50,7 +53,9 @@ public static partial class UmbracoBuilderExtensions factory.GetRequiredService(), factory.GetRequiredService(), false, - factory.GetRequiredService())); + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService>())); builder.Services.AddUnique, MediaValueSetBuilder>(); builder.Services.AddUnique, MemberValueSetBuilder>(); builder.Services.AddUnique(); diff --git a/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs b/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs index 860c6199f7..ff1df21bd1 100644 --- a/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs +++ b/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs @@ -1,14 +1,11 @@ using Examine; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; -using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Examine; @@ -52,72 +49,6 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal _logger = logger; } - [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] - public ContentValueSetBuilder( - PropertyEditorCollection propertyEditors, - UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService, - IShortStringHelper shortStringHelper, - ICoreScopeProvider scopeProvider, - bool publishedValuesOnly, - ILocalizationService localizationService, - IContentTypeService contentTypeService) - : this( - propertyEditors, - urlSegmentProviders, - userService, - shortStringHelper, - scopeProvider, - publishedValuesOnly, - localizationService, - StaticServiceProvider.Instance.GetRequiredService(), - StaticServiceProvider.Instance.GetRequiredService>()) - { - } - - [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] - public ContentValueSetBuilder( - PropertyEditorCollection propertyEditors, - UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService, - IShortStringHelper shortStringHelper, - IScopeProvider scopeProvider, - bool publishedValuesOnly, - ILocalizationService localizationService) - : this( - propertyEditors, - urlSegmentProviders, - userService, - shortStringHelper, - scopeProvider, - publishedValuesOnly, - localizationService, - StaticServiceProvider.Instance.GetRequiredService(), - StaticServiceProvider.Instance.GetRequiredService>()) - { - } - - [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] - public ContentValueSetBuilder( - PropertyEditorCollection propertyEditors, - UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService, - IShortStringHelper shortStringHelper, - IScopeProvider scopeProvider, - bool publishedValuesOnly) - : this( - propertyEditors, - urlSegmentProviders, - userService, - shortStringHelper, - scopeProvider, - publishedValuesOnly, - StaticServiceProvider.Instance.GetRequiredService(), - StaticServiceProvider.Instance.GetRequiredService(), - StaticServiceProvider.Instance.GetRequiredService>()) - { - } - /// public override IEnumerable GetValueSets(params IContent[] content) { @@ -222,7 +153,7 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal { AddPropertyValue(property, null, null, values, availableCultures, contentTypeDictionary); } - catch (JsonSerializationException ex) + catch (Exception ex) { _logger.LogError(ex, "Failed to add property '{PropertyAlias}' to index for content {ContentId}", property.Alias, c.Id); throw; @@ -236,7 +167,7 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal { AddPropertyValue(property, culture.ToLowerInvariant(), null, values, availableCultures, contentTypeDictionary); } - catch (JsonSerializationException ex) + catch (Exception ex) { _logger.LogError( ex, diff --git a/src/Umbraco.Infrastructure/Extensions/ObjectJsonExtensions.cs b/src/Umbraco.Infrastructure/Extensions/ObjectJsonExtensions.cs index 6a34ae73f0..840e55c77b 100644 --- a/src/Umbraco.Infrastructure/Extensions/ObjectJsonExtensions.cs +++ b/src/Umbraco.Infrastructure/Extensions/ObjectJsonExtensions.cs @@ -1,6 +1,6 @@ using System.Collections.Concurrent; using System.Reflection; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using Umbraco.Cms.Core; namespace Umbraco.Extensions; @@ -27,8 +27,8 @@ public static class ObjectJsonExtensions string DefaultNamer(PropertyInfo property) { - JsonPropertyAttribute? jsonProperty = property.GetCustomAttribute(); - return jsonProperty?.PropertyName ?? property.Name; + JsonPropertyNameAttribute? jsonProperty = property.GetCustomAttribute(); + return jsonProperty?.Name ?? property.Name; } Type t = obj.GetType(); diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/LogMessage.cs b/src/Umbraco.Infrastructure/Logging/Viewer/LogMessage.cs index 42ad881ea3..ee0259d9d9 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/LogMessage.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/LogMessage.cs @@ -1,5 +1,3 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using Serilog.Events; // ReSharper disable UnusedAutoPropertyAccessor.Global @@ -16,7 +14,6 @@ public class LogMessage /// /// The level of the event. /// - [JsonConverter(typeof(StringEnumConverter))] public LogEventLevel Level { get; set; } /// diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/SavedLogSearch.cs b/src/Umbraco.Infrastructure/Logging/Viewer/SavedLogSearch.cs index 5393bcd54d..6c43aafd6a 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/SavedLogSearch.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/SavedLogSearch.cs @@ -1,12 +1,8 @@ -using Newtonsoft.Json; - namespace Umbraco.Cms.Core.Logging.Viewer; public class SavedLogSearch { - [JsonProperty("name")] public required string Name { get; set; } - [JsonProperty("query")] public required string Query { get; set; } } diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/SerilogJsonLogViewer.cs b/src/Umbraco.Infrastructure/Logging/Viewer/SerilogJsonLogViewer.cs index 73d88ac8a8..3cf2768259 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/SerilogJsonLogViewer.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/SerilogJsonLogViewer.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Serilog.Events; using Serilog.Formatting.Compact.Reader; using ILogger = Serilog.ILogger; @@ -121,7 +120,7 @@ internal class SerilogJsonLogViewer : SerilogLogViewerSourceBase { return reader.TryRead(out evt); } - catch (JsonReaderException ex) + catch (Exception ex) { // As we are reading/streaming one line at a time in the JSON file // Thus we can not report the line number, as it will always be 1 diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 6cea5550d2..c2efc6d3c2 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -771,44 +771,7 @@ internal class DatabaseDataCreator }, Constants.DatabaseSchema.Tables.Node, "id"); - ConditionalInsert( - Constants.Configuration.NamedOptions.InstallDefaultData.DataTypes, - Constants.DataTypes.Guids.MediaPicker, - new NodeDto - { - NodeId = 1048, - Trashed = false, - ParentId = -1, - UserId = -1, - Level = 1, - Path = "-1,1048", - SortOrder = 2, - UniqueId = Constants.DataTypes.Guids.MediaPickerGuid, - Text = "Media Picker (legacy)", - NodeObjectType = Constants.ObjectTypes.DataType, - CreateDate = DateTime.Now, - }, - Constants.DatabaseSchema.Tables.Node, - "id"); - ConditionalInsert( - Constants.Configuration.NamedOptions.InstallDefaultData.DataTypes, - Constants.DataTypes.Guids.MultipleMediaPicker, - new NodeDto - { - NodeId = 1049, - Trashed = false, - ParentId = -1, - UserId = -1, - Level = 1, - Path = "-1,1049", - SortOrder = 2, - UniqueId = Constants.DataTypes.Guids.MultipleMediaPickerGuid, - Text = "Multiple Media Picker (legacy)", - NodeObjectType = Constants.ObjectTypes.DataType, - CreateDate = DateTime.Now, - }, - Constants.DatabaseSchema.Tables.Node, - "id"); + ConditionalInsert( Constants.Configuration.NamedOptions.InstallDefaultData.DataTypes, Constants.DataTypes.Guids.RelatedLinks, diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/MigrateDataTypeConfigurations.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/MigrateDataTypeConfigurations.cs index 9e428e5e65..f9542f7d47 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/MigrateDataTypeConfigurations.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/MigrateDataTypeConfigurations.cs @@ -86,6 +86,7 @@ public class MigrateDataTypeConfigurations : MigrationBase updated |= dataTypeDto.EditorAlias switch { PropertyEditorAliases.Boolean => HandleBoolean(ref configurationData), + PropertyEditorAliases.CheckBoxList => HandleCheckBoxList(ref configurationData), PropertyEditorAliases.ColorPicker => HandleColorPicker(ref configurationData), PropertyEditorAliases.ContentPicker => HandleContentPicker(ref configurationData), PropertyEditorAliases.DateTime => HandleDateTime(ref configurationData), @@ -126,6 +127,10 @@ public class MigrateDataTypeConfigurations : MigrationBase private bool HandleBoolean(ref Dictionary configurationData) => ReplaceIntegerStringWithBoolean(ref configurationData, "default"); + // translate "selectable items" from old "value list" format to string array + private bool HandleCheckBoxList(ref Dictionary configurationData) + => ReplaceValueListArrayWithStringArray(ref configurationData, "items"); + // translate "allowed colors" configuration from multiple old formats private bool HandleColorPicker(ref Dictionary configurationData) { diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs index 5d10e5824b..ce1b20ffef 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs @@ -1,6 +1,7 @@ using System.Data; using System.Globalization; -using System.Xml.Linq; +using System.Linq.Expressions; +using System.Reflection; using Microsoft.Extensions.Logging; using NPoco; using Umbraco.Cms.Core; @@ -11,15 +12,14 @@ using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Querying; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.PropertyEditors; -using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Cms.Infrastructure.Persistence.Factories; +using Umbraco.Cms.Infrastructure.Persistence.Mappers; using Umbraco.Cms.Infrastructure.Persistence.Querying; using Umbraco.Cms.Infrastructure.Scoping; using Umbraco.Extensions; -using static Umbraco.Cms.Core.Constants.SqlTemplates; using static Umbraco.Cms.Core.Persistence.SqlExtensionsStatics; namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; @@ -208,7 +208,6 @@ internal class DataTypeRepository : EntityRepositoryBase, IDataT return usages; } - #region Overrides of RepositoryBase protected override IDataType? PerformGet(int id) => GetMany(id).FirstOrDefault(); diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ComplexPropertyEditorContentNotificationHandler.cs b/src/Umbraco.Infrastructure/PropertyEditors/ComplexPropertyEditorContentNotificationHandler.cs index ce867d29e4..208b2a1e70 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/ComplexPropertyEditorContentNotificationHandler.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/ComplexPropertyEditorContentNotificationHandler.cs @@ -1,8 +1,6 @@ // Copyright (c) Umbraco. // See LICENSE for more details. -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Notifications; @@ -55,17 +53,13 @@ public abstract class ComplexPropertyEditorContentNotificationHandler : foreach (IPropertyValue cultureVal in propVals) { // Remove keys from published value & any nested properties - var publishedValue = cultureVal.PublishedValue is JToken jsonPublishedValue - ? jsonPublishedValue.ToString(Formatting.None) - : cultureVal.PublishedValue?.ToString(); + var publishedValue = cultureVal.PublishedValue?.ToString(); var updatedPublishedVal = FormatPropertyValue(publishedValue!, onlyMissingKeys).NullOrWhiteSpaceAsNull(); cultureVal.PublishedValue = updatedPublishedVal; // Remove keys from edited/draft value & any nested properties - var editedValue = cultureVal.EditedValue is JToken jsonEditedValue - ? jsonEditedValue.ToString(Formatting.None) - : cultureVal.EditedValue?.ToString(); + var editedValue = cultureVal.EditedValue?.ToString(); var updatedEditedVal = FormatPropertyValue(editedValue!, onlyMissingKeys).NullOrWhiteSpaceAsNull(); cultureVal.EditedValue = updatedEditedVal; } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs index e481d3d89a..b8fd53be8a 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs @@ -19,25 +19,27 @@ public class ValueListUniqueValueValidator : IValueValidator public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration) { - var stringValue = value?.ToString(); - if (stringValue.IsNullOrWhiteSpace()) + if (value is null) { yield break; } - string[]? items = null; - try + var items = value as IEnumerable; + if (items is null) { - items = _configurationEditorJsonSerializer.Deserialize(stringValue); - } - catch - { - // swallow and report error below + try + { + items = _configurationEditorJsonSerializer.Deserialize(value.ToString() ?? string.Empty); + } + catch + { + // swallow and report error below + } } if (items is null) { - yield return new ValidationResult($"The configuration value {stringValue} is not a valid value list configuration", new[] { "items" }); + yield return new ValidationResult($"The configuration value {value} is not a valid value list configuration", ["items"]); yield break; } diff --git a/src/Umbraco.Infrastructure/Services/CacheInstructionService.cs b/src/Umbraco.Infrastructure/Services/CacheInstructionService.cs index 2458705309..b708f36f14 100644 --- a/src/Umbraco.Infrastructure/Services/CacheInstructionService.cs +++ b/src/Umbraco.Infrastructure/Services/CacheInstructionService.cs @@ -1,7 +1,7 @@ +using System.Text.Json; +using System.Text.Json.Serialization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Events; @@ -189,11 +189,10 @@ namespace Umbraco.Cms => new( 0, DateTime.UtcNow, - JsonConvert.SerializeObject(instructions, new JsonSerializerSettings() + JsonSerializer.Serialize(instructions, new JsonSerializerOptions { - Formatting = Formatting.None, - DefaultValueHandling = DefaultValueHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore, + WriteIndented = false, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault, }), localIdentity, instructions.Sum(x => x.JsonIdCount)); @@ -252,13 +251,13 @@ namespace Umbraco.Cms } // Deserialize remote instructions & skip if it fails. - if (!TryDeserializeInstructions(instruction, out JArray? jsonInstructions)) + if (TryDeserializeInstructions(instruction, out JsonDocument? jsonInstructions) is false && jsonInstructions is null) { lastId = instruction.Id; // skip continue; } - List instructionBatch = GetAllInstructions(jsonInstructions); + List instructionBatch = GetAllInstructions(jsonInstructions?.RootElement); // Process as per-normal. var success = ProcessDatabaseInstructions(cacheRefreshers, instructionBatch, instruction, processed, cancellationToken, ref lastId); @@ -280,7 +279,7 @@ namespace Umbraco.Cms /// /// Attempts to deserialize the instructions to a JArray. /// - private bool TryDeserializeInstructions(CacheInstruction instruction, out JArray? jsonInstructions) + private bool TryDeserializeInstructions(CacheInstruction instruction, out JsonDocument? jsonInstructions) { if (instruction.Instructions is null) { @@ -291,10 +290,10 @@ namespace Umbraco.Cms try { - jsonInstructions = JsonConvert.DeserializeObject(instruction.Instructions); + jsonInstructions = JsonDocument.Parse(instruction.Instructions); return true; } - catch (JsonException ex) + catch (System.Text.Json.JsonException ex) { _logger.LogError(ex, "Failed to deserialize instructions ({DtoId}: '{DtoInstructions}').", instruction.Id, instruction.Instructions); jsonInstructions = null; @@ -305,7 +304,7 @@ namespace Umbraco.Cms /// /// Parses out the individual instructions to be processed. /// - private static List GetAllInstructions(IEnumerable? jsonInstructions) + private static List GetAllInstructions(JsonElement? jsonInstructions) { var result = new List(); if (jsonInstructions is null) @@ -313,13 +312,13 @@ namespace Umbraco.Cms return result; } - foreach (JToken jsonItem in jsonInstructions) + foreach (JsonElement jsonItem in jsonInstructions.Value.EnumerateArray()) { // Could be a JObject in which case we can convert to a RefreshInstruction. // Otherwise it could be another JArray - in which case we'll iterate that. - if (jsonItem is JObject jsonObj) + if (jsonItem.ValueKind is JsonValueKind.Object) { - RefreshInstruction? instruction = jsonObj.ToObject(); + RefreshInstruction? instruction = jsonItem.Deserialize(); if (instruction is not null) { result.Add(instruction); @@ -327,8 +326,7 @@ namespace Umbraco.Cms } else { - var jsonInnerArray = (JArray)jsonItem; - result.AddRange(GetAllInstructions(jsonInnerArray)); // recurse + result.AddRange(GetAllInstructions(jsonItem)); // recurse } } @@ -465,7 +463,7 @@ namespace Umbraco.Cms return; } - var ids = JsonConvert.DeserializeObject(jsonIds); + var ids = JsonSerializer.Deserialize(jsonIds); if (ids is not null) { foreach (var id in ids) diff --git a/src/Umbraco.Infrastructure/Services/ContentListViewServiceBase.cs b/src/Umbraco.Infrastructure/Services/ContentListViewServiceBase.cs index 015d5c69c0..faa83bbf4a 100644 --- a/src/Umbraco.Infrastructure/Services/ContentListViewServiceBase.cs +++ b/src/Umbraco.Infrastructure/Services/ContentListViewServiceBase.cs @@ -203,32 +203,16 @@ internal abstract class ContentListViewServiceBase GetConfiguredListViewDataTypeAsync(TContentType? contentType) { - string? listViewSuffix = null; - - // FIXME: Remove. This is a workaround to construct the custom list view name (content type - alias; media type- name) - // until we have the concrete content type + list view binding. - if (DefaultListViewKey == Constants.DataTypes.Guids.ListViewContentGuid) + // When contentType is not configured as a list view + if (contentType is not null && contentType.ListView is null) { - listViewSuffix = contentType?.Alias; - } - else if (DefaultListViewKey == Constants.DataTypes.Guids.ListViewMediaGuid) - { - listViewSuffix = contentType?.Name; + return null; } - // If we don't have a suffix (content type name or alias), we cannot look for the custom list view by name. - // So return the default one. - if (string.IsNullOrEmpty(listViewSuffix)) - { - return await _dataTypeService.GetAsync(DefaultListViewKey); - } + // When we don't have a contentType (i.e. when root), we will get the default list view + Guid configuredListViewKey = contentType?.ListView ?? DefaultListViewKey; - // FIXME: Clean up! Get the configured list view from content type once the binding task AB#37205 is done. - // This is a hack based on legacy (same thing can be seen in ListViewContentAppFactory) - we cannot infer the list view associated with a content type otherwise. - // We can use the fact that when a custom list view is removed as the content type list view configuration, the corresponding list view data type gets deleted. - var customListViewName = Constants.Conventions.DataTypes.ListViewPrefix + listViewSuffix; - - return _dataTypeService.GetDataType(customListViewName) ?? await _dataTypeService.GetAsync(DefaultListViewKey); + return await _dataTypeService.GetAsync(configuredListViewKey); } private async Task> GetAllowedListViewItemsAsync(IUser user, int contentId, string? filter, Ordering? ordering, int skip, int take) diff --git a/src/Umbraco.Infrastructure/Services/Implement/LogViewerRepository.cs b/src/Umbraco.Infrastructure/Services/Implement/LogViewerRepository.cs index 853926141e..e1aac6486a 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/LogViewerRepository.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/LogViewerRepository.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Serilog; using Serilog.Events; using Serilog.Formatting.Compact.Reader; @@ -172,7 +171,7 @@ public class LogViewerRepository : ILogViewerRepository { return reader.TryRead(out evt); } - catch (JsonReaderException ex) + catch (Exception ex) { // As we are reading/streaming one line at a time in the JSON file // Thus we can not report the line number, as it will always be 1 diff --git a/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs index 84b7f82bbe..734f6ff6d4 100644 --- a/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs @@ -54,7 +54,7 @@ public abstract class DatabaseServerMessenger : ServerMessengerBase, IDisposable IJsonSerializer jsonSerializer, LastSyncedFileManager lastSyncedFileManager, IOptionsMonitor globalSettings) - : base(distributedEnabled) + : base(distributedEnabled, jsonSerializer) { _cancellationToken = _cancellationTokenSource.Token; _mainDom = mainDom; diff --git a/src/Umbraco.Infrastructure/Sync/ServerMessengerBase.cs b/src/Umbraco.Infrastructure/Sync/ServerMessengerBase.cs index 22b25333a7..1e44a8f5bb 100644 --- a/src/Umbraco.Infrastructure/Sync/ServerMessengerBase.cs +++ b/src/Umbraco.Infrastructure/Sync/ServerMessengerBase.cs @@ -1,7 +1,9 @@ +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Infrastructure.Sync; @@ -11,12 +13,26 @@ namespace Umbraco.Cms.Infrastructure.Sync; /// public abstract class ServerMessengerBase : IServerMessenger { + private readonly IJsonSerializer _jsonSerializer; + /// /// Initializes a new instance of the class. /// /// If set to true makes distributed calls when messaging a cache refresher. + /// + public ServerMessengerBase(bool distributedEnabled, IJsonSerializer jsonSerializer) + { + DistributedEnabled = distributedEnabled; + _jsonSerializer = jsonSerializer; + } + + [Obsolete("Use constructor that takes IJsonSerializer, scheduled for removal in V16")] protected ServerMessengerBase(bool distributedEnabled) - => DistributedEnabled = distributedEnabled; + : this( + distributedEnabled, + StaticServiceProvider.Instance.GetRequiredService()) + { + } /// /// Gets or sets a value indicating whether distributed calls are made when messaging a cache refresher. @@ -377,7 +393,7 @@ public abstract class ServerMessengerBase : IServerMessenger } // deliver remote - var json = JsonConvert.SerializeObject(payload); + var json = _jsonSerializer.Serialize(payload); DeliverRemote(refresher, MessageType.RefreshByJson, null, json); } diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index f1f51237a7..a3b64b1cc5 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -23,7 +23,6 @@ - diff --git a/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs b/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs index b3cb194a11..4256f29c25 100644 --- a/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs +++ b/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs @@ -1,32 +1,22 @@ namespace Umbraco.Cms.Web.Common.Authorization; /// -/// A list of authorization policy names for use in the back office +/// A list of authorization policy names for use in the back office. /// public static class AuthorizationPolicies { public const string UmbracoFeatureEnabled = nameof(UmbracoFeatureEnabled); public const string BackOfficeAccess = nameof(BackOfficeAccess); - public const string BackOfficeAccessWithoutApproval = nameof(BackOfficeAccessWithoutApproval); - public const string UserBelongsToUserGroupInRequest = nameof(UserBelongsToUserGroupInRequest); - public const string AdminUserEditsRequireAdmin = nameof(AdminUserEditsRequireAdmin); public const string DenyLocalLoginIfConfigured = nameof(DenyLocalLoginIfConfigured); public const string RequireAdminAccess = nameof(RequireAdminAccess); + public const string UserBelongsToUserGroupInRequest = nameof(UserBelongsToUserGroupInRequest); + public const string UserPermissionByResource = nameof(UserPermissionByResource); // Content permission access public const string ContentPermissionByResource = nameof(ContentPermissionByResource); - public const string ContentPermissionEmptyRecycleBin = nameof(ContentPermissionEmptyRecycleBin); - public const string ContentPermissionAdministrationById = nameof(ContentPermissionAdministrationById); - public const string ContentPermissionPublishById = nameof(ContentPermissionPublishById); - public const string ContentPermissionRollbackById = nameof(ContentPermissionRollbackById); - public const string ContentPermissionProtectById = nameof(ContentPermissionProtectById); - public const string ContentPermissionBrowseById = nameof(ContentPermissionBrowseById); - public const string ContentPermissionDeleteById = nameof(ContentPermissionDeleteById); - public const string ContentPermissionCreateBlueprintFromId = nameof(ContentPermissionCreateBlueprintFromId); public const string MediaPermissionByResource = nameof(MediaPermissionByResource); - public const string MediaPermissionPathById = nameof(MediaPermissionPathById); // Single section access public const string SectionAccessContent = nameof(SectionAccessContent); @@ -38,19 +28,14 @@ public static class AuthorizationPolicies // Custom access based on multiple sections public const string SectionAccessContentOrMedia = nameof(SectionAccessContentOrMedia); - public const string SectionAccessForTinyMce = nameof(SectionAccessForTinyMce); public const string SectionAccessForMemberTree = nameof(SectionAccessForMemberTree); public const string SectionAccessForMediaTree = nameof(SectionAccessForMediaTree); public const string SectionAccessForContentTree = nameof(SectionAccessForContentTree); - public const string SectionAccessForDataTypeReading = nameof(SectionAccessForDataTypeReading); // Single tree access public const string TreeAccessDocuments = nameof(TreeAccessDocuments); - public const string TreeAccessUsers = nameof(TreeAccessUsers); public const string TreeAccessPartialViews = nameof(TreeAccessPartialViews); public const string TreeAccessDataTypes = nameof(TreeAccessDataTypes); - public const string TreeAccessPackages = nameof(TreeAccessPackages); - public const string TreeAccessLogs = nameof(TreeAccessLogs); public const string TreeAccessWebhooks = nameof(TreeAccessWebhooks); public const string TreeAccessTemplates = nameof(TreeAccessTemplates); public const string TreeAccessDictionary = nameof(TreeAccessDictionary); @@ -66,17 +51,8 @@ public static class AuthorizationPolicies // Custom access based on multiple trees public const string TreeAccessDocumentsOrDocumentTypes = nameof(TreeAccessDocumentsOrDocumentTypes); public const string TreeAccessMediaOrMediaTypes = nameof(TreeAccessMediaOrMediaTypes); - public const string TreeAccessMembersOrMemberTypes = nameof(TreeAccessMembersOrMemberTypes); - public const string TreeAccessAnySchemaTypes = nameof(TreeAccessAnySchemaTypes); public const string TreeAccessDictionaryOrTemplates = nameof(TreeAccessDictionaryOrTemplates); // other public const string DictionaryPermissionByResource = nameof(DictionaryPermissionByResource); - - /// - /// Defines access based on if the user has access to any tree's exposing any types of content (documents, media, - /// members) - /// or any content types (document types, media types, member types) - /// - public const string TreeAccessAnyContentOrTypes = nameof(TreeAccessAnyContentOrTypes); } diff --git a/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs index ee89a7e807..a4320b9391 100644 --- a/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs @@ -1,5 +1,4 @@ using System.Globalization; -using Newtonsoft.Json.Linq; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Media; using Umbraco.Cms.Core.Models; @@ -535,11 +534,6 @@ public static class ImageCropperTemplateCoreExtensions var mediaCrops = cropperValue as ImageCropperValue; - if (mediaCrops == null && cropperValue is JObject jobj) - { - mediaCrops = jobj.ToObject(); - } - if (mediaCrops == null && cropperValue is string imageCropperValue && string.IsNullOrEmpty(imageCropperValue) == false && imageCropperValue.DetectIsJson()) { diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index 3b32a9dbab..4fa0721a68 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -14,7 +14,6 @@ - diff --git a/src/Umbraco.Web.UI.New.Client b/src/Umbraco.Web.UI.New.Client index 84ac0b40b2..46b908c2b4 160000 --- a/src/Umbraco.Web.UI.New.Client +++ b/src/Umbraco.Web.UI.New.Client @@ -1 +1 @@ -Subproject commit 84ac0b40b2d3d47237f11326eda087977f065232 +Subproject commit 46b908c2b4ebeddcc99431a7c43053e2f2db8801 diff --git a/src/Umbraco.Web.UI.New/Views/_ViewImports.cshtml b/src/Umbraco.Web.UI.New/Views/_ViewImports.cshtml index 91d671eaa1..929938d2d1 100644 --- a/src/Umbraco.Web.UI.New/Views/_ViewImports.cshtml +++ b/src/Umbraco.Web.UI.New/Views/_ViewImports.cshtml @@ -3,6 +3,4 @@ @using Umbraco.Cms.Web.Common.Views @using Umbraco.Cms.Core.Models.PublishedContent @using Microsoft.AspNetCore.Html -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@addTagHelper *, Smidge -@inject Smidge.SmidgeHelper SmidgeHelper +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers \ No newline at end of file diff --git a/tests/Directory.Packages.props b/tests/Directory.Packages.props index 586469c2c8..0fd40d25b4 100644 --- a/tests/Directory.Packages.props +++ b/tests/Directory.Packages.props @@ -21,5 +21,6 @@ + - \ No newline at end of file + diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ApprovedColor.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ApprovedColor.spec.ts index e97f1b8e9a..54dc602a32 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ApprovedColor.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ApprovedColor.spec.ts @@ -4,7 +4,7 @@ import {expect} from "@playwright/test"; const dataTypeName = 'Approved Color'; test.describe(`${dataTypeName} tests`, () => { let dataTypeDefaultData = null; - let dataTypeData = null; + let dataTypeData = null; const colorValue = '#ffffff'; const colorLabel = 'TestColor'; @@ -16,11 +16,11 @@ test.describe(`${dataTypeName} tests`, () => { test.afterEach(async ({umbracoApi}) => { if (dataTypeDefaultData !== null) { - await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); - } + await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); + } }); - test('can include label', async ({umbracoApi, umbracoUi}) => { + test('can include label', async ({umbracoApi, umbracoUi}) => { // Arrange const expectedDataTypeValues = [ { @@ -31,7 +31,7 @@ test.describe(`${dataTypeName} tests`, () => { // Remove all existing values dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); dataTypeData.values = []; - await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); + await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); await umbracoUi.dataType.goToDataType(dataTypeName); // Act @@ -43,7 +43,8 @@ test.describe(`${dataTypeName} tests`, () => { expect(dataTypeData.values).toEqual(expectedDataTypeValues); }); - test('can add color', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can add color', async ({umbracoApi, umbracoUi}) => { // Arrange const expectedDataTypeValues = [ { @@ -59,7 +60,7 @@ test.describe(`${dataTypeName} tests`, () => { // Remove all existing values dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); dataTypeData.values = []; - await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); + await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); await umbracoUi.dataType.goToDataType(dataTypeName); // Act @@ -72,7 +73,7 @@ test.describe(`${dataTypeName} tests`, () => { }); // TODO: remove .skip when the frontend is able to display the added color. Currently the added colors are not displayed after reloading page - test.skip('can remove color', async ({umbracoApi, umbracoUi}) => { + test.skip('can remove color', async ({umbracoApi, umbracoUi}) => { // Arrange const removedDataTypeValues = [ { @@ -88,7 +89,7 @@ test.describe(`${dataTypeName} tests`, () => { // Remove all existing values and add a color to remove dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); dataTypeData.values = removedDataTypeValues; - await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); + await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); await umbracoUi.dataType.goToDataType(dataTypeName); // Act diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts index 6c31a0e699..7e4c2ed590 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts @@ -34,7 +34,7 @@ test.describe('Data Types Folder tests', () => { await umbracoApi.dataType.ensureNameNotExists(wrongDataTypeFolderName); await umbracoApi.dataType.createFolder(wrongDataTypeFolderName); expect(await umbracoApi.dataType.doesNameExist(wrongDataTypeFolderName)).toBeTruthy(); - + // Act await umbracoUi.dataType.clickRootFolderCaretButton(); await umbracoUi.dataType.clickActionsMenuForDataType(wrongDataTypeFolderName); @@ -51,7 +51,7 @@ test.describe('Data Types Folder tests', () => { // Arrange await umbracoApi.dataType.createFolder(dataTypeFolderName); expect(await umbracoApi.dataType.doesNameExist(dataTypeFolderName)).toBeTruthy(); - + // Act await umbracoUi.dataType.clickRootFolderCaretButton(); await umbracoUi.dataType.deleteDataTypeFolder(dataTypeFolderName); @@ -64,7 +64,7 @@ test.describe('Data Types Folder tests', () => { // Arrange let dataTypeFolderId = await umbracoApi.dataType.createFolder(dataTypeFolderName); expect(await umbracoApi.dataType.doesNameExist(dataTypeFolderName)).toBeTruthy(); - + // Act await umbracoUi.dataType.clickRootFolderCaretButton(); await umbracoUi.dataType.clickActionsMenuForDataType(dataTypeFolderName); @@ -76,16 +76,17 @@ test.describe('Data Types Folder tests', () => { // Assert expect(await umbracoApi.dataType.doesNameExist(dataTypeName)).toBeTruthy(); const dataTypeChildren = await umbracoApi.dataType.getChildren(dataTypeFolderId); - expect(dataTypeChildren[0].name).toBe(dataTypeName); - expect(dataTypeChildren[0].isFolder).toBeFalsy(); + expect(dataTypeChildren[0].name).toBe(dataTypeName); + expect(dataTypeChildren[0].isFolder).toBeFalsy(); }); - test('can create a folder in a folder', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can create a folder in a folder', async ({umbracoApi, umbracoUi}) => { // Arrange const childFolderName = 'Child Folder'; let dataTypeFolderId = await umbracoApi.dataType.createFolder(dataTypeFolderName); expect(await umbracoApi.dataType.doesNameExist(dataTypeFolderName)).toBeTruthy(); - + // Act await umbracoUi.dataType.clickRootFolderCaretButton(); await umbracoUi.dataType.clickActionsMenuForDataType(dataTypeFolderName); @@ -97,17 +98,18 @@ test.describe('Data Types Folder tests', () => { // Assert expect(await umbracoApi.dataType.doesNameExist(childFolderName)).toBeTruthy(); const dataTypeChildren = await umbracoApi.dataType.getChildren(dataTypeFolderId); - expect(dataTypeChildren[0].name).toBe(childFolderName); - expect(dataTypeChildren[0].isFolder).toBeTruthy(); + expect(dataTypeChildren[0].name).toBe(childFolderName); + expect(dataTypeChildren[0].isFolder).toBeTruthy(); }); - test('cannot delete a non-empty data type folder', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('cannot delete a non-empty data type folder', async ({umbracoApi, umbracoUi}) => { // Arrange let dataTypeFolderId = await umbracoApi.dataType.createFolder(dataTypeFolderName); expect(await umbracoApi.dataType.doesNameExist(dataTypeFolderName)).toBeTruthy(); await umbracoApi.dataType.create(dataTypeName, editorAlias, [], dataTypeFolderId); expect(await umbracoApi.dataType.doesNameExist(dataTypeName)).toBeTruthy(); - + // Act await umbracoUi.dataType.clickRootFolderCaretButton(); await umbracoUi.dataType.deleteDataTypeFolder(dataTypeFolderName); @@ -117,8 +119,8 @@ test.describe('Data Types Folder tests', () => { expect(await umbracoApi.dataType.doesNameExist(dataTypeName)).toBeTruthy(); expect(await umbracoApi.dataType.doesNameExist(dataTypeFolderName)).toBeTruthy(); const dataTypeChildren = await umbracoApi.dataType.getChildren(dataTypeFolderId); - expect(dataTypeChildren[0].name).toBe(dataTypeName); - expect(dataTypeChildren[0].isFolder).toBeFalsy(); + expect(dataTypeChildren[0].name).toBe(dataTypeName); + expect(dataTypeChildren[0].isFolder).toBeFalsy(); }); test.skip('can move a data type to a data type folder', async ({}) => { diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ImageCropper.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ImageCropper.spec.ts index 130f418234..12fb60e1be 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ImageCropper.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/ImageCropper.spec.ts @@ -14,11 +14,12 @@ test.describe(`${dataTypeName} tests`, () => { test.afterEach(async ({umbracoApi}) => { if (dataTypeDefaultData !== null) { - await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); - } + await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); + } }); - test('can add crop', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can add crop', async ({umbracoApi, umbracoUi}) => { // Arrange const cropData = ['Test Alias', 100, 50]; const expectedDataTypeValues = [{ @@ -52,7 +53,8 @@ test.describe(`${dataTypeName} tests`, () => { expect(dataTypeData.values).toEqual(expectedDataTypeValues); }); - test('can edit crop', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can edit crop', async ({umbracoApi, umbracoUi}) => { // Arrange const wrongCropData = ['Wrong Alias', 50, 100]; const wrongDataTypeValues = [{ diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Radiobox.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Radiobox.spec.ts index e9129cb414..d2afbb700f 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Radiobox.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Radiobox.spec.ts @@ -3,7 +3,7 @@ import {expect} from "@playwright/test"; const dataTypeName = 'Radiobox'; test.describe(`${dataTypeName} tests`, () => { - let dataTypeDefaultData = null; + let dataTypeDefaultData = null; let dataTypeData = null; test.beforeEach(async ({umbracoUi, umbracoApi}) => { @@ -14,11 +14,12 @@ test.describe(`${dataTypeName} tests`, () => { test.afterEach(async ({umbracoApi}) => { if (dataTypeDefaultData !== null) { - await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); - } + await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); + } }); - test('can add option', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can add option', async ({umbracoApi, umbracoUi}) => { // Arrange const optionName = 'Test option'; const expectedDataTypeValues = [{ @@ -32,7 +33,7 @@ test.describe(`${dataTypeName} tests`, () => { // Remove all existing options dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); dataTypeData.values = []; - await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); + await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); await umbracoUi.dataType.goToDataType(dataTypeName); // Act @@ -45,7 +46,8 @@ test.describe(`${dataTypeName} tests`, () => { expect(dataTypeData.values).toEqual(expectedDataTypeValues); }); - test('can remove option', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can remove option', async ({umbracoApi, umbracoUi}) => { // Arrange const removedOptionName = 'Removed Option'; const removedOptionValues = [{ @@ -59,7 +61,7 @@ test.describe(`${dataTypeName} tests`, () => { // Remove all existing options and add an option to remove dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); dataTypeData.values = removedOptionValues; - await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); + await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); await umbracoUi.dataType.goToDataType(dataTypeName); // Act diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Upload.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Upload.spec.ts index 2b7821abe6..152b019cef 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Upload.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Upload.spec.ts @@ -19,7 +19,8 @@ for (const uploadType of uploadTypes) { } }); - test("can add accepted file extension", async ({ umbracoApi, umbracoUi }) => { + //TODO: Remove skip when the frontend is ready + test.skip("can add accepted file extension", async ({ umbracoApi, umbracoUi }) => { // Arrange const fileExtensionValue = 'zip'; const expectedDataTypeValues = [ @@ -48,7 +49,8 @@ for (const uploadType of uploadTypes) { expect(dataTypeData.values).toEqual(expectedDataTypeValues); }); - test("can remove accepted file extension", async ({ umbracoApi, umbracoUi }) => { + //TODO: Remove skip when the frontend is ready + test.skip("can remove accepted file extension", async ({ umbracoApi, umbracoUi }) => { // Arrange const removedFileExtensionValue = "bat"; const removedFileExtensionsValues = [ diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/CreatedPackages.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/CreatedPackages.spec.ts index a14bfc64d6..2a9f0034ee 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/CreatedPackages.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/CreatedPackages.spec.ts @@ -355,7 +355,8 @@ test.describe('Created packages tests', () => { }); // Currently you are not able to download a package - test('can download a package', async ({umbracoApi, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can download a package', async ({umbracoApi, umbracoUi}) => { // Arrange const packageId = await umbracoApi.package.createEmptyPackage(packageName); await umbracoUi.reloadPage(); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/InstalledPackages.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/InstalledPackages.spec.ts index 8e5d455a89..835932b39f 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/InstalledPackages.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Packages/InstalledPackages.spec.ts @@ -2,7 +2,8 @@ import {ConstantHelper, test} from '@umbraco/playwright-testhelpers'; test.describe('Installed packages tests', () => { // We can't install any packages so we do not have any installed. - test('can see no package have been installed', async ({page, umbracoUi}) => { + //TODO: Remove skip when the frontend is ready + test.skip('can see no package have been installed', async ({page, umbracoUi}) => { // Arrange await umbracoUi.goToBackOffice(); await umbracoUi.package.goToSection(ConstantHelper.sections.packages); diff --git a/tests/Umbraco.Tests.Benchmarks/JsonSerializerSettingsBenchmarks.cs b/tests/Umbraco.Tests.Benchmarks/JsonSerializerSettingsBenchmarks.cs deleted file mode 100644 index 390bb31b61..0000000000 --- a/tests/Umbraco.Tests.Benchmarks/JsonSerializerSettingsBenchmarks.cs +++ /dev/null @@ -1,60 +0,0 @@ -using BenchmarkDotNet.Attributes; -using Newtonsoft.Json; -using Umbraco.Tests.Benchmarks.Config; - -namespace Umbraco.Tests.Benchmarks; - -[QuickRunConfig] -[MemoryDiagnoser] -public class JsonSerializerSettingsBenchmarks -{ - [Benchmark] - public void SerializerSettingsInstantiation() - { - var instances = 1000; - for (var i = 0; i < instances; i++) - { - new JsonSerializerSettings(); - } - } - - [Benchmark(Baseline = true)] - public void SerializerSettingsSingleInstantiation() => new JsonSerializerSettings(); - - // // * Summary * - - // BenchmarkDotNet=v0.11.3, OS=Windows 10.0.18362 - //Intel Core i5-8265U CPU 1.60GHz(Kaby Lake R), 1 CPU, 8 logical and 4 physical cores - // [Host] : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.8.4250.0 - // Job-JIATTD : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.8.4250.0 - - //IterationCount=3 IterationTime=100.0000 ms LaunchCount = 1 - //WarmupCount=3 - - // Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op | - //-------------------------------------- |-------------:|-------------:|------------:|-------:|--------:|------------:|------------:|------------:|--------------------:| - // SerializerSettingsInstantiation | 29,120.48 ns | 5,532.424 ns | 303.2508 ns | 997.84 | 23.66 | 73.8122 | - | - | 232346 B | - // SerializerSettingsSingleInstantiation | 29.19 ns | 8.089 ns | 0.4434 ns | 1.00 | 0.00 | 0.0738 | - | - | 232 B | - - //// * Warnings * - //MinIterationTime - // JsonSerializerSettingsBenchmarks.SerializerSettingsSingleInstantiation: IterationCount= 3, IterationTime= 100.0000 ms, LaunchCount= 1, WarmupCount= 3->MinIterationTime = 96.2493 ms which is very small. It's recommended to increase it. - - //// * Legends * - // Mean : Arithmetic mean of all measurements - // Error : Half of 99.9% confidence interval - // StdDev : Standard deviation of all measurements - // Ratio : Mean of the ratio distribution ([Current]/[Baseline]) - // RatioSD : Standard deviation of the ratio distribution([Current]/[Baseline]) - // Gen 0/1k Op : GC Generation 0 collects per 1k Operations - // Gen 1/1k Op : GC Generation 1 collects per 1k Operations - // Gen 2/1k Op : GC Generation 2 collects per 1k Operations - // Allocated Memory/Op : Allocated memory per single operation(managed only, inclusive, 1KB = 1024B) - // 1 ns : 1 Nanosecond(0.000000001 sec) - - //// * Diagnostic Output - MemoryDiagnoser * - - - // // ***** BenchmarkRunner: End ***** - // Run time: 00:00:04 (4.88 sec), executed benchmarks: 2 -} diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj index bf0dc9ddc1..cd801dc4ce 100644 --- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj +++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj @@ -13,6 +13,7 @@ + diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs index e62e1ebecf..0c09bf14e8 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs @@ -16,6 +16,7 @@ using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; using Umbraco.Cms.Infrastructure.PublishedCache; using Umbraco.Cms.Infrastructure.Scoping; +using Umbraco.Cms.Infrastructure.Serialization; using Umbraco.Cms.Infrastructure.Sync; using Umbraco.Cms.Tests.Common.Testing; using Umbraco.Cms.Tests.Integration.Testing; @@ -328,7 +329,7 @@ public class ScopedRepositoryTests : UmbracoIntegrationTest public class LocalServerMessenger : ServerMessengerBase { public LocalServerMessenger() - : base(false) + : base(false, new SystemTextJsonSerializer()) { } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Create.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Create.cs index b7d4468470..aeff75baff 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Create.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Create.cs @@ -554,6 +554,47 @@ public partial class ContentEditingServiceTests Assert.IsNull(result.Result.Content); } + [Test] + public async Task Cannot_Create_Culture_Variant_With_Incorrect_Culture_Casing() + { + var contentType = await CreateVariantContentType(); + + var createModel = new ContentCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "invariantTitle", Value = "The Invariant Title" } + }, + Variants = new[] + { + new VariantModel + { + Culture = "en-us", + Name = "The English Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The English Title" } + } + }, + new VariantModel + { + Culture = "da-dk", + Name = "The Danish Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The Danish Title" } + } + } + } + }; + + var result = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.InvalidCulture, result.Status); + } + private void AssertBodyTextEquals(string expected, IContent content) { var bodyTextValue = content.GetValue("bodyText"); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Update.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Update.cs index b560325a89..f2b966b027 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Update.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.Update.cs @@ -294,4 +294,43 @@ public partial class ContentEditingServiceTests Assert.AreEqual("The initial English title", content.GetValue("variantTitle", "en-US")); Assert.AreEqual("The initial Danish title", content.GetValue("variantTitle", "da-DK")); } + + [Test] + public async Task Cannot_Update_Variant_With_Incorrect_Culture_Casing() + { + var content = await CreateVariantContent(); + + var updateModel = new ContentUpdateModel + { + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "invariantTitle", Value = "The updated invariant title" } + }, + Variants = new [] + { + new VariantModel + { + Culture = "en-us", + Name = "Updated English Name", + Properties = new [] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The updated English title" } + } + }, + new VariantModel + { + Culture = "da-dk", + Name = "Updated Danish Name", + Properties = new [] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The updated Danish title" } + } + } + } + }; + + var result = await ContentEditingService.UpdateAsync(content.Key, updateModel, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.InvalidCulture, result.Status); + } } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs index ad77f68b10..0c843cd5d6 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs @@ -13,6 +13,7 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Sync; using Umbraco.Cms.Core.Web; +using Umbraco.Cms.Infrastructure.Serialization; using Umbraco.Cms.Infrastructure.Sync; using Umbraco.Cms.Tests.Common.Attributes; using Umbraco.Cms.Tests.Common.Builders; @@ -2088,7 +2089,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services public class LocalServerMessenger : ServerMessengerBase { public LocalServerMessenger() - : base(false) + : base(false, new SystemTextJsonSerializer()) { } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Publish.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Publish.cs index ce1cffeb25..0071745809 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Publish.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Publish.cs @@ -588,6 +588,48 @@ public partial class ContentPublishingServiceTests VerifyIsPublished(Subpage3.Key); } + [TestCase("en-us")] + [TestCase("da-dk")] + public async Task Cannot_Publish_Incorrect_Culture_Code(string cultureCode) + { + var (langEn, langDa, contentType) = await SetupVariantTest(); + + IContent content = new ContentBuilder() + .WithContentType(contentType) + .WithCultureName(langEn.IsoCode, "EN root") + .WithCultureName(langDa.IsoCode, "DA root") + .Build(); + content.SetValue("title", "EN title", culture: langEn.IsoCode); + content.SetValue("title", "DA title", culture: langDa.IsoCode); + ContentService.Save(content); + + var result = await ContentPublishingService.PublishAsync(content.Key, MakeModel(new HashSet() { cultureCode }), Constants.Security.SuperUserKey); + + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentPublishingOperationStatus.InvalidCulture, result.Status); + } + + [TestCase("de-DE")] + [TestCase("es-ES")] + public async Task Cannot_Publish_Non_Existing_Culture(string cultureCode) + { + var (langEn, langDa, contentType) = await SetupVariantTest(); + + IContent content = new ContentBuilder() + .WithContentType(contentType) + .WithCultureName(langEn.IsoCode, "EN root") + .WithCultureName(langDa.IsoCode, "DA root") + .Build(); + content.SetValue("title", "EN title", culture: langEn.IsoCode); + content.SetValue("title", "DA title", culture: langDa.IsoCode); + ContentService.Save(content); + + var result = await ContentPublishingService.PublishAsync(content.Key, MakeModel(new HashSet() { cultureCode }), Constants.Security.SuperUserKey); + + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentPublishingOperationStatus.InvalidCulture, result.Status); + } + private void AssertBranchResultSuccess(ContentPublishingBranchResult result, params Guid[] expectedKeys) { var items = result.SucceededItems.ToArray(); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Unpublish.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Unpublish.cs index 4659d4e25d..ca41cb228d 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Unpublish.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Unpublish.cs @@ -271,4 +271,56 @@ public partial class ContentPublishingServiceTests Assert.AreEqual(ContentPublishingOperationStatus.Success, result.Result); VerifyIsNotPublished(Subpage.Key); } + + [TestCase("en-us")] + [TestCase("da-dk")] + public async Task Cannot_Unpublish_Incorrect_Culture_Code(string cultureCode) + { + var (langEn, langDa, contentType) = await SetupVariantTest(false); + + IContent content = new ContentBuilder() + .WithContentType(contentType) + .WithCultureName(langEn.IsoCode, "EN root") + .WithCultureName(langDa.IsoCode, "DA root") + .Build(); + content.SetValue("title", "EN title", culture: langEn.IsoCode); + content.SetValue("title", "DA title", culture: langDa.IsoCode); + ContentService.Save(content); + await ContentPublishingService.PublishAsync(content.Key, MakeModel(new HashSet() { langEn.IsoCode, langDa.IsoCode }), Constants.Security.SuperUserKey); + VerifyIsPublished(content.Key); + + var result = await ContentPublishingService.UnpublishAsync(content.Key, new HashSet() { cultureCode }, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentPublishingOperationStatus.InvalidCulture, result.Result); + VerifyIsPublished(content.Key); + + content = ContentService.GetById(content.Key)!; + Assert.AreEqual(2, content.PublishedCultures.Count()); + } + + [TestCase("de-DE")] + [TestCase("es-ES")] + public async Task Cannot_Unpublish_Non_Existing_Culture(string cultureCode) + { + var (langEn, langDa, contentType) = await SetupVariantTest(false); + + IContent content = new ContentBuilder() + .WithContentType(contentType) + .WithCultureName(langEn.IsoCode, "EN root") + .WithCultureName(langDa.IsoCode, "DA root") + .Build(); + content.SetValue("title", "EN title", culture: langEn.IsoCode); + content.SetValue("title", "DA title", culture: langDa.IsoCode); + ContentService.Save(content); + await ContentPublishingService.PublishAsync(content.Key, MakeModel(new HashSet() { langEn.IsoCode, langDa.IsoCode }), Constants.Security.SuperUserKey); + VerifyIsPublished(content.Key); + + var result = await ContentPublishingService.UnpublishAsync(content.Key, new HashSet() { cultureCode }, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentPublishingOperationStatus.InvalidCulture, result.Result); + VerifyIsPublished(content.Key); + + content = ContentService.GetById(content.Key)!; + Assert.AreEqual(2, content.PublishedCultures.Count()); + } } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentValidationServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentValidationServiceTests.cs index 76bb7c6841..45aee41cdc 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentValidationServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentValidationServiceTests.cs @@ -8,6 +8,7 @@ using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Serialization; using Umbraco.Cms.Tests.Common.Builders; +using Umbraco.Cms.Tests.Common.Builders.Extensions; using Umbraco.Cms.Tests.Common.Testing; using Umbraco.Cms.Tests.Integration.Testing; @@ -22,6 +23,8 @@ public class ContentValidationServiceTests : UmbracoIntegrationTestWithContent { private IContentValidationService ContentValidationService => GetRequiredService(); + private ILanguageService LanguageService => GetRequiredService(); + protected override void ConfigureTestServices(IServiceCollection services) { // block list requires System.Text.Json as serializer - currently we still perform fallback to Json.NET in tests @@ -290,6 +293,39 @@ public class ContentValidationServiceTests : UmbracoIntegrationTestWithContent && r.ErrorMessages.First() == "Custom regex message")); } + [TestCase("en-US", true)] + [TestCase("en-us", false)] + [TestCase("da-DK", true)] + [TestCase("da-dk", false)] + [TestCase("de-DE", false)] + [TestCase("de-de", false)] + public async Task Can_Validate_Culture_Code(string cultureCode, bool expectedResult) + { + var language = new LanguageBuilder() + .WithCultureInfo("da-DK") + .Build(); + await LanguageService.CreateAsync(language, Constants.Security.SuperUserKey); + + var result = await ContentValidationService.ValidateCulturesAsync( + new ContentCreateModel + { + Variants = new [] + { + new VariantModel + { + Culture = cultureCode, + Name = "Whatever", + Properties = new [] + { + new PropertyValueModel { Alias = "title", Value = "Something" } + } + } + } + }); + + Assert.AreEqual(expectedResult, result); + } + private async Task<(IContentType DocumentType, IContentType ElementType)> SetupBlockListTest() { var propertyEditorCollection = GetRequiredService(); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Web.Website/Security/MemberAuthorizeTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Web.Website/Security/MemberAuthorizeTests.cs index b9711bc997..35bea8bc0e 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Web.Website/Security/MemberAuthorizeTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Web.Website/Security/MemberAuthorizeTests.cs @@ -68,36 +68,35 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.Website.Security Assert.AreEqual(cookieAuthenticationOptions.Value.AccessDeniedPath.ToString(), response.Headers.Location?.AbsolutePath); } - // FIXME: Uncomment these tests when policies are renamed back to the original names without "New" - // [Test] - // [LongRunning] - // public async Task Secure_ApiController_Should_Return_Unauthorized_WhenNotLoggedIn() - // { - // _memberManagerMock.Setup(x => x.IsLoggedIn()).Returns(false); - // var url = PrepareApiControllerUrl(x => x.Secure()); - // - // var response = await Client.GetAsync(url); - // - // Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode); - // } + [Test] + [LongRunning] + public async Task Secure_ApiController_Should_Return_Unauthorized_WhenNotLoggedIn() + { + _memberManagerMock.Setup(x => x.IsLoggedIn()).Returns(false); + var url = PrepareApiControllerUrl(x => x.Secure()); - // [Test] - // [LongRunning] - // public async Task Secure_ApiController_Should_Return_Forbidden_WhenNotAuthorized() - // { - // _memberManagerMock.Setup(x => x.IsLoggedIn()).Returns(true); - // _memberManagerMock.Setup(x => x.IsMemberAuthorizedAsync( - // It.IsAny>(), - // It.IsAny>(), - // It.IsAny>())) - // .ReturnsAsync(false); - // - // var url = PrepareApiControllerUrl(x => x.Secure()); - // - // var response = await Client.GetAsync(url); - // - // Assert.AreEqual(HttpStatusCode.Forbidden, response.StatusCode); - // } + var response = await Client.GetAsync(url); + + Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Test] + [LongRunning] + public async Task Secure_ApiController_Should_Return_Forbidden_WhenNotAuthorized() + { + _memberManagerMock.Setup(x => x.IsLoggedIn()).Returns(true); + _memberManagerMock.Setup(x => x.IsMemberAuthorizedAsync( + It.IsAny>(), + It.IsAny>(), + It.IsAny>())) + .ReturnsAsync(false); + + var url = PrepareApiControllerUrl(x => x.Secure()); + + var response = await Client.GetAsync(url); + + Assert.AreEqual(HttpStatusCode.Forbidden, response.StatusCode); + } } public class TestSurfaceController : SurfaceController diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs index 07a739d6da..8192afda99 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/EnsureUniqueValuesValidatorTest.cs @@ -73,4 +73,55 @@ public class EnsureUniqueValuesValidatorTest null); Assert.AreEqual(2, result.Count()); } + + [Test] + public void Handles_Null() + { + var validator = new ValueListUniqueValueValidator(ConfigurationEditorJsonSerializer()); + var result = + validator.Validate( + null, + null, + null); + Assert.AreEqual(0, result.Count()); + } + + [Test] + public void Handles_IEnumerable_Of_String() + { + var validator = new ValueListUniqueValueValidator(ConfigurationEditorJsonSerializer()); + IEnumerable value = new[] { "one", "two", "three" }; + var result = + validator.Validate( + value, + null, + null); + Assert.AreEqual(0, result.Count()); + } + + [Test] + public void Handles_Array_Of_String() + { + var validator = new ValueListUniqueValueValidator(ConfigurationEditorJsonSerializer()); + string[] value = { "one", "two", "three" }; + var result = + validator.Validate( + value, + null, + null); + Assert.AreEqual(0, result.Count()); + } + + [Test] + public void Handles_List_Of_String() + { + var validator = new ValueListUniqueValueValidator(ConfigurationEditorJsonSerializer()); + var value = new List { "one", "two", "three" }; + var result = + validator.Validate( + value, + null, + null); + Assert.AreEqual(0, result.Count()); + } } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/ReflectionUtilitiesTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/ReflectionUtilitiesTests.cs index 342a202a29..7a2efdedac 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/ReflectionUtilitiesTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/ReflectionUtilitiesTests.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Extensions; @@ -752,7 +752,7 @@ public class ReflectionUtilitiesTests public class Class5 : Class4 { - [JsonProperty("intValue2")] + [JsonPropertyName("intValue2")] public int IntValue2 { get; set; } public string StringValue2 { get; set; } diff --git a/version.json b/version.json index 38a18bd64c..f3570ae7b7 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "14.0.0--preview008", + "version": "14.0.0-beta001", "assemblyVersion": { "precision": "build" },