diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec
index c4aaf7344e..e62185d4b2 100644
--- a/build/NuSpecs/UmbracoCms.Core.nuspec
+++ b/build/NuSpecs/UmbracoCms.Core.nuspec
@@ -34,7 +34,7 @@
-
+
diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IRequestHandlerSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IRequestHandlerSection.cs
index 2d78e68bf5..a8b8d17ad9 100644
--- a/src/Umbraco.Core/Configuration/UmbracoSettings/IRequestHandlerSection.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IRequestHandlerSection.cs
@@ -12,6 +12,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool ConvertUrlsToAscii { get; }
+ bool TryConvertUrlsToAscii { get; }
+
IEnumerable CharCollection { get; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/RequestHandlerElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/RequestHandlerElement.cs
index 779d33c8b8..c040c83708 100644
--- a/src/Umbraco.Core/Configuration/UmbracoSettings/RequestHandlerElement.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoSettings/RequestHandlerElement.cs
@@ -111,7 +111,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool IRequestHandlerSection.ConvertUrlsToAscii
{
- get { return UrlReplacing.ConvertUrlsToAscii; }
+ get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("true"); }
+ }
+
+ bool IRequestHandlerSection.TryConvertUrlsToAscii
+ {
+ get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("try"); }
}
IEnumerable IRequestHandlerSection.CharCollection
diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/UrlReplacingElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/UrlReplacingElement.cs
index a378a27dcd..887528fb4a 100644
--- a/src/Umbraco.Core/Configuration/UmbracoSettings/UrlReplacingElement.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoSettings/UrlReplacingElement.cs
@@ -11,10 +11,10 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return (bool) base["removeDoubleDashes"]; }
}
- [ConfigurationProperty("toAscii", DefaultValue = false)]
- internal bool ConvertUrlsToAscii
+ [ConfigurationProperty("toAscii", DefaultValue = "false")]
+ internal string ConvertUrlsToAscii
{
- get { return (bool)base["toAscii"]; }
+ get { return (string) base["toAscii"]; }
}
[ConfigurationCollection(typeof(CharCollection), AddItemName = "char")]
diff --git a/src/Umbraco.Core/Security/BackOfficeUserStore.cs b/src/Umbraco.Core/Security/BackOfficeUserStore.cs
index 3d43285e4c..42873a02e2 100644
--- a/src/Umbraco.Core/Security/BackOfficeUserStore.cs
+++ b/src/Umbraco.Core/Security/BackOfficeUserStore.cs
@@ -496,7 +496,7 @@ namespace Umbraco.Core.Security
//the stamp cannot be null, so if it is currently null then we'll just return a hash of the password
return Task.FromResult(user.SecurityStamp.IsNullOrWhiteSpace()
- ? user.PasswordHash.ToMd5()
+ ? user.PasswordHash.GenerateHash()
: user.SecurityStamp);
}
diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs
index 225ac99ff7..dba7f2cfee 100644
--- a/src/Umbraco.Core/StringExtensions.cs
+++ b/src/Umbraco.Core/StringExtensions.cs
@@ -701,67 +701,72 @@ namespace Umbraco.Core
return val;
}
+ ///
+ /// Generates a hash of a string based on the FIPS compliance setting.
+ ///
+ /// Referrs to itself
+ /// The hashed string
+ public static string GenerateHash(this string str)
+ {
+ return CryptoConfig.AllowOnlyFipsAlgorithms
+ ? str.ToSHA1()
+ : str.ToMd5();
+ }
+
///
/// Converts the string to MD5
///
- /// referrs to itself
- /// the md5 hashed string
+ /// Referrs to itself
+ /// The MD5 hashed string
public static string ToMd5(this string stringToConvert)
{
- //create an instance of the MD5CryptoServiceProvider
- var md5Provider = new MD5CryptoServiceProvider();
-
- //convert our string into byte array
- var byteArray = Encoding.UTF8.GetBytes(stringToConvert);
-
- //get the hashed values created by our MD5CryptoServiceProvider
- var hashedByteArray = md5Provider.ComputeHash(byteArray);
-
- //create a StringBuilder object
- var stringBuilder = new StringBuilder();
-
- //loop to each each byte
- foreach (var b in hashedByteArray)
- {
- //append it to our StringBuilder
- stringBuilder.Append(b.ToString("x2").ToLower());
- }
-
- //return the hashed value
- return stringBuilder.ToString();
+ return stringToConvert.GenerateHash("MD5");
}
///
/// Converts the string to SHA1
///
/// referrs to itself
- /// the md5 hashed string
+ /// The SHA1 hashed string
public static string ToSHA1(this string stringToConvert)
{
- //create an instance of the SHA1CryptoServiceProvider
- var md5Provider = new SHA1CryptoServiceProvider();
-
- //convert our string into byte array
- var byteArray = Encoding.UTF8.GetBytes(stringToConvert);
-
- //get the hashed values created by our SHA1CryptoServiceProvider
- var hashedByteArray = md5Provider.ComputeHash(byteArray);
-
- //create a StringBuilder object
- var stringBuilder = new StringBuilder();
-
- //loop to each each byte
- foreach (var b in hashedByteArray)
- {
- //append it to our StringBuilder
- stringBuilder.Append(b.ToString("x2").ToLower());
- }
-
- //return the hashed value
- return stringBuilder.ToString();
+ return stringToConvert.GenerateHash("SHA1");
}
+ /// Generate a hash of a string based on the hashType passed in
+ ///
+ /// Referrs to itself
+ /// String with the hash type. See remarks section of the CryptoConfig Class in MSDN docs for a list of possible values.
+ /// The hashed string
+ private static string GenerateHash(this string str, string hashType)
+ {
+ //create an instance of the correct hashing provider based on the type passed in
+ var hasher = HashAlgorithm.Create(hashType);
+ if (hasher == null) throw new InvalidOperationException("No hashing type found by name " + hashType);
+ using (hasher)
+ {
+ //convert our string into byte array
+ var byteArray = Encoding.UTF8.GetBytes(str);
+
+ //get the hashed values created by our selected provider
+ var hashedByteArray = hasher.ComputeHash(byteArray);
+
+ //create a StringBuilder object
+ var stringBuilder = new StringBuilder();
+
+ //loop to each each byte
+ foreach (var b in hashedByteArray)
+ {
+ //append it to our StringBuilder
+ stringBuilder.Append(b.ToString("x2").ToLower());
+ }
+
+ //return the hashed value
+ return stringBuilder.ToString();
+ }
+ }
+
///
/// Decodes a string that was encoded with UrlTokenEncode
///
@@ -1465,10 +1470,84 @@ namespace Umbraco.Core
///
internal static Guid ToGuid(this string text)
{
- var md5 = MD5.Create();
- byte[] myStringBytes = Encoding.ASCII.GetBytes(text);
- byte[] hash = md5.ComputeHash(myStringBytes);
- return new Guid(hash);
+ return CreateGuidFromHash(UrlNamespace,
+ text,
+ CryptoConfig.AllowOnlyFipsAlgorithms
+ ? 5 // SHA1
+ : 3); // MD5
+ }
+
+ ///
+ /// The namespace for URLs (from RFC 4122, Appendix C).
+ ///
+ /// See RFC 4122
+ ///
+ internal static readonly Guid UrlNamespace = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
+
+ ///
+ /// Creates a name-based UUID using the algorithm from RFC 4122 §4.3.
+ ///
+ /// See GuidUtility.cs for original implementation.
+ ///
+ /// The ID of the namespace.
+ /// The name (within that namespace).
+ /// The version number of the UUID to create; this value must be either
+ /// 3 (for MD5 hashing) or 5 (for SHA-1 hashing).
+ /// A UUID derived from the namespace and name.
+ /// See Generating a deterministic GUID.
+ internal static Guid CreateGuidFromHash(Guid namespaceId, string name, int version)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (version != 3 && version != 5)
+ throw new ArgumentOutOfRangeException("version", "version must be either 3 or 5.");
+
+ // convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3)
+ // ASSUME: UTF-8 encoding is always appropriate
+ byte[] nameBytes = Encoding.UTF8.GetBytes(name);
+
+ // convert the namespace UUID to network order (step 3)
+ byte[] namespaceBytes = namespaceId.ToByteArray();
+ SwapByteOrder(namespaceBytes);
+
+ // comput the hash of the name space ID concatenated with the name (step 4)
+ byte[] hash;
+ using (HashAlgorithm algorithm = version == 3 ? (HashAlgorithm)MD5.Create() : SHA1.Create())
+ {
+ algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0);
+ algorithm.TransformFinalBlock(nameBytes, 0, nameBytes.Length);
+ hash = algorithm.Hash;
+ }
+
+ // most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12)
+ byte[] newGuid = new byte[16];
+ Array.Copy(hash, 0, newGuid, 0, 16);
+
+ // set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3 (step 8)
+ newGuid[6] = (byte)((newGuid[6] & 0x0F) | (version << 4));
+
+ // set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively (step 10)
+ newGuid[8] = (byte)((newGuid[8] & 0x3F) | 0x80);
+
+ // convert the resulting UUID to local byte order (step 13)
+ SwapByteOrder(newGuid);
+ return new Guid(newGuid);
+ }
+
+ // Converts a GUID (expressed as a byte array) to/from network order (MSB-first).
+ internal static void SwapByteOrder(byte[] guid)
+ {
+ SwapBytes(guid, 0, 3);
+ SwapBytes(guid, 1, 2);
+ SwapBytes(guid, 4, 5);
+ SwapBytes(guid, 6, 7);
+ }
+
+ private static void SwapBytes(byte[] guid, int left, int right)
+ {
+ byte temp = guid[left];
+ guid[left] = guid[right];
+ guid[right] = temp;
}
}
}
diff --git a/src/Umbraco.Core/Strings/CleanStringType.cs b/src/Umbraco.Core/Strings/CleanStringType.cs
index 0e0a7c9908..c8c99be869 100644
--- a/src/Umbraco.Core/Strings/CleanStringType.cs
+++ b/src/Umbraco.Core/Strings/CleanStringType.cs
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Strings
///
/// Flag mask for encoding.
///
- CodeMask = Unicode | Utf8 | Ascii,
+ CodeMask = Unicode | Utf8 | Ascii | TryAscii,
///
/// Unicode encoding.
@@ -86,6 +86,10 @@ namespace Umbraco.Core.Strings
///
Ascii = 0x0400,
+ ///
+ /// Ascii encoding, if possible.
+ ///
+ TryAscii = 0x0800,
// role values
diff --git a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs
index 96b8187e22..40a0c71778 100644
--- a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs
+++ b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs
@@ -152,12 +152,18 @@ namespace Umbraco.Core.Strings
/// The short string helper.
public DefaultShortStringHelper WithDefaultConfig()
{
+ var urlSegmentConvertTo = CleanStringType.Utf8;
+ if (_umbracoSettings.RequestHandler.ConvertUrlsToAscii)
+ urlSegmentConvertTo = CleanStringType.Ascii;
+ if (_umbracoSettings.RequestHandler.TryConvertUrlsToAscii)
+ urlSegmentConvertTo = CleanStringType.TryAscii;
+
return WithConfig(CleanStringType.UrlSegment, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
PostFilter = x => CutMaxLength(x, 240),
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
- StringType = (_umbracoSettings.RequestHandler.ConvertUrlsToAscii ? CleanStringType.Ascii : CleanStringType.Utf8) | CleanStringType.LowerCase,
+ StringType = urlSegmentConvertTo | CleanStringType.LowerCase,
BreakTermsOnUpper = false,
Separator = '-'
}).WithConfig(CleanStringType.FileName, new Config
@@ -542,9 +548,20 @@ function validateSafeAlias(input, value, immediate, callback) {{
// recode
var codeType = stringType & CleanStringType.CodeMask;
- text = codeType == CleanStringType.Ascii
- ? Utf8ToAsciiConverter.ToAsciiString(text)
- : RemoveSurrogatePairs(text);
+ switch (codeType)
+ {
+ case CleanStringType.Ascii:
+ text = Utf8ToAsciiConverter.ToAsciiString(text);
+ break;
+ case CleanStringType.TryAscii:
+ const char ESC = (char) 27;
+ var ctext = Utf8ToAsciiConverter.ToAsciiString(text, ESC);
+ if (ctext.Contains(ESC) == false) text = ctext;
+ break;
+ default:
+ text = RemoveSurrogatePairs(text);
+ break;
+ }
// clean
text = CleanCodeString(text, stringType, separator.Value, culture, config);
diff --git a/src/Umbraco.Core/Strings/Utf8ToAsciiConverter.cs b/src/Umbraco.Core/Strings/Utf8ToAsciiConverter.cs
index e08defdedd..7a25f18c11 100644
--- a/src/Umbraco.Core/Strings/Utf8ToAsciiConverter.cs
+++ b/src/Umbraco.Core/Strings/Utf8ToAsciiConverter.cs
@@ -17,8 +17,9 @@ namespace Umbraco.Core.Strings
/// Converts an Utf8 string into an Ascii string.
///
/// The text to convert.
+ /// The character to used to replace characters that cannot properly be converted.
/// The converted text.
- public static string ToAsciiString(string text)
+ public static string ToAsciiString(string text, char fail = '?')
{
var input = text.ToCharArray();
@@ -26,7 +27,7 @@ namespace Umbraco.Core.Strings
// but... we should be filtering short strings only...
var output = new char[input.Length * 3]; // *3 because of things such as OE
- var len = ToAscii(input, output);
+ var len = ToAscii(input, output, fail);
return new string(output, 0, len);
//var output = new StringBuilder(input.Length + 16); // default is 16, start with at least input length + little extra
@@ -38,8 +39,9 @@ namespace Umbraco.Core.Strings
/// Converts an Utf8 string into an array of Ascii characters.
///
/// The text to convert.
+ /// The character to used to replace characters that cannot properly be converted.
/// The converted text.
- public static char[] ToAsciiCharArray(string text)
+ public static char[] ToAsciiCharArray(string text, char fail = '?')
{
var input = text.ToCharArray();
@@ -47,7 +49,7 @@ namespace Umbraco.Core.Strings
// but... we should be filtering short strings only...
var output = new char[input.Length * 3]; // *3 because of things such as OE
- var len = ToAscii(input, output);
+ var len = ToAscii(input, output, fail);
var array = new char[len];
Array.Copy(output, array, len);
return array;
@@ -64,10 +66,11 @@ namespace Umbraco.Core.Strings
///
/// The input array.
/// The output array.
+ /// The character to used to replace characters that cannot properly be converted.
/// The number of characters in the output array.
/// The caller must ensure that the output array is big enough.
/// The output array is not big enough.
- private static int ToAscii(char[] input, char[] output)
+ private static int ToAscii(char[] input, char[] output, char fail = '?')
{
var opos = 0;
@@ -75,10 +78,10 @@ namespace Umbraco.Core.Strings
if (char.IsSurrogate(input[ipos])) // ignore high surrogate
{
ipos++; // and skip low surrogate
- output[opos++] = '?';
+ output[opos++] = fail;
}
else
- ToAscii(input, ipos, output, ref opos);
+ ToAscii(input, ipos, output, ref opos, fail);
return opos;
}
@@ -109,12 +112,13 @@ namespace Umbraco.Core.Strings
/// The input position.
/// The output array.
/// The output position.
+ /// The character to used to replace characters that cannot properly be converted.
///
/// Adapted from various sources on the 'net including Lucene.Net.Analysis.ASCIIFoldingFilter.
/// Input should contain Utf8 characters exclusively and NOT Unicode.
/// Removes controls, normalizes whitespaces, replaces symbols by '?'.
///
- private static void ToAscii(char[] input, int ipos, char[] output, ref int opos)
+ private static void ToAscii(char[] input, int ipos, char[] output, ref int opos, char fail = '?')
{
var c = input[ipos];
@@ -3583,7 +3587,7 @@ namespace Umbraco.Core.Strings
// output[opos++] = c;
// strict ASCII
- output[opos++] = '?';
+ output[opos++] = fail;
break;
}
diff --git a/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs b/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs
index 58b0451995..b528e81131 100644
--- a/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs
+++ b/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs
@@ -16,7 +16,7 @@ using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Strings
{
[TestFixture]
- public class DefaultShortStringHelperTests
+ public class DefaultShortStringHelperTests
{
private DefaultShortStringHelper _helper;
@@ -145,6 +145,33 @@ namespace Umbraco.Tests.Strings
Assert.AreEqual("aeoa-and-aeoa-and-and-and-grosser-bbddzhzh-page", output);
}
+ [Test]
+ public void U4_4056_TryAscii()
+ {
+ var settings = SettingsForTests.GenerateMockSettings();
+ var contentMock = Mock.Get(settings.RequestHandler);
+ contentMock.Setup(x => x.CharCollection).Returns(Enumerable.Empty());
+ contentMock.Setup(x => x.ConvertUrlsToAscii).Returns(false);
+ SettingsForTests.ConfigureSettings(settings);
+
+ const string input1 = "ÆØÅ and æøå and 中文测试 and אודות האתר and größer БбДдЖж page";
+ const string input2 = "ÆØÅ and æøå and größer БбДдЖж page";
+
+ var helper = new DefaultShortStringHelper(settings).WithDefaultConfig(); // unicode
+ Assert.AreEqual("æøå-and-æøå-and-中文测试-and-אודות-האתר-and-größer-ббдджж-page", helper.CleanStringForUrlSegment(input1));
+ Assert.AreEqual("æøå-and-æøå-and-größer-ббдджж-page", helper.CleanStringForUrlSegment(input2));
+
+ helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
+ .WithConfig(CleanStringType.UrlSegment, new DefaultShortStringHelper.Config
+ {
+ IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_',
+ StringType = CleanStringType.LowerCase | CleanStringType.TryAscii, // try ascii
+ Separator = '-'
+ });
+ Assert.AreEqual("æøå-and-æøå-and-中文测试-and-אודות-האתר-and-größer-ббдджж-page", helper.CleanStringForUrlSegment(input1));
+ Assert.AreEqual("aeoa-and-aeoa-and-grosser-bbddzhzh-page", helper.CleanStringForUrlSegment(input2));
+ }
+
[Test]
public void CleanStringUnderscoreInTerm()
{
@@ -339,7 +366,7 @@ namespace Umbraco.Tests.Strings
Separator = '*'
});
Assert.AreEqual("house*2", helper.CleanString("house (2)", CleanStringType.Alias));
-
+
// FIXME but for a filename we want to keep them!
// FIXME and what about a url?
}
@@ -574,7 +601,7 @@ namespace Umbraco.Tests.Strings
{
var output = _helper.SplitPascalCasing(input, ' ');
Assert.AreEqual(expected, output);
-
+
output = _helper.SplitPascalCasing(input, '*');
expected = expected.Replace(' ', '*');
Assert.AreEqual(expected, output);
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 34f736f964..1ecf3aaf15 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -61,8 +61,9 @@
..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll
-
- ..\packages\Examine.0.1.82\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.83\lib\net45\Examine.dll
+ True
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config
index 533d2206dd..aea8b3acdf 100644
--- a/src/Umbraco.Tests/packages.config
+++ b/src/Umbraco.Tests/packages.config
@@ -2,7 +2,7 @@
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js
index 4d9222fa45..8ef43df47b 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js
@@ -255,7 +255,8 @@ Use this directive to construct a header inside the main editor window.
description: "=",
hideDescription: "@",
descriptionLocked: "@",
- navigation: "="
+ navigation: "=",
+ key: "="
},
link: link
};
diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.service.js b/src/Umbraco.Web.UI.Client/src/installer/installer.service.js
index 3ba655d934..b2693f344e 100644
--- a/src/Umbraco.Web.UI.Client/src/installer/installer.service.js
+++ b/src/Umbraco.Web.UI.Client/src/installer/installer.service.js
@@ -31,7 +31,7 @@ angular.module("umbraco.install").factory('installerService', function($rootScop
"At least 4 people have the Umbraco logo tattooed on them",
"'Umbraco' is the danish name for an allen key",
"Umbraco has been around since 2005, that's a looong time in IT",
- "More than 550 people from all over the world meet each year in Denmark in June for our annual conference CodeGarden",
+ "More than 550 people from all over the world meet each year in Denmark in June for our annual conference CodeGarden",
"While you are installing Umbraco someone else on the other side of the planet is probably doing it too",
"You can extend Umbraco without modifying the source code using either JavaScript or C#",
"Umbraco was installed in more than 165 countries in 2015"
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html
index f55b587c04..fdc1ddf0f5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html
@@ -17,6 +17,7 @@
-
+
+
-
+
+
+
-
diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/edit.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/edit.html
index fc53982b90..9f52357c31 100644
--- a/src/Umbraco.Web.UI.Client/src/views/datatypes/edit.html
+++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/edit.html
@@ -12,6 +12,7 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.html
index 5bde09f8e0..f0d3a8fbf6 100644
--- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.html
+++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.html
@@ -9,6 +9,7 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/edit.html b/src/Umbraco.Web.UI.Client/src/views/templates/edit.html
index ec8ca3e9b4..2d59b644d0 100644
--- a/src/Umbraco.Web.UI.Client/src/views/templates/edit.html
+++ b/src/Umbraco.Web.UI.Client/src/views/templates/edit.html
@@ -13,6 +13,7 @@
..\packages\dotless.1.5.2\lib\dotless.Core.dll
-
- ..\packages\Examine.0.1.82\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.83\lib\net45\Examine.dll
+ True
False
diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config
index 555740eda3..8b22708406 100644
--- a/src/Umbraco.Web.UI/packages.config
+++ b/src/Umbraco.Web.UI/packages.config
@@ -4,7 +4,7 @@
-
+
diff --git a/src/Umbraco.Web.UI/umbraco/developer/Macros/editMacro.aspx b/src/Umbraco.Web.UI/umbraco/developer/Macros/editMacro.aspx
index ee0dfe02bd..05bfab1115 100644
--- a/src/Umbraco.Web.UI/umbraco/developer/Macros/editMacro.aspx
+++ b/src/Umbraco.Web.UI/umbraco/developer/Macros/editMacro.aspx
@@ -58,6 +58,9 @@
+
+
+
diff --git a/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs
index 91c1aefdb0..ffa4e4e100 100644
--- a/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs
@@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using System.Linq;
using System.Runtime.Serialization;
-using System.Text;
-using System.Threading.Tasks;
-using Umbraco.Core.Models.Validation;
namespace Umbraco.Web.Models.ContentEditing
{
@@ -24,6 +20,9 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "alias")]
public string Alias { get; set; }
+ [DataMember(Name = "key")]
+ public Guid Key { get; set; }
+
[DataMember(Name = "content")]
public string Content { get; set; }
diff --git a/src/Umbraco.Web/Models/Mapping/TemplateModelMapper.cs b/src/Umbraco.Web/Models/Mapping/TemplateModelMapper.cs
index 19677fccc8..6111941084 100644
--- a/src/Umbraco.Web/Models/Mapping/TemplateModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/TemplateModelMapper.cs
@@ -15,7 +15,6 @@ namespace Umbraco.Web.Models.Mapping
config.CreateMap()
.ForMember(x => x.DeletedDate, exp => exp.Ignore())
- .ForMember(x => x.Key, exp => exp.Ignore())
.ForMember(x => x.Path, exp => exp.Ignore())
.ForMember(x => x.CreateDate, exp => exp.Ignore())
.ForMember(x => x.UpdateDate, exp => exp.Ignore())
diff --git a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
index e559d6777d..46e60fc8eb 100644
--- a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
@@ -16,7 +16,7 @@ using Umbraco.Core.Services;
using UserProfile = Umbraco.Web.Models.ContentEditing.UserProfile;
namespace Umbraco.Web.Models.Mapping
-{
+{
internal class UserModelMapper : MapperConfiguration
{
@@ -38,8 +38,8 @@ namespace Umbraco.Web.Models.Mapping
config.CreateMap()
.ConstructUsing(invite => new User(invite.Name, invite.Email, invite.Email, Guid.NewGuid().ToString("N")))
- .IgnoreAllUnmapped()
- //generate a new token
+ .IgnoreAllUnmapped()
+ //generate a new token
.ForMember(user => user.SecurityStamp, expression => expression.MapFrom(x => (DateTime.Now + x.Email).ToSHA1()))
//all invited users will not be approved, completing the invite will approve the user
.ForMember(user => user.IsApproved, expression => expression.UseValue(false))
@@ -115,7 +115,7 @@ namespace Umbraco.Web.Models.Mapping
opt => opt.MapFrom(user => applicationContext.Services.TextService.GetSupportedCultures().ToDictionary(x => x.Name, x => x.DisplayName)))
.ForMember(
detail => detail.EmailHash,
- opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().ToMd5()))
+ opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().GenerateHash()))
.ForMember(detail => detail.ParentId, opt => opt.UseValue(-1))
.ForMember(detail => detail.Path, opt => opt.MapFrom(user => "-1," + user.Id))
.ForMember(detail => detail.Notifications, opt => opt.Ignore())
@@ -169,7 +169,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(detail => detail.Culture, opt => opt.MapFrom(user => user.GetUserCulture(applicationContext.Services.TextService)))
.ForMember(
detail => detail.EmailHash,
- opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().ToMd5()))
+ opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().GenerateHash()))
.ForMember(detail => detail.SecondsUntilTimeout, opt => opt.Ignore());
config.CreateMap()
@@ -207,7 +207,7 @@ namespace Umbraco.Web.Models.Mapping
{
display.Icon = "icon-users";
}
- }
+ }
private static int GetIntId(object id)
{
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 6631c5be02..68dee8bb67 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -116,8 +116,8 @@
..\packages\dotless.1.5.2\lib\dotless.Core.dll
-
- ..\packages\Examine.0.1.82\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.83\lib\net45\Examine.dll
True
diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs
index fec4e144fb..6f3da17254 100644
--- a/src/Umbraco.Web/UmbracoHelper.cs
+++ b/src/Umbraco.Web/UmbracoHelper.cs
@@ -1317,20 +1317,33 @@ namespace Umbraco.Web
return _stringUtilities.ReplaceLineBreaksForHtml(text);
}
- ///
- /// Returns an MD5 hash of the string specified
- ///
- /// The text to create a hash from
- /// Md5 has of the string
- public string CreateMd5Hash(string text)
- {
- return text.ToMd5();
- }
+ ///
+ /// Returns an MD5 hash of the string specified
+ ///
+ /// The text to create a hash from
+ /// Md5 hash of the string
+ [Obsolete("Please use the CreateHash method instead. This may be removed in future versions")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public string CreateMd5Hash(string text)
+ {
+ return text.ToMd5();
+ }
- ///
- /// Strips all html tags from a given string, all contents of the tags will remain.
- ///
- public HtmlString StripHtml(IHtmlString html, params string[] tags)
+ ///
+ /// Generates a hash based on the text string passed in. This method will detect the
+ /// security requirements (is FIPS enabled) and return an appropriate hash.
+ ///
+ /// The text to create a hash from
+ /// Hash of the text string
+ public string CreateHash(string text)
+ {
+ return text.GenerateHash();
+ }
+
+ ///
+ /// Strips all html tags from a given string, all contents of the tags will remain.
+ ///
+ public HtmlString StripHtml(IHtmlString html, params string[] tags)
{
return StripHtml(html.ToHtmlString(), tags);
}
diff --git a/src/Umbraco.Web/UrlHelperRenderExtensions.cs b/src/Umbraco.Web/UrlHelperRenderExtensions.cs
index 614c815f79..a451503803 100644
--- a/src/Umbraco.Web/UrlHelperRenderExtensions.cs
+++ b/src/Umbraco.Web/UrlHelperRenderExtensions.cs
@@ -343,5 +343,24 @@ namespace Umbraco.Web
{
return url.SurfaceAction(action, typeof (T), additionalRouteVals);
}
+
+ ///
+ /// Generates a Absolute Media Item URL based on the current context
+ ///
+ ///
+ ///
+ ///
+ public static string GetAbsoluteMediaUrl(this UrlHelper urlHelper, IPublishedContent mediaItem)
+ {
+ if (urlHelper == null) throw new ArgumentNullException("urlHelper");
+ if (mediaItem == null) throw new ArgumentNullException("mediaItem");
+
+ if (urlHelper.RequestContext.HttpContext.Request.Url != null)
+ {
+ var requestUrl = urlHelper.RequestContext.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
+ return string.Format("{0}{1}", requestUrl, mediaItem.Url);
+ }
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config
index b7625770a3..daef6ee7fd 100644
--- a/src/Umbraco.Web/packages.config
+++ b/src/Umbraco.Web/packages.config
@@ -3,7 +3,7 @@
-
+
diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs
index 8bd94aa5b6..38b8b1b95d 100644
--- a/src/Umbraco.Web/umbraco.presentation/library.cs
+++ b/src/Umbraco.Web/umbraco.presentation/library.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -660,10 +661,23 @@ namespace umbraco
/// Returns an MD5 hash of the string specified
///
/// The text to create a hash from
- /// Md5 has of the string
+ /// Md5 hash of the string
+ [Obsolete("Please use the CreateHash method instead. This may be removed in future versions")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
public static string md5(string text)
{
- return text.ToMd5();
+ return text.ToMd5();
+ }
+
+ ///
+ /// Generates a hash based on the text string passed in. This method will detect the
+ /// security requirements (is FIPS enabled) and return an appropriate hash.
+ ///
+ /// The text to create a hash from
+ /// hash of the string
+ public static string CreateHash(string text)
+ {
+ return text.GenerateHash();
}
///
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs
index b40515578b..73800ca117 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs
@@ -88,6 +88,7 @@ namespace umbraco.cms.presentation.developer
{
macroName.Text = macro.Name;
macroAlias.Text = macro.Alias;
+ macroKey.Text = macro.Key.ToString();
macroXslt.Text = macro.XsltPath;
macroPython.Text = macro.ScriptPath;
cachePeriod.Text = macro.CacheDuration.ToInvariantString();
@@ -209,7 +210,7 @@ namespace umbraco.cms.presentation.developer
}
protected IEnumerable GetMacroParameterEditors()
- {
+ {
// we need to show the depracated ones for backwards compatibility
return ParameterEditorResolver.Current.GetParameterEditors(true);
}
@@ -433,14 +434,23 @@ namespace umbraco.cms.presentation.developer
///
protected global::System.Web.UI.WebControls.TextBox macroAlias;
- ///
- /// Pane1_2 control.
- ///
- ///
- /// Auto-generated field.
- /// To modify move field declaration from designer file to code-behind file.
- ///
- protected global::umbraco.uicontrols.Pane Pane1_2;
+ ///
+ /// macroAlias control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label macroKey;
+
+ ///
+ /// Pane1_2 control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::umbraco.uicontrols.Pane Pane1_2;
///
/// macroXslt control.
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs
index bdcbfaa775..a9bf7b5e43 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs
@@ -134,7 +134,7 @@ namespace umbraco.presentation.developer.packages
protected void fetchProtectedPackage(object sender, EventArgs e)
{
//we auth against the webservice. This key will be used to fetch the protected package.
- string memberGuid = _repo.Webservice.authenticate(tb_email.Text, library.md5(tb_password.Text));
+ string memberGuid = _repo.Webservice.authenticate(tb_email.Text, library.CreateHash(tb_password.Text));
//if we auth correctly and get a valid key back, we will fetch the file from the repo webservice.
if (string.IsNullOrEmpty(memberGuid) == false)
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/plugins/tinymce3/GzipCompressor.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/plugins/tinymce3/GzipCompressor.cs
index d03dca1d6d..c9df806242 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/plugins/tinymce3/GzipCompressor.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/plugins/tinymce3/GzipCompressor.cs
@@ -12,6 +12,7 @@ using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
+using Umbraco.Core;
namespace umbraco.presentation.plugins.tinymce3
{
@@ -91,7 +92,7 @@ namespace umbraco.presentation.plugins.tinymce3
key += item.Data;
}
- key = MD5(key);
+ key = Hash(key);
if (this.NoCompression) {
this.SendPlainText(key, to_stream);
return;
@@ -224,12 +225,10 @@ namespace umbraco.presentation.plugins.tinymce3
}
}
- private string MD5(string str) {
- MD5 md5 = new MD5CryptoServiceProvider();
- byte[] result = md5.ComputeHash(Encoding.ASCII.GetBytes(str));
- str = BitConverter.ToString(result);
+ private string Hash(string str)
+ {
+ return str.GenerateHash();
- return str.Replace("-", "");
}
#endregion
diff --git a/src/UmbracoExamine/LocalStorage/AzureLocalStorageDirectory.cs b/src/UmbracoExamine/LocalStorage/AzureLocalStorageDirectory.cs
index 56d1b414c5..72a894f32f 100644
--- a/src/UmbracoExamine/LocalStorage/AzureLocalStorageDirectory.cs
+++ b/src/UmbracoExamine/LocalStorage/AzureLocalStorageDirectory.cs
@@ -16,7 +16,7 @@ namespace UmbracoExamine.LocalStorage
{
public DirectoryInfo GetLocalStorageDirectory(NameValueCollection config, string configuredPath)
{
- var appDomainHash = HttpRuntime.AppDomainAppId.ToMd5();
+ var appDomainHash = HttpRuntime.AppDomainAppId.GenerateHash();
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "LuceneDir",
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
diff --git a/src/UmbracoExamine/UmbracoExamine.csproj b/src/UmbracoExamine/UmbracoExamine.csproj
index 19abcf9313..9a3299fb7e 100644
--- a/src/UmbracoExamine/UmbracoExamine.csproj
+++ b/src/UmbracoExamine/UmbracoExamine.csproj
@@ -82,8 +82,8 @@
..\Solution Items\TheFARM-Public.snk
-
- ..\packages\Examine.0.1.82\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.83\lib\net45\Examine.dll
True
diff --git a/src/UmbracoExamine/packages.config b/src/UmbracoExamine/packages.config
index 17c77f7284..10206f1d14 100644
--- a/src/UmbracoExamine/packages.config
+++ b/src/UmbracoExamine/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs b/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs
index e3c7a22bd0..f3f488ac1b 100644
--- a/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs
+++ b/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading;
@@ -26,8 +27,21 @@ namespace umbraco.MacroEngines
return "~/" + physicalPath;
}
- public string GetMd5(string text) {
- return text.ToMd5();
+ [Obsolete("Please use the GetHash method instead. This may be removed in future versions")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public string GetMd5(string text)
+ {
+ return text.ToMd5();
+ }
+
+ ///
+ /// Generates a hash based on the text string passed in. This method will detect the
+ /// security requirements (is FIPS enabled) and return an appropriate hash.
+ ///
+ /// String value to hash
+ /// The hash of the text string
+ public string GetHash(string text) {
+ return text.GenerateHash();
}
///
@@ -145,7 +159,7 @@ namespace umbraco.MacroEngines
//Get Rid Of Whitespace From Start/End
razorSyntax = razorSyntax.Trim();
//Use MD5 as a cache key
- var syntaxMd5 = GetMd5(razorSyntax);
+ var syntaxMd5 = GetHash(razorSyntax);
var fileName = "inline-" + syntaxMd5 + "." + scriptLanguage;
return CreateTemporaryRazorFile(razorSyntax, fileName, true);
}
diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config
index e125024a28..7479987df2 100644
--- a/src/umbraco.MacroEngines/packages.config
+++ b/src/umbraco.MacroEngines/packages.config
@@ -1,6 +1,6 @@
-
+
diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
index 33cfdacd2f..07b70e24a4 100644
--- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
+++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
@@ -45,8 +45,8 @@
false
-
- ..\packages\Examine.0.1.82\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.83\lib\net45\Examine.dll
True
diff --git a/src/umbraco.editorControls/tinyMCE3/webcontrol/plugin/GzipCompressor.cs b/src/umbraco.editorControls/tinyMCE3/webcontrol/plugin/GzipCompressor.cs
index cbd2fc24d8..d84453fa03 100644
--- a/src/umbraco.editorControls/tinyMCE3/webcontrol/plugin/GzipCompressor.cs
+++ b/src/umbraco.editorControls/tinyMCE3/webcontrol/plugin/GzipCompressor.cs
@@ -12,6 +12,7 @@ using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
+using Umbraco.Core;
namespace umbraco.editorControls.tinyMCE3.webcontrol.plugin
{
@@ -93,7 +94,7 @@ namespace umbraco.editorControls.tinyMCE3.webcontrol.plugin
key += item.Data;
}
- key = MD5(key);
+ key = Hash(key);
if (this.NoCompression) {
this.SendPlainText(key, to_stream);
return;
@@ -226,12 +227,9 @@ namespace umbraco.editorControls.tinyMCE3.webcontrol.plugin
}
}
- private string MD5(string str) {
- MD5 md5 = new MD5CryptoServiceProvider();
- byte[] result = md5.ComputeHash(Encoding.ASCII.GetBytes(str));
- str = BitConverter.ToString(result);
-
- return str.Replace("-", "");
+ private string Hash(string str)
+ {
+ return str.GenerateHash();
}
#endregion