using System.Net; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.WebAssets; using Umbraco.Cms.Infrastructure.Install; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Filters; using Umbraco.Extensions; namespace Umbraco.Cms.Web.BackOffice.Install; /// /// The Installation controller /// [InstallAuthorize] [Area(Constants.Web.Mvc.InstallArea)] public class InstallController : Controller { private static bool _reported; private static RuntimeLevel _reportedLevel; private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; private readonly GlobalSettings _globalSettings; private readonly IHostingEnvironment _hostingEnvironment; private readonly InstallHelper _installHelper; private readonly LinkGenerator _linkGenerator; private readonly ILogger _logger; private readonly IRuntimeState _runtime; private readonly IRuntimeMinifier _runtimeMinifier; private readonly IUmbracoVersion _umbracoVersion; public InstallController( IBackOfficeSecurityAccessor backofficeSecurityAccessor, InstallHelper installHelper, IRuntimeState runtime, IOptions globalSettings, IRuntimeMinifier runtimeMinifier, IHostingEnvironment hostingEnvironment, IUmbracoVersion umbracoVersion, ILogger logger, LinkGenerator linkGenerator) { _backofficeSecurityAccessor = backofficeSecurityAccessor; _installHelper = installHelper; _runtime = runtime; _globalSettings = globalSettings.Value; _runtimeMinifier = runtimeMinifier; _hostingEnvironment = hostingEnvironment; _umbracoVersion = umbracoVersion; _logger = logger; _linkGenerator = linkGenerator; } [HttpGet] [StatusCodeResult(HttpStatusCode.ServiceUnavailable)] [TypeFilter(typeof(StatusCodeResultAttribute), Arguments = new object[] { HttpStatusCode.ServiceUnavailable })] public async Task Index() { var umbracoPath = Url.GetBackOfficeUrl(); if (_runtime.Level == RuntimeLevel.Run) { return Redirect(umbracoPath!); } // TODO: Update for package migrations if (_runtime.Level == RuntimeLevel.Upgrade) { AuthenticateResult authResult = await this.AuthenticateBackOfficeAsync(); if (!authResult.Succeeded) { return Redirect(_globalSettings.UmbracoPath + "/AuthorizeUpgrade?redir=" + Request.GetEncodedUrl()); } } // gen the install base URL ViewData.SetInstallApiBaseUrl(_linkGenerator.GetInstallerApiUrl()); // get the base umbraco folder var baseFolder = _hostingEnvironment.ToAbsolute(_globalSettings.UmbracoPath); ViewData.SetUmbracoBaseFolder(baseFolder); ViewData.SetUmbracoVersion(_umbracoVersion.SemanticVersion); await _installHelper.SetInstallStatusAsync(false, string.Empty); return View(Path.Combine(Constants.SystemDirectories.Umbraco.TrimStart("~"), Constants.Web.Mvc.InstallArea, nameof(Index) + ".cshtml")); } /// /// Used to perform the redirect to the installer when the runtime level is or /// /// /// [HttpGet] [IgnoreFromNotFoundSelectorPolicy] public ActionResult Redirect() { var uri = HttpContext.Request.GetEncodedUrl(); // redirect to install ReportRuntime(_logger, _runtime.Level, "Umbraco must install or upgrade."); var installUrl = $"{_linkGenerator.GetInstallerUrl()}?redir=true&url={uri}"; return Redirect(installUrl); } private static void ReportRuntime(ILogger logger, RuntimeLevel level, string message) { if (_reported && _reportedLevel == level) { return; } _reported = true; _reportedLevel = level; logger.LogWarning(message); } }