Fixing settings parsing to handle values containing colon chars

Also applies to standard installations, but was raised in Azure because the suggested connection strings for SQL Azure contains a colon
Work Item: 17011

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2010-12-18 20:39:04 +01:00
parent 9838c67424
commit 4b5f2db33d
3 changed files with 78 additions and 61 deletions

View File

@@ -76,5 +76,13 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
Assert.That(foo.DataProvider, Is.StringContaining("Bar")); Assert.That(foo.DataProvider, Is.StringContaining("Bar"));
Assert.That(foo.DataConnectionString, Is.StringContaining("Quux")); Assert.That(foo.DataConnectionString, Is.StringContaining("Quux"));
} }
[Test]
public void SettingsCanContainSeparatorChar() {
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;" });
var settings = ShellSettingsManager.LoadSettings().Where(s => s.Name == "Default").Single();
Assert.That(settings.DataConnectionString, Is.EqualTo("Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;"));
}
} }
} }

View File

@@ -5,19 +5,18 @@ using System.Linq;
using Microsoft.WindowsAzure; using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.ServiceRuntime;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Localization;
namespace Orchard.Azure.Environment.Configuration { namespace Orchard.Azure.Environment.Configuration {
public class AzureShellSettingsManager : IShellSettingsManager { public class AzureShellSettingsManager : IShellSettingsManager {
public const string ContainerName = "sites"; // container names must be lower cased public const string ContainerName = "sites"; // container names must be lower cased
public const string SettingsFilename = "Settings.txt"; public const string SettingsFilename = "Settings.txt";
public const char Separator = ':';
public const string EmptyValue = "null";
private readonly IShellSettingsManagerEventHandler _events; private readonly IShellSettingsManagerEventHandler _events;
private readonly AzureFileSystem _fileSystem; private readonly AzureFileSystem _fileSystem;
Localizer T { get; set; }
public AzureShellSettingsManager(IShellSettingsManagerEventHandler events) public AzureShellSettingsManager(IShellSettingsManagerEventHandler events)
: this(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")), events) {} : this(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")), events) {}
@@ -33,7 +32,7 @@ namespace Orchard.Azure.Environment.Configuration {
void IShellSettingsManager.SaveSettings(ShellSettings settings) { void IShellSettingsManager.SaveSettings(ShellSettings settings) {
var content = ComposeSettings(settings); var content = ComposeSettings(settings);
var filePath = String.Concat(settings.Name, "/", SettingsFilename); var filePath = _fileSystem.Combine(settings.Name, SettingsFilename);
var file = _fileSystem.CreateFile(filePath); var file = _fileSystem.CreateFile(filePath);
using (var stream = file.OpenWrite()) { using (var stream = file.OpenWrite()) {
@@ -62,50 +61,51 @@ namespace Orchard.Azure.Environment.Configuration {
if (String.IsNullOrEmpty(text)) if (String.IsNullOrEmpty(text))
return shellSettings; return shellSettings;
string[] settings = text.Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries); var settings = text.Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries);
foreach (var setting in settings) { foreach (var setting in settings) {
string[] settingFields = setting.Split(new[] {":"}, StringSplitOptions.RemoveEmptyEntries); var separatorIndex = setting.IndexOf(Separator);
int fieldsLength = settingFields.Length; if(separatorIndex == -1) {
if (fieldsLength != 2)
continue; continue;
for (int i = 0; i < fieldsLength; i++) {
settingFields[i] = settingFields[i].Trim();
} }
if (settingFields[1] != "null") { string key = setting.Substring(0, separatorIndex).Trim();
switch (settingFields[0]) { string value = setting.Substring(separatorIndex + 1).Trim();
if (value != EmptyValue) {
switch (key) {
case "Name": case "Name":
shellSettings.Name = settingFields[1]; shellSettings.Name = value;
break; break;
case "DataProvider": case "DataProvider":
shellSettings.DataProvider = settingFields[1]; shellSettings.DataProvider = value;
break; break;
case "State": case "State":
shellSettings.State = new TenantState(settingFields[1]); shellSettings.State = new TenantState(value);
break; break;
case "DataConnectionString": case "DataConnectionString":
shellSettings.DataConnectionString = settingFields[1]; shellSettings.DataConnectionString = value;
break; break;
case "DataPrefix": case "DataPrefix":
shellSettings.DataTablePrefix = settingFields[1]; shellSettings.DataTablePrefix = value;
break; break;
case "RequestUrlHost": case "RequestUrlHost":
shellSettings.RequestUrlHost = settingFields[1]; shellSettings.RequestUrlHost = value;
break; break;
case "RequestUrlPrefix": case "RequestUrlPrefix":
shellSettings.RequestUrlPrefix = settingFields[1]; shellSettings.RequestUrlPrefix = value;
break; break;
case "EncryptionAlgorithm": case "EncryptionAlgorithm":
shellSettings.EncryptionAlgorithm = settingFields[1]; shellSettings.EncryptionAlgorithm = value;
break; break;
case "EncryptionKey": case "EncryptionKey":
shellSettings.EncryptionKey = settingFields[1]; shellSettings.EncryptionKey = value;
break; break;
case "EncryptionIV": case "EncryptionIV":
shellSettings.EncryptionIV = settingFields[1]; shellSettings.EncryptionIV = value;
break; break;
} }
} }
} }
return shellSettings; return shellSettings;
} }
@@ -116,14 +116,14 @@ namespace Orchard.Azure.Environment.Configuration {
return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n", return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n",
settings.Name, settings.Name,
settings.DataProvider, settings.DataProvider,
settings.DataConnectionString ?? "null", settings.DataConnectionString ?? EmptyValue,
settings.DataTablePrefix ?? "null", settings.DataTablePrefix ?? EmptyValue,
settings.RequestUrlHost ?? "null", settings.RequestUrlHost ?? EmptyValue,
settings.RequestUrlPrefix ?? "null", settings.RequestUrlPrefix ?? EmptyValue,
settings.State != null ? settings.State.ToString() : String.Empty, settings.State != null ? settings.State.ToString() : String.Empty,
settings.EncryptionAlgorithm ?? "null", settings.EncryptionAlgorithm ?? EmptyValue,
settings.EncryptionKey ?? "null", settings.EncryptionKey ?? EmptyValue,
settings.EncryptionIV ?? "null" settings.EncryptionIV ?? EmptyValue
); );
} }
} }

