From 525ca95acf7a11bc66087c095bf1a25839095f44 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 22 Sep 2020 08:01:04 +0200 Subject: [PATCH 1/3] uncomment SMTP info by default Signed-off-by: Bjarke Berg --- src/Umbraco.Web.UI.NetCore/appsettings.Development.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json index 9f81927bdc..13f4c95bbd 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json @@ -3,9 +3,9 @@ "CMS": { "Global":{ "Smtp": { - "From": "your@email.here", - "Host": "localhost", - "Port": "25" +// "From": "your@email.here", +// "Host": "localhost", +// "Port": "25" } }, "Hosting":{ From 96facc4d35ce13ebc3c7f43fe51d678494656779 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 22 Sep 2020 10:01:00 +0200 Subject: [PATCH 2/3] Netcore: Introduce BackofficeSecurityAccessor (#8871) * Introduced IWebSecurityAccessor Signed-off-by: Bjarke Berg * Fixed tests Signed-off-by: Bjarke Berg * Renamed WebSecurity to BackofficeSecurity and all related names * Fixes typos Co-authored-by: Elitsa Marinovska --- .../HybridBackofficeSecurityAccessor.cs | 30 ++++++++++ .../IBackofficeSecurityFactory.cs | 15 +++++ src/Umbraco.Core/IUmbracoContext.cs | 4 +- ...IWebSecurity.cs => IBackofficeSecurity.cs} | 2 +- .../Security/IBackofficeSecurityAccessor.cs | 9 +++ .../InstallSteps/StarterKitDownloadStep.cs | 11 ++-- .../InstallSteps/StarterKitInstallStep.cs | 9 +-- .../Mapping/MemberTabsAndPropertiesMapper.cs | 16 +++-- .../UmbracoTestServerTestBase.cs | 2 + .../Testing/UmbracoIntegrationTest.cs | 1 + .../Filters/ContentModelValidatorTests.cs | 7 ++- .../AppendUserModifiedHeaderAttributeTests.cs | 8 +-- ...terAllowedOutgoingContentAttributeTests.cs | 11 ++-- .../Controllers/SurfaceControllerTests.cs | 20 ++++--- .../PublishedContentCacheTests.cs | 2 +- .../PublishedContentSnapshotTestBase.cs | 2 +- .../Scoping/ScopedNuCacheTests.cs | 2 +- .../TestControllerActivatorBase.cs | 10 ++-- .../TestHelpers/TestWithDatabaseBase.cs | 2 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 2 +- .../Web/Mvc/UmbracoViewPageTests.cs | 2 +- .../Web/WebExtensionMethodTests.cs | 6 +- .../Controllers/AuthenticationController.cs | 15 ++--- .../Controllers/BackOfficeController.cs | 11 ++-- .../Controllers/ContentController.cs | 60 +++++++++---------- .../Controllers/ContentTypeController.cs | 17 +++--- .../Controllers/CurrentUserController.cs | 43 ++++++------- .../Controllers/DictionaryController.cs | 15 ++--- .../Controllers/EntityController.cs | 17 +++--- .../Controllers/LogController.cs | 9 +-- .../Controllers/MacrosController.cs | 11 ++-- .../Controllers/MediaController.cs | 31 +++++----- .../Controllers/MediaTypeController.cs | 15 ++--- .../Controllers/MemberController.cs | 14 ++--- .../Controllers/MemberTypeController.cs | 11 ++-- .../Controllers/PackageController.cs | 9 +-- .../Controllers/PackageInstallController.cs | 17 +++--- .../Controllers/PreviewController.cs | 11 ++-- .../RedirectUrlManagementController.cs | 14 +++-- .../Controllers/SectionController.cs | 15 ++--- .../Controllers/TourController.cs | 11 ++-- .../Controllers/UpdateCheckController.cs | 9 +-- .../Controllers/UserGroupsController.cs | 23 +++---- .../Controllers/UsersController.cs | 28 +++++---- .../Filters/AdminUsersAuthorizeAttribute.cs | 9 +-- .../AppendUserModifiedHeaderAttribute.cs | 4 +- .../Filters/ContentModelValidator.cs | 10 ++-- .../Filters/ContentSaveModelValidator.cs | 4 +- .../Filters/ContentSaveValidationAttribute.cs | 18 +++--- ...EnsureUserPermissionForContentAttribute.cs | 26 ++++---- .../EnsureUserPermissionForMediaAttribute.cs | 19 +++--- .../FilterAllowedOutgoingContentAttribute.cs | 5 +- .../FilterAllowedOutgoingMediaAttribute.cs | 8 +-- .../IsCurrentUserModelFilterAttribute.cs | 9 +-- .../MediaItemSaveValidationAttribute.cs | 11 ++-- .../Filters/MediaSaveModelValidator.cs | 4 +- .../Filters/MemberSaveModelValidator.cs | 6 +- .../Filters/MemberSaveValidationAttribute.cs | 9 +-- .../OutgoingEditorModelEventAttribute.cs | 9 +-- .../UmbracoApplicationAuthorizeAttribute.cs | 15 ++--- .../Filters/UmbracoTreeAuthorizeAttribute.cs | 17 +++--- .../UserGroupAuthorizationAttribute.cs | 9 +-- .../Trees/ApplicationTreeController.cs | 3 +- .../Trees/ContentTreeController.cs | 15 ++--- .../Trees/ContentTreeControllerBase.cs | 24 ++++---- .../Trees/MediaTreeController.cs | 13 ++-- .../Trees/MemberTreeController.cs | 9 +-- .../Install/InstallController.cs | 9 +-- .../Middleware/UmbracoRequestMiddleware.cs | 11 +++- .../Runtime/AspNetCoreComposer.cs | 3 +- .../{WebSecurity.cs => BackofficeSecurity.cs} | 5 +- .../Security/BackofficeSecurityFactory.cs | 43 +++++++++++++ .../UmbracoContext/UmbracoContext.cs | 10 ++-- .../UmbracoContext/UmbracoContextFactory.cs | 9 +-- .../Mvc/UmbracoAuthorizeAttribute.cs | 13 ++-- src/Umbraco.Web/Mvc/UmbracoController.cs | 2 +- .../{WebSecurity.cs => BackofficeSecurity.cs} | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- src/Umbraco.Web/UmbracoContext.cs | 10 ++-- src/Umbraco.Web/UmbracoContextFactory.cs | 2 +- src/Umbraco.Web/UmbracoHttpHandler.cs | 2 +- src/Umbraco.Web/UmbracoWebService.cs | 2 +- .../WebApi/UmbracoApiControllerBase.cs | 2 +- .../WebApi/UmbracoAuthorizeAttribute.cs | 13 ++-- 84 files changed, 571 insertions(+), 404 deletions(-) create mode 100644 src/Umbraco.Core/HybridBackofficeSecurityAccessor.cs create mode 100644 src/Umbraco.Core/IBackofficeSecurityFactory.cs rename src/Umbraco.Core/Security/{IWebSecurity.cs => IBackofficeSecurity.cs} (97%) create mode 100644 src/Umbraco.Core/Security/IBackofficeSecurityAccessor.cs rename src/Umbraco.Web.Common/Security/{WebSecurity.cs => BackofficeSecurity.cs} (98%) create mode 100644 src/Umbraco.Web.Common/Security/BackofficeSecurityFactory.cs rename src/Umbraco.Web/Security/{WebSecurity.cs => BackofficeSecurity.cs} (95%) diff --git a/src/Umbraco.Core/HybridBackofficeSecurityAccessor.cs b/src/Umbraco.Core/HybridBackofficeSecurityAccessor.cs new file mode 100644 index 0000000000..a953ed8b82 --- /dev/null +++ b/src/Umbraco.Core/HybridBackofficeSecurityAccessor.cs @@ -0,0 +1,30 @@ +using Umbraco.Core.Cache; +using Umbraco.Core.Security; +using Umbraco.Web; +using Umbraco.Web.Security; + +namespace Umbraco.Core +{ + + public class HybridBackofficeSecurityAccessor : HybridAccessorBase, IBackofficeSecurityAccessor + { + /// + /// Initializes a new instance of the class. + /// + public HybridBackofficeSecurityAccessor(IRequestCache requestCache) + : base(requestCache) + { } + + /// + protected override string ItemKey => "Umbraco.Web.HybridBackofficeSecurityAccessor"; + + /// + /// Gets or sets the object. + /// + public IBackofficeSecurity BackofficeSecurity + { + get => Value; + set => Value = value; + } + } +} diff --git a/src/Umbraco.Core/IBackofficeSecurityFactory.cs b/src/Umbraco.Core/IBackofficeSecurityFactory.cs new file mode 100644 index 0000000000..9f8f791e4c --- /dev/null +++ b/src/Umbraco.Core/IBackofficeSecurityFactory.cs @@ -0,0 +1,15 @@ +using Umbraco.Web.Security; + +namespace Umbraco.Core +{ + /// + /// Creates and manages instances. + /// + public interface IBackofficeSecurityFactory + { + /// + /// Ensures that a current exists. + /// + void EnsureBackofficeSecurity(); + } +} diff --git a/src/Umbraco.Core/IUmbracoContext.cs b/src/Umbraco.Core/IUmbracoContext.cs index 66b3dc3965..03fb305fb6 100644 --- a/src/Umbraco.Core/IUmbracoContext.cs +++ b/src/Umbraco.Core/IUmbracoContext.cs @@ -16,9 +16,9 @@ namespace Umbraco.Web DateTime ObjectCreated { get; } /// - /// Gets the WebSecurity class + /// Gets the BackofficeSecurity class /// - IWebSecurity Security { get; } + IBackofficeSecurity Security { get; } /// /// Gets the uri that is handled by ASP.NET after server-side rewriting took place. diff --git a/src/Umbraco.Core/Security/IWebSecurity.cs b/src/Umbraco.Core/Security/IBackofficeSecurity.cs similarity index 97% rename from src/Umbraco.Core/Security/IWebSecurity.cs rename to src/Umbraco.Core/Security/IBackofficeSecurity.cs index 594f6d96ea..3a0e0baa1d 100644 --- a/src/Umbraco.Core/Security/IWebSecurity.cs +++ b/src/Umbraco.Core/Security/IBackofficeSecurity.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Models.Membership; namespace Umbraco.Web.Security { - public interface IWebSecurity + public interface IBackofficeSecurity { /// /// Gets the current user. diff --git a/src/Umbraco.Core/Security/IBackofficeSecurityAccessor.cs b/src/Umbraco.Core/Security/IBackofficeSecurityAccessor.cs new file mode 100644 index 0000000000..d3cea99f9f --- /dev/null +++ b/src/Umbraco.Core/Security/IBackofficeSecurityAccessor.cs @@ -0,0 +1,9 @@ +using Umbraco.Web.Security; + +namespace Umbraco.Core.Security +{ + public interface IBackofficeSecurityAccessor + { + IBackofficeSecurity BackofficeSecurity { get; set; } + } +} diff --git a/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitDownloadStep.cs b/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitDownloadStep.cs index 24133d3be1..d060db2c43 100644 --- a/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitDownloadStep.cs +++ b/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitDownloadStep.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Umbraco.Core.Services; using Umbraco.Core.Configuration; using Umbraco.Core.Models.Packaging; +using Umbraco.Core.Security; using Umbraco.Net; using Umbraco.Web.Install.Models; using Umbraco.Web.Security; @@ -17,16 +18,16 @@ namespace Umbraco.Web.Install.InstallSteps internal class StarterKitDownloadStep : InstallSetupStep { private readonly InstallHelper _installHelper; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IUmbracoVersion _umbracoVersion; private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime; private readonly IContentService _contentService; private readonly IPackagingService _packageService; - public StarterKitDownloadStep(IContentService contentService, IPackagingService packageService, InstallHelper installHelper, IWebSecurity webSecurity, IUmbracoVersion umbracoVersion, IUmbracoApplicationLifetime umbracoApplicationLifetime) + public StarterKitDownloadStep(IContentService contentService, IPackagingService packageService, InstallHelper installHelper, IBackofficeSecurityAccessor backofficeSecurityAccessor, IUmbracoVersion umbracoVersion, IUmbracoApplicationLifetime umbracoApplicationLifetime) { _installHelper = installHelper; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _umbracoVersion = umbracoVersion; _umbracoApplicationLifetime = umbracoApplicationLifetime; _contentService = contentService; @@ -67,7 +68,7 @@ namespace Umbraco.Web.Install.InstallSteps private async Task<(string packageFile, int packageId)> DownloadPackageFilesAsync(Guid kitGuid) { //Go get the package file from the package repo - var packageFile = await _packageService.FetchPackageFileAsync(kitGuid, _umbracoVersion.Current, _webSecurity.GetUserId().ResultOr(0)); + var packageFile = await _packageService.FetchPackageFileAsync(kitGuid, _umbracoVersion.Current, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); if (packageFile == null) throw new InvalidOperationException("Could not fetch package file " + kitGuid); //add an entry to the installedPackages.config @@ -77,7 +78,7 @@ namespace Umbraco.Web.Install.InstallSteps _packageService.SaveInstalledPackage(packageDefinition); - _packageService.InstallCompiledPackageFiles(packageDefinition, packageFile, _webSecurity.GetUserId().ResultOr(-1)); + _packageService.InstallCompiledPackageFiles(packageDefinition, packageFile, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(-1)); return (compiledPackage.PackageFile.Name, packageDefinition.Id); } diff --git a/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitInstallStep.cs b/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitInstallStep.cs index daf8255132..0f2394dcf4 100644 --- a/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitInstallStep.cs +++ b/src/Umbraco.Infrastructure/Install/InstallSteps/StarterKitInstallStep.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using Umbraco.Core.Security; using Umbraco.Net; using Umbraco.Core.Services; using Umbraco.Web.Install.Models; @@ -15,13 +16,13 @@ namespace Umbraco.Web.Install.InstallSteps internal class StarterKitInstallStep : InstallSetupStep { private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IPackagingService _packagingService; - public StarterKitInstallStep(IUmbracoApplicationLifetime umbracoApplicationLifetime, IWebSecurity webSecurity, IPackagingService packagingService) + public StarterKitInstallStep(IUmbracoApplicationLifetime umbracoApplicationLifetime, IBackofficeSecurityAccessor backofficeSecurityAccessor, IPackagingService packagingService) { _umbracoApplicationLifetime = umbracoApplicationLifetime; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _packagingService = packagingService; } @@ -48,7 +49,7 @@ namespace Umbraco.Web.Install.InstallSteps var packageFile = new FileInfo(definition.PackagePath); - _packagingService.InstallCompiledPackageData(definition, packageFile, _webSecurity.GetUserId().ResultOr(-1)); + _packagingService.InstallCompiledPackageData(definition, packageFile, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(-1)); } public override bool RequiresExecution(object model) diff --git a/src/Umbraco.Infrastructure/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Infrastructure/Models/Mapping/MemberTabsAndPropertiesMapper.cs index b281e18b73..abc32fc008 100644 --- a/src/Umbraco.Infrastructure/Models/Mapping/MemberTabsAndPropertiesMapper.cs +++ b/src/Umbraco.Infrastructure/Models/Mapping/MemberTabsAndPropertiesMapper.cs @@ -10,6 +10,10 @@ using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; +using Umbraco.Core.Dictionary; +using Umbraco.Core.Configuration; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Security; using Umbraco.Web.Security; namespace Umbraco.Web.Models.Mapping @@ -24,7 +28,7 @@ namespace Umbraco.Web.Models.Mapping /// public class MemberTabsAndPropertiesMapper : TabsAndPropertiesMapper { - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly ILocalizedTextService _localizedTextService; private readonly IMemberTypeService _memberTypeService; private readonly IMemberService _memberService; @@ -33,7 +37,7 @@ namespace Umbraco.Web.Models.Mapping private readonly PropertyEditorCollection _propertyEditorCollection; public MemberTabsAndPropertiesMapper(ICultureDictionary cultureDictionary, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService localizedTextService, IMemberTypeService memberTypeService, IMemberService memberService, @@ -43,7 +47,7 @@ namespace Umbraco.Web.Models.Mapping PropertyEditorCollection propertyEditorCollection) : base(cultureDictionary, localizedTextService, contentTypeBaseServiceProvider) { - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); _memberService = memberService ?? throw new ArgumentNullException(nameof(memberService)); @@ -76,8 +80,8 @@ namespace Umbraco.Web.Models.Mapping isLockedOutProperty.Value = _localizedTextService.Localize("general/no"); } - if (_webSecurity.CurrentUser != null - && _webSecurity.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser != null + && _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) { var memberTypeLink = string.Format("#/member/memberTypes/edit/{0}", source.ContentTypeId); @@ -191,7 +195,7 @@ namespace Umbraco.Web.Models.Mapping // check if this property is flagged as sensitive var isSensitiveProperty = memberType.IsSensitiveProperty(prop.Alias); // check permissions for viewing sensitive data - if (isSensitiveProperty && (_webSecurity.CurrentUser.HasAccessToSensitiveData() == false)) + if (isSensitiveProperty && (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasAccessToSensitiveData() == false)) { // mark this property as sensitive prop.IsSensitive = true; diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index 08be22c07b..465305cd24 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -90,6 +90,7 @@ namespace Umbraco.Tests.Integration.TestServerTest { var url = LinkGenerator.GetUmbracoApiService(methodSelector); + var backofficeSecurityFactory = GetRequiredService(); var umbracoContextFactory = GetRequiredService(); var httpContextAccessor = GetRequiredService(); @@ -104,6 +105,7 @@ namespace Umbraco.Tests.Integration.TestServerTest } }; + backofficeSecurityFactory.EnsureBackofficeSecurity(); umbracoContextFactory.EnsureUmbracoContext(); return url; diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index b21de325cc..705690b898 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -243,6 +243,7 @@ namespace Umbraco.Tests.Integration.Testing public virtual void Configure(IApplicationBuilder app) { + Services.GetRequiredService().EnsureBackofficeSecurity(); Services.GetRequiredService().EnsureUmbracoContext(); // get the currently set ptions diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs index 236338390b..1a343a1e0b 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Filters/ContentModelValidatorTests.cs @@ -18,6 +18,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Mapping; using Umbraco.Core.Models; + using Umbraco.Core.Security; using Umbraco.Core.Strings; using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.TestHelpers.Entities; @@ -138,12 +139,14 @@ public void Validating_ContentItemSave() { var logger = Services.GetRequiredService(); - var webSecurity = Services.GetRequiredService(); + var backofficeSecurityFactory = Services.GetRequiredService(); + backofficeSecurityFactory.EnsureBackofficeSecurity(); + var backofficeSecurityAccessor = Services.GetRequiredService(); var localizedTextService = Services.GetRequiredService(); var propertyValidationService = Services.GetRequiredService(); var umbracoMapper = Services.GetRequiredService(); - var validator = new ContentSaveModelValidator(logger, webSecurity, localizedTextService, propertyValidationService); + var validator = new ContentSaveModelValidator(logger, backofficeSecurityAccessor.BackofficeSecurity, localizedTextService, propertyValidationService); var content = MockedContent.CreateTextpageContent(_contentType, "test", -1); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttributeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttributeTests.cs index f087a4851c..6c725d1049 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttributeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttributeTests.cs @@ -91,16 +91,16 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Filters .SetupGet(x => x.Id) .Returns(100); - var webSecurityMock = new Mock(); - webSecurityMock + var backofficeSecurityMock = new Mock(); + backofficeSecurityMock .SetupGet(x => x.CurrentUser) .Returns(currentUserMock.Object); var serviceProviderMock = new Mock(); serviceProviderMock - .Setup(x => x.GetService(typeof(IWebSecurity))) - .Returns(webSecurityMock.Object); + .Setup(x => x.GetService(typeof(IBackofficeSecurity))) + .Returns(backofficeSecurityMock.Object); httpContext.RequestServices = serviceProviderMock.Object; diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs index 54499d97ba..f6e551dc27 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttributeTests.cs @@ -8,6 +8,7 @@ using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Tests.Common.TestHelpers.Entities; using Umbraco.Web.Actions; @@ -30,7 +31,7 @@ namespace Umbraco.Tests.Web.Controllers ActionBrowse.ActionLetter, Mock.Of(), Mock.Of(), - Mock.Of() ); + Mock.Of() ); var result = att.GetValueFromResponse(new ObjectResult(expected)); @@ -48,7 +49,7 @@ namespace Umbraco.Tests.Web.Controllers ActionBrowse.ActionLetter, Mock.Of(), Mock.Of(), - Mock.Of() ); + Mock.Of() ); var result = att.GetValueFromResponse(new ObjectResult(container)); @@ -66,7 +67,7 @@ namespace Umbraco.Tests.Web.Controllers ActionBrowse.ActionLetter, Mock.Of(), Mock.Of(), - Mock.Of() ); + Mock.Of() ); var actual = att.GetValueFromResponse(new ObjectResult(container)); @@ -94,7 +95,7 @@ namespace Umbraco.Tests.Web.Controllers ActionBrowse.ActionLetter, userService, entityService, - Mock.Of() ); + Mock.Of() ); var path = ""; for (var i = 0; i < 10; i++) @@ -145,7 +146,7 @@ namespace Umbraco.Tests.Web.Controllers ActionBrowse.ActionLetter, userService, Mock.Of(), - Mock.Of() ); + Mock.Of() ); att.FilterBasedOnPermissions(list, user); Assert.AreEqual(3, list.Count); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs index 0d288b6310..a1904cb0da 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs @@ -9,6 +9,7 @@ using NUnit.Framework; using Umbraco.Core.Cache; using Umbraco.Core.Hosting; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Tests.Common; using Umbraco.Tests.Common.Builders; @@ -39,6 +40,8 @@ namespace Umbraco.Tests.Integration { var httpContextAccessor = Mock.Of(); var hostingEnvironment = Mock.Of(); + var backofficeSecurityAccessor = Mock.Of(); + Mock.Get(backofficeSecurityAccessor).Setup(x => x.BackofficeSecurity).Returns(Mock.Of()); var globalSettings = new GlobalSettingsBuilder().Build(); var umbracoContextFactory = new UmbracoContextFactory( @@ -53,7 +56,7 @@ namespace Umbraco.Tests.Integration httpContextAccessor, Mock.Of(), Mock.Of(), - Mock.Of()); + backofficeSecurityAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); var umbracoContext = umbracoContextReference.UmbracoContext; @@ -73,7 +76,8 @@ namespace Umbraco.Tests.Integration var globalSettings = new GlobalSettingsBuilder().Build(); var httpContextAccessor = Mock.Of(); var hostingEnvironment = Mock.Of(); - + var backofficeSecurityAccessor = Mock.Of(); + Mock.Get(backofficeSecurityAccessor).Setup(x => x.BackofficeSecurity).Returns(Mock.Of()); var umbracoContextFactory = new UmbracoContextFactory( _umbracoContextAccessor, Mock.Of(), @@ -86,7 +90,7 @@ namespace Umbraco.Tests.Integration httpContextAccessor, Mock.Of(), Mock.Of(), - Mock.Of()); + backofficeSecurityAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); var umbCtx = umbracoContextReference.UmbracoContext; @@ -105,7 +109,8 @@ namespace Umbraco.Tests.Integration publishedSnapshot.Setup(x => x.Members).Returns(Mock.Of()); var content = new Mock(); content.Setup(x => x.Id).Returns(2); - + var backofficeSecurityAccessor = Mock.Of(); + Mock.Get(backofficeSecurityAccessor).Setup(x => x.BackofficeSecurity).Returns(Mock.Of()); var publishedSnapshotService = new Mock(); var httpContextAccessor = Mock.Of(); var hostingEnvironment = Mock.Of(); @@ -123,7 +128,7 @@ namespace Umbraco.Tests.Integration httpContextAccessor, Mock.Of(), Mock.Of(), - Mock.Of()); + backofficeSecurityAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); var umbracoContext = umbracoContextReference.UmbracoContext; @@ -147,7 +152,8 @@ namespace Umbraco.Tests.Integration var globalSettings = new GlobalSettingsBuilder().Build(); var httpContextAccessor = Mock.Of(); var hostingEnvironment = Mock.Of(); - + var backofficeSecurityAccessor = Mock.Of(); + Mock.Get(backofficeSecurityAccessor).Setup(x => x.BackofficeSecurity).Returns(Mock.Of()); var umbracoContextFactory = new UmbracoContextFactory( _umbracoContextAccessor, Mock.Of(), @@ -160,7 +166,7 @@ namespace Umbraco.Tests.Integration httpContextAccessor, Mock.Of(), Mock.Of(), - Mock.Of()); + backofficeSecurityAccessor); var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); var umbracoContext = umbracoContextReference.UmbracoContext; diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index 13f58f8021..02f6f24779 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -81,7 +81,7 @@ namespace Umbraco.Tests.Cache.PublishedCache _umbracoContext = new UmbracoContext( httpContextAccessor, publishedSnapshotService.Object, - Mock.Of(), + Mock.Of(), globalSettings, HostingEnvironment, new TestVariationContextAccessor(), diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs index 3d9b4af526..1c70879da1 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs @@ -74,7 +74,7 @@ namespace Umbraco.Tests.PublishedContent var umbracoContext = new UmbracoContext( httpContextAccessor, publishedSnapshotService.Object, - Mock.Of(), + Mock.Of(), globalSettings, HostingEnvironment, new TestVariationContextAccessor(), diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index 243ad50eef..edd4d38075 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -126,7 +126,7 @@ namespace Umbraco.Tests.Scoping var umbracoContext = new UmbracoContext( httpContextAccessor, service, - Mock.Of(), + Mock.Of(), globalSettings, HostingEnvironment, new TestVariationContextAccessor(), diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs index 87d470f31e..379c176099 100644 --- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs +++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs @@ -95,7 +95,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting var backofficeIdentity = (UmbracoBackOfficeIdentity) owinContext.Authentication.User.Identity; - var webSecurity = new Mock(); + var backofficeSecurity = new Mock(); //mock CurrentUser var groups = new List(); @@ -116,13 +116,13 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting mockUser.Setup(x => x.StartContentIds).Returns(backofficeIdentity.StartContentNodes); mockUser.Setup(x => x.StartMediaIds).Returns(backofficeIdentity.StartMediaNodes); mockUser.Setup(x => x.Username).Returns(backofficeIdentity.Username); - webSecurity.Setup(x => x.CurrentUser) + backofficeSecurity.Setup(x => x.CurrentUser) .Returns(mockUser.Object); //mock Validate - webSecurity.Setup(x => x.ValidateCurrentUser()) + backofficeSecurity.Setup(x => x.ValidateCurrentUser()) .Returns(() => true); - webSecurity.Setup(x => x.UserHasSectionAccess(It.IsAny(), It.IsAny())) + backofficeSecurity.Setup(x => x.UserHasSectionAccess(It.IsAny(), It.IsAny())) .Returns(() => true); var publishedSnapshot = new Mock(); @@ -135,7 +135,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting var httpContextAccessor = TestHelper.GetHttpContextAccessor(httpContext); var umbCtx = new UmbracoContext(httpContextAccessor, publishedSnapshotService.Object, - webSecurity.Object, + backofficeSecurity.Object, globalSettings, TestHelper.GetHostingEnvironment(), new TestVariationContextAccessor(), diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index f1a834021f..fe41ac2d9c 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -372,7 +372,7 @@ namespace Umbraco.Tests.TestHelpers var umbracoContext = new UmbracoContext( httpContextAccessor, service, - Mock.Of(), + Mock.Of(), globalSettings ?? new GlobalSettingsBuilder().Build(), HostingEnvironment, new TestVariationContextAccessor(), diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 0c39ee47f0..08a1297cda 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -316,7 +316,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(); Composition.RegisterUnique(); - Composition.RegisterUnique(); + Composition.RegisterUnique(); Composition.RegisterUnique(); Composition.RegisterUnique(); Composition.RegisterUnique(); diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 5e89f29496..bcaf1ceccf 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -440,7 +440,7 @@ namespace Umbraco.Tests.Web.Mvc var ctx = new UmbracoContext( httpContextAccessor, _service, - Mock.Of(), + Mock.Of(), globalSettings, HostingEnvironment, new TestVariationContextAccessor(), diff --git a/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs b/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs index 32d8e0917b..0e5b963d9f 100644 --- a/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs +++ b/src/Umbraco.Tests/Web/WebExtensionMethodTests.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Web var umbCtx = new UmbracoContext( httpContextAccessor, Mock.Of(), - Mock.Of(), + Mock.Of(), TestObjects.GetGlobalSettings(), HostingEnvironment, new TestVariationContextAccessor(), @@ -53,7 +53,7 @@ namespace Umbraco.Tests.Web var umbCtx = new UmbracoContext( httpContextAccessor, Mock.Of(), - Mock.Of(), + Mock.Of(), TestObjects.GetGlobalSettings(), HostingEnvironment, new TestVariationContextAccessor(), @@ -84,7 +84,7 @@ namespace Umbraco.Tests.Web var umbCtx = new UmbracoContext( httpContextAccessor, Mock.Of(), - Mock.Of(), + Mock.Of(), TestObjects.GetGlobalSettings(), HostingEnvironment, new TestVariationContextAccessor(), diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs index 53a7a324dc..185269b6f1 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs @@ -16,6 +16,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Extensions; using Umbraco.Net; @@ -39,7 +40,7 @@ namespace Umbraco.Web.BackOffice.Controllers [IsBackOffice] // TODO: This could be applied with our Application Model conventions public class AuthenticationController : UmbracoApiControllerBase { - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly BackOfficeUserManager _userManager; private readonly BackOfficeSignInManager _signInManager; private readonly IUserService _userService; @@ -58,7 +59,7 @@ namespace Umbraco.Web.BackOffice.Controllers // TODO: We need to review all _userManager.Raise calls since many/most should be on the usermanager or signinmanager, very few should be here public AuthenticationController( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, BackOfficeUserManager backOfficeUserManager, BackOfficeSignInManager signInManager, IUserService userService, @@ -73,7 +74,7 @@ namespace Umbraco.Web.BackOffice.Controllers Core.Hosting.IHostingEnvironment hostingEnvironment, IRequestAccessor requestAccessor) { - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _userManager = backOfficeUserManager; _signInManager = signInManager; _userService = userService; @@ -96,7 +97,7 @@ namespace Umbraco.Web.BackOffice.Controllers [UmbracoAuthorize] public IDictionary GetPasswordConfig(int userId) { - return _passwordConfiguration.GetConfiguration(userId != _webSecurity.CurrentUser.Id); + return _passwordConfiguration.GetConfiguration(userId != _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); } /// @@ -164,7 +165,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpGet] public bool IsAuthenticated() { - var attempt = _webSecurity.AuthorizeRequest(); + var attempt = _backofficeSecurityAccessor.BackofficeSecurity.AuthorizeRequest(); if (attempt == ValidateRequestAttempt.Success) { return true; @@ -186,7 +187,7 @@ namespace Umbraco.Web.BackOffice.Controllers //[CheckIfUserTicketDataIsStale] // TODO: Migrate this, though it will need to be done differently at the cookie auth level public UserDetail GetCurrentUser() { - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; var result = _umbracoMapper.Map(user); //set their remaining seconds @@ -207,7 +208,7 @@ namespace Umbraco.Web.BackOffice.Controllers [SetAngularAntiForgeryTokens] public ActionResult GetCurrentInvitedUser() { - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; if (user.IsApproved) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index 141578cccd..6db4efab40 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -15,6 +15,7 @@ using Umbraco.Core.Configuration.Grid; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Hosting; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Extensions; @@ -45,7 +46,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly BackOfficeServerVariables _backOfficeServerVariables; private readonly AppCaches _appCaches; private readonly BackOfficeSignInManager _signInManager; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly ILogger _logger; public BackOfficeController( @@ -59,7 +60,7 @@ namespace Umbraco.Web.BackOffice.Controllers BackOfficeServerVariables backOfficeServerVariables, AppCaches appCaches, BackOfficeSignInManager signInManager, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILogger logger) { _userManager = userManager; @@ -72,7 +73,7 @@ namespace Umbraco.Web.BackOffice.Controllers _backOfficeServerVariables = backOfficeServerVariables; _appCaches = appCaches; _signInManager = signInManager; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _logger = logger; } @@ -93,7 +94,7 @@ namespace Umbraco.Web.BackOffice.Controllers //if you are hitting VerifyInvite, you're already signed in as a different user, and the token is invalid //you'll exit on one of the return RedirectToAction(nameof(Default)) but you're still logged in so you just get //dumped at the default admin view with no detail - if (_webSecurity.IsAuthenticated()) + if (_backofficeSecurityAccessor.BackofficeSecurity.IsAuthenticated()) { await _signInManager.SignOutAsync(); } @@ -186,7 +187,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpGet] public Dictionary> LocalizedText(string culture = null) { - var isAuthenticated = _webSecurity.IsAuthenticated(); + var isAuthenticated = _backofficeSecurityAccessor.BackofficeSecurity.IsAuthenticated(); var cultureInfo = string.IsNullOrWhiteSpace(culture) //if the user is logged in, get their culture, otherwise default to 'en' diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs index 7704b198ae..66ece55162 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs @@ -56,7 +56,7 @@ namespace Umbraco.Web.Editors private readonly IContentService _contentService; private readonly ILocalizedTextService _localizedTextService; private readonly IUserService _userService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IEntityService _entityService; private readonly IContentTypeService _contentTypeService; private readonly UmbracoMapper _umbracoMapper; @@ -84,7 +84,7 @@ namespace Umbraco.Web.Editors PropertyEditorCollection propertyEditors, IContentService contentService, IUserService userService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IContentTypeService contentTypeService, UmbracoMapper umbracoMapper, @@ -105,7 +105,7 @@ namespace Umbraco.Web.Editors _contentService = contentService; _localizedTextService = localizedTextService; _userService = userService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _entityService = entityService; _contentTypeService = contentTypeService; _umbracoMapper = umbracoMapper; @@ -428,7 +428,7 @@ namespace Umbraco.Web.Editors private ContentItemDisplay GetEmpty(IContentType contentType, int parentId) { - var emptyContent = _contentService.Create("", parentId, contentType.Alias, _webSecurity.GetUserId().ResultOr(0)); + var emptyContent = _contentService.Create("", parentId, contentType.Alias, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); var mapped = MapToDisplay(emptyContent); // translate the content type name if applicable mapped.ContentTypeName = _localizedTextService.UmbracoDictionaryTranslate(CultureDictionary, mapped.ContentTypeName); @@ -597,9 +597,9 @@ namespace Umbraco.Web.Editors EnsureUniqueName(name, content, nameof(name)); - var blueprint = _contentService.CreateContentFromBlueprint(content, name, _webSecurity.GetUserId().ResultOr(0)); + var blueprint = _contentService.CreateContentFromBlueprint(content, name, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); - _contentService.SaveBlueprint(blueprint, _webSecurity.GetUserId().ResultOr(0)); + _contentService.SaveBlueprint(blueprint, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); var notificationModel = new SimpleNotificationModel(); notificationModel.AddSuccessNotification( @@ -633,7 +633,7 @@ namespace Umbraco.Web.Editors { EnsureUniqueName(content.Name, content, "Name"); - _contentService.SaveBlueprint(contentItem.PersistedContent, _webSecurity.CurrentUser.Id); + _contentService.SaveBlueprint(contentItem.PersistedContent, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); //we need to reuse the underlying logic so return the result that it wants return OperationResult.Succeed(new EventMessages()); }, @@ -658,7 +658,7 @@ namespace Umbraco.Web.Editors { var contentItemDisplay = PostSaveInternal( contentItem, - content => _contentService.Save(contentItem.PersistedContent, _webSecurity.CurrentUser.Id), + content => _contentService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id), MapToDisplay); return contentItemDisplay; @@ -760,7 +760,7 @@ namespace Umbraco.Web.Editors case ContentSaveAction.SendPublish: case ContentSaveAction.SendPublishNew: - var sendResult = _contentService.SendToPublication(contentItem.PersistedContent, _webSecurity.CurrentUser.Id); + var sendResult = _contentService.SendToPublication(contentItem.PersistedContent, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); wasCancelled = sendResult == false; if (sendResult) { @@ -1204,7 +1204,7 @@ namespace Umbraco.Web.Editors //if this item's path has already been denied or if the user doesn't have access to it, add to the deny list if (denied.Any(x => c.Path.StartsWith($"{x.Path},")) || (ContentPermissionsHelper.CheckPermissions(c, - _webSecurity.CurrentUser, _userService, _entityService, + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, _userService, _entityService, ActionPublish.ActionLetter) == ContentPermissionsHelper.ContentAccess.Denied)) { denied.Add(c); @@ -1221,7 +1221,7 @@ namespace Umbraco.Web.Editors if (!contentItem.PersistedContent.ContentType.VariesByCulture()) { //its invariant, proceed normally - var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent, force, userId: _webSecurity.CurrentUser.Id); + var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent, force, userId: _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); // TODO: Deal with multiple cancellations wasCancelled = publishStatus.Any(x => x.Result == PublishResultType.FailedPublishCancelledByEvent); successfulCultures = null; //must be null! this implies invariant @@ -1256,7 +1256,7 @@ namespace Umbraco.Web.Editors if (canPublish) { //proceed to publish if all validation still succeeds - var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent, force, culturesToPublish, _webSecurity.CurrentUser.Id); + var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent, force, culturesToPublish, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); // TODO: Deal with multiple cancellations wasCancelled = publishStatus.Any(x => x.Result == PublishResultType.FailedPublishCancelledByEvent); successfulCultures = contentItem.Variants.Where(x => x.Publish).Select(x => x.Culture).ToArray(); @@ -1265,7 +1265,7 @@ namespace Umbraco.Web.Editors else { //can only save - var saveResult = _contentService.Save(contentItem.PersistedContent, _webSecurity.CurrentUser.Id); + var saveResult = _contentService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); var publishStatus = new[] { new PublishResult(PublishResultType.FailedPublishMandatoryCultureMissing, null, contentItem.PersistedContent) @@ -1293,7 +1293,7 @@ namespace Umbraco.Web.Editors if (!contentItem.PersistedContent.ContentType.VariesByCulture()) { //its invariant, proceed normally - var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent, userId: _webSecurity.CurrentUser.Id); + var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent, userId: _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); wasCancelled = publishStatus.Result == PublishResultType.FailedPublishCancelledByEvent; successfulCultures = null; //must be null! this implies invariant return publishStatus; @@ -1338,7 +1338,7 @@ namespace Umbraco.Web.Editors if (canPublish) { //proceed to publish if all validation still succeeds - var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent, culturesToPublish, _webSecurity.CurrentUser.Id); + var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent, culturesToPublish, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); wasCancelled = publishStatus.Result == PublishResultType.FailedPublishCancelledByEvent; successfulCultures = culturesToPublish; return publishStatus; @@ -1346,7 +1346,7 @@ namespace Umbraco.Web.Editors else { //can only save - var saveResult = _contentService.Save(contentItem.PersistedContent, _webSecurity.CurrentUser.Id); + var saveResult = _contentService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); var publishStatus = new PublishResult(PublishResultType.FailedPublishMandatoryCultureMissing, null, contentItem.PersistedContent); wasCancelled = saveResult.Result == OperationResultType.FailedCancelledByEvent; successfulCultures = Array.Empty(); @@ -1501,7 +1501,7 @@ namespace Umbraco.Web.Editors return HandleContentNotFound(id, false); } - var publishResult = _contentService.SaveAndPublish(foundContent, userId: _webSecurity.GetUserId().ResultOr(0)); + var publishResult = _contentService.SaveAndPublish(foundContent, userId: _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); if (publishResult.Success == false) { var notificationModel = new SimpleNotificationModel(); @@ -1553,7 +1553,7 @@ namespace Umbraco.Web.Editors //if the current item is in the recycle bin if (foundContent.Trashed == false) { - var moveResult = _contentService.MoveToRecycleBin(foundContent, _webSecurity.GetUserId().ResultOr(0)); + var moveResult = _contentService.MoveToRecycleBin(foundContent, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); if (moveResult.Success == false) { //returning an object of INotificationModel will ensure that any pending @@ -1563,7 +1563,7 @@ namespace Umbraco.Web.Editors } else { - var deleteResult = _contentService.Delete(foundContent, _webSecurity.GetUserId().ResultOr(0)); + var deleteResult = _contentService.Delete(foundContent, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); if (deleteResult.Success == false) { //returning an object of INotificationModel will ensure that any pending @@ -1587,7 +1587,7 @@ namespace Umbraco.Web.Editors [EnsureUserPermissionForContent(Constants.System.RecycleBinContent, ActionDelete.ActionLetter)] public IActionResult EmptyRecycleBin() { - _contentService.EmptyRecycleBin(_webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + _contentService.EmptyRecycleBin(_backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); return new UmbracoNotificationSuccessResponse(_localizedTextService.Localize("defaultdialogs/recycleBinIsEmpty")); } @@ -1616,7 +1616,7 @@ namespace Umbraco.Web.Editors var contentService = _contentService; // Save content with new sort order and update content xml in db accordingly - var sortResult = contentService.Sort(sorted.IdSortOrder, _webSecurity.CurrentUser.Id); + var sortResult = contentService.Sort(sorted.IdSortOrder, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); if (!sortResult.Success) { Logger.Warn("Content sorting failed, this was probably caused by an event being cancelled"); @@ -1643,7 +1643,7 @@ namespace Umbraco.Web.Editors { var toMove = ValidateMoveOrCopy(move); - _contentService.Move(toMove, move.ParentId, _webSecurity.GetUserId().ResultOr(0)); + _contentService.Move(toMove, move.ParentId, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); return Content(toMove.Path, MediaTypeNames.Text.Plain, Encoding.UTF8); } @@ -1658,7 +1658,7 @@ namespace Umbraco.Web.Editors { var toCopy = ValidateMoveOrCopy(copy); - var c = _contentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal, copy.Recursive, _webSecurity.GetUserId().ResultOr(0)); + var c = _contentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal, copy.Recursive, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); return Content(c.Path, MediaTypeNames.Text.Plain, Encoding.UTF8); } @@ -1681,7 +1681,7 @@ namespace Umbraco.Web.Editors if (model.Cultures.Length == 0 || model.Cultures.Length == languageCount) { //this means that the entire content item will be unpublished - var unpublishResult = _contentService.Unpublish(foundContent, userId: _webSecurity.GetUserId().ResultOr(0)); + var unpublishResult = _contentService.Unpublish(foundContent, userId: _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); var content = MapToDisplay(foundContent); @@ -1704,7 +1704,7 @@ namespace Umbraco.Web.Editors var results = new Dictionary(); foreach (var c in model.Cultures) { - var result = _contentService.Unpublish(foundContent, culture: c, userId: _webSecurity.GetUserId().ResultOr(0)); + var result = _contentService.Unpublish(foundContent, culture: c, userId: _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); results[c] = result; if (result.Result == PublishResultType.SuccessUnpublishMandatoryCulture) { @@ -1772,7 +1772,7 @@ namespace Umbraco.Web.Editors return NotFound("There is no content node with id {model.NodeId}."); } - var permission = _userService.GetPermissions(_webSecurity.CurrentUser, node.Path); + var permission = _userService.GetPermissions(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, node.Path); if (permission.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) == false) @@ -2260,7 +2260,7 @@ namespace Umbraco.Web.Editors { var display = _umbracoMapper.Map(content, context => { - context.Items["CurrentUser"] = _webSecurity.CurrentUser; + context.Items["CurrentUser"] = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; }); display.AllowPreview = display.AllowPreview && content.Trashed == false && content.ContentType.IsElement == false; return display; @@ -2275,7 +2275,7 @@ namespace Umbraco.Web.Editors var content = _contentService.GetById(contentId); if (content == null) return NotFound(); - var userNotifications = _notificationService.GetUserNotifications(_webSecurity.CurrentUser, content.Path).ToList(); + var userNotifications = _notificationService.GetUserNotifications(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, content.Path).ToList(); foreach (var a in _actionCollection.Where(x => x.ShowInNotifier)) { @@ -2297,7 +2297,7 @@ namespace Umbraco.Web.Editors var content = _contentService.GetById(contentId); if (content == null) return NotFound(); - _notificationService.SetNotifications(_webSecurity.CurrentUser, content, notifyOptions); + _notificationService.SetNotifications(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, content, notifyOptions); return NoContent(); } @@ -2362,7 +2362,7 @@ namespace Umbraco.Web.Editors [HttpPost] public IActionResult PostRollbackContent(int contentId, int versionId, string culture = "*") { - var rollbackResult = _contentService.Rollback(contentId, versionId, culture, _webSecurity.GetUserId().ResultOr(0)); + var rollbackResult = _contentService.Rollback(contentId, versionId, culture, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); if (rollbackResult.Success) return Ok(); diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs index 4f7260a35c..7955b82eeb 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs @@ -26,6 +26,7 @@ using Umbraco.Web.Models; using Umbraco.Web.Models.ContentEditing; using Constants = Umbraco.Core.Constants; using Umbraco.Core.Mapping; +using Umbraco.Core.Security; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Exceptions; @@ -56,7 +57,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IIOHelper _ioHelper; private readonly IContentTypeService _contentTypeService; private readonly UmbracoMapper _umbracoMapper; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IDataTypeService _dataTypeService; private readonly IShortStringHelper _shortStringHelper; private readonly ILocalizedTextService _localizedTextService; @@ -81,7 +82,7 @@ namespace Umbraco.Web.BackOffice.Controllers PropertyEditorCollection propertyEditors, IScopeProvider scopeProvider, IIOHelper ioHelper, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IDataTypeService dataTypeService, IShortStringHelper shortStringHelper, IFileService fileService, @@ -108,7 +109,7 @@ namespace Umbraco.Web.BackOffice.Controllers _ioHelper = ioHelper; _contentTypeService = contentTypeService; _umbracoMapper = umbracoMapper; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _dataTypeService = dataTypeService; _shortStringHelper = shortStringHelper; _localizedTextService = localizedTextService; @@ -207,7 +208,7 @@ namespace Umbraco.Web.BackOffice.Controllers throw new HttpResponseException(HttpStatusCode.NotFound); } - _contentTypeService.Delete(foundType, _webSecurity.CurrentUser.Id); + _contentTypeService.Delete(foundType, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return Ok(); } @@ -306,14 +307,14 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpPost] public IActionResult DeleteContainer(int id) { - _contentTypeService.DeleteContainer(id, _webSecurity.CurrentUser.Id); + _contentTypeService.DeleteContainer(id, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return Ok(); } public IActionResult PostCreateContainer(int parentId, string name) { - var result = _contentTypeService.CreateContainer(parentId, name, _webSecurity.CurrentUser.Id); + var result = _contentTypeService.CreateContainer(parentId, name, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return result ? Ok(result.Result) //return the id @@ -322,7 +323,7 @@ namespace Umbraco.Web.BackOffice.Controllers public IActionResult PostRenameContainer(int id, string name) { - var result = _contentTypeService.RenameContainer(id, name, _webSecurity.CurrentUser.Id); + var result = _contentTypeService.RenameContainer(id, name, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return result ? Ok(result.Result) //return the id @@ -622,7 +623,7 @@ namespace Umbraco.Web.BackOffice.Controllers var xd = new XmlDocument {XmlResolver = null}; xd.Load(filePath); - var userId = _webSecurity.GetUserId().ResultOr(0); + var userId = _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0); var element = XElement.Parse(xd.InnerXml); dataInstaller.ImportDocumentType(element, userId); diff --git a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs index 433c26169f..3aab1853dc 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs @@ -16,6 +16,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Mapping; using Umbraco.Core.Media; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Extensions; @@ -39,7 +40,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly ContentSettings _contentSettings; private readonly IHostingEnvironment _hostingEnvironment; private readonly IImageUrlGenerator _imageUrlGenerator; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IUserService _userService; private readonly UmbracoMapper _umbracoMapper; private readonly BackOfficeUserManager _backOfficeUserManager; @@ -53,7 +54,7 @@ namespace Umbraco.Web.BackOffice.Controllers IOptions contentSettings, IHostingEnvironment hostingEnvironment, IImageUrlGenerator imageUrlGenerator, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IUserService userService, UmbracoMapper umbracoMapper, BackOfficeUserManager backOfficeUserManager, @@ -66,7 +67,7 @@ namespace Umbraco.Web.BackOffice.Controllers _contentSettings = contentSettings.Value; _hostingEnvironment = hostingEnvironment; _imageUrlGenerator = imageUrlGenerator; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _userService = userService; _umbracoMapper = umbracoMapper; _backOfficeUserManager = backOfficeUserManager; @@ -86,7 +87,7 @@ namespace Umbraco.Web.BackOffice.Controllers public Dictionary GetPermissions(int[] nodeIds) { var permissions = _userService - .GetPermissions(_webSecurity.CurrentUser, nodeIds); + .GetPermissions(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, nodeIds); var permissionsDictionary = new Dictionary(); foreach (var nodeId in nodeIds) @@ -107,7 +108,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpGet] public bool HasPermission(string permissionToCheck, int nodeId) { - var p = _userService.GetPermissions(_webSecurity.CurrentUser, nodeId).GetAllPermissions(); + var p = _userService.GetPermissions(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, nodeId).GetAllPermissions(); if (p.Contains(permissionToCheck.ToString(CultureInfo.InvariantCulture))) { return true; @@ -126,15 +127,15 @@ namespace Umbraco.Web.BackOffice.Controllers if (status == null) throw new ArgumentNullException(nameof(status)); List userTours; - if (_webSecurity.CurrentUser.TourData.IsNullOrWhiteSpace()) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.TourData.IsNullOrWhiteSpace()) { userTours = new List { status }; - _webSecurity.CurrentUser.TourData = JsonConvert.SerializeObject(userTours); - _userService.Save(_webSecurity.CurrentUser); + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.TourData = JsonConvert.SerializeObject(userTours); + _userService.Save(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser); return userTours; } - userTours = JsonConvert.DeserializeObject>(_webSecurity.CurrentUser.TourData).ToList(); + userTours = JsonConvert.DeserializeObject>(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.TourData).ToList(); var found = userTours.FirstOrDefault(x => x.Alias == status.Alias); if (found != null) { @@ -142,8 +143,8 @@ namespace Umbraco.Web.BackOffice.Controllers userTours.Remove(found); } userTours.Add(status); - _webSecurity.CurrentUser.TourData = JsonConvert.SerializeObject(userTours); - _userService.Save(_webSecurity.CurrentUser); + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.TourData = JsonConvert.SerializeObject(userTours); + _userService.Save(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser); return userTours; } @@ -153,10 +154,10 @@ namespace Umbraco.Web.BackOffice.Controllers /// public IEnumerable GetUserTours() { - if (_webSecurity.CurrentUser.TourData.IsNullOrWhiteSpace()) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.TourData.IsNullOrWhiteSpace()) return Enumerable.Empty(); - var userTours = JsonConvert.DeserializeObject>(_webSecurity.CurrentUser.TourData); + var userTours = JsonConvert.DeserializeObject>(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.TourData); return userTours; } @@ -172,7 +173,7 @@ namespace Umbraco.Web.BackOffice.Controllers [UmbracoAuthorize(redirectToUmbracoLogin: false, requireApproval : true)] public async Task PostSetInvitedUserPassword([FromBody]string newPassword) { - var user = await _backOfficeUserManager.FindByIdAsync(_webSecurity.GetUserId().ResultOr(0).ToString()); + var user = await _backOfficeUserManager.FindByIdAsync(_backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0).ToString()); if (user == null) throw new InvalidOperationException("Could not find user"); var result = await _backOfficeUserManager.AddPasswordAsync(user, newPassword); @@ -187,13 +188,13 @@ namespace Umbraco.Web.BackOffice.Controllers } //They've successfully set their password, we can now update their user account to be approved - _webSecurity.CurrentUser.IsApproved = true; + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsApproved = true; //They've successfully set their password, and will now get fully logged into the back office, so the lastlogindate is set so the backoffice shows they have logged in - _webSecurity.CurrentUser.LastLoginDate = DateTime.UtcNow; - _userService.Save(_webSecurity.CurrentUser); + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.LastLoginDate = DateTime.UtcNow; + _userService.Save(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser); //now we can return their full object since they are now really logged into the back office - var userDisplay = _umbracoMapper.Map(_webSecurity.CurrentUser); + var userDisplay = _umbracoMapper.Map(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser); userDisplay.SecondsUntilTimeout = HttpContext.User.GetRemainingAuthSeconds(); return userDisplay; @@ -203,7 +204,7 @@ namespace Umbraco.Web.BackOffice.Controllers public async Task PostSetAvatar(IList files) { //borrow the logic from the user controller - return await UsersController.PostSetAvatarInternal(files, _userService, _appCaches.RuntimeCache, _mediaFileSystem, _shortStringHelper, _contentSettings, _hostingEnvironment, _imageUrlGenerator, _webSecurity.GetUserId().ResultOr(0)); + return await UsersController.PostSetAvatarInternal(files, _userService, _appCaches.RuntimeCache, _mediaFileSystem, _shortStringHelper, _contentSettings, _hostingEnvironment, _imageUrlGenerator, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); } /// @@ -216,7 +217,7 @@ namespace Umbraco.Web.BackOffice.Controllers public async Task> PostChangePassword(ChangingPasswordModel data) { var passwordChanger = new PasswordChanger(_logger); - var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(_webSecurity.CurrentUser, _webSecurity.CurrentUser, data, _backOfficeUserManager); + var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, data, _backOfficeUserManager); if (passwordChangeResult.Success) { @@ -238,7 +239,7 @@ namespace Umbraco.Web.BackOffice.Controllers [ValidateAngularAntiForgeryToken] public async Task> GetCurrentUserLinkedLogins() { - var identityUser = await _backOfficeUserManager.FindByIdAsync(_webSecurity.GetUserId().ResultOr(0).ToString()); + var identityUser = await _backOfficeUserManager.FindByIdAsync(_backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0).ToString()); return identityUser.Logins.ToDictionary(x => x.LoginProvider, x => x.ProviderKey); } } diff --git a/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs b/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs index 2882c28f4f..207dee60f4 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/DictionaryController.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Mapping; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; @@ -34,7 +35,7 @@ namespace Umbraco.Web.BackOffice.Controllers { private readonly ILogger _logger; private readonly ILocalizationService _localizationService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly GlobalSettings _globalSettings; private readonly ILocalizedTextService _localizedTextService; private readonly UmbracoMapper _umbracoMapper; @@ -42,7 +43,7 @@ namespace Umbraco.Web.BackOffice.Controllers public DictionaryController( ILogger logger, ILocalizationService localizationService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IOptions globalSettings, ILocalizedTextService localizedTextService, UmbracoMapper umbracoMapper @@ -50,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Controllers { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _localizationService = localizationService ?? throw new ArgumentNullException(nameof(localizationService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _globalSettings = globalSettings.Value ?? throw new ArgumentNullException(nameof(globalSettings)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); @@ -74,10 +75,10 @@ namespace Umbraco.Web.BackOffice.Controllers foreach (var dictionaryItem in foundDictionaryDescendants) { - _localizationService.Delete(dictionaryItem, _webSecurity.CurrentUser.Id); + _localizationService.Delete(dictionaryItem, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); } - _localizationService.Delete(foundDictionary, _webSecurity.CurrentUser.Id); + _localizationService.Delete(foundDictionary, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return Ok(); } @@ -104,7 +105,7 @@ namespace Umbraco.Web.BackOffice.Controllers { var message = _localizedTextService.Localize( "dictionaryItem/changeKeyError", - _webSecurity.CurrentUser.GetUserCulture(_localizedTextService, _globalSettings), + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.GetUserCulture(_localizedTextService, _globalSettings), new Dictionary { { "0", key } }); throw HttpResponseException.CreateNotificationValidationErrorResponse(message); } @@ -218,7 +219,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (dictionaryItem == null) throw HttpResponseException.CreateNotificationValidationErrorResponse("Dictionary item does not exist"); - var userCulture = _webSecurity.CurrentUser.GetUserCulture(_localizedTextService, _globalSettings); + var userCulture = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.GetUserCulture(_localizedTextService, _globalSettings); if (dictionary.NameIsDirty) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs b/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs index 1afe9bccf4..35d9c51cd4 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Core.Mapping; using Umbraco.Core.Models.Entities; using Umbraco.Core.Persistence; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Core.Xml; @@ -53,7 +54,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IPublishedContentQuery _publishedContentQuery; private readonly IShortStringHelper _shortStringHelper; private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IPublishedUrlProvider _publishedUrlProvider; private readonly IContentService _contentService; private readonly UmbracoMapper _umbracoMapper; @@ -74,7 +75,7 @@ namespace Umbraco.Web.BackOffice.Controllers IPublishedContentQuery publishedContentQuery, IShortStringHelper shortStringHelper, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IPublishedUrlProvider publishedUrlProvider, IContentService contentService, UmbracoMapper umbracoMapper, @@ -96,7 +97,7 @@ namespace Umbraco.Web.BackOffice.Controllers publishedContentQuery ?? throw new ArgumentNullException(nameof(publishedContentQuery)); _shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _publishedUrlProvider = publishedUrlProvider ?? throw new ArgumentNullException(nameof(publishedUrlProvider)); _contentService = contentService ?? throw new ArgumentNullException(nameof(contentService)); @@ -175,7 +176,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (string.IsNullOrEmpty(query)) return result; - var allowedSections = _webSecurity.CurrentUser.AllowedSections.ToArray(); + var allowedSections = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.AllowedSections.ToArray(); foreach (var searchableTree in _searchableTreeCollection.SearchableApplicationTrees.OrderBy(t => t.Value.SortOrder)) { @@ -721,9 +722,9 @@ namespace Umbraco.Web.BackOffice.Controllers switch (type) { case UmbracoEntityTypes.Document: - return _webSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService); + return _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService); case UmbracoEntityTypes.Media: - return _webSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService); + return _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService); default: return Array.Empty(); } @@ -862,10 +863,10 @@ namespace Umbraco.Web.BackOffice.Controllers switch (entityType) { case UmbracoEntityTypes.Document: - aids = _webSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService); + aids = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService); break; case UmbracoEntityTypes.Media: - aids = _webSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService); + aids = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService); break; } diff --git a/src/Umbraco.Web.BackOffice/Controllers/LogController.cs b/src/Umbraco.Web.BackOffice/Controllers/LogController.cs index e99ea890d7..7dd2b1af44 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/LogController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/LogController.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Mapping; using Umbraco.Core.Media; using Umbraco.Core.Models; using Umbraco.Core.Persistence; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; @@ -26,7 +27,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IImageUrlGenerator _imageUrlGenerator; private readonly IAuditService _auditService; private readonly UmbracoMapper _umbracoMapper; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IUserService _userService; private readonly AppCaches _appCaches; private readonly ISqlContext _sqlContext; @@ -36,7 +37,7 @@ namespace Umbraco.Web.BackOffice.Controllers IImageUrlGenerator imageUrlGenerator, IAuditService auditService, UmbracoMapper umbracoMapper, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IUserService userService, AppCaches appCaches, ISqlContext sqlContext) @@ -45,7 +46,7 @@ namespace Umbraco.Web.BackOffice.Controllers _imageUrlGenerator = imageUrlGenerator ?? throw new ArgumentNullException(nameof(imageUrlGenerator)); _auditService = auditService ?? throw new ArgumentNullException(nameof(auditService)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _appCaches = appCaches ?? throw new ArgumentNullException(nameof(appCaches)); _sqlContext = sqlContext ?? throw new ArgumentNullException(nameof(sqlContext)); @@ -89,7 +90,7 @@ namespace Umbraco.Web.BackOffice.Controllers long totalRecords; var dateQuery = sinceDate.HasValue ? _sqlContext.Query().Where(x => x.CreateDate >= sinceDate) : null; - var userId = _webSecurity.GetUserId().ResultOr(0); + var userId = _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0); var result = _auditService.GetPagedItemsByUser(userId, pageNumber - 1, pageSize, out totalRecords, orderDirection, customFilter:dateQuery); var mapped = _umbracoMapper.MapEnumerable(result); return new PagedResult(totalRecords, pageNumber, pageSize) diff --git a/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs b/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs index cf951a57c3..b64a4753bb 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs @@ -18,6 +18,7 @@ using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Security; using Umbraco.Core; using Umbraco.Core.Mapping; +using Umbraco.Core.Security; namespace Umbraco.Web.BackOffice.Controllers { @@ -32,7 +33,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly ParameterEditorCollection _parameterEditorCollection; private readonly IMacroService _macroService; private readonly IShortStringHelper _shortStringHelper; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly ILogger _logger; private readonly IHostingEnvironment _hostingEnvironment; private readonly UmbracoMapper _umbracoMapper; @@ -41,7 +42,7 @@ namespace Umbraco.Web.BackOffice.Controllers ParameterEditorCollection parameterEditorCollection, IMacroService macroService, IShortStringHelper shortStringHelper, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILogger logger, IHostingEnvironment hostingEnvironment, UmbracoMapper umbracoMapper @@ -50,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Controllers _parameterEditorCollection = parameterEditorCollection ?? throw new ArgumentNullException(nameof(parameterEditorCollection)); _macroService = macroService ?? throw new ArgumentNullException(nameof(macroService)); _shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); @@ -95,7 +96,7 @@ namespace Umbraco.Web.BackOffice.Controllers MacroSource = string.Empty }; - _macroService.Save(macro, _webSecurity.CurrentUser.Id); + _macroService.Save(macro, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return macro.Id; } @@ -215,7 +216,7 @@ namespace Umbraco.Web.BackOffice.Controllers try { - _macroService.Save(macro, _webSecurity.CurrentUser.Id); + _macroService.Save(macro, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); macroDisplay.Notifications.Clear(); diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs index c9eaea0d4a..34f0f0afd7 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs @@ -26,6 +26,9 @@ using Umbraco.Core.Models.Validation; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Security; +using Umbraco.Web.ContentApps; +using Umbraco.Web.WebApi.Filters; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Extensions; @@ -55,7 +58,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IMediaTypeService _mediaTypeService; private readonly IMediaService _mediaService; private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly UmbracoMapper _umbracoMapper; private readonly IDataTypeService _dataTypeService; private readonly ILocalizedTextService _localizedTextService; @@ -72,7 +75,7 @@ namespace Umbraco.Web.BackOffice.Controllers IMediaTypeService mediaTypeService, IMediaService mediaService, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, UmbracoMapper umbracoMapper, IDataTypeService dataTypeService, ISqlContext sqlContext, @@ -88,7 +91,7 @@ namespace Umbraco.Web.BackOffice.Controllers _mediaTypeService = mediaTypeService; _mediaService = mediaService; _entityService = entityService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _umbracoMapper = umbracoMapper; _dataTypeService = dataTypeService; _localizedTextService = localizedTextService; @@ -115,7 +118,7 @@ namespace Umbraco.Web.BackOffice.Controllers throw new HttpResponseException(HttpStatusCode.NotFound); } - var emptyContent = _mediaService.CreateMedia("", parentId, contentType.Alias, _webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + var emptyContent = _mediaService.CreateMedia("", parentId, contentType.Alias, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); var mapped = _umbracoMapper.Map(emptyContent); //remove the listview app if it exists @@ -277,7 +280,7 @@ namespace Umbraco.Web.BackOffice.Controllers protected int[] UserStartNodes { - get { return _userStartNodes ?? (_userStartNodes = _webSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService)); } + get { return _userStartNodes ?? (_userStartNodes = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService)); } } /// @@ -434,7 +437,7 @@ namespace Umbraco.Web.BackOffice.Controllers //if the current item is in the recycle bin if (foundMedia.Trashed == false) { - var moveResult = _mediaService.MoveToRecycleBin(foundMedia, _webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + var moveResult = _mediaService.MoveToRecycleBin(foundMedia, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); if (moveResult == false) { //returning an object of INotificationModel will ensure that any pending @@ -444,7 +447,7 @@ namespace Umbraco.Web.BackOffice.Controllers } else { - var deleteResult = _mediaService.Delete(foundMedia, _webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + var deleteResult = _mediaService.Delete(foundMedia, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); if (deleteResult == false) { //returning an object of INotificationModel will ensure that any pending @@ -468,7 +471,7 @@ namespace Umbraco.Web.BackOffice.Controllers var destinationParentID = move.ParentId; var sourceParentID = toMove.ParentId; - var moveResult = _mediaService.Move(toMove, move.ParentId, _webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + var moveResult = _mediaService.Move(toMove, move.ParentId, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); if (sourceParentID == destinationParentID) { @@ -542,7 +545,7 @@ namespace Umbraco.Web.BackOffice.Controllers } //save the item - var saveStatus = _mediaService.Save(contentItem.PersistedContent, _webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + var saveStatus = _mediaService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); //return the updated model var display = _umbracoMapper.Map(contentItem.PersistedContent); @@ -588,7 +591,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpPost] public IActionResult EmptyRecycleBin() { - _mediaService.EmptyRecycleBin(_webSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); + _mediaService.EmptyRecycleBin(_backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId)); return new UmbracoNotificationSuccessResponse(_localizedTextService.Localize("defaultdialogs/recycleBinIsEmpty")); } @@ -645,7 +648,7 @@ namespace Umbraco.Web.BackOffice.Controllers var mediaService = _mediaService; var f = mediaService.CreateMedia(folder.Name, parentId.Value, Constants.Conventions.MediaTypes.Folder); - mediaService.Save(f, _webSecurity.CurrentUser.Id); + mediaService.Save(f, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return _umbracoMapper.Map(f); } @@ -753,7 +756,7 @@ namespace Umbraco.Web.BackOffice.Controllers var mediaItemName = fileName.ToFriendlyName(); - var f = mediaService.CreateMedia(mediaItemName, parentId.Value, mediaType, _webSecurity.CurrentUser.Id); + var f = mediaService.CreateMedia(mediaItemName, parentId.Value, mediaType, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); await using (var stream = formFile.OpenReadStream()) @@ -762,7 +765,7 @@ namespace Umbraco.Web.BackOffice.Controllers } - var saveResult = mediaService.Save(f, _webSecurity.CurrentUser.Id); + var saveResult = mediaService.Save(f, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); if (saveResult == false) { AddCancelMessage(tempFiles, @@ -855,7 +858,7 @@ namespace Umbraco.Web.BackOffice.Controllers //ensure the user has access to this folder by parent id! if (validatePermissions && CheckPermissions( new Dictionary(), - _webSecurity.CurrentUser, + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, _mediaService, _entityService, intParentId) == false) diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs index 617d3f1538..31cc5d63cd 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Dictionary; using Umbraco.Core.Mapping; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.BackOffice.Filters; @@ -36,7 +37,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IMediaTypeService _mediaTypeService; private readonly IShortStringHelper _shortStringHelper; private readonly UmbracoMapper _umbracoMapper; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public MediaTypeController(ICultureDictionary cultureDictionary, EditorValidatorCollection editorValidatorCollection, @@ -48,7 +49,7 @@ namespace Umbraco.Web.BackOffice.Controllers IShortStringHelper shortStringHelper, IEntityService entityService, IMediaService mediaService, - IWebSecurity webSecurity) + IBackofficeSecurityAccessor backofficeSecurityAccessor) : base( cultureDictionary, editorValidatorCollection, @@ -64,7 +65,7 @@ namespace Umbraco.Web.BackOffice.Controllers _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); _contentTypeService = contentTypeService ?? throw new ArgumentNullException(nameof(contentTypeService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); } @@ -147,7 +148,7 @@ namespace Umbraco.Web.BackOffice.Controllers throw new HttpResponseException(HttpStatusCode.NotFound); } - _mediaTypeService.Delete(foundType, _webSecurity.CurrentUser.Id); + _mediaTypeService.Delete(foundType, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return Ok(); } @@ -241,14 +242,14 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpPost] public IActionResult DeleteContainer(int id) { - _mediaTypeService.DeleteContainer(id, _webSecurity.CurrentUser.Id); + _mediaTypeService.DeleteContainer(id, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return Ok(); } public IActionResult PostCreateContainer(int parentId, string name) { - var result = _mediaTypeService.CreateContainer(parentId, name, _webSecurity.CurrentUser.Id); + var result = _mediaTypeService.CreateContainer(parentId, name, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return result ? Ok(result.Result) //return the id @@ -257,7 +258,7 @@ namespace Umbraco.Web.BackOffice.Controllers public IActionResult PostRenameContainer(int id, string name) { - var result = _mediaTypeService.RenameContainer(id, name, _webSecurity.CurrentUser.Id); + var result = _mediaTypeService.RenameContainer(id, name, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return result ? Ok(result.Result) //return the id diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs index 6a93bf6437..6d60da0910 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs @@ -54,7 +54,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IMemberTypeService _memberTypeService; private readonly IDataTypeService _dataTypeService; private readonly ILocalizedTextService _localizedTextService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IJsonSerializer _jsonSerializer; public MemberController( @@ -70,7 +70,7 @@ namespace Umbraco.Web.BackOffice.Controllers IMemberService memberService, IMemberTypeService memberTypeService, IDataTypeService dataTypeService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IJsonSerializer jsonSerializer) : base(cultureDictionary, logger, shortStringHelper, eventMessages, localizedTextService) { @@ -82,7 +82,7 @@ namespace Umbraco.Web.BackOffice.Controllers _memberTypeService = memberTypeService; _dataTypeService = dataTypeService; _localizedTextService = localizedTextService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _jsonSerializer = jsonSerializer; } @@ -310,7 +310,7 @@ namespace Umbraco.Web.BackOffice.Controllers throw new InvalidOperationException($"No member type found with alias {contentItem.ContentTypeAlias}"); var member = new Member(contentItem.Name, contentItem.Email, contentItem.Username, memberType, true) { - CreatorId = _webSecurity.CurrentUser.Id, + CreatorId = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id, RawPasswordValue = _passwordSecurity.HashPasswordForStorage(contentItem.Password.NewPassword), Comments = contentItem.Comments, IsApproved = contentItem.IsApproved @@ -328,13 +328,13 @@ namespace Umbraco.Web.BackOffice.Controllers /// private void UpdateMemberData(MemberSave contentItem) { - contentItem.PersistedContent.WriterId = _webSecurity.CurrentUser.Id; + contentItem.PersistedContent.WriterId = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id; // If the user doesn't have access to sensitive values, then we need to check if any of the built in member property types // have been marked as sensitive. If that is the case we cannot change these persisted values no matter what value has been posted. // There's only 3 special ones we need to deal with that are part of the MemberSave instance: Comments, IsApproved, IsLockedOut // but we will take care of this in a generic way below so that it works for all props. - if (!_webSecurity.CurrentUser.HasAccessToSensitiveData()) + if (!_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasAccessToSensitiveData()) { var memberType = _memberTypeService.Get(contentItem.PersistedContent.ContentTypeId); var sensitiveProperties = memberType @@ -458,7 +458,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpGet] public IActionResult ExportMemberData(Guid key) { - var currentUser = _webSecurity.CurrentUser; + var currentUser = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; if (currentUser.HasAccessToSensitiveData() == false) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs index 8ef8749c2d..e4d616cc43 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs @@ -16,6 +16,7 @@ using Umbraco.Core.Strings; using Umbraco.Web.Models.ContentEditing; using Constants = Umbraco.Core.Constants; using Umbraco.Core.Mapping; +using Umbraco.Core.Security; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; @@ -33,7 +34,7 @@ namespace Umbraco.Web.Editors public class MemberTypeController : ContentTypeControllerBase { private readonly IMemberTypeService _memberTypeService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IShortStringHelper _shortStringHelper; private readonly UmbracoMapper _umbracoMapper; private readonly ILocalizedTextService _localizedTextService; @@ -46,7 +47,7 @@ namespace Umbraco.Web.Editors IMemberTypeService memberTypeService, UmbracoMapper umbracoMapper, ILocalizedTextService localizedTextService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IShortStringHelper shortStringHelper) : base(cultureDictionary, editorValidatorCollection, @@ -57,7 +58,7 @@ namespace Umbraco.Web.Editors localizedTextService) { _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); _localizedTextService = @@ -141,7 +142,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.NotFound); } - _memberTypeService.Delete(foundType, _webSecurity.CurrentUser.Id); + _memberTypeService.Delete(foundType, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); return Ok(); } @@ -201,7 +202,7 @@ namespace Umbraco.Web.Editors var ctId = Convert.ToInt32(contentTypeSave.Id); var ct = ctId > 0 ? _memberTypeService.Get(ctId) : null; - if (_webSecurity.CurrentUser.HasAccessToSensitiveData() == false) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasAccessToSensitiveData() == false) { //We need to validate if any properties on the contentTypeSave have had their IsSensitiveValue changed, //and if so, we need to check if the current user has access to sensitive values. If not, we have to return an error diff --git a/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs b/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs index d8df34748d..fa16288fb5 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs @@ -10,6 +10,7 @@ using Semver; using Umbraco.Core; using Umbraco.Core.Hosting; using Umbraco.Core.Models.Packaging; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; @@ -27,16 +28,16 @@ namespace Umbraco.Web.BackOffice.Controllers { private readonly IHostingEnvironment _hostingEnvironment; private readonly IPackagingService _packagingService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public PackageController( IHostingEnvironment hostingEnvironment, IPackagingService packagingService, - IWebSecurity webSecurity) + IBackofficeSecurityAccessor backofficeSecurityAccessor) { _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); _packagingService = packagingService ?? throw new ArgumentNullException(nameof(packagingService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); } public IEnumerable GetCreatedPackages() @@ -90,7 +91,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpDelete] public IActionResult DeleteCreatedPackage(int packageId) { - _packagingService.DeleteCreatedPackage(packageId, _webSecurity.GetUserId().ResultOr(0)); + _packagingService.DeleteCreatedPackage(packageId, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); return Ok(); } diff --git a/src/Umbraco.Web.BackOffice/Controllers/PackageInstallController.cs b/src/Umbraco.Web.BackOffice/Controllers/PackageInstallController.cs index b61e86746a..fe9523f410 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/PackageInstallController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/PackageInstallController.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models.Packaging; using Umbraco.Net; using Umbraco.Core.Packaging; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Web.BackOffice.Filters; @@ -38,7 +39,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IRuntimeMinifier _runtimeMinifier; private readonly IPackagingService _packagingService; private readonly ILogger _logger; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly ILocalizedTextService _localizedTextService; public PackageInstallController( @@ -48,7 +49,7 @@ namespace Umbraco.Web.BackOffice.Controllers IRuntimeMinifier runtimeMinifier, IPackagingService packagingService, ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService localizedTextService) { _umbracoVersion = umbracoVersion ?? throw new ArgumentNullException(nameof(umbracoVersion)); @@ -57,7 +58,7 @@ namespace Umbraco.Web.BackOffice.Controllers _runtimeMinifier = runtimeMinifier ?? throw new ArgumentNullException(nameof(runtimeMinifier)); _packagingService = packagingService ?? throw new ArgumentNullException(nameof(packagingService)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); } @@ -87,14 +88,14 @@ namespace Umbraco.Web.BackOffice.Controllers var package = _packagingService.GetInstalledPackageById(packageId); if (package == null) return NotFound(); - var summary = _packagingService.UninstallPackage(package.Name, _webSecurity.GetUserId().ResultOr(0)); + var summary = _packagingService.UninstallPackage(package.Name, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); //now get all other packages by this name since we'll uninstall all versions foreach (var installed in _packagingService.GetAllInstalledPackages() .Where(x => x.Name == package.Name && x.Id != package.Id)) { //remove from the xml - _packagingService.DeleteInstalledPackage(installed.Id, _webSecurity.GetUserId().ResultOr(0)); + _packagingService.DeleteInstalledPackage(installed.Id, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); } } catch (Exception ex) @@ -223,7 +224,7 @@ namespace Umbraco.Web.BackOffice.Controllers var packageFile = await _packagingService.FetchPackageFileAsync( Guid.Parse(packageGuid), _umbracoVersion.Current, - _webSecurity.GetUserId().ResultOr(0)); + _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); fileName = packageFile.Name; } @@ -310,7 +311,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (definition == null) throw new InvalidOperationException("Not package definition found with id " + model.Id); var zipFile = new FileInfo(definition.PackagePath); - var installedFiles = _packagingService.InstallCompiledPackageFiles(definition, zipFile, _webSecurity.GetUserId().ResultOr(0)); + var installedFiles = _packagingService.InstallCompiledPackageFiles(definition, zipFile, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); //set a restarting marker and reset the app pool _umbracoApplicationLifetime.Restart(); @@ -342,7 +343,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (definition == null) throw new InvalidOperationException("Not package definition found with id " + model.Id); var zipFile = new FileInfo(definition.PackagePath); - var installSummary = _packagingService.InstallCompiledPackageData(definition, zipFile, _webSecurity.GetUserId().ResultOr(0)); + var installSummary = _packagingService.InstallCompiledPackageData(definition, zipFile, _backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); return model; } diff --git a/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs b/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs index 3878eb9b14..771ca28f55 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs @@ -10,6 +10,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Hosting; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Extensions; @@ -32,8 +33,8 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly UmbracoFeatures _features; private readonly GlobalSettings _globalSettings; private readonly IPublishedSnapshotService _publishedSnapshotService; - private readonly IWebSecurity _webSecurity; - private readonly ILocalizationService _localizationService; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; + private readonly ILocalizationService _localizationService; private readonly IHostingEnvironment _hostingEnvironment; private readonly ICookieManager _cookieManager; private readonly IRuntimeMinifier _runtimeMinifier; @@ -43,7 +44,7 @@ namespace Umbraco.Web.BackOffice.Controllers UmbracoFeatures features, IOptions globalSettings, IPublishedSnapshotService publishedSnapshotService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizationService localizationService, IHostingEnvironment hostingEnvironment, ICookieManager cookieManager, @@ -53,7 +54,7 @@ namespace Umbraco.Web.BackOffice.Controllers _features = features; _globalSettings = globalSettings.Value; _publishedSnapshotService = publishedSnapshotService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _localizationService = localizationService; _hostingEnvironment = hostingEnvironment; _cookieManager = cookieManager; @@ -107,7 +108,7 @@ namespace Umbraco.Web.BackOffice.Controllers [UmbracoAuthorize] public ActionResult Frame(int id, string culture) { - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; var previewToken = _publishedSnapshotService.EnterPreview(user, id); diff --git a/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs b/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs index 7a4b18e807..c5a2108ced 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/RedirectUrlManagementController.cs @@ -15,6 +15,7 @@ using Umbraco.Web.Security; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Microsoft.Extensions.Options; +using Umbraco.Core.Security; namespace Umbraco.Web.BackOffice.Controllers { @@ -23,15 +24,16 @@ namespace Umbraco.Web.BackOffice.Controllers { private readonly ILogger _logger; private readonly WebRoutingSettings _webRoutingSettings; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IRedirectUrlService _redirectUrlService; private readonly UmbracoMapper _umbracoMapper; private readonly IHostingEnvironment _hostingEnvironment; private readonly IConfigManipulator _configManipulator; - public RedirectUrlManagementController(ILogger logger, + public RedirectUrlManagementController( + ILogger logger, IOptions webRoutingSettings, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IRedirectUrlService redirectUrlService, UmbracoMapper umbracoMapper, IHostingEnvironment hostingEnvironment, @@ -39,7 +41,7 @@ namespace Umbraco.Web.BackOffice.Controllers { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _webRoutingSettings = webRoutingSettings.Value ?? throw new ArgumentNullException(nameof(webRoutingSettings)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _redirectUrlService = redirectUrlService ?? throw new ArgumentNullException(nameof(redirectUrlService)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); @@ -54,7 +56,7 @@ namespace Umbraco.Web.BackOffice.Controllers public IActionResult GetEnableState() { var enabled = _webRoutingSettings.DisableRedirectUrlTracking == false; - var userIsAdmin = _webSecurity.CurrentUser.IsAdmin(); + var userIsAdmin = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin(); return Ok(new { enabled, userIsAdmin }); } @@ -110,7 +112,7 @@ namespace Umbraco.Web.BackOffice.Controllers [HttpPost] public IActionResult ToggleUrlTracker(bool disable) { - var userIsAdmin = _webSecurity.CurrentUser.IsAdmin(); + var userIsAdmin = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin(); if (userIsAdmin == false) { var errorMessage = "User is not a member of the administrators group and so is not allowed to toggle the URL tracker"; diff --git a/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs b/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs index 5239994e04..810e3e5646 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc.Controllers; using Umbraco.Core; using Umbraco.Core.Mapping; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Common.Attributes; @@ -27,15 +28,15 @@ namespace Umbraco.Web.Editors private readonly ISectionService _sectionService; private readonly ITreeService _treeService; private readonly UmbracoMapper _umbracoMapper; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public SectionController( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService localizedTextService, IDashboardService dashboardService, ISectionService sectionService, ITreeService treeService, UmbracoMapper umbracoMapper, IControllerFactory controllerFactory) { - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _localizedTextService = localizedTextService; _dashboardService = dashboardService; _sectionService = sectionService; @@ -46,7 +47,7 @@ namespace Umbraco.Web.Editors public IEnumerable
GetSections() { - var sections = _sectionService.GetAllowedSections(_webSecurity.GetUserId().ResultOr(0)); + var sections = _sectionService.GetAllowedSections(_backofficeSecurityAccessor.BackofficeSecurity.GetUserId().ResultOr(0)); var sectionModels = sections.Select(_umbracoMapper.Map
).ToArray(); @@ -58,7 +59,7 @@ namespace Umbraco.Web.Editors ControllerContext = ControllerContext }; - var dashboards = _dashboardService.GetDashboards(_webSecurity.CurrentUser); + var dashboards = _dashboardService.GetDashboards(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser); //now we can add metadata for each section so that the UI knows if there's actually anything at all to render for //a dashboard for a given section, then the UI can deal with it accordingly (i.e. redirect to the first tree) @@ -104,10 +105,10 @@ namespace Umbraco.Web.Editors { var sections = _sectionService.GetSections(); var mapped = sections.Select(_umbracoMapper.Map
); - if (_webSecurity.CurrentUser.IsAdmin()) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin()) return mapped; - return mapped.Where(x => _webSecurity.CurrentUser.AllowedSections.Contains(x.Alias)).ToArray(); + return mapped.Where(x => _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.AllowedSections.Contains(x.Alias)).ToArray(); } } } diff --git a/src/Umbraco.Web.BackOffice/Controllers/TourController.cs b/src/Umbraco.Web.BackOffice/Controllers/TourController.cs index 6e7af87a11..818b4edf66 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/TourController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/TourController.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json; using Umbraco.Core; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Hosting; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models; @@ -21,21 +22,21 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly TourFilterCollection _filters; private readonly IHostingEnvironment _hostingEnvironment; private readonly TourSettings _tourSettings; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IContentTypeService _contentTypeService; public TourController( TourFilterCollection filters, IHostingEnvironment hostingEnvironment, IOptions tourSettings, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IContentTypeService contentTypeService) { _filters = filters; _hostingEnvironment = hostingEnvironment; _tourSettings = tourSettings.Value; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _contentTypeService = contentTypeService; } @@ -46,7 +47,7 @@ namespace Umbraco.Web.BackOffice.Controllers if (_tourSettings.EnableTours == false) return result; - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; if (user == null) return result; @@ -188,7 +189,7 @@ namespace Umbraco.Web.BackOffice.Controllers var backOfficeTours = tours.Where(x => aliasFilters.Count == 0 || aliasFilters.All(filter => filter.IsMatch(x.Alias)) == false); - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; var localizedTours = backOfficeTours.Where(x => string.IsNullOrWhiteSpace(x.Culture) || x.Culture.Equals(user.Language, diff --git a/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs b/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs index 16fcb5b38c..71dc97c835 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs @@ -10,6 +10,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Models; @@ -23,20 +24,20 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IUpgradeService _upgradeService; private readonly IUmbracoVersion _umbracoVersion; private readonly ICookieManager _cookieManager; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly GlobalSettings _globalSettings; public UpdateCheckController( IUpgradeService upgradeService, IUmbracoVersion umbracoVersion, ICookieManager cookieManager, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IOptions globalSettings) { _upgradeService = upgradeService ?? throw new ArgumentNullException(nameof(upgradeService)); _umbracoVersion = umbracoVersion ?? throw new ArgumentNullException(nameof(umbracoVersion)); _cookieManager = cookieManager ?? throw new ArgumentNullException(nameof(cookieManager)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _globalSettings = globalSettings.Value ?? throw new ArgumentNullException(nameof(globalSettings)); } @@ -45,7 +46,7 @@ namespace Umbraco.Web.BackOffice.Controllers { var updChkCookie = _cookieManager.GetCookieValue("UMB_UPDCHK"); var updateCheckCookie = updChkCookie ?? string.Empty; - if (_globalSettings.VersionCheckPeriod > 0 && string.IsNullOrEmpty(updateCheckCookie) && _webSecurity.CurrentUser.IsAdmin()) + if (_globalSettings.VersionCheckPeriod > 0 && string.IsNullOrEmpty(updateCheckCookie) && _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin()) { try { diff --git a/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs b/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs index 44b675771b..6d641c9cf9 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.BackOffice.Filters; @@ -27,13 +28,13 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IContentService _contentService; private readonly IEntityService _entityService; private readonly IMediaService _mediaService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly UmbracoMapper _umbracoMapper; private readonly ILocalizedTextService _localizedTextService; private readonly IShortStringHelper _shortStringHelper; public UserGroupsController(IUserService userService, IContentService contentService, - IEntityService entityService, IMediaService mediaService, IWebSecurity webSecurity, + IEntityService entityService, IMediaService mediaService, IBackofficeSecurityAccessor backofficeSecurityAccessor, UmbracoMapper umbracoMapper, ILocalizedTextService localizedTextService, IShortStringHelper shortStringHelper) { @@ -41,7 +42,7 @@ namespace Umbraco.Web.BackOffice.Controllers _contentService = contentService ?? throw new ArgumentNullException(nameof(contentService)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); @@ -57,19 +58,19 @@ namespace Umbraco.Web.BackOffice.Controllers var authHelper = new UserGroupEditorAuthorizationHelper( _userService, _contentService, _mediaService, _entityService); - var isAuthorized = authHelper.AuthorizeGroupAccess(_webSecurity.CurrentUser, userGroupSave.Alias); + var isAuthorized = authHelper.AuthorizeGroupAccess(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, userGroupSave.Alias); if (isAuthorized == false) throw new HttpResponseException(HttpStatusCode.Unauthorized, isAuthorized.Result); //if sections were added we need to check that the current user has access to that section - isAuthorized = authHelper.AuthorizeSectionChanges(_webSecurity.CurrentUser, + isAuthorized = authHelper.AuthorizeSectionChanges(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, userGroupSave.PersistedUserGroup.AllowedSections, userGroupSave.Sections); if (isAuthorized == false) throw new HttpResponseException(HttpStatusCode.Unauthorized, isAuthorized.Result); //if start nodes were changed we need to check that the current user has access to them - isAuthorized = authHelper.AuthorizeStartNodeChanges(_webSecurity.CurrentUser, + isAuthorized = authHelper.AuthorizeStartNodeChanges(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, userGroupSave.PersistedUserGroup.StartContentId, userGroupSave.StartContentId, userGroupSave.PersistedUserGroup.StartMediaId, @@ -111,18 +112,18 @@ namespace Umbraco.Web.BackOffice.Controllers private void EnsureNonAdminUserIsInSavedUserGroup(UserGroupSave userGroupSave) { - if (_webSecurity.CurrentUser.IsAdmin()) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin()) { return; } var userIds = userGroupSave.Users.ToList(); - if (userIds.Contains(_webSecurity.CurrentUser.Id)) + if (userIds.Contains(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id)) { return; } - userIds.Add(_webSecurity.CurrentUser.Id); + userIds.Add(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Id); userGroupSave.Users = userIds; } @@ -144,7 +145,7 @@ namespace Umbraco.Web.BackOffice.Controllers var allGroups = _umbracoMapper.MapEnumerable(_userService.GetAllUserGroups()) .ToList(); - var isAdmin = _webSecurity.CurrentUser.IsAdmin(); + var isAdmin = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin(); if (isAdmin) return allGroups; if (onlyCurrentUserGroups == false) @@ -155,7 +156,7 @@ namespace Umbraco.Web.BackOffice.Controllers } //we cannot return user groups that this user does not have access to - var currentUserGroups = _webSecurity.CurrentUser.Groups.Select(x => x.Alias).ToArray(); + var currentUserGroups = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Groups.Select(x => x.Alias).ToArray(); return allGroups.Where(x => currentUserGroups.Contains(x.Alias)).ToArray(); } diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs index 3cffa307eb..cfa1e980bd 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs @@ -24,8 +24,12 @@ using Umbraco.Core.Media; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; +using Umbraco.Web.Models; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.WebApi.Filters; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.ModelBinders; @@ -58,7 +62,7 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly SecuritySettings _securitySettings; private readonly IRequestAccessor _requestAccessor; private readonly IEmailSender _emailSender; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly AppCaches _appCaches; private readonly IShortStringHelper _shortStringHelper; private readonly IUserService _userService; @@ -81,7 +85,7 @@ namespace Umbraco.Web.BackOffice.Controllers IOptions securitySettings, IRequestAccessor requestAccessor, IEmailSender emailSender, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, AppCaches appCaches, IShortStringHelper shortStringHelper, IUserService userService, @@ -103,7 +107,7 @@ namespace Umbraco.Web.BackOffice.Controllers _securitySettings = securitySettings.Value; _requestAccessor = requestAccessor; _emailSender = emailSender; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _appCaches = appCaches; _shortStringHelper = shortStringHelper; _userService = userService; @@ -124,7 +128,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// public string[] GetCurrentUserAvatarUrls() { - var urls = _webSecurity.CurrentUser.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator); + var urls = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator); if (urls == null) throw new HttpResponseException(HttpStatusCode.BadRequest, "Could not access Gravatar endpoint"); @@ -290,7 +294,7 @@ namespace Umbraco.Web.BackOffice.Controllers var hideDisabledUsers = _securitySettings.HideDisabledUsersInBackoffice; var excludeUserGroups = new string[0]; - var isAdmin = _webSecurity.CurrentUser.IsAdmin(); + var isAdmin = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsAdmin(); if (isAdmin == false) { //this user is not an admin so in that case we need to exclude all admin users @@ -299,7 +303,7 @@ namespace Umbraco.Web.BackOffice.Controllers var filterQuery = _sqlContext.Query(); - if (!_webSecurity.CurrentUser.IsSuper()) + if (!_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.IsSuper()) { // only super can see super - but don't use IsSuper, cannot be mapped to SQL //filterQuery.Where(x => !x.IsSuper()); @@ -360,7 +364,7 @@ namespace Umbraco.Web.BackOffice.Controllers //Perform authorization here to see if the current user can actually save this user with the info being requested var authHelper = new UserEditorAuthorizationHelper(_contentService,_mediaService, _userService, _entityService); - var canSaveUser = authHelper.IsAuthorized(_webSecurity.CurrentUser, null, null, null, userSave.UserGroups); + var canSaveUser = authHelper.IsAuthorized(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, null, null, null, userSave.UserGroups); if (canSaveUser == false) { throw new HttpResponseException(HttpStatusCode.Unauthorized, canSaveUser.Result); @@ -444,7 +448,7 @@ namespace Umbraco.Web.BackOffice.Controllers //Perform authorization here to see if the current user can actually save this user with the info being requested var authHelper = new UserEditorAuthorizationHelper(_contentService,_mediaService, _userService, _entityService); - var canSaveUser = authHelper.IsAuthorized(_webSecurity.CurrentUser, user, null, null, userSave.UserGroups); + var canSaveUser = authHelper.IsAuthorized(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, user, null, null, userSave.UserGroups); if (canSaveUser == false) { throw new HttpResponseException(HttpStatusCode.Unauthorized, canSaveUser.Result); @@ -479,7 +483,7 @@ namespace Umbraco.Web.BackOffice.Controllers //send the email - await SendUserInviteEmailAsync(display, _webSecurity.CurrentUser.Name, _webSecurity.CurrentUser.Email, user, userSave.Message); + await SendUserInviteEmailAsync(display, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Name, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Email, user, userSave.Message); display.AddSuccessNotification(_localizedTextService.Localize("speechBubbles/resendInviteHeader"), _localizedTextService.Localize("speechBubbles/resendInviteSuccess", new[] { user.Name })); @@ -575,7 +579,7 @@ namespace Umbraco.Web.BackOffice.Controllers //Perform authorization here to see if the current user can actually save this user with the info being requested var authHelper = new UserEditorAuthorizationHelper(_contentService,_mediaService, _userService, _entityService); - var canSaveUser = authHelper.IsAuthorized(_webSecurity.CurrentUser, found, userSave.StartContentIds, userSave.StartMediaIds, userSave.UserGroups); + var canSaveUser = authHelper.IsAuthorized(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, found, userSave.StartContentIds, userSave.StartMediaIds, userSave.UserGroups); if (canSaveUser == false) { throw new HttpResponseException(HttpStatusCode.Unauthorized, canSaveUser.Result); @@ -658,7 +662,7 @@ namespace Umbraco.Web.BackOffice.Controllers } var passwordChanger = new PasswordChanger(_logger); - var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(_webSecurity.CurrentUser, found, changingPasswordModel, _backOfficeUserManager); + var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, found, changingPasswordModel, _backOfficeUserManager); if (passwordChangeResult.Success) { @@ -683,7 +687,7 @@ namespace Umbraco.Web.BackOffice.Controllers [AdminUsersAuthorize("userIds")] public IActionResult PostDisableUsers([FromQuery]int[] userIds) { - var tryGetCurrentUserId = _webSecurity.GetUserId(); + var tryGetCurrentUserId = _backofficeSecurityAccessor.BackofficeSecurity.GetUserId(); if (tryGetCurrentUserId && userIds.Contains(tryGetCurrentUserId.Result)) { throw HttpResponseException.CreateNotificationValidationErrorResponse("The current user cannot disable itself"); diff --git a/src/Umbraco.Web.BackOffice/Filters/AdminUsersAuthorizeAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/AdminUsersAuthorizeAttribute.cs index 526504b04d..4920b6351a 100644 --- a/src/Umbraco.Web.BackOffice/Filters/AdminUsersAuthorizeAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/AdminUsersAuthorizeAttribute.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Editors; using Umbraco.Web.Security; @@ -34,7 +35,7 @@ namespace Umbraco.Web.BackOffice.Filters private readonly IContentService _contentService; private readonly IMediaService _mediaService; private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public AdminUsersAuthorizeFilter( IRequestAccessor requestAccessor, @@ -42,7 +43,7 @@ namespace Umbraco.Web.BackOffice.Filters IContentService contentService, IMediaService mediaService, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, string parameterName) { _requestAccessor = requestAccessor; @@ -50,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Filters _contentService = contentService; _mediaService = mediaService; _entityService = entityService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _parameterName = parameterName; } @@ -86,7 +87,7 @@ namespace Umbraco.Web.BackOffice.Filters var users = _userService.GetUsersById(userIds); var authHelper = new UserEditorAuthorizationHelper(_contentService, _mediaService, _userService, _entityService); - return users.All(user => authHelper.IsAuthorized(_webSecurity.CurrentUser, user, null, null, null) != false); + return users.All(user => authHelper.IsAuthorized(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, user, null, null, null) != false); } } diff --git a/src/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttribute.cs index 6541d122ab..c484de3bfb 100644 --- a/src/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/AppendUserModifiedHeaderAttribute.cs @@ -43,8 +43,8 @@ namespace Umbraco.Web.BackOffice.Filters throw new InvalidOperationException($"No argument found for the current action with the name: {_userIdParameter}"); } - var webSecurity = context.HttpContext.RequestServices.GetService(); - var user = webSecurity.CurrentUser; + var backofficeSecurity = context.HttpContext.RequestServices.GetService(); + var user = backofficeSecurity.CurrentUser; if (user == null) { return; diff --git a/src/Umbraco.Web.BackOffice/Filters/ContentModelValidator.cs b/src/Umbraco.Web.BackOffice/Filters/ContentModelValidator.cs index 71323b1659..eee5cb6d30 100644 --- a/src/Umbraco.Web.BackOffice/Filters/ContentModelValidator.cs +++ b/src/Umbraco.Web.BackOffice/Filters/ContentModelValidator.cs @@ -22,14 +22,14 @@ namespace Umbraco.Web.BackOffice.Filters internal abstract class ContentModelValidator { - protected IWebSecurity WebSecurity { get; } + protected IBackofficeSecurity BackofficeSecurity { get; } public IPropertyValidationService PropertyValidationService { get; } protected ILogger Logger { get; } - protected ContentModelValidator(ILogger logger, IWebSecurity webSecurity, IPropertyValidationService propertyValidationService) + protected ContentModelValidator(ILogger logger, IBackofficeSecurity backofficeSecurity, IPropertyValidationService propertyValidationService) { Logger = logger ?? throw new ArgumentNullException(nameof(logger)); - WebSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + BackofficeSecurity = backofficeSecurity ?? throw new ArgumentNullException(nameof(backofficeSecurity)); PropertyValidationService = propertyValidationService ?? throw new ArgumentNullException(nameof(propertyValidationService)); } } @@ -53,10 +53,10 @@ namespace Umbraco.Web.BackOffice.Filters protected ContentModelValidator( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurity backofficeSecurity, ILocalizedTextService textService, IPropertyValidationService propertyValidationService) - : base(logger, webSecurity, propertyValidationService) + : base(logger, backofficeSecurity, propertyValidationService) { _textService = textService ?? throw new ArgumentNullException(nameof(textService)); } diff --git a/src/Umbraco.Web.BackOffice/Filters/ContentSaveModelValidator.cs b/src/Umbraco.Web.BackOffice/Filters/ContentSaveModelValidator.cs index 493b2e04ea..a73b20dca5 100644 --- a/src/Umbraco.Web.BackOffice/Filters/ContentSaveModelValidator.cs +++ b/src/Umbraco.Web.BackOffice/Filters/ContentSaveModelValidator.cs @@ -13,10 +13,10 @@ namespace Umbraco.Web.BackOffice.Filters { public ContentSaveModelValidator( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurity backofficeSecurity, ILocalizedTextService textService, IPropertyValidationService propertyValidationService) - : base(logger, webSecurity, textService, propertyValidationService) + : base(logger, backofficeSecurity, textService, propertyValidationService) { } diff --git a/src/Umbraco.Web.BackOffice/Filters/ContentSaveValidationAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/ContentSaveValidationAttribute.cs index 216f94499b..457929690f 100644 --- a/src/Umbraco.Web.BackOffice/Filters/ContentSaveValidationAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/ContentSaveValidationAttribute.cs @@ -35,12 +35,12 @@ namespace Umbraco.Web.BackOffice.Filters private readonly ILogger _logger; private readonly ILocalizedTextService _textService; private readonly IUserService _userService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public ContentSaveValidationFilter( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService textService, IContentService contentService, IUserService userService, @@ -48,7 +48,7 @@ namespace Umbraco.Web.BackOffice.Filters IPropertyValidationService propertyValidationService) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _textService = textService ?? throw new ArgumentNullException(nameof(textService)); _contentService = contentService ?? throw new ArgumentNullException(nameof(contentService)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); @@ -59,11 +59,11 @@ namespace Umbraco.Web.BackOffice.Filters public void OnActionExecuting(ActionExecutingContext context) { var model = (ContentItemSave) context.ActionArguments["contentItem"]; - var contentItemValidator = new ContentSaveModelValidator(_logger, _webSecurity, _textService, _propertyValidationService); + var contentItemValidator = new ContentSaveModelValidator(_logger, _backofficeSecurityAccessor.BackofficeSecurity, _textService, _propertyValidationService); if (!ValidateAtLeastOneVariantIsBeingSaved(model, context)) return; if (!contentItemValidator.ValidateExistingContent(model, context)) return; - if (!ValidateUserAccess(model, context, _webSecurity)) return; + if (!ValidateUserAccess(model, context, _backofficeSecurityAccessor.BackofficeSecurity)) return; //validate for each variant that is being updated foreach (var variant in model.Variants.Where(x => x.Save)) @@ -101,9 +101,9 @@ namespace Umbraco.Web.BackOffice.Filters ///
/// /// - /// + /// private bool ValidateUserAccess(ContentItemSave contentItem, ActionExecutingContext actionContext, - IWebSecurity webSecurity) + IBackofficeSecurity backofficeSecurity) { // We now need to validate that the user is allowed to be doing what they are doing. // Based on the action we need to check different permissions. @@ -217,13 +217,13 @@ namespace Umbraco.Web.BackOffice.Filters actionContext.HttpContext.Items[typeof(IContent).ToString()] = contentItem; accessResult = ContentPermissionsHelper.CheckPermissions( - contentToCheck, webSecurity.CurrentUser, + contentToCheck, backofficeSecurity.CurrentUser, _userService, _entityService, permissionToCheck.ToArray()); } else { accessResult = ContentPermissionsHelper.CheckPermissions( - contentIdToCheck, webSecurity.CurrentUser, + contentIdToCheck, backofficeSecurity.CurrentUser, _userService, _contentService, _entityService, out contentToCheck, permissionToCheck.ToArray()); diff --git a/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForContentAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForContentAttribute.cs index 131854808e..1c271d93e6 100644 --- a/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForContentAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForContentAttribute.cs @@ -75,7 +75,7 @@ namespace Umbraco.Web.BackOffice.Filters private sealed class EnsureUserPermissionForContentFilter : IActionFilter { private readonly int? _nodeId; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IEntityService _entityService; private readonly IUserService _userService; private readonly IContentService _contentService; @@ -83,58 +83,58 @@ namespace Umbraco.Web.BackOffice.Filters private readonly char? _permissionToCheck; public EnsureUserPermissionForContentFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IUserService userService, IContentService contentService, string paramName) - :this(webSecurity, entityService, userService, contentService, null, paramName, ActionBrowse.ActionLetter) + :this(backofficeSecurityAccessor, entityService, userService, contentService, null, paramName, ActionBrowse.ActionLetter) { } public EnsureUserPermissionForContentFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IUserService userService, IContentService contentService, int nodeId, char permissionToCheck) - :this(webSecurity, entityService, userService, contentService, nodeId, null, permissionToCheck) + :this(backofficeSecurityAccessor, entityService, userService, contentService, nodeId, null, permissionToCheck) { } public EnsureUserPermissionForContentFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IUserService userService, IContentService contentService, int nodeId) - :this(webSecurity, entityService, userService, contentService, nodeId, null, null) + :this(backofficeSecurityAccessor, entityService, userService, contentService, nodeId, null, null) { } public EnsureUserPermissionForContentFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IUserService userService, IContentService contentService, string paramName, char permissionToCheck) - :this(webSecurity, entityService, userService, contentService, null, paramName, permissionToCheck) + :this(backofficeSecurityAccessor, entityService, userService, contentService, null, paramName, permissionToCheck) { } private EnsureUserPermissionForContentFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IUserService userService, IContentService contentService, int? nodeId, string paramName, char? permissionToCheck) { - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _contentService = contentService ?? throw new ArgumentNullException(nameof(contentService)); @@ -156,7 +156,7 @@ namespace Umbraco.Web.BackOffice.Filters public void OnActionExecuting(ActionExecutingContext context) { - if (_webSecurity.CurrentUser == null) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser == null) { //not logged in throw new HttpResponseException(HttpStatusCode.Unauthorized); @@ -213,7 +213,7 @@ namespace Umbraco.Web.BackOffice.Filters } var permissionResult = ContentPermissionsHelper.CheckPermissions(nodeId, - _webSecurity.CurrentUser, + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, _userService, _contentService, _entityService, diff --git a/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs index 526e95cf96..3bf3bd8730 100644 --- a/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/EnsureUserPermissionForMediaAttribute.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Common.Exceptions; @@ -40,7 +41,7 @@ namespace Umbraco.Web.WebApi.Filters { private readonly int? _nodeId; private readonly string _paramName; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IEntityService _entityService; private readonly IMediaService _mediaService; @@ -48,21 +49,21 @@ namespace Umbraco.Web.WebApi.Filters /// This constructor will only be able to test the start node access ///
public EnsureUserPermissionForMediaFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IMediaService mediaService, int nodeId) - :this(webSecurity, entityService, mediaService, nodeId, null) + :this(backofficeSecurityAccessor, entityService, mediaService, nodeId, null) { _nodeId = nodeId; } public EnsureUserPermissionForMediaFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IMediaService mediaService, string paramName) - :this(webSecurity, entityService, mediaService,null, paramName) + :this(backofficeSecurityAccessor, entityService, mediaService,null, paramName) { if (paramName == null) throw new ArgumentNullException(nameof(paramName)); if (string.IsNullOrEmpty(paramName)) @@ -70,12 +71,12 @@ namespace Umbraco.Web.WebApi.Filters } private EnsureUserPermissionForMediaFilter( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, IEntityService entityService, IMediaService mediaService, int? nodeId, string paramName) { - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); @@ -117,7 +118,7 @@ namespace Umbraco.Web.WebApi.Filters public void OnActionExecuting(ActionExecutingContext context) { - if (_webSecurity.CurrentUser == null) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser == null) { throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized); } @@ -158,7 +159,7 @@ namespace Umbraco.Web.WebApi.Filters if (MediaController.CheckPermissions( context.HttpContext.Items, - _webSecurity.CurrentUser, + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, _mediaService, _entityService, nodeId)) diff --git a/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttribute.cs index 855cd05829..c67bbefd89 100644 --- a/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttribute.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Actions; using Umbraco.Web.Security; @@ -60,8 +61,8 @@ namespace Umbraco.Web.BackOffice.Filters - public FilterAllowedOutgoingContentFilter(Type outgoingType, string propertyName, char permissionToCheck, IUserService userService, IEntityService entityService, IWebSecurity webSecurity) - : base(entityService, webSecurity, outgoingType, propertyName) + public FilterAllowedOutgoingContentFilter(Type outgoingType, string propertyName, char permissionToCheck, IUserService userService, IEntityService entityService, IBackofficeSecurityAccessor backofficeSecurityAccessor) + : base(entityService, backofficeSecurityAccessor, outgoingType, propertyName) { _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); diff --git a/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs index a600f5a928..a6325e0650 100644 --- a/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs @@ -34,13 +34,13 @@ namespace Umbraco.Web.WebApi.Filters { private readonly Type _outgoingType; private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly string _propertyName; - public FilterAllowedOutgoingMediaFilter(IEntityService entityService, IWebSecurity webSecurity, Type outgoingType, string propertyName) + public FilterAllowedOutgoingMediaFilter(IEntityService entityService, IBackofficeSecurityAccessor backofficeSecurityAccessor, Type outgoingType, string propertyName) { _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _propertyName = propertyName; _outgoingType = outgoingType; @@ -57,7 +57,7 @@ namespace Umbraco.Web.WebApi.Filters { if (context.Result == null) return; - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; if (user == null) return; var objectContent = context.Result as ObjectResult; diff --git a/src/Umbraco.Web.BackOffice/Filters/IsCurrentUserModelFilterAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/IsCurrentUserModelFilterAttribute.cs index 521dd34d77..380995db4d 100644 --- a/src/Umbraco.Web.BackOffice/Filters/IsCurrentUserModelFilterAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/IsCurrentUserModelFilterAttribute.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; +using Umbraco.Core.Security; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Security; @@ -15,11 +16,11 @@ namespace Umbraco.Web.BackOffice.Filters private class IsCurrentUserModelFilter : IActionFilter { - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; - public IsCurrentUserModelFilter(IWebSecurity webSecurity) + public IsCurrentUserModelFilter(IBackofficeSecurityAccessor backofficeSecurityAccessor) { - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; } @@ -27,7 +28,7 @@ namespace Umbraco.Web.BackOffice.Filters { if (context.Result == null) return; - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; if (user == null) return; var objectContent = context.Result as ObjectResult; diff --git a/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs index a81f4d329a..ee89a8e2fd 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Models.ContentEditing; @@ -29,18 +30,18 @@ namespace Umbraco.Web.BackOffice.Filters private readonly ILogger _logger; private readonly IMediaService _mediaService; private readonly ILocalizedTextService _textService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public MediaItemSaveValidationFilter( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService textService, IMediaService mediaService, IEntityService entityService, IPropertyValidationService propertyValidationService) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _textService = textService ?? throw new ArgumentNullException(nameof(textService)); _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); @@ -50,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Filters public void OnActionExecuting(ActionExecutingContext context) { var model = (MediaItemSave) context.ActionArguments["contentItem"]; - var contentItemValidator = new MediaSaveModelValidator(_logger, _webSecurity, _textService, _propertyValidationService); + var contentItemValidator = new MediaSaveModelValidator(_logger, _backofficeSecurityAccessor.BackofficeSecurity, _textService, _propertyValidationService); if (ValidateUserAccess(model, context)) { @@ -101,7 +102,7 @@ namespace Umbraco.Web.BackOffice.Filters if (MediaController.CheckPermissions( actionContext.HttpContext.Items, - _webSecurity.CurrentUser, + _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, _mediaService, _entityService, contentIdToCheck, contentToCheck) == false) { diff --git a/src/Umbraco.Web.BackOffice/Filters/MediaSaveModelValidator.cs b/src/Umbraco.Web.BackOffice/Filters/MediaSaveModelValidator.cs index 4dd9e6592c..7eaf0cb60f 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MediaSaveModelValidator.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MediaSaveModelValidator.cs @@ -13,10 +13,10 @@ namespace Umbraco.Web.BackOffice.Filters { public MediaSaveModelValidator( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurity backofficeSecurity, ILocalizedTextService textService, IPropertyValidationService propertyValidationService) - : base(logger, webSecurity, textService, propertyValidationService) + : base(logger, backofficeSecurity, textService, propertyValidationService) { } } diff --git a/src/Umbraco.Web.BackOffice/Filters/MemberSaveModelValidator.cs b/src/Umbraco.Web.BackOffice/Filters/MemberSaveModelValidator.cs index 208f0eeb07..9ca7cc4f31 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MemberSaveModelValidator.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MemberSaveModelValidator.cs @@ -26,13 +26,13 @@ namespace Umbraco.Web.BackOffice.Filters public MemberSaveModelValidator( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurity backofficeSecurity, ILocalizedTextService textService, IMemberTypeService memberTypeService, IMemberService memberService, IShortStringHelper shortStringHelper, IPropertyValidationService propertyValidationService) - : base(logger, webSecurity, textService, propertyValidationService) + : base(logger, backofficeSecurity, textService, propertyValidationService) { _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); _memberService = memberService ?? throw new ArgumentNullException(nameof(memberService)); @@ -96,7 +96,7 @@ namespace Umbraco.Web.BackOffice.Filters //if the user doesn't have access to sensitive values, then we need to validate the incoming properties to check //if a sensitive value is being submitted. - if (WebSecurity.CurrentUser.HasAccessToSensitiveData() == false) + if (BackofficeSecurity.CurrentUser.HasAccessToSensitiveData() == false) { var contentType = _memberTypeService.Get(model.PersistedContent.ContentTypeId); var sensitiveProperties = contentType diff --git a/src/Umbraco.Web.BackOffice/Filters/MemberSaveValidationAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/MemberSaveValidationAttribute.cs index e6f6edb2e3..bfa03264c3 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MemberSaveValidationAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MemberSaveValidationAttribute.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Web.Models.ContentEditing; @@ -22,7 +23,7 @@ namespace Umbraco.Web.BackOffice.Filters private sealed class MemberSaveValidationFilter : IActionFilter { private readonly ILogger _logger; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly ILocalizedTextService _textService; private readonly IMemberTypeService _memberTypeService; private readonly IMemberService _memberService; @@ -31,7 +32,7 @@ namespace Umbraco.Web.BackOffice.Filters public MemberSaveValidationFilter( ILogger logger, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService textService, IMemberTypeService memberTypeService, IMemberService memberService, @@ -39,7 +40,7 @@ namespace Umbraco.Web.BackOffice.Filters IPropertyValidationService propertyValidationService) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _textService = textService ?? throw new ArgumentNullException(nameof(textService)); _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); _memberService = memberService ?? throw new ArgumentNullException(nameof(memberService)); @@ -50,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Filters public void OnActionExecuting(ActionExecutingContext context) { var model = (MemberSave)context.ActionArguments["contentItem"]; - var contentItemValidator = new MemberSaveModelValidator(_logger, _webSecurity, _textService, _memberTypeService, _memberService, _shortStringHelper, _propertyValidationService); + var contentItemValidator = new MemberSaveModelValidator(_logger, _backofficeSecurityAccessor.BackofficeSecurity, _textService, _memberTypeService, _memberService, _shortStringHelper, _propertyValidationService); //now do each validation step if (contentItemValidator.ValidateExistingContent(model, context)) if (contentItemValidator.ValidateProperties(model, model, context)) diff --git a/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs index d433ba9886..9952eb52f9 100644 --- a/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core; +using Umbraco.Core.Security; using Umbraco.Web.Editors; using Umbraco.Web.Security; @@ -13,12 +14,12 @@ namespace Umbraco.Web.WebApi.Filters internal sealed class OutgoingEditorModelEventAttribute : ActionFilterAttribute { private readonly IUmbracoContextAccessor _umbracoContextAccessor; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; - public OutgoingEditorModelEventAttribute(IUmbracoContextAccessor umbracoContextAccessor, IWebSecurity webSecurity) + public OutgoingEditorModelEventAttribute(IUmbracoContextAccessor umbracoContextAccessor, IBackofficeSecurityAccessor backofficeSecurityAccessor) { _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); } public override void OnActionExecuted(ActionExecutedContext context) @@ -26,7 +27,7 @@ namespace Umbraco.Web.WebApi.Filters if (context.Result == null) return; var umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext(); - var user = _webSecurity.CurrentUser; + var user = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; if (user == null) return; if (context.Result is ObjectResult objectContent) diff --git a/src/Umbraco.Web.BackOffice/Filters/UmbracoApplicationAuthorizeAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/UmbracoApplicationAuthorizeAttribute.cs index 4465436e77..3850682cf2 100644 --- a/src/Umbraco.Web.BackOffice/Filters/UmbracoApplicationAuthorizeAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/UmbracoApplicationAuthorizeAttribute.cs @@ -1,6 +1,7 @@ using System.Linq; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; +using Umbraco.Core.Security; using Umbraco.Web.Security; namespace Umbraco.Web.BackOffice.Filters @@ -22,19 +23,19 @@ namespace Umbraco.Web.BackOffice.Filters ///
internal static bool Enable = true; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly string[] _appNames; /// /// Constructor to set any number of applications that the user needs access to be authorized /// - /// + /// /// /// If the user has access to any of the specified apps, they will be authorized. /// - public UmbracoApplicationAuthorizeFilter(IWebSecurity webSecurity, params string[] appName) + public UmbracoApplicationAuthorizeFilter(IBackofficeSecurityAccessor backofficeSecurityAccessor, params string[] appName) { - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _appNames = appName; } @@ -54,9 +55,9 @@ namespace Umbraco.Web.BackOffice.Filters return true; } - var authorized = _webSecurity.CurrentUser != null - && _appNames.Any(app => _webSecurity.UserHasSectionAccess( - app, _webSecurity.CurrentUser)); + var authorized = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser != null + && _appNames.Any(app => _backofficeSecurityAccessor.BackofficeSecurity.UserHasSectionAccess( + app, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser)); return authorized; } diff --git a/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs index d4ec1b45e1..5f6e00e82e 100644 --- a/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/UmbracoTreeAuthorizeAttribute.cs @@ -3,6 +3,7 @@ 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; @@ -34,22 +35,22 @@ namespace Umbraco.Web.BackOffice.Filters private readonly string[] _treeAliases; private readonly ITreeService _treeService; - private readonly IWebSecurity _webSecurity; + 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, IWebSecurity webSecurity, + public UmbracoTreeAuthorizeFilter(ITreeService treeService, IBackofficeSecurityAccessor backofficeSecurityAccessor, params string[] treeAliases) { _treeService = treeService ?? throw new ArgumentNullException(nameof(treeService)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _treeAliases = treeAliases; } @@ -75,9 +76,9 @@ namespace Umbraco.Web.BackOffice.Filters .Distinct() .ToArray(); - return _webSecurity.CurrentUser != null - && apps.Any(app => _webSecurity.UserHasSectionAccess( - app, _webSecurity.CurrentUser)); + return _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser != null + && apps.Any(app => _backofficeSecurityAccessor.BackofficeSecurity.UserHasSectionAccess( + app, _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser)); } } } diff --git a/src/Umbraco.Web.BackOffice/Filters/UserGroupAuthorizationAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/UserGroupAuthorizationAttribute.cs index b0175fe6ec..d867cc90bc 100644 --- a/src/Umbraco.Web.BackOffice/Filters/UserGroupAuthorizationAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/UserGroupAuthorizationAttribute.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Security; @@ -34,7 +35,7 @@ namespace Umbraco.Web.BackOffice.Filters private readonly IContentService _contentService; private readonly IMediaService _mediaService; private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public UserGroupAuthorizationFilter( IRequestAccessor requestAccessor, @@ -42,7 +43,7 @@ namespace Umbraco.Web.BackOffice.Filters IContentService contentService, IMediaService mediaService, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, string parameterName) { _requestAccessor = requestAccessor; @@ -50,7 +51,7 @@ namespace Umbraco.Web.BackOffice.Filters _contentService = contentService; _mediaService = mediaService; _entityService = entityService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _parameterName = parameterName; } @@ -64,7 +65,7 @@ namespace Umbraco.Web.BackOffice.Filters private bool IsAuthorized(AuthorizationFilterContext actionContext) { - var currentUser = _webSecurity.CurrentUser; + var currentUser = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser; var queryString = actionContext.HttpContext.Request.Query; diff --git a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs index c9bcf01fad..6253aa1ff4 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs @@ -1,4 +1,5 @@ -using System; + +using System; using System.Collections.Generic; using System.Linq; using System.Net; diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs index 44c83e3009..10fbdea0b6 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs @@ -13,6 +13,7 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Constants = Umbraco.Core.Constants; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.Trees; @@ -44,7 +45,7 @@ namespace Umbraco.Web.Trees private readonly ActionCollection _actions; private readonly GlobalSettings _globalSettings; private readonly IMenuItemCollectionFactory _menuItemCollectionFactory; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IContentService _contentService; private readonly IEntityService _entityService; private readonly IPublicAccessService _publicAccessService; @@ -56,7 +57,7 @@ namespace Umbraco.Web.Trees UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, IMenuItemCollectionFactory menuItemCollectionFactory, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILogger logger, ActionCollection actionCollection, IUserService userService, @@ -67,13 +68,13 @@ namespace Umbraco.Web.Trees IContentService contentService, IPublicAccessService publicAccessService, ILocalizationService localizationService) - : base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory, entityService, webSecurity, logger, actionCollection, userService, dataTypeService) + : base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory, entityService, backofficeSecurityAccessor, logger, actionCollection, userService, dataTypeService) { _treeSearcher = treeSearcher; _actions = actions; _globalSettings = globalSettings.Value; _menuItemCollectionFactory = menuItemCollectionFactory; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _contentService = contentService; _entityService = entityService; _publicAccessService = publicAccessService; @@ -88,7 +89,7 @@ namespace Umbraco.Web.Trees private int[] _userStartNodes; protected override int[] UserStartNodes - => _userStartNodes ?? (_userStartNodes = _webSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService)); + => _userStartNodes ?? (_userStartNodes = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService)); @@ -166,7 +167,7 @@ namespace Umbraco.Web.Trees menu.DefaultMenuAlias = ActionNew.ActionAlias; // we need to get the default permissions as you can't set permissions on the very root node - var permission = _userService.GetPermissions(_webSecurity.CurrentUser, Constants.System.Root).First(); + var permission = _userService.GetPermissions(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, Constants.System.Root).First(); var nodeActions = _actions.FromEntityPermission(permission) .Select(x => new MenuItem(x)); @@ -202,7 +203,7 @@ namespace Umbraco.Web.Trees } //if the user has no path access for this node, all they can do is refresh - if (!_webSecurity.CurrentUser.HasContentPathAccess(item, _entityService)) + if (!_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasContentPathAccess(item, _entityService)) { var menu = _menuItemCollectionFactory.Create(); menu.Items.Add(new RefreshNode(LocalizedTextService, true)); diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs index 8e05cb874e..ef2f4c2899 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs @@ -25,7 +25,7 @@ namespace Umbraco.Web.Trees public abstract class ContentTreeControllerBase : TreeController, ITreeNodeController { private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly ILogger _logger; private readonly ActionCollection _actionCollection; private readonly IUserService _userService; @@ -38,7 +38,7 @@ namespace Umbraco.Web.Trees UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, IMenuItemCollectionFactory menuItemCollectionFactory, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILogger logger, ActionCollection actionCollection, IUserService userService, @@ -47,7 +47,7 @@ namespace Umbraco.Web.Trees : base(localizedTextService, umbracoApiControllerTypeCollection) { _entityService = entityService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _logger = logger; _actionCollection = actionCollection; _userService = userService; @@ -147,12 +147,12 @@ namespace Umbraco.Web.Trees switch (RecycleBinId) { case Constants.System.RecycleBinMedia: - startNodeIds = _webSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService); - startNodePaths = _webSecurity.CurrentUser.GetMediaStartNodePaths(_entityService); + startNodeIds = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService); + startNodePaths = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.GetMediaStartNodePaths(_entityService); break; case Constants.System.RecycleBinContent: - startNodeIds = _webSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService); - startNodePaths = _webSecurity.CurrentUser.GetContentStartNodePaths(_entityService); + startNodeIds = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateContentStartNodeIds(_entityService); + startNodePaths = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.GetContentStartNodePaths(_entityService); break; default: throw new NotSupportedException("Path access is only determined on content or media"); @@ -196,7 +196,7 @@ namespace Umbraco.Web.Trees // TODO: in the future we could return a validation statement so we can have some UI to notify the user they don't have access if (ignoreUserStartNodes == false && HasPathAccess(id, queryStrings) == false) { - _logger.Warn("User {Username} does not have access to node with id {Id}", _webSecurity.CurrentUser.Username, id); + _logger.Warn("User {Username} does not have access to node with id {Id}", _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.Username, id); return nodes; } @@ -312,8 +312,8 @@ namespace Umbraco.Web.Trees { if (entity == null) return false; return RecycleBinId == Constants.System.RecycleBinContent - ? _webSecurity.CurrentUser.HasContentPathAccess(entity, _entityService) - : _webSecurity.CurrentUser.HasMediaPathAccess(entity, _entityService); + ? _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasContentPathAccess(entity, _entityService) + : _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasMediaPathAccess(entity, _entityService); } /// @@ -441,7 +441,7 @@ namespace Umbraco.Web.Trees var deleteAction = _actionCollection.FirstOrDefault(y => y.Letter == ActionDelete.ActionLetter); if (deleteAction != null) { - var perms = _webSecurity.CurrentUser.GetPermissions(Constants.System.RecycleBinContentString, _userService); + var perms = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.GetPermissions(Constants.System.RecycleBinContentString, _userService); deleteAllowed = perms.FirstOrDefault(x => x.Contains(deleteAction.Letter)) != null; } @@ -492,7 +492,7 @@ namespace Umbraco.Web.Trees internal IEnumerable GetAllowedUserMenuItemsForNode(IUmbracoEntity dd) { - var permissionsForPath = _userService.GetPermissionsForPath(_webSecurity.CurrentUser, dd.Path).GetAllPermissions(); + var permissionsForPath = _userService.GetPermissionsForPath(_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser, dd.Path).GetAllPermissions(); return _actionCollection.GetByLetters(permissionsForPath).Select(x => new MenuItem(x)); } diff --git a/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs index 46ef45e85d..2a7f769c7b 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs @@ -12,6 +12,7 @@ using Umbraco.Web.Models.Trees; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Constants = Umbraco.Core.Constants; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.Trees; @@ -39,26 +40,26 @@ namespace Umbraco.Web.Trees private readonly UmbracoTreeSearcher _treeSearcher; private readonly IMediaService _mediaService; private readonly IEntityService _entityService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public MediaTreeController( ILocalizedTextService localizedTextService, UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, IMenuItemCollectionFactory menuItemCollectionFactory, IEntityService entityService, - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, ILogger logger, ActionCollection actionCollection, IUserService userService, IDataTypeService dataTypeService, UmbracoTreeSearcher treeSearcher, IMediaService mediaService) - : base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory, entityService, webSecurity, logger, actionCollection, userService, dataTypeService) + : base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory, entityService, backofficeSecurityAccessor, logger, actionCollection, userService, dataTypeService) { _treeSearcher = treeSearcher; _mediaService = mediaService; _entityService = entityService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; } protected override int RecycleBinId => Constants.System.RecycleBinMedia; @@ -67,7 +68,7 @@ namespace Umbraco.Web.Trees private int[] _userStartNodes; protected override int[] UserStartNodes - => _userStartNodes ?? (_userStartNodes = _webSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService)); + => _userStartNodes ?? (_userStartNodes = _backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.CalculateMediaStartNodeIds(_entityService)); /// /// Creates a tree node for a content item based on an UmbracoEntity @@ -134,7 +135,7 @@ namespace Umbraco.Web.Trees } //if the user has no path access for this node, all they can do is refresh - if (!_webSecurity.CurrentUser.HasMediaPathAccess(item, _entityService)) + if (!_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasMediaPathAccess(item, _entityService)) { menu.Items.Add(new RefreshNode(LocalizedTextService, true)); return menu; diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs index 967e4f22fc..859ee2f846 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Extensions; using Umbraco.Web.Actions; @@ -37,7 +38,7 @@ namespace Umbraco.Web.Trees private readonly IMenuItemCollectionFactory _menuItemCollectionFactory; private readonly IMemberService _memberService; private readonly IMemberTypeService _memberTypeService; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; public MemberTreeController( ILocalizedTextService localizedTextService, @@ -46,14 +47,14 @@ namespace Umbraco.Web.Trees IMenuItemCollectionFactory menuItemCollectionFactory, IMemberService memberService, IMemberTypeService memberTypeService, - IWebSecurity webSecurity) + IBackofficeSecurityAccessor backofficeSecurityAccessor) : base(localizedTextService, umbracoApiControllerTypeCollection) { _treeSearcher = treeSearcher; _menuItemCollectionFactory = menuItemCollectionFactory; _memberService = memberService; _memberTypeService = memberTypeService; - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; } /// @@ -145,7 +146,7 @@ namespace Umbraco.Web.Trees //add delete option for all members menu.Items.Add(LocalizedTextService, opensDialog: true); - if (_webSecurity.CurrentUser.HasAccessToSensitiveData()) + if (_backofficeSecurityAccessor.BackofficeSecurity.CurrentUser.HasAccessToSensitiveData()) { menu.Items.Add(new ExportMember(LocalizedTextService)); } diff --git a/src/Umbraco.Web.Common/Install/InstallController.cs b/src/Umbraco.Web.Common/Install/InstallController.cs index 306a376533..026f604d50 100644 --- a/src/Umbraco.Web.Common/Install/InstallController.cs +++ b/src/Umbraco.Web.Common/Install/InstallController.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Hosting; using Umbraco.Core.Logging; +using Umbraco.Core.Security; using Umbraco.Core.WebAssets; using Umbraco.Extensions; using Umbraco.Web.Common.Filters; @@ -25,7 +26,7 @@ namespace Umbraco.Web.Common.Install [Area(Umbraco.Core.Constants.Web.Mvc.InstallArea)] public class InstallController : Controller { - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly InstallHelper _installHelper; private readonly IRuntimeState _runtime; private readonly GlobalSettings _globalSettings; @@ -36,7 +37,7 @@ namespace Umbraco.Web.Common.Install private readonly IRuntimeMinifier _runtimeMinifier; public InstallController( - IWebSecurity webSecurity, + IBackofficeSecurityAccessor backofficeSecurityAccessor, InstallHelper installHelper, IRuntimeState runtime, IOptions globalSettings, @@ -46,7 +47,7 @@ namespace Umbraco.Web.Common.Install ILogger logger, LinkGenerator linkGenerator) { - _webSecurity = webSecurity; + _backofficeSecurityAccessor = backofficeSecurityAccessor; _installHelper = installHelper; _runtime = runtime; _globalSettings = globalSettings.Value; @@ -72,7 +73,7 @@ namespace Umbraco.Web.Common.Install // Update ClientDependency version and delete its temp directories to make sure we get fresh caches _runtimeMinifier.Reset(); - var result = _webSecurity.ValidateCurrentUser(false); + var result = _backofficeSecurityAccessor.BackofficeSecurity.ValidateCurrentUser(false); switch (result) { diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs index 587a60caa9..f5b8d74402 100644 --- a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs +++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Logging; using System.Threading; using Umbraco.Core.Cache; using System.Collections.Generic; +using Umbraco.Core.Security; namespace Umbraco.Web.Common.Middleware { @@ -24,17 +25,20 @@ namespace Umbraco.Web.Common.Middleware private readonly IUmbracoRequestLifetimeManager _umbracoRequestLifetimeManager; private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly IRequestCache _requestCache; + private readonly IBackofficeSecurityFactory _backofficeSecurityFactory; public UmbracoRequestMiddleware( ILogger logger, IUmbracoRequestLifetimeManager umbracoRequestLifetimeManager, IUmbracoContextFactory umbracoContextFactory, - IRequestCache requestCache) + IRequestCache requestCache, + IBackofficeSecurityFactory backofficeSecurityFactory) { _logger = logger; _umbracoRequestLifetimeManager = umbracoRequestLifetimeManager; _umbracoContextFactory = umbracoContextFactory; _requestCache = requestCache; + _backofficeSecurityFactory = backofficeSecurityFactory; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) @@ -47,13 +51,14 @@ namespace Umbraco.Web.Common.Middleware await next(context); return; } - + _backofficeSecurityFactory.EnsureBackofficeSecurity(); // Needs to be before UmbracoContext var umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext(); + try { if (umbracoContextReference.UmbracoContext.IsFrontEndUmbracoRequest) - { + { LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache); _logger.Verbose("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, requestUri); } diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs index 67755da5ea..58b7fc16b5 100644 --- a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs @@ -75,7 +75,8 @@ namespace Umbraco.Web.Common.Runtime // register the umbraco context factory composition.RegisterUnique(); - composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); //register the install components //NOTE: i tried to not have these registered if we weren't installing or upgrading but post install when the site restarts diff --git a/src/Umbraco.Web.Common/Security/WebSecurity.cs b/src/Umbraco.Web.Common/Security/BackofficeSecurity.cs similarity index 98% rename from src/Umbraco.Web.Common/Security/WebSecurity.cs rename to src/Umbraco.Web.Common/Security/BackofficeSecurity.cs index b822adf656..6587501be7 100644 --- a/src/Umbraco.Web.Common/Security/WebSecurity.cs +++ b/src/Umbraco.Web.Common/Security/BackofficeSecurity.cs @@ -13,14 +13,15 @@ using Umbraco.Web.Security; namespace Umbraco.Web.Common.Security { - public class WebSecurity : IWebSecurity + + public class BackofficeSecurity : IBackofficeSecurity { private readonly IUserService _userService; private readonly GlobalSettings _globalSettings; private readonly IHostingEnvironment _hostingEnvironment; private readonly IHttpContextAccessor _httpContextAccessor; - public WebSecurity( + public BackofficeSecurity( IUserService userService, IOptions globalSettings, IHostingEnvironment hostingEnvironment, diff --git a/src/Umbraco.Web.Common/Security/BackofficeSecurityFactory.cs b/src/Umbraco.Web.Common/Security/BackofficeSecurityFactory.cs new file mode 100644 index 0000000000..7718981b27 --- /dev/null +++ b/src/Umbraco.Web.Common/Security/BackofficeSecurityFactory.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Hosting; +using Umbraco.Core.Security; +using Umbraco.Core.Services; + +namespace Umbraco.Web.Common.Security +{ + public class BackofficeSecurityFactory: IBackofficeSecurityFactory + { + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; + private readonly IUserService _userService; + private readonly IOptions _globalSettings; + private readonly IHostingEnvironment _hostingEnvironment; + private readonly IHttpContextAccessor _httpContextAccessor; + + public BackofficeSecurityFactory( + IBackofficeSecurityAccessor backofficeSecurityAccessor, + IUserService userService, + IOptions globalSettings, + IHostingEnvironment hostingEnvironment, + IHttpContextAccessor httpContextAccessor) + { + _backofficeSecurityAccessor = backofficeSecurityAccessor; + _userService = userService; + _globalSettings = globalSettings; + _hostingEnvironment = hostingEnvironment; + _httpContextAccessor = httpContextAccessor; + } + + public void EnsureBackofficeSecurity() + { + if (_backofficeSecurityAccessor.BackofficeSecurity is null) + { + _backofficeSecurityAccessor.BackofficeSecurity = new BackofficeSecurity(_userService, _globalSettings, _hostingEnvironment, _httpContextAccessor); + } + + } + } +} diff --git a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs index b255013b7f..6b4ce706e3 100644 --- a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs +++ b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs @@ -31,7 +31,7 @@ namespace Umbraco.Web // warn: does *not* manage setting any IUmbracoContextAccessor internal UmbracoContext( IPublishedSnapshotService publishedSnapshotService, - IWebSecurity webSecurity, + IBackofficeSecurity backofficeSecurity, GlobalSettings globalSettings, IHostingEnvironment hostingEnvironment, IVariationContextAccessor variationContextAccessor, @@ -40,7 +40,7 @@ namespace Umbraco.Web IRequestAccessor requestAccessor) { if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService)); - if (webSecurity == null) throw new ArgumentNullException(nameof(webSecurity)); + if (backofficeSecurity == null) throw new ArgumentNullException(nameof(backofficeSecurity)); VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor)); _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); _hostingEnvironment = hostingEnvironment; @@ -49,7 +49,7 @@ namespace Umbraco.Web ObjectCreated = DateTime.Now; UmbracoRequestId = Guid.NewGuid(); - Security = webSecurity; + Security = backofficeSecurity; // beware - we cannot expect a current user here, so detecting preview mode must be a lazy thing _publishedSnapshot = new Lazy(() => publishedSnapshotService.CreatePublishedSnapshot(PreviewToken)); @@ -78,9 +78,9 @@ namespace Umbraco.Web public Guid UmbracoRequestId { get; } /// - /// Gets the WebSecurity class + /// Gets the BackofficeSecurity class /// - public IWebSecurity Security { get; } + public IBackofficeSecurity Security { get; } /// /// Gets the uri that is handled by ASP.NET after server-side rewriting took place. diff --git a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs index d9df11e4a9..a31ef614cf 100644 --- a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs +++ b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Hosting; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Common.Security; using Umbraco.Web.PublishedCache; @@ -30,7 +31,7 @@ namespace Umbraco.Web private readonly IHttpContextAccessor _httpContextAccessor; private readonly ICookieManager _cookieManager; private readonly IRequestAccessor _requestAccessor; - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly UriUtility _uriUtility; /// @@ -48,7 +49,7 @@ namespace Umbraco.Web IHttpContextAccessor httpContextAccessor, ICookieManager cookieManager, IRequestAccessor requestAccessor, - IWebSecurity webSecurity) + IBackofficeSecurityAccessor backofficeSecurityAccessor) { _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); _publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService)); @@ -61,7 +62,7 @@ namespace Umbraco.Web _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); _cookieManager = cookieManager ?? throw new ArgumentNullException(nameof(cookieManager)); _requestAccessor = requestAccessor ?? throw new ArgumentNullException(nameof(requestAccessor)); - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); } private IUmbracoContext CreateUmbracoContext() @@ -79,7 +80,7 @@ namespace Umbraco.Web return new UmbracoContext( _publishedSnapshotService, - _webSecurity, + _backofficeSecurityAccessor.BackofficeSecurity, _globalSettings, _hostingEnvironment, _variationContextAccessor, diff --git a/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs b/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs index 64a9e56014..6148535d46 100644 --- a/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs @@ -3,6 +3,7 @@ using System.Web; using System.Web.Mvc; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Security; using Umbraco.Core.Configuration.Models; using Umbraco.Web.Composing; using Umbraco.Web.Security; @@ -14,22 +15,22 @@ namespace Umbraco.Web.Mvc public sealed class UmbracoAuthorizeAttribute : AuthorizeAttribute { // see note in HttpInstallAuthorizeAttribute - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IRuntimeState _runtimeState; private readonly string _redirectUrl; private IRuntimeState RuntimeState => _runtimeState ?? Current.RuntimeState; - private IWebSecurity WebSecurity => _webSecurity ?? Current.UmbracoContext.Security; + private IBackofficeSecurity BackofficeSecurity => _backofficeSecurityAccessor.BackofficeSecurity ?? Current.UmbracoContext.Security; /// /// THIS SHOULD BE ONLY USED FOR UNIT TESTS /// - /// + /// /// - public UmbracoAuthorizeAttribute(IWebSecurity webSecurity, IRuntimeState runtimeState) + public UmbracoAuthorizeAttribute(IBackofficeSecurityAccessor backofficeSecurityAccessor, IRuntimeState runtimeState) { - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); } @@ -75,7 +76,7 @@ namespace Umbraco.Web.Mvc // otherwise we need to ensure that a user is logged in return RuntimeState.Level == RuntimeLevel.Install || RuntimeState.Level == RuntimeLevel.Upgrade - || WebSecurity.ValidateCurrentUser(); + || BackofficeSecurity.ValidateCurrentUser(); } catch (Exception) { diff --git a/src/Umbraco.Web/Mvc/UmbracoController.cs b/src/Umbraco.Web/Mvc/UmbracoController.cs index 940a9521aa..29f0949473 100644 --- a/src/Umbraco.Web/Mvc/UmbracoController.cs +++ b/src/Umbraco.Web/Mvc/UmbracoController.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web.Mvc /// /// Gets the web security helper. /// - public virtual IWebSecurity Security => UmbracoContext.Security; + public virtual IBackofficeSecurity Security => UmbracoContext.Security; protected UmbracoController() : this( diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/BackofficeSecurity.cs similarity index 95% rename from src/Umbraco.Web/Security/WebSecurity.cs rename to src/Umbraco.Web/Security/BackofficeSecurity.cs index 5776ec876a..e5e46ea37f 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/BackofficeSecurity.cs @@ -14,7 +14,7 @@ namespace Umbraco.Web.Security { // NOTE: Moved to netcore - public class WebSecurity : IWebSecurity + public class BackofficeSecurity : IBackofficeSecurity { public IUser CurrentUser => throw new NotImplementedException(); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index c2d36285e6..dfade80794 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -157,7 +157,7 @@ - + diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index bda836c847..a4b6e1dd14 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -30,7 +30,7 @@ namespace Umbraco.Web // warn: does *not* manage setting any IUmbracoContextAccessor internal UmbracoContext(IHttpContextAccessor httpContextAccessor, IPublishedSnapshotService publishedSnapshotService, - IWebSecurity webSecurity, + IBackofficeSecurity backofficeSecurity, GlobalSettings globalSettings, IHostingEnvironment hostingEnvironment, IVariationContextAccessor variationContextAccessor, @@ -39,7 +39,7 @@ namespace Umbraco.Web { if (httpContextAccessor == null) throw new ArgumentNullException(nameof(httpContextAccessor)); if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService)); - if (webSecurity == null) throw new ArgumentNullException(nameof(webSecurity)); + if (backofficeSecurity == null) throw new ArgumentNullException(nameof(backofficeSecurity)); VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor)); _httpContextAccessor = httpContextAccessor; _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); @@ -58,7 +58,7 @@ namespace Umbraco.Web ObjectCreated = DateTime.Now; UmbracoRequestId = Guid.NewGuid(); - Security = webSecurity; + Security = backofficeSecurity; // beware - we cannot expect a current user here, so detecting preview mode must be a lazy thing _publishedSnapshot = new Lazy(() => publishedSnapshotService.CreatePublishedSnapshot(PreviewToken)); @@ -87,9 +87,9 @@ namespace Umbraco.Web public Guid UmbracoRequestId { get; } /// - /// Gets the WebSecurity class + /// Gets the BackofficeSecurity class /// - public IWebSecurity Security { get; } + public IBackofficeSecurity Security { get; } /// /// Gets the uri that is handled by ASP.NET after server-side rewriting took place. diff --git a/src/Umbraco.Web/UmbracoContextFactory.cs b/src/Umbraco.Web/UmbracoContextFactory.cs index 4eba56c36f..cc0bd59fa1 100644 --- a/src/Umbraco.Web/UmbracoContextFactory.cs +++ b/src/Umbraco.Web/UmbracoContextFactory.cs @@ -68,7 +68,7 @@ namespace Umbraco.Web _variationContextAccessor.VariationContext = new VariationContext(_defaultCultureAccessor.DefaultCulture); } - return new UmbracoContext(_httpContextAccessor, _publishedSnapshotService, new WebSecurity(), _globalSettings, _hostingEnvironment, _variationContextAccessor, _uriUtility, _cookieManager); + return new UmbracoContext(_httpContextAccessor, _publishedSnapshotService, new BackofficeSecurity(), _globalSettings, _hostingEnvironment, _variationContextAccessor, _uriUtility, _cookieManager); } /// diff --git a/src/Umbraco.Web/UmbracoHttpHandler.cs b/src/Umbraco.Web/UmbracoHttpHandler.cs index eb219f82d2..7db09b62ff 100644 --- a/src/Umbraco.Web/UmbracoHttpHandler.cs +++ b/src/Umbraco.Web/UmbracoHttpHandler.cs @@ -52,7 +52,7 @@ namespace Umbraco.Web /// /// Gets the web security helper. /// - public IWebSecurity Security => UmbracoContextAccessor.UmbracoContext.Security; + public IBackofficeSecurity Security => UmbracoContextAccessor.UmbracoContext.Security; /// /// Gets the Url helper. diff --git a/src/Umbraco.Web/UmbracoWebService.cs b/src/Umbraco.Web/UmbracoWebService.cs index a0d12cba93..9dca6f5d33 100644 --- a/src/Umbraco.Web/UmbracoWebService.cs +++ b/src/Umbraco.Web/UmbracoWebService.cs @@ -62,7 +62,7 @@ namespace Umbraco.Web /// /// Gets the web security helper. /// - public IWebSecurity Security => UmbracoContext.Security; + public IBackofficeSecurity Security => UmbracoContext.Security; /// /// Gets the Url helper. diff --git a/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs b/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs index 7c15775f7b..3434d825fe 100644 --- a/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs +++ b/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs @@ -118,7 +118,7 @@ namespace Umbraco.Web.WebApi /// /// Gets the web security helper. /// - public IWebSecurity Security => UmbracoContext.Security; + public IBackofficeSecurity Security => UmbracoContext.Security; /// /// Tries to get the current HttpContext. diff --git a/src/Umbraco.Web/WebApi/UmbracoAuthorizeAttribute.cs b/src/Umbraco.Web/WebApi/UmbracoAuthorizeAttribute.cs index 69c697d0fc..83f08660d9 100644 --- a/src/Umbraco.Web/WebApi/UmbracoAuthorizeAttribute.cs +++ b/src/Umbraco.Web/WebApi/UmbracoAuthorizeAttribute.cs @@ -1,6 +1,7 @@ using System; using System.Web.Http; using Umbraco.Core; +using Umbraco.Core.Security; using Umbraco.Web.Composing; using Umbraco.Web.Security; @@ -19,21 +20,21 @@ namespace Umbraco.Web.WebApi internal static bool Enable = true; // TODO: inject! - private readonly IWebSecurity _webSecurity; + private readonly IBackofficeSecurityAccessor _backofficeSecurityAccessor; private readonly IRuntimeState _runtimeState; private IRuntimeState RuntimeState => _runtimeState ?? Current.RuntimeState; - private IWebSecurity WebSecurity => _webSecurity ?? Current.UmbracoContext.Security; + private IBackofficeSecurity BackofficeSecurity => _backofficeSecurityAccessor.BackofficeSecurity ?? Current.UmbracoContext.Security; /// /// THIS SHOULD BE ONLY USED FOR UNIT TESTS /// - /// + /// /// - public UmbracoAuthorizeAttribute(IWebSecurity webSecurity, IRuntimeState runtimeState) + public UmbracoAuthorizeAttribute(IBackofficeSecurityAccessor backofficeSecurityAccessor, IRuntimeState runtimeState) { - _webSecurity = webSecurity ?? throw new ArgumentNullException(nameof(webSecurity)); + _backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor)); _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); } @@ -58,7 +59,7 @@ namespace Umbraco.Web.WebApi // otherwise we need to ensure that a user is logged in return RuntimeState.Level == RuntimeLevel.Install || RuntimeState.Level == RuntimeLevel.Upgrade - || WebSecurity.ValidateCurrentUser(false, _requireApproval) == ValidateRequestAttempt.Success; + || BackofficeSecurity.ValidateCurrentUser(false, _requireApproval) == ValidateRequestAttempt.Success; } catch (Exception) { From a80de91031aa474e428a9f1232a1a4c2b6df3555 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 22 Sep 2020 13:19:54 +0200 Subject: [PATCH 3/3] Netcore: Handle tree authentication (#8866) * Added helper methods to invoke the authorization filters of the other controller action Signed-off-by: Bjarke Berg * Implemented Tree Auth Signed-off-by: Bjarke Berg * cleanup Signed-off-by: Bjarke Berg * Throw forbidden if user has no access instead of InternalServerError Signed-off-by: Bjarke Berg * EnsureBackofficeSecurity for background jobs Signed-off-by: Bjarke Berg Co-authored-by: Elitsa Marinovska --- .../Scheduling/ScheduledPublishing.cs | 5 +- .../Scheduling/SchedulerComponent.cs | 7 +- .../Controllers/SectionController.cs | 8 +- .../Extensions/ControllerContextExtensions.cs | 125 ++++++++++++++++++ .../Trees/ApplicationTreeController.cs | 81 ++++-------- .../UmbracoContext/UmbracoContext.cs | 4 +- src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../WebApi/HttpControllerContextExtensions.cs | 54 -------- 8 files changed, 170 insertions(+), 115 deletions(-) create mode 100644 src/Umbraco.Web.BackOffice/Extensions/ControllerContextExtensions.cs delete mode 100644 src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs diff --git a/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs b/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs index 6ec0250d90..674012e797 100644 --- a/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs +++ b/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs @@ -14,13 +14,14 @@ namespace Umbraco.Web.Scheduling private readonly IMainDom _mainDom; private readonly IRuntimeState _runtime; private readonly IServerMessenger _serverMessenger; + private readonly IBackofficeSecurityFactory _backofficeSecurityFactory; private readonly IServerRegistrar _serverRegistrar; private readonly IUmbracoContextFactory _umbracoContextFactory; public ScheduledPublishing(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds, IRuntimeState runtime, IMainDom mainDom, IServerRegistrar serverRegistrar, IContentService contentService, - IUmbracoContextFactory umbracoContextFactory, ILogger logger, IServerMessenger serverMessenger) + IUmbracoContextFactory umbracoContextFactory, ILogger logger, IServerMessenger serverMessenger, IBackofficeSecurityFactory backofficeSecurityFactory) : base(runner, delayMilliseconds, periodMilliseconds) { _runtime = runtime; @@ -30,6 +31,7 @@ namespace Umbraco.Web.Scheduling _umbracoContextFactory = umbracoContextFactory; _logger = logger; _serverMessenger = serverMessenger; + _backofficeSecurityFactory = backofficeSecurityFactory; } public override bool IsAsync => false; @@ -76,6 +78,7 @@ namespace Umbraco.Web.Scheduling // but then what should be its "scope"? could we attach it to scopes? // - and we should definitively *not* have to flush it here (should be auto) // + _backofficeSecurityFactory.EnsureBackofficeSecurity(); using (var contextReference = _umbracoContextFactory.EnsureUmbracoContext()) { try diff --git a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs index cbf1df197d..5fb4f19473 100644 --- a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs +++ b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs @@ -39,6 +39,7 @@ namespace Umbraco.Web.Scheduling private readonly HealthChecksSettings _healthChecksSettings; private readonly IServerMessenger _serverMessenger; private readonly IRequestAccessor _requestAccessor; + private readonly IBackofficeSecurityFactory _backofficeSecurityFactory; private readonly LoggingSettings _loggingSettings; private readonly KeepAliveSettings _keepAliveSettings; private readonly IHostingEnvironment _hostingEnvironment; @@ -60,7 +61,8 @@ namespace Umbraco.Web.Scheduling IApplicationShutdownRegistry applicationShutdownRegistry, IOptions healthChecksSettings, IServerMessenger serverMessenger, IRequestAccessor requestAccessor, IOptions loggingSettings, IOptions keepAliveSettings, - IHostingEnvironment hostingEnvironment) + IHostingEnvironment hostingEnvironment, + IBackofficeSecurityFactory backofficeSecurityFactory) { _runtime = runtime; _mainDom = mainDom; @@ -77,6 +79,7 @@ namespace Umbraco.Web.Scheduling _healthChecksSettings = healthChecksSettings.Value ?? throw new ArgumentNullException(nameof(healthChecksSettings)); _serverMessenger = serverMessenger; _requestAccessor = requestAccessor; + _backofficeSecurityFactory = backofficeSecurityFactory; _loggingSettings = loggingSettings.Value; _keepAliveSettings = keepAliveSettings.Value; _hostingEnvironment = hostingEnvironment; @@ -150,7 +153,7 @@ namespace Umbraco.Web.Scheduling { // scheduled publishing/unpublishing // install on all, will only run on non-replica servers - var task = new ScheduledPublishing(_publishingRunner, DefaultDelayMilliseconds, OneMinuteMilliseconds, _runtime, _mainDom, _serverRegistrar, _contentService, _umbracoContextFactory, _logger, _serverMessenger); + var task = new ScheduledPublishing(_publishingRunner, DefaultDelayMilliseconds, OneMinuteMilliseconds, _runtime, _mainDom, _serverRegistrar, _contentService, _umbracoContextFactory, _logger, _serverMessenger, _backofficeSecurityFactory); _publishingRunner.TryAdd(task); return task; } diff --git a/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs b/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs index 810e3e5646..c579a3ec1d 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/SectionController.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Infrastructure; using Umbraco.Core; using Umbraco.Core.Mapping; using Umbraco.Core.Models; @@ -23,6 +24,7 @@ namespace Umbraco.Web.Editors public class SectionController : UmbracoAuthorizedJsonController { private readonly IControllerFactory _controllerFactory; + private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider; private readonly IDashboardService _dashboardService; private readonly ILocalizedTextService _localizedTextService; private readonly ISectionService _sectionService; @@ -34,7 +36,8 @@ namespace Umbraco.Web.Editors IBackofficeSecurityAccessor backofficeSecurityAccessor, ILocalizedTextService localizedTextService, IDashboardService dashboardService, ISectionService sectionService, ITreeService treeService, - UmbracoMapper umbracoMapper, IControllerFactory controllerFactory) + UmbracoMapper umbracoMapper, IControllerFactory controllerFactory, + IActionDescriptorCollectionProvider actionDescriptorCollectionProvider) { _backofficeSecurityAccessor = backofficeSecurityAccessor; _localizedTextService = localizedTextService; @@ -43,6 +46,7 @@ namespace Umbraco.Web.Editors _treeService = treeService; _umbracoMapper = umbracoMapper; _controllerFactory = controllerFactory; + _actionDescriptorCollectionProvider = actionDescriptorCollectionProvider; } public IEnumerable
GetSections() @@ -54,7 +58,7 @@ namespace Umbraco.Web.Editors // this is a bit nasty since we'll be proxying via the app tree controller but we sort of have to do that // since tree's by nature are controllers and require request contextual data var appTreeController = - new ApplicationTreeController(_treeService, _sectionService, _localizedTextService, _controllerFactory) + new ApplicationTreeController(_treeService, _sectionService, _localizedTextService, _controllerFactory, _actionDescriptorCollectionProvider) { ControllerContext = ControllerContext }; diff --git a/src/Umbraco.Web.BackOffice/Extensions/ControllerContextExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/ControllerContextExtensions.cs new file mode 100644 index 0000000000..ca17d97fc7 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Extensions/ControllerContextExtensions.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; + +namespace Umbraco.Extensions +{ + internal static class ControllerContextExtensions + { + /// + /// Invokes the authorization filters for the controller action. + /// + /// Whether the user is authenticated or not. + internal static async Task InvokeAuthorizationFiltersForRequest(this ControllerContext controllerContext, ActionContext actionContext) + { + var actionDescriptor = controllerContext.ActionDescriptor; + + var filters = actionDescriptor.FilterDescriptors; + var filterGrouping = new FilterGrouping(filters, controllerContext.HttpContext.RequestServices); + + // because the continuation gets built from the inside out we need to reverse the filter list + // so that least specific filters (Global) get run first and the most specific filters (Action) get run last. + var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToList(); + var asyncAuthorizationFilters = filterGrouping.AsyncAuthorizationFilters.Reverse().ToList(); + + if (authorizationFilters.Count == 0 && asyncAuthorizationFilters.Count == 0) + return true; + + // if the authorization filter returns a result, it means it failed to authorize + var authorizationFilterContext = new AuthorizationFilterContext(actionContext, filters.Select(x=>x.Filter).ToArray()); + return await ExecuteAuthorizationFiltersAsync(authorizationFilterContext, authorizationFilters, asyncAuthorizationFilters); + } + + /// + /// Executes a chain of filters. + /// + /// + /// Recursively calls in to itself as its continuation for the next filter in the chain. + /// + private static async Task ExecuteAuthorizationFiltersAsync( + AuthorizationFilterContext authorizationFilterContext, + IList authorizationFilters, + IList asyncAuthorizationFilters) + { + + foreach (var authorizationFilter in authorizationFilters) + { + authorizationFilter.OnAuthorization(authorizationFilterContext); + if (!(authorizationFilterContext.Result is null)) + { + return false; + } + + } + + foreach (var asyncAuthorizationFilter in asyncAuthorizationFilters) + { + await asyncAuthorizationFilter.OnAuthorizationAsync(authorizationFilterContext); + if (!(authorizationFilterContext.Result is null)) + { + return false; + } + } + + return true; + } + + /// + /// Quickly split filters into different types + /// + private class FilterGrouping + { + private readonly List _actionFilters = new List(); + private readonly List _asyncActionFilters = new List(); + private readonly List _authorizationFilters = new List(); + private readonly List _asyncAuthorizationFilters = new List(); + private readonly List _exceptionFilters = new List(); + private readonly List _asyncExceptionFilters = new List(); + + public FilterGrouping(IEnumerable filters, IServiceProvider serviceProvider) + { + if (filters == null) throw new ArgumentNullException("filters"); + + foreach (FilterDescriptor f in filters) + { + var filter = f.Filter; + Categorize(filter, _actionFilters, serviceProvider); + Categorize(filter, _authorizationFilters, serviceProvider); + Categorize(filter, _exceptionFilters, serviceProvider); + Categorize(filter, _asyncActionFilters, serviceProvider); + Categorize(filter, _asyncAuthorizationFilters, serviceProvider); + } + } + + public IEnumerable ActionFilters => _actionFilters; + public IEnumerable AsyncActionFilters => _asyncActionFilters; + public IEnumerable AuthorizationFilters => _authorizationFilters; + + public IEnumerable AsyncAuthorizationFilters => _asyncAuthorizationFilters; + + public IEnumerable ExceptionFilters => _exceptionFilters; + + public IEnumerable AsyncExceptionFilters => _asyncExceptionFilters; + + private static void Categorize(IFilterMetadata filter, List list, IServiceProvider serviceProvider) where T : class + { + if(filter is TypeFilterAttribute typeFilterAttribute) + { + filter = typeFilterAttribute.CreateInstance(serviceProvider); + } + + T match = filter as T; + if (match != null) + { + list.Add(match); + } + } + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs index 6253aa1ff4..92cb5b1b93 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs @@ -8,10 +8,12 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Primitives; using Umbraco.Core; using Umbraco.Core.Services; +using Umbraco.Extensions; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Attributes; @@ -35,18 +37,22 @@ namespace Umbraco.Web.Trees private readonly ISectionService _sectionService; private readonly ILocalizedTextService _localizedTextService; private readonly IControllerFactory _controllerFactory; + private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider; + public ApplicationTreeController( ITreeService treeService, ISectionService sectionService, ILocalizedTextService localizedTextService, - IControllerFactory controllerFactory + IControllerFactory controllerFactory, + IActionDescriptorCollectionProvider actionDescriptorCollectionProvider ) { _treeService = treeService; _sectionService = sectionService; _localizedTextService = localizedTextService; _controllerFactory = controllerFactory; + _actionDescriptorCollectionProvider = actionDescriptorCollectionProvider; } /// @@ -251,67 +257,36 @@ namespace Umbraco.Web.Trees private async Task GetApiControllerProxy(Type controllerType, string action, FormCollection querystring) { // note: this is all required in order to execute the auth-filters for the sub request, we - // need to "trick" web-api into thinking that it is actually executing the proxied controller. - + // need to "trick" mvc into thinking that it is actually executing the proxied controller. + var controllerName = controllerType.Name.Substring(0, controllerType.Name.Length - 10); // remove controller part of name; // create proxy route data specifying the action & controller to execute var routeData = new RouteData(new RouteValueDictionary() { ["action"] = action, - ["controller"] = controllerType.Name.Substring(0,controllerType.Name.Length-10) // remove controller part of name; - + ["controller"] = controllerName }); + if (!(querystring is null)) + { + foreach (var (key,value) in querystring) + { + routeData.Values[key] = value; + } + } + var actionDescriptor = _actionDescriptorCollectionProvider.ActionDescriptors.Items + .Cast() + .First(x => + x.ControllerName.Equals(controllerName) && + x.ActionName == action); - var controllerContext = new ControllerContext( - new ActionContext( - HttpContext, - routeData, - new ControllerActionDescriptor() - { - ControllerTypeInfo = controllerType.GetTypeInfo() - } - )); + var actionContext = new ActionContext(HttpContext, routeData, actionDescriptor); + var proxyControllerContext = new ControllerContext(actionContext); + var controller = (TreeController) _controllerFactory.CreateController(proxyControllerContext); - var controller = (TreeController) _controllerFactory.CreateController(controllerContext); - - - //TODO Refactor trees or reimplement this hacks to check authentication. - //https://dev.azure.com/umbraco/D-Team%20Tracker/_workitems/edit/3694 - - // var context = ControllerContext; - // - // // get the controller - // var controller = (TreeController) DependencyResolver.Current.GetService(controllerType) - // ?? throw new Exception($"Failed to create controller of type {controllerType.FullName}."); - // - // // create the proxy URL for the controller action - // var proxyUrl = HttpContext.Request.RequestUri.GetLeftPart(UriPartial.Authority) - // + HttpContext.Request.GetUrlHelper().GetUmbracoApiService(action, controllerType) - // + "?" + querystring.ToQueryString(); - // - // - // - // // create a proxy request - // var proxyRequest = new HttpRequestMessage(HttpMethod.Get, proxyUrl); - // - // // create a proxy controller context - // var proxyContext = new HttpControllerContext(context.Configuration, proxyRoute, proxyRequest) - // { - // ControllerDescriptor = new HttpControllerDescriptor(context.ControllerDescriptor.Configuration, ControllerExtensions.GetControllerName(controllerType), controllerType), - // RequestContext = context.RequestContext, - // Controller = controller - // }; - // - // // wire everything - // controller.ControllerContext = proxyContext; - // controller.Request = proxyContext.Request; - // controller.RequestContext.RouteData = proxyRoute; - // - // // auth - // var authResult = await controller.ControllerContext.InvokeAuthorizationFiltersForRequest(); - // if (authResult != null) - // throw new HttpResponseException(authResult); + var isAllowed = await controller.ControllerContext.InvokeAuthorizationFiltersForRequest(actionContext); + if (!isAllowed) + throw new HttpResponseException(HttpStatusCode.Forbidden); return controller; } diff --git a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs index 6b4ce706e3..5e5b6f6910 100644 --- a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs +++ b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContext.cs @@ -40,16 +40,16 @@ namespace Umbraco.Web IRequestAccessor requestAccessor) { if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService)); - if (backofficeSecurity == null) throw new ArgumentNullException(nameof(backofficeSecurity)); VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor)); _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); + _hostingEnvironment = hostingEnvironment; _cookieManager = cookieManager; _requestAccessor = requestAccessor; ObjectCreated = DateTime.Now; UmbracoRequestId = Guid.NewGuid(); - Security = backofficeSecurity; + Security = backofficeSecurity ?? throw new ArgumentNullException(nameof(backofficeSecurity)); // beware - we cannot expect a current user here, so detecting preview mode must be a lazy thing _publishedSnapshot = new Lazy(() => publishedSnapshotService.CreatePublishedSnapshot(PreviewToken)); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index dfade80794..962c8ed528 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -296,7 +296,6 @@ - diff --git a/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs b/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs deleted file mode 100644 index 323e52eb36..0000000000 --- a/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Web.Http; -using System.Web.Http.Controllers; -using System.Web.Http.Filters; -using Umbraco.Web.WebApi.Filters; - -namespace Umbraco.Web.WebApi -{ - internal static class HttpControllerContextExtensions - { - /// - /// Invokes the authorization filters for the controller action. - /// - /// The response of the first filter returning a result, if any, otherwise null (authorized). - internal static async Task InvokeAuthorizationFiltersForRequest(this HttpControllerContext controllerContext) - { - var controllerDescriptor = controllerContext.ControllerDescriptor; - var controllerServices = controllerDescriptor.Configuration.Services; - var actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext); - - var filters = actionDescriptor.GetFilterPipeline(); - var filterGrouping = new FilterGrouping(filters); - - // because the continuation gets built from the inside out we need to reverse the filter list - // so that least specific filters (Global) get run first and the most specific filters (Action) get run last. - var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToList(); - - if (authorizationFilters.Count == 0) - return null; - - // if the authorization filter returns a result, it means it failed to authorize - var actionContext = new HttpActionContext(controllerContext, actionDescriptor); - return await ExecuteAuthorizationFiltersAsync(actionContext, CancellationToken.None, authorizationFilters); - } - - /// - /// Executes a chain of filters. - /// - /// - /// Recursively calls in to itself as its continuation for the next filter in the chain. - /// - private static async Task ExecuteAuthorizationFiltersAsync(HttpActionContext actionContext, CancellationToken token, IList filters, int index = 0) - { - return await filters[index].ExecuteAuthorizationFilterAsync(actionContext, token, - () => ++index == filters.Count - ? Task.FromResult(null) - : ExecuteAuthorizationFiltersAsync(actionContext, token, filters, index)); - } - } -}