Skip to content

Commit

Permalink
Merge pull request #4707 from daguiler/bugfix/DNN-47653
Browse files Browse the repository at this point in the history
Adding Web.config schema validation to the Configuration Manager
  • Loading branch information
mitchelsellers authored Jun 11, 2021
2 parents da4d732 + e878435 commit 8828bba
Show file tree
Hide file tree
Showing 13 changed files with 34,410 additions and 8 deletions.
1 change: 1 addition & 0 deletions DNN Platform/Library/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@
[assembly: InternalsVisibleTo("DotNetNuke.Modules.Journal")] // Once Globals is refactored to Dependency Injection we should be able to remove this
[assembly: InternalsVisibleTo("DotNetNuke.Modules.RazorHost")] // Once Globals is refactored to Dependency Injection we should be able to remove this
[assembly: InternalsVisibleTo("DotNetNuke.Website")] // Once Globals is refactored to Dependency Injection we should be able to remove this
[assembly: InternalsVisibleTo("Dnn.PersonaBar.ConfigConsole.Tests")] // Once Globals is refactored to Dependency Injection we should be able to remove this
27 changes: 27 additions & 0 deletions DNN_Platform.sln
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dnn.GoogleTagManagerConnect
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Build", "Build\Build.csproj", "{22E535CC-385B-44BB-998D-A3C0A144F9E1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dnn.PersonaBar.ConfigConsole.Tests", "Dnn.AdminExperience\Tests\Dnn.PersonaBar.ConfigConsole.Tests\Dnn.PersonaBar.ConfigConsole.Tests.csproj", "{12583A7E-7BEF-4F79-9CEA-3736D28C3241}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Cloud_Debug|Any CPU = Cloud_Debug|Any CPU
Expand Down Expand Up @@ -2007,6 +2009,30 @@ Global
{22E535CC-385B-44BB-998D-A3C0A144F9E1}.Release-Net45|Any CPU.Build.0 = Release|Any CPU
{22E535CC-385B-44BB-998D-A3C0A144F9E1}.Release-Net45|x86.ActiveCfg = Release|Any CPU
{22E535CC-385B-44BB-998D-A3C0A144F9E1}.Release-Net45|x86.Build.0 = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Debug|Any CPU.Build.0 = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Debug|x86.ActiveCfg = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Debug|x86.Build.0 = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Release|Any CPU.ActiveCfg = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Release|Any CPU.Build.0 = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Release|x86.ActiveCfg = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Cloud_Release|x86.Build.0 = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug|x86.ActiveCfg = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug|x86.Build.0 = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug-Net45|Any CPU.ActiveCfg = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug-Net45|Any CPU.Build.0 = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug-Net45|x86.ActiveCfg = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Debug-Net45|x86.Build.0 = Debug|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release|Any CPU.Build.0 = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release|x86.ActiveCfg = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release|x86.Build.0 = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release-Net45|Any CPU.ActiveCfg = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release-Net45|Any CPU.Build.0 = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release-Net45|x86.ActiveCfg = Release|Any CPU
{12583A7E-7BEF-4F79-9CEA-3736D28C3241}.Release-Net45|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -2117,6 +2143,7 @@ Global
{AE7E021E-7C7B-4003-9BD6-5A04C781C277} = {8BA6DD11-0CD5-4556-8853-282B3C1C3A06}
{7B43D266-D6E1-4496-A9A1-487AFEE0D9C0} = {9A986091-4238-4804-8C86-6A9A005F72C2}
{22E535CC-385B-44BB-998D-A3C0A144F9E1} = {29273BE6-1AA8-4970-98A0-41BFFEEDA67B}
{12583A7E-7BEF-4F79-9CEA-3736D28C3241} = {8EB4193C-A708-4DA0-9F2A-F5B7599F6F8F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46B6A641-57EB-4B19-B199-23E6FC2AB40B}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ namespace Dnn.PersonaBar.ConfigConsole.Components
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Xml;
using System.Xml.Schema;

using DotNetNuke.Application;
using DotNetNuke.Common;
Expand All @@ -18,6 +20,11 @@ namespace Dnn.PersonaBar.ConfigConsole.Components

public class ConfigConsoleController
{
/// <summary>
/// Name of the Web configuration file.
/// </summary>
internal const string WebConfig = "Web.config";

private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(ConfigConsoleController));
private const string CONFIG_EXT = ".config";
private const string ROBOTS_EXT = "robots.txt"; // in multi-portal instances, there may be multiple robots.txt files (e.g., site1.com.robots.txt, site2.com.robots.txt, etc.)
Expand Down Expand Up @@ -73,6 +80,31 @@ public void UpdateConfigFile(string fileName, string fileContent)
}
}

/// <summary>
/// Validates a config file against a well known schema.
/// </summary>
/// <param name="fileName">The config file name.</param>
/// <param name="fileContent">The contents of the config file.</param>
/// <returns>A list of validation errors.</returns>
public IEnumerable<string> ValidateConfigFile(string fileName, string fileContent)
{
this.ValidateFilePath(fileName);

if (!fileName.EndsWith(CONFIG_EXT, StringComparison.InvariantCultureIgnoreCase))
{
return new string[0];
}

if (fileName.EndsWith(WebConfig, StringComparison.InvariantCultureIgnoreCase))
{
var configDoc = new XmlDocument { XmlResolver = null };
configDoc.LoadXml(fileContent);
return ValidateSchema(configDoc, "Schemas/DotNetConfig.xsd");
}

return new string[0];
}

public void MergeConfigFile(string fileContent)
{
if (this.IsValidXmlMergDocument(fileContent))
Expand All @@ -85,6 +117,39 @@ public void MergeConfigFile(string fileContent)
}
}

private static IEnumerable<string> ValidateSchema(XmlDocument configDoc, string schemaRelPath)
{
var errors = new List<string>();

configDoc.Schemas.Add(LoadSchema(schemaRelPath));
configDoc.Validate((_, e) => errors.Add(e.Message));

return errors;
}

private static XmlSchema LoadSchema(string schemaRelPath)
{
var xsd = LoadResource(schemaRelPath);

using (var reader = new StringReader(xsd))
{
return XmlSchema.Read(reader, (_, e) => { });
}
}

private static string LoadResource(string relativePath)
{
var segments = relativePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var relativeName = string.Join(".", segments);
var name = $"Dnn.PersonaBar.Extensions.Components.ConfigConsole.{relativeName}";

using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}

private bool IsValidXmlMergDocument(string mergeDocText)
{
if (string.IsNullOrEmpty(mergeDocText.Trim()))
Expand Down
Loading

0 comments on commit 8828bba

Please # to comment.