using System.Linq; using System.Threading.Tasks; using System.Web.Configuration; using System.Xml.Linq; using Umbraco.Core.IO; using Umbraco.Core.Security; using Umbraco.Web.Install.Models; namespace Umbraco.Web.Install.InstallSteps { [InstallSetupStep(InstallationType.NewInstall, "ConfigureMachineKey", "machinekey", 2, "Updating some security settings...", PerformsAppRestart = true)] internal class ConfigureMachineKey : InstallSetupStep { public override string View => HasMachineKey() == false ? base.View : ""; /// /// Don't display the view or execute if a machine key already exists /// /// private static bool HasMachineKey() { var section = (MachineKeySection) WebConfigurationManager.GetSection("system.web/machineKey"); return section.ElementInformation.Source != null; } /// /// The step execution method /// /// /// public override Task ExecuteAsync(bool? model) { if (model.HasValue && model.Value == false) return Task.FromResult(null); //install the machine key var fileName = IOHelper.MapPath($"{SystemDirectories.Root}/web.config"); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); // we only want to get the element that is under the root, (there may be more under tags we don't want them) var systemWeb = xml.Root.Element("system.web"); // Update appSetting if it exists, or else create a new appSetting for the given key and value var machineKey = systemWeb.Descendants("machineKey").FirstOrDefault(); if (machineKey != null) return Task.FromResult(null); var generator = new MachineKeyGenerator(); var generatedSection = generator.GenerateConfigurationBlock(); systemWeb.Add(XElement.Parse(generatedSection)); xml.Save(fileName, SaveOptions.DisableFormatting); return Task.FromResult(null); } public override bool RequiresExecution(bool? model) { return HasMachineKey() == false; } } }