Skip to content

Commit

Permalink
Implemented DowngradeBlueprintSecurity app setting and new filter
Browse files Browse the repository at this point in the history
  • Loading branch information
kasparboelkjeldsen committed Jan 23, 2024
1 parent 104ba5f commit bccf606
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/Umbraco.Core/Configuration/GlobalSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,23 @@ public bool SanitizeTinyMce
}
}

/// <summary>
/// Returns true if Blueprints should be savable and removable by users who only has Content access
/// </summary>
public bool DowngradeBlueprintSecurity
{
get
{
try
{
return bool.Parse(ConfigurationManager.AppSettings[Constants.AppSettings.DowngradeBlueprintSecurity]);
}
catch
{
return false;
}
}
}
/// <summary>
/// An int value representing the time in milliseconds to lock the database for a write operation
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Umbraco.Core/Configuration/IGlobalSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,10 @@ public interface IGlobalSettings
/// Returns true if TinyMCE scripting sanitization should be applied
/// </summary>
bool SanitizeTinyMce { get; }

/// <summary>
/// Returns true if Blueprints should be savable and removable by users who only has Content access
/// </summary>
bool DowngradeBlueprintSecurity { get; }
}
}
6 changes: 6 additions & 0 deletions src/Umbraco.Core/Constants-AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ public static class Debug
/// Returns true if TinyMCE scripting sanitization should be applied
/// </summary>
public const string SanitizeTinyMce = "Umbraco.Web.SanitizeTinyMce";

/// <summary>
/// Allows creating and deleting blueprints who has Constant.Trees.Content access
/// NOTE: This downgrades security of ContentController/PostSaveBlueprint and ContentController/DeleteBlueprint
/// </summary>
public const string DowngradeBlueprintSecurity = "Umbraco.Web.DowngradeBlueprintSecurity";
}
}
}
4 changes: 2 additions & 2 deletions src/Umbraco.Web/Editors/ContentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ private void EnsureUniqueName(string name, IContent content, string modelName)
/// Saves content
/// </summary>
/// <returns></returns>
[UmbracoTreeAuthorize(Constants.Trees.DocumentTypes)]
[UmbracoBlueprintAuthorize(Constants.Trees.DocumentTypes)]
[FileUploadCleanupFilter]
[ContentSaveValidation(skipUserAccessValidation:true)] // skip user access validation because we "only" require Settings access to create new blueprints from scratch
public ContentItemDisplay PostSaveBlueprint([ModelBinder(typeof(BlueprintItemBinder))] ContentItemSave contentItem)
Expand Down Expand Up @@ -1588,7 +1588,7 @@ public HttpResponseMessage PostPublishById(int id)

}

[UmbracoTreeAuthorize(Constants.Trees.DocumentTypes)]
[UmbracoBlueprintAuthorize(Constants.Trees.DocumentTypes)]
[HttpDelete]
[HttpPost]
public HttpResponseMessage DeleteBlueprint(int id)
Expand Down
1 change: 1 addition & 0 deletions src/Umbraco.Web/Umbraco.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@
<Compile Include="Editors\Binders\BlueprintItemBinder.cs" />
<Compile Include="UmbracoApplicationBase.cs" />
<Compile Include="WebApi\Filters\HttpQueryStringModelBinder.cs" />
<Compile Include="WebApi\Filters\UmbracoBlueprintAuthorizeAttribute.cs" />
<Compile Include="WebApi\HttpActionContextExtensions.cs" />
<Compile Include="Models\ContentEditing\IContentSave.cs" />
<Compile Include="WebApi\SerializeVersionAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Linq;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Web.Composing;

namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// Identical to UmbracoTreeAuthorizeAttribute, except it will default it's behavior to allow everything by
/// users with access to the content tree, if the setting DowngradeBlueprintSecurity is true
///
/// Ensures that the current user has access to the application for which the specified tree(s) belongs
/// </summary>
/// <remarks>
/// This would allow a tree to be moved between sections
/// Should only be used on PostSaveBlueprint and DeleteBlueprint
/// </remarks>
public sealed class UmbracoBlueprintAuthorizeAttribute : OverridableAuthorizationAttribute
{
/// <summary>
/// Can be used by unit tests to enable/disable this filter
/// </summary>
internal static bool Enable = true;

private readonly string[] _treeAliases;

private IGlobalSettings _globalSettings;
private IGlobalSettings GlobalSettings
{
get
{
return _globalSettings ?? (_globalSettings = Current.Factory.GetInstance<IGlobalSettings>());
}
}

/// <summary>
/// Constructor to set authorization to be based on a tree alias for which application security will be applied
/// Overrides authorization to Constant.Tree.Content if the setting DowngradeBlueprintSecurity is true
/// </summary>
/// <param name="treeAliases">
/// If the user has access to the application that the treeAlias is specified in, they will be authorized.
/// Multiple trees may be specified.
/// </param>
public UmbracoBlueprintAuthorizeAttribute(params string[] treeAliases)
{
_treeAliases = treeAliases;

if(GlobalSettings.DowngradeBlueprintSecurity)
{
_treeAliases = [Constants.Trees.Content];
}
}

protected override bool IsAuthorized(HttpActionContext actionContext)
{
if (Enable == false)
{
return true;
}

var apps = _treeAliases.Select(x => Current.TreeService
.GetByAlias(x))
.WhereNotNull()
.Select(x => x.SectionAlias)
.Distinct()
.ToArray();

return Current.UmbracoContext.Security.CurrentUser != null
&& apps.Any(app => Current.UmbracoContext.Security.UserHasSectionAccess(
app, Current.UmbracoContext.Security.CurrentUser));
}
}
}

0 comments on commit bccf606

Please sign in to comment.