Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b1efa718e | |||
| f60ad15f70 | |||
| 836e1bba54 | |||
| 5a953761b0 | |||
| 1b17f4e9df | |||
| ac496b0cf6 | |||
| 6036136938 | |||
| 454aad2170 | |||
| f4eb37d44d | |||
| c79aaa9c48 | |||
| 6aa00c52dc | |||
| 30f63eefb3 | |||
| 6114193fd5 | |||
| 82420605ef |
@@ -1,3 +1,3 @@
|
|||||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||||
7.6.0
|
7.6.0
|
||||||
alpha074
|
beta03
|
||||||
|
|||||||
+1
-1
@@ -12,4 +12,4 @@ using System.Resources;
|
|||||||
[assembly: AssemblyVersion("1.0.*")]
|
[assembly: AssemblyVersion("1.0.*")]
|
||||||
|
|
||||||
[assembly: AssemblyFileVersion("7.6.0")]
|
[assembly: AssemblyFileVersion("7.6.0")]
|
||||||
[assembly: AssemblyInformationalVersion("7.6.0-alpha074")]
|
[assembly: AssemblyInformationalVersion("7.6.0-beta03")]
|
||||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
|
|||||||
/// Gets the version comment (like beta or RC).
|
/// Gets the version comment (like beta or RC).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The version comment.</value>
|
/// <value>The version comment.</value>
|
||||||
public static string CurrentComment { get { return "alpha074"; } }
|
public static string CurrentComment { get { return "beta03"; } }
|
||||||
|
|
||||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||||
|
|||||||
@@ -218,11 +218,11 @@ namespace Umbraco.Core.IO
|
|||||||
var normPath = NormPath(path);
|
var normPath = NormPath(path);
|
||||||
var shadows = Nodes.Where(kvp => IsChild(normPath, kvp.Key)).ToArray();
|
var shadows = Nodes.Where(kvp => IsChild(normPath, kvp.Key)).ToArray();
|
||||||
var files = filter != null ? _fs.GetFiles(path, filter) : _fs.GetFiles(path);
|
var files = filter != null ? _fs.GetFiles(path, filter) : _fs.GetFiles(path);
|
||||||
var regexFilter = FilterToRegex(filter);
|
var wildcard = filter == null ? null : new WildcardExpression(filter);
|
||||||
return files
|
return files
|
||||||
.Except(shadows.Where(kvp => (kvp.Value.IsFile && kvp.Value.IsDelete) || kvp.Value.IsDir)
|
.Except(shadows.Where(kvp => (kvp.Value.IsFile && kvp.Value.IsDelete) || kvp.Value.IsDir)
|
||||||
.Select(kvp => kvp.Key))
|
.Select(kvp => kvp.Key))
|
||||||
.Union(shadows.Where(kvp => kvp.Value.IsFile && kvp.Value.IsExist && FilterByRegex(kvp.Key, regexFilter)).Select(kvp => kvp.Key))
|
.Union(shadows.Where(kvp => kvp.Value.IsFile && kvp.Value.IsExist && (wildcard == null || wildcard.IsMatch(kvp.Key))).Select(kvp => kvp.Key))
|
||||||
.Distinct();
|
.Distinct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,32 +326,65 @@ namespace Umbraco.Core.IO
|
|||||||
_sfs.AddFile(path, physicalPath, overrideIfExists, copy);
|
_sfs.AddFile(path, physicalPath, overrideIfExists, copy);
|
||||||
Nodes[normPath] = new ShadowNode(false, false);
|
Nodes[normPath] = new ShadowNode(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper function for filtering keys by Regex if a filter is specified.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <param name="regexFilter"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
internal static bool FilterByRegex(string input, string regexFilter)
|
|
||||||
{
|
|
||||||
if (regexFilter == null) return true;
|
|
||||||
return regexFilter != string.Empty && Regex.IsMatch(input, regexFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
// copied from System.Web.Util.Wildcard internal
|
||||||
/// Transforms a filter pattern into a Regex pattern
|
internal class WildcardExpression
|
||||||
/// </summary>
|
|
||||||
/// <param name="pattern"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// Appending '$' only if not containing wildcard is stupid and broken.
|
|
||||||
/// It is however what seems to be what they're doing in .NET so we need to match the functionality.
|
|
||||||
/// </remarks>
|
|
||||||
internal static string FilterToRegex(string pattern)
|
|
||||||
{
|
{
|
||||||
if (pattern == null) return null;
|
private readonly string _pattern;
|
||||||
return "^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + (pattern.Contains("*") ? string.Empty : "$");
|
private readonly bool _caseInsensitive;
|
||||||
|
private Regex _regex;
|
||||||
|
|
||||||
|
private static Regex metaRegex = new Regex("[\\+\\{\\\\\\[\\|\\(\\)\\.\\^\\$]");
|
||||||
|
private static Regex questRegex = new Regex("\\?");
|
||||||
|
private static Regex starRegex = new Regex("\\*");
|
||||||
|
private static Regex commaRegex = new Regex(",");
|
||||||
|
private static Regex slashRegex = new Regex("(?=/)");
|
||||||
|
private static Regex backslashRegex = new Regex("(?=[\\\\:])");
|
||||||
|
|
||||||
|
public WildcardExpression(string pattern, bool caseInsensitive = true)
|
||||||
|
{
|
||||||
|
_pattern = pattern;
|
||||||
|
_caseInsensitive = caseInsensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureRegex(string pattern)
|
||||||
|
{
|
||||||
|
if (_regex != null) return;
|
||||||
|
|
||||||
|
var options = RegexOptions.None;
|
||||||
|
|
||||||
|
// match right-to-left (for speed) if the pattern starts with a *
|
||||||
|
|
||||||
|
if (pattern.Length > 0 && pattern[0] == '*')
|
||||||
|
options = RegexOptions.RightToLeft | RegexOptions.Singleline;
|
||||||
|
else
|
||||||
|
options = RegexOptions.Singleline;
|
||||||
|
|
||||||
|
// case insensitivity
|
||||||
|
|
||||||
|
if (_caseInsensitive)
|
||||||
|
options |= RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;
|
||||||
|
|
||||||
|
// Remove regex metacharacters
|
||||||
|
|
||||||
|
pattern = metaRegex.Replace(pattern, "\\$0");
|
||||||
|
|
||||||
|
// Replace wildcard metacharacters with regex codes
|
||||||
|
|
||||||
|
pattern = questRegex.Replace(pattern, ".");
|
||||||
|
pattern = starRegex.Replace(pattern, ".*");
|
||||||
|
pattern = commaRegex.Replace(pattern, "\\z|\\A");
|
||||||
|
|
||||||
|
// anchor the pattern at beginning and end, and return the regex
|
||||||
|
|
||||||
|
_regex = new Regex("\\A" + pattern + "\\z", options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsMatch(string input)
|
||||||
|
{
|
||||||
|
EnsureRegex(_pattern);
|
||||||
|
return _regex.IsMatch(input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,5 +47,9 @@ using System.Security.Permissions;
|
|||||||
[assembly: InternalsVisibleTo("Umbraco.Deploy.UI")]
|
[assembly: InternalsVisibleTo("Umbraco.Deploy.UI")]
|
||||||
[assembly: InternalsVisibleTo("Umbraco.Deploy.Cloud")]
|
[assembly: InternalsVisibleTo("Umbraco.Deploy.Cloud")]
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("Umbraco.Forms.Core")]
|
||||||
|
[assembly: InternalsVisibleTo("Umbraco.Forms.Core.Providers")]
|
||||||
|
[assembly: InternalsVisibleTo("Umbraco.Forms.Web")]
|
||||||
|
|
||||||
//allow this to be mocked in our unit tests
|
//allow this to be mocked in our unit tests
|
||||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||||
@@ -326,7 +326,8 @@ namespace Umbraco.Core.Security
|
|||||||
|
|
||||||
//Special case to allow changing password without validating existing credentials
|
//Special case to allow changing password without validating existing credentials
|
||||||
//This is used during installation only
|
//This is used during installation only
|
||||||
if (AllowManuallyChangingPassword == false && ApplicationContext.Current.IsConfigured == false && oldPassword == "default")
|
if (AllowManuallyChangingPassword == false && ApplicationContext.Current != null
|
||||||
|
&& ApplicationContext.Current.IsConfigured == false && oldPassword == "default")
|
||||||
{
|
{
|
||||||
return PerformChangePassword(username, oldPassword, newPassword);
|
return PerformChangePassword(username, oldPassword, newPassword);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -805,101 +805,6 @@ namespace Umbraco.Tests.IO
|
|||||||
Assert.AreEqual(3, sfsFiles.Length);
|
Assert.AreEqual(3, sfsFiles.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Ignore("Does not work on all environments, Directory.GetFiles is broken.")]
|
|
||||||
public void ShadowGetFilesUsingWildcardAndSingleCharacterFilter()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var path = IOHelper.MapPath("FileSysTests");
|
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
Directory.CreateDirectory(path + "/ShadowTests");
|
|
||||||
Directory.CreateDirectory(path + "/ShadowSystem");
|
|
||||||
|
|
||||||
var fs = new PhysicalFileSystem(path + "/ShadowTests/", "ignore");
|
|
||||||
var sfs = new PhysicalFileSystem(path + "/ShadowSystem/", "ignore");
|
|
||||||
var ss = new ShadowFileSystem(fs, sfs);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
File.WriteAllText(path + "/ShadowTests/f2.txt", "foo");
|
|
||||||
File.WriteAllText(path + "/ShadowTests/f2.doc", "foo");
|
|
||||||
File.WriteAllText(path + "/ShadowTests/f2.docx", "foo");
|
|
||||||
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
|
|
||||||
ss.AddFile("f1.txt", ms);
|
|
||||||
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
|
|
||||||
ss.AddFile("f1.doc", ms);
|
|
||||||
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
|
|
||||||
ss.AddFile("f1.docx", ms);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
// ensure we get 6 files from the shadow
|
|
||||||
var getFiles = ss.GetFiles(string.Empty);
|
|
||||||
Assert.AreEqual(6, getFiles.Count());
|
|
||||||
var getFilesWithWildcardSinglecharFilter = ss.GetFiles(string.Empty, "*.d?c");
|
|
||||||
|
|
||||||
Assert.AreEqual(4, getFilesWithWildcardSinglecharFilter.Count());
|
|
||||||
var getFilesWithWildcardSinglecharFilter2 = ss.GetFiles(string.Empty, "*.d?cx");
|
|
||||||
Assert.AreEqual(2, getFilesWithWildcardSinglecharFilter2.Count());
|
|
||||||
|
|
||||||
var fsFiles = fs.GetFiles(string.Empty).ToArray();
|
|
||||||
Assert.AreEqual(3, fsFiles.Length);
|
|
||||||
var sfsFiles = sfs.GetFiles(string.Empty).ToArray();
|
|
||||||
Assert.AreEqual(3, sfsFiles.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Ignore("Does not work on all environments, Directory.GetFiles is broken.")]
|
|
||||||
public void ShadowFileSystemFilterIsAsBrokenAsRealFileSystemFilter()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var path = IOHelper.MapPath("FileSysTests");
|
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
Directory.CreateDirectory(path + "/filter");
|
|
||||||
// create files on disk and create a "fake" list of files to verify filters against
|
|
||||||
File.WriteAllText(path + "/filter/f1.txt", "foo");
|
|
||||||
File.WriteAllText(path + "/filter/f1.doc", "foo");
|
|
||||||
File.WriteAllText(path + "/filter/f1.docx", "foo");
|
|
||||||
var files = new string[]
|
|
||||||
{
|
|
||||||
"f1.txt",
|
|
||||||
"f1.doc",
|
|
||||||
"f1.docx",
|
|
||||||
};
|
|
||||||
var filter1 = "";
|
|
||||||
var filter2 = "*";
|
|
||||||
var filter3 = "*.doc";
|
|
||||||
var filter4 = "*.d?c";
|
|
||||||
var filter5 = "f1.doc";
|
|
||||||
var filter6 = "f1.d?c";
|
|
||||||
var filter7 = "**.d?c";
|
|
||||||
var filter8 = "f*.doc";
|
|
||||||
|
|
||||||
// Act & Assert
|
|
||||||
var result1Disk = Directory.GetFiles(path + "/filter/", filter1).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result1Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter1))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result1Disk, result1Fake);
|
|
||||||
var result2Disk = Directory.GetFiles(path + "/filter/", filter2).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result2Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter2))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result2Disk, result2Fake);
|
|
||||||
var result3Disk = Directory.GetFiles(path + "/filter/", filter3).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result3Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter3))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result3Disk, result3Fake);
|
|
||||||
var result4Disk = Directory.GetFiles(path + "/filter/", filter4).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result4Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter4))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result4Disk, result4Fake);
|
|
||||||
var result5Disk = Directory.GetFiles(path + "/filter/", filter5).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result5Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter5))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result5Disk, result5Fake);
|
|
||||||
var result6Disk = Directory.GetFiles(path + "/filter/", filter6).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result6Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter6))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result6Disk, result6Fake);
|
|
||||||
var result7Disk = Directory.GetFiles(path + "/filter/", filter7).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result7Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter7))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result7Disk, result7Fake);
|
|
||||||
var result8Disk = Directory.GetFiles(path + "/filter/", filter8).Select(Path.GetFileName).OrderBy(x => x).ToArray();
|
|
||||||
var result8Fake = files.Where(x => ShadowFileSystem.FilterByRegex(x, ShadowFileSystem.FilterToRegex(filter8))).OrderBy(x => x).ToArray();
|
|
||||||
Assert.AreEqual(result8Disk, result8Fake);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the full paths of the files on the disk.
|
/// Returns the full paths of the files on the disk.
|
||||||
/// Note that this will be the *actual* path of the file, meaning a file existing on the initialized FS
|
/// Note that this will be the *actual* path of the file, meaning a file existing on the initialized FS
|
||||||
|
|||||||
@@ -41,4 +41,9 @@ using System.Security;
|
|||||||
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
|
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
|
||||||
[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder")]
|
[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder")]
|
||||||
[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder.AspNet")]
|
[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder.AspNet")]
|
||||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("Umbraco.Forms.Core")]
|
||||||
|
[assembly: InternalsVisibleTo("Umbraco.Forms.Core.Providers")]
|
||||||
|
[assembly: InternalsVisibleTo("Umbraco.Forms.Web")]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user