diff --git a/src/Umbraco.Web.BackOffice/Authorization/AuthorizationPolicies.cs b/src/Umbraco.Web.BackOffice/Authorization/AuthorizationPolicies.cs new file mode 100644 index 0000000000..7352a43b47 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Authorization/AuthorizationPolicies.cs @@ -0,0 +1,32 @@ +namespace Umbraco.Web.BackOffice.Authorization +{ + public static class AuthorizationPolicies + { + public const string TreeAccessUsers = "TreeAccessUsers"; + public const string TreeAccessPartialViews = "TreeAccessPartialViews"; + public const string TreeAccessPartialViewMacros = "TreeAccessPartialViewMacros"; + public const string TreeAccessDataTypes = "TreeAccessDataTypes"; + public const string TreeAccessPackages = "TreeAccessPackages"; + public const string TreeAccessLogs = "TreeAccessLogs"; + public const string TreeAccessTemplates = "TreeAccessTemplates"; + public const string TreeAccessDictionary = "TreeAccessDictionary"; + public const string TreeAccessRelationTypes = "TreeAccessRelationTypes"; + public const string TreeAccessMediaTypes = "TreeAccessMediaTypes"; + public const string TreeAccessMacros = "TreeAccessMacros"; + public const string TreeAccessLanguages = "TreeAccessLanguages"; + public const string TreeAccessMemberGroups = "TreeAccessMemberGroups"; + public const string TreeAccessDocumentTypes = "TreeAccessDocumentTypes"; + public const string TreeAccessMemberTypes = "TreeAccessMemberTypes"; + public const string TreeAccessDocumentsOrDocumentTypes = "TreeAccessDocumentsAndDocumentTypes"; + public const string TreeAccessMediaOrMediaTypes = "TreeAccessMediaAndMediaTypes"; + public const string TreeAccessMembersOrMemberTypes = "TreeAccessMembersAndMemberTypes"; + public const string TreeAccessAnySchemaTypes = "TreeAccessSchemaTypes"; + public const string TreeAccessDictionaryOrTemplates = "TreeAccessDictionaryOrTemplates"; + + /// + /// 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 = "TreeAccessAnyContentOrTypes"; + } +} diff --git a/src/Umbraco.Web.BackOffice/Authorization/TreeAliasesRequirement.cs b/src/Umbraco.Web.BackOffice/Authorization/TreeAliasesRequirement.cs new file mode 100644 index 0000000000..44ecb8dfe3 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Authorization/TreeAliasesRequirement.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Authorization; +using System.Collections.Generic; + +namespace Umbraco.Web.BackOffice.Authorization +{ + + /// + /// Authorization requirements for + /// + public class TreeAliasesRequirement : IAuthorizationRequirement + { + /// + /// The aliases for trees that the user will need access to + /// + public IReadOnlyCollection TreeAliases { get; } + + public TreeAliasesRequirement(params string[] aliases) => TreeAliases = aliases; + } +} diff --git a/src/Umbraco.Web.BackOffice/Authorization/UmbracoTreeAuthorizeHandler.cs b/src/Umbraco.Web.BackOffice/Authorization/UmbracoTreeAuthorizeHandler.cs new file mode 100644 index 0000000000..b2cd18c1ce --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Authorization/UmbracoTreeAuthorizeHandler.cs @@ -0,0 +1,76 @@ +using Microsoft.AspNetCore.Authorization; +using System; +using System.Linq; +using Umbraco.Core; +using System.Threading.Tasks; +using Umbraco.Core.Security; +using Umbraco.Web.Services; + +namespace Umbraco.Web.BackOffice.Authorization +{ + /// + /// Ensures that the current user has access to the application for which the specified tree(s) belongs + /// + /// + /// This would allow a tree to be moved between sections. + /// The user only needs access to one of the trees specified, not all of the trees. + /// + public class UmbracoTreeAuthorizeHandler : AuthorizationHandler + { + /// + /// Can be used by unit tests to enable/disable this filter + /// + internal static readonly bool Enable = true; + + private readonly ITreeService _treeService; + private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; + + /// + /// Constructor to set authorization to be based on a tree alias for which application security will be applied + /// + /// + /// + /// + /// If the user has access to the application that the treeAlias is specified in, they will be authorized. + /// Multiple trees may be specified. + /// + public UmbracoTreeAuthorizeHandler(ITreeService treeService, IBackOfficeSecurityAccessor backofficeSecurityAccessor) + { + _treeService = treeService ?? throw new ArgumentNullException(nameof(treeService)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); + } + + private bool IsAuthorized(TreeAliasesRequirement requirement) + { + if (Enable == false) + { + return true; + } + + var apps = requirement.TreeAliases.Select(x => _treeService + .GetByAlias(x)) + .WhereNotNull() + .Select(x => x.SectionAlias) + .Distinct() + .ToArray(); + + return _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser != null + && apps.Any(app => _backofficeSecurityAccessor.BackOfficeSecurity.UserHasSectionAccess( + app, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser)); + } + + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TreeAliasesRequirement requirement) + { + if (IsAuthorized(requirement)) + { + context.Succeed(requirement); + } + else + { + context.Fail(); + } + + return Task.CompletedTask; + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs index 9d18727c62..33f19141c3 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs @@ -36,6 +36,8 @@ using ContentType = Umbraco.Core.Models.ContentType; using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; using Umbraco.Core.Serialization; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.BackOffice.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -48,7 +50,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// An API controller used for dealing with content types /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.DocumentTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public class ContentTypeController : ContentTypeControllerBase { private readonly IEntityXmlSerializer _serializer; @@ -136,7 +138,7 @@ namespace Umbraco.Web.BackOffice.Controllers } [HttpGet] - [UmbracoTreeAuthorize(Constants.Trees.DocumentTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] public bool HasContentNodes(int id) { return _contentTypeService.HasContentNodes(id); @@ -223,10 +225,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Gets all user defined properties. /// /// - [UmbracoTreeAuthorize( - Constants.Trees.DocumentTypes, Constants.Trees.Content, - Constants.Trees.MediaTypes, Constants.Trees.Media, - Constants.Trees.MemberTypes, Constants.Trees.Members)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)] public IEnumerable GetAllPropertyTypeAliases() { return _contentTypeService.GetAllPropertyTypeAliases(); @@ -236,10 +235,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Gets all the standard fields. /// /// - [UmbracoTreeAuthorize( - Constants.Trees.DocumentTypes, Constants.Trees.Content, - Constants.Trees.MediaTypes, Constants.Trees.Media, - Constants.Trees.MemberTypes, Constants.Trees.Members)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)] public IEnumerable GetAllStandardFields() { string[] preValuesSource = { "createDate", "creatorName", "level", "nodeType", "nodeTypeAlias", "pageID", "pageName", "parentID", "path", "template", "updateDate", "writerID", "writerName" }; @@ -280,10 +276,7 @@ namespace Umbraco.Web.BackOffice.Controllers return Ok(result); } - [UmbracoTreeAuthorize( - Constants.Trees.DocumentTypes, Constants.Trees.Content, - Constants.Trees.MediaTypes, Constants.Trees.Media, - Constants.Trees.MemberTypes, Constants.Trees.Members)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)] public ContentPropertyDisplay GetPropertyTypeScaffold(int id) { var dataTypeDiff = _dataTypeService.GetDataType(id); @@ -523,7 +516,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Returns the allowed child content type objects for the content item id passed in /// /// - [UmbracoTreeAuthorize(Constants.Trees.DocumentTypes, Constants.Trees.Content)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] public IEnumerable GetAllowedChildren(int contentId) { if (contentId == Constants.System.RecycleBinContent) diff --git a/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs index c88d0d16c9..f8bc313bed 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Net; using System.Net.Mime; using System.Text; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Umbraco.Core; @@ -14,6 +15,7 @@ using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; @@ -31,7 +33,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Content Types, Member Types or Media Types ... and of course to Data Types /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.DataTypes, Constants.Trees.DocumentTypes, Constants.Trees.MediaTypes, Constants.Trees.MemberTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)] public class DataTypeController : BackOfficeNotificationsController { private readonly PropertyEditorCollection _propertyEditors; @@ -414,7 +416,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Permission is granted to this method if the user has access to any of these sections: Content, media, settings, developer, members /// - [UmbracoApplicationAuthorizeAttribute(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, + [UmbracoApplicationAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, Constants.Applications.Settings, Constants.Applications.Packages)] public IEnumerable GetAll() { @@ -430,7 +432,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Permission is granted to this method if the user has access to any of these sections: Content, media, settings, developer, members /// - [UmbracoTreeAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, + [UmbracoApplicationAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, Constants.Applications.Settings, Constants.Applications.Packages)] public IDictionary> GetGroupedDataTypes() { @@ -462,9 +464,8 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Permission is granted to this method if the user has access to any of these sections: Content, media, settings, developer, members /// - [UmbracoTreeAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, + [UmbracoApplicationAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, Constants.Applications.Settings, Constants.Applications.Packages)] - public IDictionary> GetGroupedPropertyEditors() { var datatypes = new List(); @@ -495,9 +496,8 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Permission is granted to this method if the user has access to any of these sections: Content, media, settings, developer, members /// - [UmbracoTreeAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, + [UmbracoApplicationAuthorize(Constants.Applications.Content, Constants.Applications.Media, Constants.Applications.Members, Constants.Applications.Settings, Constants.Applications.Packages)] - public IEnumerable GetAllPropertyEditors() { return _propertyEditorCollection diff --git a/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs b/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs index 785264d816..00e10852c7 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs @@ -18,6 +18,8 @@ using Umbraco.Web.Security; using Constants = Umbraco.Core.Constants; using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.BackOffice.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -30,7 +32,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Dictionary /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.Dictionary)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDictionary)] public class DictionaryController : BackOfficeNotificationsController { private readonly ILogger _logger; diff --git a/src/Umbraco.Web.BackOffice/Controllers/LanguageController.cs b/src/Umbraco.Web.BackOffice/Controllers/LanguageController.cs index 66f8b6d7e0..a3e6c83ae6 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/LanguageController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/LanguageController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Umbraco.Core; @@ -10,6 +11,7 @@ using Umbraco.Core.Configuration.Models; using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; @@ -80,7 +82,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Deletes a language with a given ID /// - [UmbracoTreeAuthorize(Constants.Trees.Languages)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] [HttpDelete] [HttpPost] public IActionResult DeleteLanguage(int id) @@ -109,7 +111,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Creates or saves a language /// - [UmbracoTreeAuthorize(Constants.Trees.Languages)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] [HttpPost] public Language SaveLanguage(Language language) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs b/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs index e4ef90b30c..8b9fb8e7d2 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs @@ -19,6 +19,8 @@ using Umbraco.Web.Security; using Umbraco.Core; using Umbraco.Core.Mapping; using Umbraco.Core.Security; +using Umbraco.Web.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -27,7 +29,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// The API controller used for editing dictionary items /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.Macros)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMacros)] public class MacrosController : BackOfficeNotificationsController { private readonly ParameterEditorCollection _parameterEditorCollection; diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs index cd834e79fb..84a3e5a260 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Umbraco.Core; using Umbraco.Core.Dictionary; @@ -10,6 +11,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; @@ -27,7 +29,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// An API controller used for dealing with content types /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] public class MediaTypeController : ContentTypeControllerBase { private readonly IContentTypeService _contentTypeService; @@ -78,7 +80,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// [DetermineAmbiguousActionByPassingParameters] - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] public MediaTypeDisplay GetById(int id) { var ct = _mediaTypeService.Get(id); @@ -97,7 +99,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// [DetermineAmbiguousActionByPassingParameters] - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] public MediaTypeDisplay GetById(Guid id) { var mediaType = _mediaTypeService.Get(id); @@ -116,7 +118,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// [DetermineAmbiguousActionByPassingParameters] - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] public MediaTypeDisplay GetById(Udi id) { var guidUdi = id as GuidUdi; @@ -314,7 +316,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Returns the allowed child content type objects for the content item id passed in - based on an INT id /// /// - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] [DetermineAmbiguousActionByPassingParameters] public IEnumerable GetAllowedChildren(int contentId) { @@ -361,7 +363,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Returns the allowed child content type objects for the content item id passed in - based on a GUID id /// /// - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] [DetermineAmbiguousActionByPassingParameters] public IEnumerable GetAllowedChildren(Guid contentId) { @@ -378,7 +380,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Returns the allowed child content type objects for the content item id passed in - based on a UDI id /// /// - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaOrMediaTypes)] [DetermineAmbiguousActionByPassingParameters] public IEnumerable GetAllowedChildren(Udi contentId) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs index d3d06132d3..12f26f484b 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs @@ -2,11 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Umbraco.Core; using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; @@ -19,7 +21,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// An API controller used for dealing with member groups /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.MemberGroups)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMemberGroups)] public class MemberGroupController : UmbracoAuthorizedJsonController { private readonly IMemberGroupService _memberGroupService; diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs index 3557680ab1..dccc2b7907 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs @@ -24,6 +24,8 @@ using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Editors; using Umbraco.Web.Routing; using Umbraco.Web.Security; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.BackOffice.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -31,7 +33,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// An API controller used for dealing with member types /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(new string[] { Constants.Trees.MemberTypes, Constants.Trees.Members})] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)] public class MemberTypeController : ContentTypeControllerBase { private readonly IMemberTypeService _memberTypeService; @@ -71,7 +73,6 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] [DetermineAmbiguousActionByPassingParameters] public MemberTypeDisplay GetById(int id) { @@ -90,7 +91,6 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] [DetermineAmbiguousActionByPassingParameters] public MemberTypeDisplay GetById(Guid id) { @@ -109,7 +109,6 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] [DetermineAmbiguousActionByPassingParameters] public MemberTypeDisplay GetById(Udi id) { @@ -134,7 +133,6 @@ namespace Umbraco.Web.BackOffice.Controllers /// [HttpDelete] [HttpPost] - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] public IActionResult DeleteById(int id) { var foundType = _memberTypeService.Get(id); @@ -161,8 +159,6 @@ namespace Umbraco.Web.BackOffice.Controllers /// be looked up via the db, they need to be passed in. /// /// - - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] public IActionResult GetAvailableCompositeMemberTypes(int contentTypeId, [FromQuery]string[] filterContentTypes, [FromQuery]string[] filterPropertyTypes) @@ -176,7 +172,6 @@ namespace Umbraco.Web.BackOffice.Controllers return Ok(result); } - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] public MemberTypeDisplay GetEmpty() { var ct = new MemberType(_shortStringHelper, -1); @@ -190,13 +185,13 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Returns all member types /// + [Authorize(Policy = AuthorizationPolicies.TreeAccessMembersOrMemberTypes)] public IEnumerable GetAllTypes() { return _memberTypeService.GetAll() .Select(_umbracoMapper.Map); } - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] public ActionResult PostSave(MemberTypeSave contentTypeSave) { //get the persisted member type diff --git a/src/Umbraco.Web.BackOffice/Controllers/RelationTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/RelationTypeController.cs index 1ab5bd9bfa..7c80ebcc81 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/RelationTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/RelationTypeController.cs @@ -15,6 +15,8 @@ using Umbraco.Core.Mapping; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; +using Umbraco.Web.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -22,7 +24,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// The API controller for editing relation types. /// [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.RelationTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessRelationTypes)] public class RelationTypeController : BackOfficeNotificationsController { private readonly ILogger _logger; diff --git a/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs b/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs index f80c3015e9..d60e87a23b 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Umbraco.Core; using Umbraco.Core.IO; @@ -9,6 +10,7 @@ using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Strings; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; @@ -18,7 +20,7 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Controllers { [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] - [UmbracoTreeAuthorize(Constants.Trees.Templates)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessTemplates)] public class TemplateController : BackOfficeNotificationsController { private readonly IFileService _fileService; diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs index 93c6576d4e..7a77739342 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; @@ -9,6 +10,7 @@ using Umbraco.Core.Security; using Umbraco.Core.Serialization; using Umbraco.Infrastructure.BackOffice; using Umbraco.Net; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.Security; using Umbraco.Web.Common.AspNetCore; @@ -42,6 +44,8 @@ namespace Umbraco.Extensions // TODO: Need to add more cookie options, see https://github.com/dotnet/aspnetcore/blob/3.0/src/Identity/Core/src/IdentityServiceCollectionExtensions.cs#L45 services.ConfigureOptions(); + + services.AddBackOfficeAuthorizationPolicies(); } public static void AddUmbracoPreview(this IServiceCollection services) @@ -87,7 +91,7 @@ namespace Umbraco.Extensions services.GetRequiredService())); services.TryAddScoped, DefaultUserConfirmation>(); services.TryAddScoped, UserClaimsPrincipalFactory>(); - + // CUSTOM: services.TryAddScoped(); services.TryAddScoped(); @@ -104,5 +108,82 @@ namespace Umbraco.Extensions return new BackOfficeIdentityBuilder(services); } + + private static void AddBackOfficeAuthorizationPolicies(this IServiceCollection services) + { + services.AddAuthorization(options => + { + options.AddPolicy(AuthorizationPolicies.TreeAccessUsers, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Users))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessPartialViews, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.PartialViews))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessPartialViewMacros, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.PartialViewMacros))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessPackages, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Packages))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessLogs, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.LogViewer))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessDataTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.DataTypes))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessTemplates, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Templates))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessMemberTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.MemberTypes))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessRelationTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.RelationTypes))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessDocumentTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.DocumentTypes))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessMemberGroups, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.MemberGroups))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessMediaTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.MediaTypes))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessMacros, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Macros))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessLanguages, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Languages))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessDocumentTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Dictionary))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessDictionary, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Dictionary, Constants.Trees.Dictionary))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessDictionaryOrTemplates, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.Dictionary, Constants.Trees.Templates))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.DocumentTypes, Constants.Trees.Content))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessMediaOrMediaTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.MediaTypes, Constants.Trees.Media))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessMembersOrMemberTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.MemberTypes, Constants.Trees.Members))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessAnySchemaTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement(Constants.Trees.DataTypes, Constants.Trees.DocumentTypes, Constants.Trees.MediaTypes, Constants.Trees.MemberTypes))); + + options.AddPolicy(AuthorizationPolicies.TreeAccessAnyContentOrTypes, policy => + policy.Requirements.Add(new TreeAliasesRequirement( + Constants.Trees.DocumentTypes, Constants.Trees.Content, + Constants.Trees.MediaTypes, Constants.Trees.Media, + Constants.Trees.MemberTypes, Constants.Trees.Members))); + }); + + services.AddSingleton(); + } } } diff --git a/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs deleted file mode 100644 index eef7469322..0000000000 --- a/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Linq; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Umbraco.Core; -using Umbraco.Core.Security; -using Umbraco.Web.Security; -using Umbraco.Web.Services; - -namespace Umbraco.Web.BackOffice.Filters -{ - /// - /// Ensures that the current user has access to the application for which the specified tree(s) belongs - /// - /// - /// This would allow a tree to be moved between sections - /// - public class UmbracoTreeAuthorizeAttribute : TypeFilterAttribute - { - public UmbracoTreeAuthorizeAttribute(params string[] treeAliases) : base(typeof(UmbracoTreeAuthorizeFilter)) - { - Arguments = new object[] - { - treeAliases - }; - } - - private sealed class UmbracoTreeAuthorizeFilter : IAuthorizationFilter - { - /// - /// Can be used by unit tests to enable/disable this filter - /// - internal static readonly bool Enable = true; - - private readonly string[] _treeAliases; - - private readonly ITreeService _treeService; - private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; - - /// - /// Constructor to set authorization to be based on a tree alias for which application security will be applied - /// - /// - /// - /// - /// If the user has access to the application that the treeAlias is specified in, they will be authorized. - /// Multiple trees may be specified. - /// - public UmbracoTreeAuthorizeFilter(ITreeService treeService, IBackOfficeSecurityAccessor backofficeSecurityAccessor, - params string[] treeAliases) - { - _treeService = treeService ?? throw new ArgumentNullException(nameof(treeService)); - _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); - _treeAliases = treeAliases; - } - - public void OnAuthorization(AuthorizationFilterContext context) - { - if (!IsAuthorized()) - { - context.Result = new ForbidResult(); - } - } - - private bool IsAuthorized() - { - if (Enable == false) - { - return true; - } - - var apps = _treeAliases.Select(x => _treeService - .GetByAlias(x)) - .WhereNotNull() - .Select(x => x.SectionAlias) - .Distinct() - .ToArray(); - - return _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser != null - && apps.Any(app => _backofficeSecurityAccessor.BackOfficeSecurity.UserHasSectionAccess( - app, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser)); - } - } - } -} diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs index 5c8312c058..15c206e65f 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Actions; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.ContentEditing; @@ -16,7 +18,7 @@ using Umbraco.Web.WebApi; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.DocumentTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.DocumentTypes, SortOrder = 0, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs index 3502d7a506..f4e42729f0 100644 --- a/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs @@ -14,10 +14,12 @@ using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; +using Umbraco.Web.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.DataTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.DataTypes, SortOrder = 3, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs index a9878a3dbc..163e1607a7 100644 --- a/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs @@ -1,10 +1,12 @@ using System; using System.Linq; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Actions; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; @@ -14,12 +16,9 @@ using Umbraco.Web.WebApi; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize( - Constants.Trees.Dictionary, - Constants.Trees.Templates - // We are allowed to see the dictionary tree, if we are allowed to manage templates, such that se can use the - // dictionary items in templates, even when we dont have authorization to manage the dictionary items - )] + // We are allowed to see the dictionary tree, if we are allowed to manage templates, such that se can use the + // dictionary items in templates, even when we dont have authorization to manage the dictionary items + [Authorize(Policy = AuthorizationPolicies.TreeAccessDictionaryOrTemplates)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] [Tree(Constants.Applications.Translation, Constants.Trees.Dictionary, TreeGroup = Constants.Trees.Groups.Settings)] diff --git a/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs index d4a2c91fad..9ac3d0d43c 100644 --- a/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs @@ -1,5 +1,7 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; @@ -9,7 +11,7 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.Languages)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessLanguages)] [Tree(Constants.Applications.Settings, Constants.Trees.Languages, SortOrder = 11, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs index 9ffe6e8b68..4e484c447c 100644 --- a/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; @@ -9,7 +11,7 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.LogViewer)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessLogs)] [Tree(Constants.Applications.Settings, Constants.Trees.LogViewer, SortOrder= 9, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs index 567f0a3646..1df741ce81 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs @@ -8,10 +8,12 @@ using Umbraco.Web.Common.Attributes; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; +using Umbraco.Web.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.Macros)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMacros)] [Tree(Constants.Applications.Settings, Constants.Trees.Macros, TreeTitle = "Macros", SortOrder = 4, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs index 4df81b7023..de8e51719d 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs @@ -13,10 +13,12 @@ using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; +using Umbraco.Web.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.MediaTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.MediaTypes, SortOrder = 1, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs index 17de4ca37d..440a3439f2 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberGroupTreeController.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; @@ -11,7 +13,7 @@ using Umbraco.Web.WebApi; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.MemberGroups)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMemberGroups)] [Tree(Constants.Applications.Members, Constants.Trees.MemberGroups, SortOrder = 1)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs index c9e340617e..9f560700e8 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTypeTreeController.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; @@ -16,7 +18,7 @@ using Umbraco.Web.WebApi; namespace Umbraco.Web.BackOffice.Trees { [CoreTree] - [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.MemberTypes, SortOrder = 2, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] public class MemberTypeTreeController : MemberTypeAndGroupTreeControllerBase, ISearchableTree diff --git a/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs index fc1f3d876f..08051c6ab3 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; @@ -9,7 +11,7 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.Packages)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessPackages)] [Tree(Constants.Applications.Packages, Constants.Trees.Packages, SortOrder = 0, IsSingleNodeTree = true)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs index 5baeac7d17..c5f95ebc5e 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PartialViewMacrosTreeController.cs @@ -1,5 +1,7 @@ -using Umbraco.Core.IO; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Core.IO; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Trees; @@ -12,7 +14,7 @@ namespace Umbraco.Web.BackOffice.Trees /// Tree for displaying partial view macros in the developer app /// [Tree(Constants.Applications.Settings, Constants.Trees.PartialViewMacros, SortOrder = 8, TreeGroup = Constants.Trees.Groups.Templating)] - [UmbracoTreeAuthorize(Constants.Trees.PartialViewMacros)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessPartialViewMacros)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] public class PartialViewMacrosTreeController : PartialViewsTreeController diff --git a/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs index dcb98ac5b4..8fd7d8de6a 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PartialViewsTreeController.cs @@ -1,5 +1,7 @@ -using Umbraco.Core.IO; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Core.IO; using Umbraco.Core.Services; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Composing; @@ -14,7 +16,7 @@ namespace Umbraco.Web.BackOffice.Trees /// Tree for displaying partial views in the settings app /// [Tree(Core.Constants.Applications.Settings, Core.Constants.Trees.PartialViews, SortOrder = 7, TreeGroup = Core.Constants.Trees.Groups.Templating)] - [UmbracoTreeAuthorize(Constants.Trees.PartialViews)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessPartialViews)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] public class PartialViewsTreeController : FileSystemTreeController diff --git a/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs index 965e957f02..ceb8b9a032 100644 --- a/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs @@ -9,10 +9,12 @@ using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; +using Umbraco.Web.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.RelationTypes)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessRelationTypes)] [Tree(Constants.Applications.Settings, Constants.Trees.RelationTypes, SortOrder = 5, TreeGroup = Constants.Trees.Groups.Settings)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs index cfe2d57ce5..2054a6b5f4 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Models; @@ -8,6 +9,7 @@ using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; using Umbraco.Extensions; using Umbraco.Web.Actions; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.ContentEditing; @@ -19,7 +21,7 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.Templates)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessTemplates)] [Tree(Constants.Applications.Settings, Constants.Trees.Templates, SortOrder = 6, TreeGroup = Constants.Trees.Groups.Templating)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree] diff --git a/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs index feb8d2a9ec..33e943e9b4 100644 --- a/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs @@ -1,22 +1,16 @@ -using Microsoft.AspNetCore.Http; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Mapping; -using Umbraco.Core.Persistence; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Umbraco.Core.Services; -using Umbraco.Web.BackOffice.Filters; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models.Trees; -using Umbraco.Web.Routing; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.BackOffice.Trees { - [UmbracoTreeAuthorize(Constants.Trees.Users)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessUsers)] [Tree(Constants.Applications.Users, Constants.Trees.Users, SortOrder = 0, IsSingleNodeTree = true)] [PluginController(Constants.Web.Mvc.BackOfficeTreeArea)] [CoreTree]