2020-05-11 17:05:57 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2020-05-11 17:05:57 +02:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using Umbraco.Core;
|
2020-05-20 15:25:42 +10:00
|
|
|
|
using Umbraco.Core.BackOffice;
|
2020-05-20 16:43:06 +10:00
|
|
|
|
using Umbraco.Core.Cache;
|
2020-04-02 17:41:00 +11:00
|
|
|
|
using Umbraco.Core.Configuration;
|
2020-05-11 17:05:57 +02:00
|
|
|
|
using Umbraco.Core.Configuration.Grid;
|
2020-04-03 11:03:06 +11:00
|
|
|
|
using Umbraco.Core.Hosting;
|
2020-05-11 17:05:57 +02:00
|
|
|
|
using Umbraco.Core.Services;
|
2020-04-02 17:41:00 +11:00
|
|
|
|
using Umbraco.Core.WebAssets;
|
2020-05-20 15:25:42 +10:00
|
|
|
|
using Umbraco.Extensions;
|
2020-05-01 13:40:26 +02:00
|
|
|
|
using Umbraco.Net;
|
2020-05-11 17:05:57 +02:00
|
|
|
|
using Umbraco.Web.BackOffice.ActionResults;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
using Umbraco.Web.BackOffice.Filters;
|
2020-03-31 10:57:56 +02:00
|
|
|
|
using Umbraco.Web.Common.ActionResults;
|
2020-05-20 15:25:42 +10:00
|
|
|
|
using Umbraco.Web.Models;
|
2020-04-02 21:19:42 +11:00
|
|
|
|
using Umbraco.Web.WebAssets;
|
2020-05-14 20:59:29 +10:00
|
|
|
|
using Constants = Umbraco.Core.Constants;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.BackOffice.Controllers
|
|
|
|
|
|
{
|
2020-05-13 16:09:54 +10:00
|
|
|
|
|
2020-05-14 20:59:29 +10:00
|
|
|
|
[Area(Constants.Web.Mvc.BackOfficeArea)]
|
2020-03-30 21:27:35 +02:00
|
|
|
|
public class BackOfficeController : Controller
|
|
|
|
|
|
{
|
2020-05-20 15:25:42 +10:00
|
|
|
|
private readonly BackOfficeUserManager _userManager;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
private readonly IRuntimeMinifier _runtimeMinifier;
|
2020-04-02 17:41:00 +11:00
|
|
|
|
private readonly IGlobalSettings _globalSettings;
|
2020-04-03 11:03:06 +11:00
|
|
|
|
private readonly IHostingEnvironment _hostingEnvironment;
|
2020-05-01 13:40:26 +02:00
|
|
|
|
private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime;
|
2020-05-11 17:05:57 +02:00
|
|
|
|
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
|
|
|
|
|
private readonly ILocalizedTextService _textService;
|
|
|
|
|
|
private readonly IGridConfig _gridConfig;
|
2020-05-20 16:43:06 +10:00
|
|
|
|
private readonly BackOfficeServerVariables _backOfficeServerVariables;
|
|
|
|
|
|
private readonly AppCaches _appCaches;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
|
2020-05-20 15:25:42 +10:00
|
|
|
|
public BackOfficeController(
|
|
|
|
|
|
BackOfficeUserManager userManager,
|
|
|
|
|
|
IRuntimeMinifier runtimeMinifier,
|
|
|
|
|
|
IGlobalSettings globalSettings,
|
|
|
|
|
|
IHostingEnvironment hostingEnvironment,
|
|
|
|
|
|
IUmbracoApplicationLifetime umbracoApplicationLifetime,
|
|
|
|
|
|
IUmbracoContextAccessor umbracoContextAccessor,
|
|
|
|
|
|
ILocalizedTextService textService,
|
2020-05-20 16:43:06 +10:00
|
|
|
|
IGridConfig gridConfig,
|
|
|
|
|
|
BackOfficeServerVariables backOfficeServerVariables,
|
|
|
|
|
|
AppCaches appCaches)
|
2020-03-30 21:27:35 +02:00
|
|
|
|
{
|
2020-05-20 15:25:42 +10:00
|
|
|
|
_userManager = userManager;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
_runtimeMinifier = runtimeMinifier;
|
2020-04-02 17:41:00 +11:00
|
|
|
|
_globalSettings = globalSettings;
|
2020-04-03 11:03:06 +11:00
|
|
|
|
_hostingEnvironment = hostingEnvironment;
|
2020-05-01 13:40:26 +02:00
|
|
|
|
_umbracoApplicationLifetime = umbracoApplicationLifetime;
|
2020-05-11 17:05:57 +02:00
|
|
|
|
_umbracoContextAccessor = umbracoContextAccessor;
|
|
|
|
|
|
_textService = textService;
|
|
|
|
|
|
_gridConfig = gridConfig ?? throw new ArgumentNullException(nameof(gridConfig));
|
2020-05-20 16:43:06 +10:00
|
|
|
|
_backOfficeServerVariables = backOfficeServerVariables;
|
|
|
|
|
|
_appCaches = appCaches;
|
2020-03-30 21:27:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-13 14:49:00 +10:00
|
|
|
|
[HttpGet]
|
|
|
|
|
|
public IActionResult Default()
|
2020-03-30 21:27:35 +02:00
|
|
|
|
{
|
2020-05-20 15:25:42 +10:00
|
|
|
|
// TODO: Migrate this
|
2020-03-30 21:27:35 +02:00
|
|
|
|
return View();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns the JavaScript main file including all references found in manifests
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[MinifyJavaScriptResult(Order = 0)]
|
2020-05-13 14:49:00 +10:00
|
|
|
|
[HttpGet]
|
2020-03-30 21:27:35 +02:00
|
|
|
|
public async Task<IActionResult> Application()
|
|
|
|
|
|
{
|
2020-04-03 11:03:06 +11:00
|
|
|
|
var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(_globalSettings, _hostingEnvironment);
|
2020-03-30 21:27:35 +02:00
|
|
|
|
|
|
|
|
|
|
return new JavaScriptResult(result);
|
|
|
|
|
|
}
|
2020-05-11 17:05:57 +02:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get the json localized text for a given culture or the culture for the current user
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="culture"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[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 };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-20 16:43:06 +10:00
|
|
|
|
[UmbracoAuthorize(Order = 0)] // TODO: Re-implement UmbracoAuthorizeAttribute
|
2020-05-11 17:05:57 +02:00
|
|
|
|
[HttpGet]
|
|
|
|
|
|
public JsonNetResult GetGridConfig()
|
|
|
|
|
|
{
|
|
|
|
|
|
return new JsonNetResult { Data = _gridConfig.EditorsConfig.Editors, Formatting = Formatting.None };
|
|
|
|
|
|
}
|
2020-05-20 15:25:42 +10:00
|
|
|
|
|
2020-05-20 16:43:06 +10:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns the JavaScript object representing the static server variables javascript object
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[UmbracoAuthorize(Order = 0)]
|
|
|
|
|
|
[MinifyJavaScriptResult(Order = 1)]
|
|
|
|
|
|
public async Task<JavaScriptResult> ServerVariables()
|
|
|
|
|
|
{
|
|
|
|
|
|
//cache the result if debugging is disabled
|
|
|
|
|
|
var serverVars = ServerVariablesParser.Parse(await _backOfficeServerVariables.GetServerVariablesAsync());
|
|
|
|
|
|
var result = _hostingEnvironment.IsDebugMode
|
|
|
|
|
|
? serverVars
|
|
|
|
|
|
: _appCaches.RuntimeCache.GetCacheItem<string>(
|
|
|
|
|
|
typeof(BackOfficeController) + "ServerVariables",
|
|
|
|
|
|
() => serverVars,
|
|
|
|
|
|
new TimeSpan(0, 10, 0));
|
|
|
|
|
|
|
|
|
|
|
|
return new JavaScriptResult(result);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-20 15:25:42 +10:00
|
|
|
|
[HttpGet]
|
|
|
|
|
|
public async Task<ActionResult> ValidatePasswordResetCode([Bind(Prefix = "u")]int userId, [Bind(Prefix = "r")]string resetCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
var user = await _userManager.FindByIdAsync(userId.ToString());
|
|
|
|
|
|
if (user != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var result = await _userManager.VerifyUserTokenAsync(user, "ResetPassword", "ResetPassword", resetCode);
|
|
|
|
|
|
if (result)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Add a flag and redirect for it to be displayed
|
|
|
|
|
|
TempData[ViewDataExtensions.TokenPasswordResetCode] = new ValidatePasswordResetCodeModel { UserId = userId, ResetCode = resetCode };
|
|
|
|
|
|
return RedirectToLocal(Url.Action("Default", "BackOffice"));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Add error and redirect for it to be displayed
|
|
|
|
|
|
TempData[ViewDataExtensions.TokenPasswordResetCode] = new[] { _textService.Localize("login/resetCodeExpired") };
|
|
|
|
|
|
return RedirectToLocal(Url.Action("Default", "BackOffice"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private ActionResult RedirectToLocal(string returnUrl)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Url.IsLocalUrl(returnUrl))
|
|
|
|
|
|
{
|
|
|
|
|
|
return Redirect(returnUrl);
|
|
|
|
|
|
}
|
|
|
|
|
|
return Redirect("/");
|
|
|
|
|
|
}
|
2020-03-30 21:27:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|