View File

@@ -9,6 +9,8 @@ namespace Orchard.Environment.Configuration {
public class ShellSettingsManager : IShellSettingsManager { public class ShellSettingsManager : IShellSettingsManager {
private readonly IAppDataFolder _appDataFolder; private readonly IAppDataFolder _appDataFolder;
private readonly IShellSettingsManagerEventHandler _events; private readonly IShellSettingsManagerEventHandler _events;
public const char Separator = ':';
public const string EmptyValue = "null";
Localizer T { get; set; } Localizer T { get; set; }
@@ -47,74 +49,81 @@ namespace Orchard.Environment.Configuration {
} }
} }
static ShellSettings ParseSettings(string text) { static ShellSettings ParseSettings(string text)
{
var shellSettings = new ShellSettings(); var shellSettings = new ShellSettings();
if (String.IsNullOrEmpty(text)) if (String.IsNullOrEmpty(text))
return shellSettings; return shellSettings;
string[] settings = text.Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries); var settings = text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var setting in settings) { foreach (var setting in settings)
string[] settingFields = setting.Split(new[] {":"}, StringSplitOptions.RemoveEmptyEntries); {
int fieldsLength = settingFields.Length; var separatorIndex = setting.IndexOf(Separator);
if (fieldsLength != 2) if (separatorIndex == -1)
{
continue; continue;
for (int i = 0; i < fieldsLength; i++) {
settingFields[i] = settingFields[i].Trim();
} }
if (settingFields[1] != "null") { string key = setting.Substring(0, separatorIndex).Trim();
switch (settingFields[0]) { string value = setting.Substring(separatorIndex + 1).Trim();
if (value != EmptyValue)
{
switch (key)
{
case "Name": case "Name":
shellSettings.Name = settingFields[1]; shellSettings.Name = value;
break; break;
case "DataProvider": case "DataProvider":
shellSettings.DataProvider = settingFields[1]; shellSettings.DataProvider = value;
break; break;
case "State": case "State":
shellSettings.State = new TenantState(settingFields[1]); shellSettings.State = new TenantState(value);
break; break;
case "DataConnectionString": case "DataConnectionString":
shellSettings.DataConnectionString = settingFields[1]; shellSettings.DataConnectionString = value;
break; break;
case "DataPrefix": case "DataPrefix":
shellSettings.DataTablePrefix = settingFields[1]; shellSettings.DataTablePrefix = value;
break; break;
case "RequestUrlHost": case "RequestUrlHost":
shellSettings.RequestUrlHost = settingFields[1]; shellSettings.RequestUrlHost = value;
break; break;
case "RequestUrlPrefix": case "RequestUrlPrefix":
shellSettings.RequestUrlPrefix = settingFields[1]; shellSettings.RequestUrlPrefix = value;
break; break;
case "EncryptionAlgorithm": case "EncryptionAlgorithm":
shellSettings.EncryptionAlgorithm = settingFields[1]; shellSettings.EncryptionAlgorithm = value;
break; break;
case "EncryptionKey": case "EncryptionKey":
shellSettings.EncryptionKey = settingFields[1]; shellSettings.EncryptionKey = value;
break; break;
case "EncryptionIV": case "EncryptionIV":
shellSettings.EncryptionIV = settingFields[1]; shellSettings.EncryptionIV = value;
break; break;
} }
} }
} }
return shellSettings; return shellSettings;
} }
static string ComposeSettings(ShellSettings settings) { static string ComposeSettings(ShellSettings settings)
{
if (settings == null) if (settings == null)
return ""; return "";
return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n", return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n",
settings.Name, settings.Name,
settings.DataProvider, settings.DataProvider,
settings.DataConnectionString ?? "null", settings.DataConnectionString ?? EmptyValue,
settings.DataTablePrefix ?? "null", settings.DataTablePrefix ?? EmptyValue,
settings.RequestUrlHost ?? "null", settings.RequestUrlHost ?? EmptyValue,
settings.RequestUrlPrefix ?? "null", settings.RequestUrlPrefix ?? EmptyValue,
settings.State != null ? settings.State.ToString() : String.Empty, settings.State != null ? settings.State.ToString() : String.Empty,
settings.EncryptionAlgorithm ?? "null", settings.EncryptionAlgorithm ?? EmptyValue,
settings.EncryptionKey ?? "null", settings.EncryptionKey ?? EmptyValue,
settings.EncryptionIV ?? "null" settings.EncryptionIV ?? EmptyValue
); );
} }
} }
} }