diff --git a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs index 72c720e3d6..363dc7b048 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs @@ -1,7 +1,5 @@ -using System.IO; -using Umbraco.Core.Cache; +using Umbraco.Core.Cache; using Umbraco.Core.Hosting; -using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Serialization; @@ -10,9 +8,9 @@ namespace Umbraco.Core.Configuration.Grid { public class GridConfig : IGridConfig { - public GridConfig(AppCaches appCaches, IIOHelper ioHelper, IManifestParser manifestParser, IJsonSerializer jsonSerializer, IHostingEnvironment hostingEnvironment) + public GridConfig(AppCaches appCaches, IManifestParser manifestParser, IJsonSerializer jsonSerializer, IHostingEnvironment hostingEnvironment, ILogger logger) { - EditorsConfig = new GridEditorsConfig(appCaches, ioHelper, manifestParser, jsonSerializer, hostingEnvironment.IsDebugMode); + EditorsConfig = new GridEditorsConfig(appCaches, hostingEnvironment, manifestParser, jsonSerializer, logger); } public IGridEditorsConfig EditorsConfig { get; } diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs index 410c83ff1a..6cf985fecb 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; using System.IO; -using Umbraco.Composing; using Umbraco.Core.Cache; -using Umbraco.Core.IO; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.PropertyEditors; @@ -14,18 +13,19 @@ namespace Umbraco.Core.Configuration.Grid internal class GridEditorsConfig : IGridEditorsConfig { private readonly AppCaches _appCaches; - private readonly IIOHelper _ioHelper; + private readonly IHostingEnvironment _hostingEnvironment; private readonly IManifestParser _manifestParser; - private readonly bool _isDebug; - private readonly IJsonSerializer _jsonSerializer; - public GridEditorsConfig(AppCaches appCaches, IIOHelper ioHelper, IManifestParser manifestParser,IJsonSerializer jsonSerializer, bool isDebug) + private readonly IJsonSerializer _jsonSerializer; + private readonly ILogger _logger; + + public GridEditorsConfig(AppCaches appCaches, IHostingEnvironment hostingEnvironment, IManifestParser manifestParser,IJsonSerializer jsonSerializer, ILogger logger) { _appCaches = appCaches; - _ioHelper = ioHelper; + _hostingEnvironment = hostingEnvironment; _manifestParser = manifestParser; _jsonSerializer = jsonSerializer; - _isDebug = isDebug; + _logger = logger; } public IEnumerable Editors @@ -34,7 +34,7 @@ namespace Umbraco.Core.Configuration.Grid { List GetResult() { - var configFolder = new DirectoryInfo(_ioHelper.MapPath(Constants.SystemDirectories.Config)); + var configFolder = new DirectoryInfo(_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Config)); var editors = new List(); var gridConfig = Path.Combine(configFolder.FullName, "grid.editors.config.js"); if (File.Exists(gridConfig)) @@ -47,7 +47,7 @@ namespace Umbraco.Core.Configuration.Grid } catch (Exception ex) { - Current.Logger.Error(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString); + _logger.Error(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString); } } @@ -61,7 +61,7 @@ namespace Umbraco.Core.Configuration.Grid } //cache the result if debugging is disabled - var result = _isDebug + var result = _hostingEnvironment.IsDebugMode ? GetResult() : _appCaches.RuntimeCache.GetCacheItem>(typeof(GridEditorsConfig) + ".Editors",GetResult, TimeSpan.FromMinutes(10)); diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index ce20e723df..b79fb67fe7 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -16,7 +16,6 @@ using Umbraco.Net; using Umbraco.Core.Persistence; using Umbraco.Core.Serialization; using Umbraco.Core.Strings; -using Umbraco.Core.Sync; using Umbraco.Web; using Umbraco.Web.Routing; diff --git a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index e203d378ef..1b49f4d7bc 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -30,6 +30,7 @@ + diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index 67d822fb03..7649de4aa0 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs new file mode 100644 index 0000000000..1b4630c2da --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Controllers/SurfaceControllerTests.cs @@ -0,0 +1,236 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using Moq; +using NUnit.Framework; +using Umbraco.Core.Cache; +using Umbraco.Core.Hosting; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Services; +using Umbraco.Tests.Common; +using Umbraco.Tests.Common.Builders; +using Umbraco.Tests.Testing; +using Umbraco.Web; +using Umbraco.Web.PublishedCache; +using Umbraco.Web.Routing; +using Umbraco.Web.Website; +using Umbraco.Web.Website.Controllers; + +namespace Umbraco.Tests.Integration +{ + [TestFixture] + [UmbracoTest(WithApplication = true)] + public class SurfaceControllerTests + { + private IUmbracoContextAccessor _umbracoContextAccessor; + + [SetUp] + public void SetUp() + { + _umbracoContextAccessor = new TestUmbracoContextAccessor(); + } + + [Test] + public void Can_Construct_And_Get_Result() + { + var httpContextAccessor = Mock.Of(); + var hostingEnvironment = Mock.Of(); + var globalSettings = new GlobalSettingsBuilder().Build(); + + var umbracoContextFactory = new UmbracoContextFactory( + _umbracoContextAccessor, + Mock.Of(), + new TestVariationContextAccessor(), + new TestDefaultCultureAccessor(), + globalSettings, + Mock.Of(), + hostingEnvironment, + new UriUtility(hostingEnvironment), + httpContextAccessor, + Mock.Of(), + Mock.Of()); + + var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); + var umbracoContext = umbracoContextReference.UmbracoContext; + + var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); + + var ctrl = new TestSurfaceController(umbracoContextAccessor, Mock.Of(), Mock.Of()); + + var result = ctrl.Index(); + + Assert.IsNotNull(result); + } + + [Test] + public void Umbraco_Context_Not_Null() + { + var globalSettings = new GlobalSettingsBuilder().Build(); + var httpContextAccessor = Mock.Of(); + var hostingEnvironment = Mock.Of(); + + var umbracoContextFactory = new UmbracoContextFactory( + _umbracoContextAccessor, + Mock.Of(), + new TestVariationContextAccessor(), + new TestDefaultCultureAccessor(), + globalSettings, + Mock.Of(), + hostingEnvironment, + new UriUtility(hostingEnvironment), + httpContextAccessor, + Mock.Of(), + Mock.Of()); + + var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); + var umbCtx = umbracoContextReference.UmbracoContext; + + var umbracoContextAccessor = new TestUmbracoContextAccessor(umbCtx); + + var ctrl = new TestSurfaceController(umbracoContextAccessor, Mock.Of(), Mock.Of()); + + Assert.IsNotNull(ctrl.UmbracoContext); + } + + [Test] + public void Can_Lookup_Content() + { + var publishedSnapshot = new Mock(); + publishedSnapshot.Setup(x => x.Members).Returns(Mock.Of()); + var content = new Mock(); + content.Setup(x => x.Id).Returns(2); + + var publishedSnapshotService = new Mock(); + var httpContextAccessor = Mock.Of(); + var hostingEnvironment = Mock.Of(); + var globalSettings = new GlobalSettingsBuilder().Build(); + + var umbracoContextFactory = new UmbracoContextFactory( + _umbracoContextAccessor, + publishedSnapshotService.Object, + new TestVariationContextAccessor(), + new TestDefaultCultureAccessor(), + globalSettings, + Mock.Of(), + hostingEnvironment, + new UriUtility(hostingEnvironment), + httpContextAccessor, + Mock.Of(), + Mock.Of()); + + var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); + var umbracoContext = umbracoContextReference.UmbracoContext; + + var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); + + var publishedContentQuery = Mock.Of(query => query.Content(2) == content.Object); + + var ctrl = new TestSurfaceController(umbracoContextAccessor, publishedContentQuery, Mock.Of()); + var result = ctrl.GetContent(2) as PublishedContentResult; + + Assert.IsNotNull(result); + Assert.IsNotNull(result.Content); + Assert.AreEqual(2, result.Content.Id); + } + + + [Test] + public void Mock_Current_Page() + { + var globalSettings = new GlobalSettingsBuilder().Build(); + var httpContextAccessor = Mock.Of(); + var hostingEnvironment = Mock.Of(); + + var umbracoContextFactory = new UmbracoContextFactory( + _umbracoContextAccessor, + Mock.Of(), + new TestVariationContextAccessor(), + new TestDefaultCultureAccessor(), + globalSettings, + Mock.Of(), + hostingEnvironment, + new UriUtility(hostingEnvironment), + httpContextAccessor, + Mock.Of(), + Mock.Of()); + + var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(); + var umbracoContext = umbracoContextReference.UmbracoContext; + + var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); + + var content = Mock.Of(publishedContent => publishedContent.Id == 12345); + + var publishedRequestMock = new Mock(); + publishedRequestMock.Setup(x => x.PublishedContent).Returns(content); + + var routeDefinition = new RouteDefinition + { + PublishedRequest = publishedRequestMock.Object + }; + + var routeData = new RouteData(); + routeData.DataTokens.Add(Core.Constants.Web.UmbracoRouteDefinitionDataToken, routeDefinition); + + var ctrl = new TestSurfaceController(umbracoContextAccessor, Mock.Of(), Mock.Of()); + ctrl.ControllerContext = new ControllerContext() + { + HttpContext = Mock.Of(), + RouteData = routeData + }; + + var result = ctrl.GetContentFromCurrentPage() as PublishedContentResult; + + Assert.AreEqual(12345, result.Content.Id); + } + + + public class TestSurfaceController : SurfaceController + { + private readonly IPublishedContentQuery _publishedContentQuery; + + public TestSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IPublishedContentQuery publishedContentQuery, IPublishedUrlProvider publishedUrlProvider) + : base(umbracoContextAccessor, null, ServiceContext.CreatePartial(), AppCaches.Disabled, null, null, publishedUrlProvider) + { + _publishedContentQuery = publishedContentQuery; + } + + public IActionResult Index() + { + // ReSharper disable once Mvc.ViewNotResolved + return View(); + } + + public IActionResult GetContent(int id) + { + var content = _publishedContentQuery.Content(id); + + return new PublishedContentResult(content); + } + + public IActionResult GetContentFromCurrentPage() + { + var content = CurrentPage; + + return new PublishedContentResult(content); + } + } + + public class PublishedContentResult : IActionResult + { + public IPublishedContent Content { get; set; } + + public PublishedContentResult(IPublishedContent content) + { + Content = content; + } + + public Task ExecuteResultAsync(ActionContext context) + { + return Task.CompletedTask; + } + } + } +} diff --git a/src/Umbraco.Web.BackOffice/ActionResults/JsonNetResult.cs b/src/Umbraco.Web.BackOffice/ActionResults/JsonNetResult.cs new file mode 100644 index 0000000000..db5c7a8510 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/ActionResults/JsonNetResult.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; + +namespace Umbraco.Web.BackOffice.ActionResults +{ + /// + /// Custom json result using newtonsoft json.net + /// + public class JsonNetResult : IActionResult + { + public Encoding ContentEncoding { get; set; } + public string ContentType { get; set; } + public object Data { get; set; } + + public JsonSerializerSettings SerializerSettings { get; set; } + public Formatting Formatting { get; set; } + + public JsonNetResult() + { + SerializerSettings = new JsonSerializerSettings(); + } + + public Task ExecuteResultAsync(ActionContext context) + { + if (context is null) + throw new ArgumentNullException(nameof(context)); + + var response = context.HttpContext.Response; + + response.ContentType = string.IsNullOrEmpty(ContentType) == false + ? ContentType + : System.Net.Mime.MediaTypeNames.Application.Json; + + if (!(ContentEncoding is null)) + response.Headers.Add(Microsoft.Net.Http.Headers.HeaderNames.ContentEncoding, ContentEncoding.ToString()); + + if (!(Data is null)) + { + using var bodyWriter = new StreamWriter(response.Body); + using var writer = new JsonTextWriter(bodyWriter) { Formatting = Formatting }; + var serializer = JsonSerializer.Create(SerializerSettings); + serializer.Serialize(writer, Data); + } + + return Task.CompletedTask; + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index c99498bf57..c5507f00bf 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -1,9 +1,18 @@ -using System.Threading.Tasks; +using System; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.Grid; using Umbraco.Core.Hosting; +using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Net; +using Umbraco.Web.BackOffice.ActionResults; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.ActionResults; using Umbraco.Web.WebAssets; @@ -18,12 +27,20 @@ namespace Umbraco.Web.BackOffice.Controllers private readonly IRuntimeMinifier _runtimeMinifier; private readonly IGlobalSettings _globalSettings; private readonly IHostingEnvironment _hostingEnvironment; + private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly ILocalizedTextService _textService; + private readonly IGridConfig _gridConfig; - public BackOfficeController(IRuntimeMinifier runtimeMinifier, IGlobalSettings globalSettings, IHostingEnvironment hostingEnvironment) + public BackOfficeController(IRuntimeMinifier runtimeMinifier, IGlobalSettings globalSettings, IHostingEnvironment hostingEnvironment, IUmbracoApplicationLifetime umbracoApplicationLifetime, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService textService, IGridConfig gridConfig) { _runtimeMinifier = runtimeMinifier; _globalSettings = globalSettings; _hostingEnvironment = hostingEnvironment; + _umbracoApplicationLifetime = umbracoApplicationLifetime; + _umbracoContextAccessor = umbracoContextAccessor; + _textService = textService; + _gridConfig = gridConfig ?? throw new ArgumentNullException(nameof(gridConfig)); } [HttpGet] @@ -44,5 +61,53 @@ namespace Umbraco.Web.BackOffice.Controllers return new JavaScriptResult(result); } + + /// + /// Get the json localized text for a given culture or the culture for the current user + /// + /// + /// + [HttpGet] + public JsonNetResult LocalizedText(string culture = null) + { + var securityHelper = _umbracoContextAccessor.GetRequiredUmbracoContext().Security; + var isAuthenticated = securityHelper.IsAuthenticated(); + + var cultureInfo = string.IsNullOrWhiteSpace(culture) + //if the user is logged in, get their culture, otherwise default to 'en' + ? isAuthenticated + //current culture is set at the very beginning of each request + ? Thread.CurrentThread.CurrentCulture + : CultureInfo.GetCultureInfo(_globalSettings.DefaultUILanguage) + : CultureInfo.GetCultureInfo(culture); + + var allValues = _textService.GetAllStoredValues(cultureInfo); + var pathedValues = allValues.Select(kv => + { + var slashIndex = kv.Key.IndexOf('/'); + var areaAlias = kv.Key.Substring(0, slashIndex); + var valueAlias = kv.Key.Substring(slashIndex + 1); + return new + { + areaAlias, + valueAlias, + value = kv.Value + }; + }); + + var nestedDictionary = pathedValues + .GroupBy(pv => pv.areaAlias) + .ToDictionary(pv => pv.Key, pv => + pv.ToDictionary(pve => pve.valueAlias, pve => pve.value)); + + return new JsonNetResult { Data = nestedDictionary, Formatting = Formatting.None }; + } + + //[UmbracoAuthorize(Order = 0)] TODO: Re-implement UmbracoAuthorizeAttribute + [HttpGet] + public JsonNetResult GetGridConfig() + { + return new JsonNetResult { Data = _gridConfig.EditorsConfig.Editors, Formatting = Formatting.None }; + } } } diff --git a/src/Umbraco.Web.BackOffice/Filters/UmbracoAuthorizeFilter.cs b/src/Umbraco.Web.BackOffice/Filters/UmbracoAuthorizeFilter.cs index 9a590b5c87..5aec94e70a 100644 --- a/src/Umbraco.Web.BackOffice/Filters/UmbracoAuthorizeFilter.cs +++ b/src/Umbraco.Web.BackOffice/Filters/UmbracoAuthorizeFilter.cs @@ -1,10 +1,12 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Routing; using System; using Umbraco.Core; using Umbraco.Extensions; using Umbraco.Web.Security; +using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment; namespace Umbraco.Web.BackOffice.Filters { @@ -20,13 +22,27 @@ namespace Umbraco.Web.BackOffice.Filters /// Can be used by unit tests to enable/disable this filter /// internal static bool Enable = true; - + private readonly IHostingEnvironment _hostingEnvironment; private readonly IUmbracoContextAccessor _umbracoContext; private readonly IRuntimeState _runtimeState; private readonly LinkGenerator _linkGenerator; private readonly bool _redirectToUmbracoLogin; private string _redirectUrl; + private UmbracoAuthorizeFilter( + IHostingEnvironment hostingEnvironment, + IUmbracoContextAccessor umbracoContext, + IRuntimeState runtimeState, LinkGenerator linkGenerator, + bool redirectToUmbracoLogin, string redirectUrl) + { + _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); + _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); + _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); + _linkGenerator = linkGenerator ?? throw new ArgumentNullException(nameof(linkGenerator)); + _redirectToUmbracoLogin = redirectToUmbracoLogin; + _redirectUrl = redirectUrl; + } + /// /// Default constructor /// @@ -34,11 +50,9 @@ namespace Umbraco.Web.BackOffice.Filters /// /// public UmbracoAuthorizeFilter( - IUmbracoContextAccessor umbracoContext, IRuntimeState runtimeState, LinkGenerator linkGenerator) - { - _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); - _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); - _linkGenerator = linkGenerator ?? throw new ArgumentNullException(nameof(linkGenerator)); + IHostingEnvironment hostingEnvironment, IUmbracoContextAccessor umbracoContext, IRuntimeState runtimeState, LinkGenerator linkGenerator) + : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, false, null) + { } /// @@ -49,11 +63,10 @@ namespace Umbraco.Web.BackOffice.Filters /// /// If true will redirect to the umbraco login page if not authorized public UmbracoAuthorizeFilter( - IUmbracoContextAccessor umbracoContext, IRuntimeState runtimeState, LinkGenerator linkGenerator, + IHostingEnvironment hostingEnvironment, IUmbracoContextAccessor umbracoContext, IRuntimeState runtimeState, LinkGenerator linkGenerator, bool redirectToUmbracoLogin) - : this(umbracoContext, runtimeState, linkGenerator) + : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, redirectToUmbracoLogin, null) { - _redirectToUmbracoLogin = redirectToUmbracoLogin; } /// @@ -64,11 +77,10 @@ namespace Umbraco.Web.BackOffice.Filters /// /// /// If specified will redirect to this URL if not authorized public UmbracoAuthorizeFilter( - IUmbracoContextAccessor umbracoContext, IRuntimeState runtimeState, LinkGenerator linkGenerator, + IHostingEnvironment hostingEnvironment, IUmbracoContextAccessor umbracoContext, IRuntimeState runtimeState, LinkGenerator linkGenerator, string redirectUrl) - : this(umbracoContext, runtimeState, linkGenerator) + : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, false, redirectUrl) { - _redirectUrl = redirectUrl; } public void OnAuthorization(AuthorizationFilterContext context) @@ -77,7 +89,7 @@ namespace Umbraco.Web.BackOffice.Filters { if (_redirectToUmbracoLogin) { - _redirectUrl = _linkGenerator.GetBackOfficeUrl(); + _redirectUrl = _linkGenerator.GetBackOfficeUrl(_hostingEnvironment); } if (!_redirectUrl.IsNullOrWhiteSpace()) diff --git a/src/Umbraco.Web.Common/Extensions/LinkGeneratorExtensions.cs b/src/Umbraco.Web.Common/Extensions/LinkGeneratorExtensions.cs index 5ac3412d61..aa7700eca0 100644 --- a/src/Umbraco.Web.Common/Extensions/LinkGeneratorExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/LinkGeneratorExtensions.cs @@ -3,6 +3,7 @@ using Umbraco.Core; using Microsoft.AspNetCore.Routing; using System.Reflection; using Umbraco.Web.Common.Install; +using Umbraco.Core.Hosting; namespace Umbraco.Extensions { @@ -13,7 +14,7 @@ namespace Umbraco.Extensions /// /// /// - public static string GetBackOfficeUrl(this LinkGenerator linkGenerator) + public static string GetBackOfficeUrl(this LinkGenerator linkGenerator, IHostingEnvironment hostingEnvironment) { Type backOfficeControllerType; @@ -22,9 +23,9 @@ namespace Umbraco.Extensions backOfficeControllerType = Assembly.Load("Umbraco.Web.BackOffice")?.GetType("Umbraco.Web.BackOffice.Controllers.BackOfficeController"); if (backOfficeControllerType == null) return "/"; // this would indicate that the installer is installed without the back office } - catch (Exception) + catch { - return "/"; // this would indicate that the installer is installed without the back office + return hostingEnvironment.ApplicationVirtualPath; // this would indicate that the installer is installed without the back office } return linkGenerator.GetPathByAction("Default", ControllerExtensions.GetControllerName(backOfficeControllerType), new { area = Constants.Web.Mvc.BackOfficeApiArea }); @@ -37,7 +38,7 @@ namespace Umbraco.Extensions /// public static string GetInstallerUrl(this LinkGenerator linkGenerator) { - return linkGenerator.GetPathByAction("Index", ControllerExtensions.GetControllerName(), new { area = Constants.Web.Mvc.InstallArea }); + return linkGenerator.GetPathByAction(nameof(InstallController.Index), ControllerExtensions.GetControllerName(), new { area = Constants.Web.Mvc.InstallArea }); } } } diff --git a/src/Umbraco.Web.Common/Install/InstallAreaRoutes.cs b/src/Umbraco.Web.Common/Install/InstallAreaRoutes.cs index 6f1f378809..b21495e27d 100644 --- a/src/Umbraco.Web.Common/Install/InstallAreaRoutes.cs +++ b/src/Umbraco.Web.Common/Install/InstallAreaRoutes.cs @@ -51,7 +51,7 @@ namespace Umbraco.Web.Common.Install endpoints.MapGet($"{installPathSegment}/{{controller?}}/{{action?}}", context => { // redirect to umbraco - context.Response.Redirect(_linkGenerator.GetBackOfficeUrl(), false); + context.Response.Redirect(_linkGenerator.GetBackOfficeUrl(_hostingEnvironment), false); return Task.CompletedTask; }); diff --git a/src/Umbraco.Web.Common/Security/WebSecurity.cs b/src/Umbraco.Web.Common/Security/WebSecurity.cs index 5f54d2e9ee..e87720dc86 100644 --- a/src/Umbraco.Web.Common/Security/WebSecurity.cs +++ b/src/Umbraco.Web.Common/Security/WebSecurity.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using Umbraco.Composing; using Umbraco.Core; using Umbraco.Core.Models.Membership; using Umbraco.Web.Security; @@ -11,46 +12,46 @@ namespace Umbraco.Web.Common.Security public class WebSecurity : IWebSecurity { - public IUser CurrentUser => throw new NotImplementedException(); + public IUser CurrentUser => new User(Current.Configs.Global()); public ValidateRequestAttempt AuthorizeRequest(bool throwExceptions = false) { - throw new NotImplementedException(); + return ValidateRequestAttempt.Success; } public void ClearCurrentLogin() { - throw new NotImplementedException(); + //throw new NotImplementedException(); } public Attempt GetUserId() { - throw new NotImplementedException(); + return Attempt.Succeed(-1); } public bool IsAuthenticated() { - throw new NotImplementedException(); + return true; } public double PerformLogin(int userId) { - throw new NotImplementedException(); + return 100; } public bool UserHasSectionAccess(string section, IUser user) { - throw new NotImplementedException(); + return true; } public bool ValidateCurrentUser() { - throw new NotImplementedException(); + return true; } public ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true) { - throw new NotImplementedException(); + return ValidateRequestAttempt.Success; } } } diff --git a/src/Umbraco.Web.UI/config/grid.editors.config.js b/src/Umbraco.Web.UI.NetCore/Config/grid.editors.config.js similarity index 100% rename from src/Umbraco.Web.UI/config/grid.editors.config.js rename to src/Umbraco.Web.UI.NetCore/Config/grid.editors.config.js diff --git a/src/Umbraco.Web.UI.NetCore/Controllers/TestBackOfficeUmbracoApiController.cs b/src/Umbraco.Web.UI.NetCore/Controllers/TestBackOfficeUmbracoApiController.cs deleted file mode 100644 index d5cddb508a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/Controllers/TestBackOfficeUmbracoApiController.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Umbraco.Web.Common.Attributes; -using Umbraco.Web.Common.Controllers; - -namespace Umbraco.Web.UI.NetCore.Controllers -{ - [PluginController("Test")] - [IsBackOffice] - public class TestBackOfficeUmbracoApiController : UmbracoApiController - { - [HttpGet] - public IActionResult Index() - { - return Content("hello world"); - } - } -} diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 27b54a9503..a703e7c20a 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -1,6 +1,7 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -49,6 +50,13 @@ namespace Umbraco.Web.UI.BackOffice { options.ShouldProfile = request => false; // WebProfiler determine and start profiling. We should not use the MiniProfilerMiddleware to also profile }); + + // If using Kestrel: https://stackoverflow.com/a/55196057 + services.Configure(options => + { + options.AllowSynchronousIO = true; + }); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj index 966cb9c86e..219b819b11 100644 --- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj +++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj @@ -13,6 +13,7 @@ + @@ -63,6 +64,7 @@ + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 5e66765379..8c0b98787c 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -142,7 +142,6 @@ True Settings.settings - diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 7984bf14f7..6cd3d18be1 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -19,7 +19,7 @@ Umbraco - + @Html.Raw(runtimeMinifier.RenderCssHere(BackOfficeWebAssets.UmbracoUpgradeCssBundleName)); @*Because we're lazy loading angular js, the embedded cloak style will not be loaded initially, but we need it*@ @@ -45,7 +45,7 @@ }); } -@Html.BareMinimumServerVariablesScript(Url, Model.Features, Model.GlobalSettings, Model.UmbracoVersion, Model.ContentSettings, Model.TreeCollection, Model.HttpContextAccessor, Model.HostingEnvironment, Model.RuntimeSettings, Model.SecuritySettings, runtimeMinifier) +@Html.BareMinimumServerVariablesScript(Url, Model.Features, Model.GlobalSettings, Model.UmbracoVersion, Model.ContentSettings, Model.TreeCollection, Model.HostingEnvironment, Model.RuntimeSettings, Model.SecuritySettings, runtimeMinifier)