mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge 1.x -> default
This commit is contained in:
@@ -128,6 +128,14 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
|
||||
Assert.AreEqual("folder", _azureBlobStorageProvider.ListFolders("folder").First().GetName());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FoldersShouldBeCreatedRecursively() {
|
||||
_azureBlobStorageProvider.CreateFolder("foo/bar/baz");
|
||||
Assert.That(_azureBlobStorageProvider.ListFolders("").Count(), Is.EqualTo(1));
|
||||
Assert.That(_azureBlobStorageProvider.ListFolders("foo").Count(), Is.EqualTo(1));
|
||||
Assert.That(_azureBlobStorageProvider.ListFolders("foo/bar").Count(), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldDeleteFiles() {
|
||||
_azureBlobStorageProvider.CreateFile("folder/foo1.txt");
|
||||
@@ -190,9 +198,9 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanCreateAlreadyExistingFolder() {
|
||||
public void TryCreateFolderShouldReturnFalseIfFolderAlreadyExists() {
|
||||
_azureBlobStorageProvider.CreateFile("folder1/foo.txt");
|
||||
Assert.That(_azureBlobStorageProvider.TryCreateFolder("folder1"), Is.True);
|
||||
Assert.That(_azureBlobStorageProvider.TryCreateFolder("folder1"), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -215,5 +223,25 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
|
||||
|
||||
Assert.AreEqual(teststring, content);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldTruncateFile() {
|
||||
var sf = _azureBlobStorageProvider.CreateFile("folder/foo1.txt");
|
||||
using (var sw = new StreamWriter(sf.OpenWrite())) {
|
||||
sw.Write("foo");
|
||||
}
|
||||
|
||||
using (var sw = new StreamWriter(sf.CreateFile())) {
|
||||
sw.Write("fo");
|
||||
}
|
||||
|
||||
sf = _azureBlobStorageProvider.GetFile("folder/foo1.txt");
|
||||
string content;
|
||||
using (var sr = new StreamReader(sf.OpenRead())) {
|
||||
content = sr.ReadToEnd();
|
||||
}
|
||||
|
||||
Assert.That(content, Is.EqualTo("fo"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,9 +8,8 @@ using Microsoft.WindowsAzure.StorageClient;
|
||||
using Orchard.FileSystems.Media;
|
||||
|
||||
namespace Orchard.Azure {
|
||||
public class AzureFileSystem
|
||||
{
|
||||
private const string FolderEntry = "$$$ORCHARD$$$.$$$";
|
||||
public class AzureFileSystem {
|
||||
public const string FolderEntry = "$$$ORCHARD$$$.$$$";
|
||||
|
||||
public string ContainerName { get; protected set; }
|
||||
|
||||
@@ -71,15 +70,13 @@ namespace Orchard.Azure {
|
||||
return path2;
|
||||
}
|
||||
|
||||
if ( path2.StartsWith("http://") || path2.StartsWith("https://") )
|
||||
{
|
||||
if ( path2.StartsWith("http://") || path2.StartsWith("https://") ) {
|
||||
return path2;
|
||||
}
|
||||
|
||||
var ch = path1[path1.Length - 1];
|
||||
|
||||
if (ch != '/')
|
||||
{
|
||||
if (ch != '/') {
|
||||
return (path1.TrimEnd('/') + '/' + path2.TrimStart('/'));
|
||||
}
|
||||
|
||||
@@ -91,7 +88,7 @@ namespace Orchard.Azure {
|
||||
|
||||
using ( new HttpContextWeaver() ) {
|
||||
Container.EnsureBlobExists(String.Concat(_root, path));
|
||||
return new AzureBlobFileStorage(Container.GetBlockBlobReference(path), _absoluteRoot);
|
||||
return new AzureBlobFileStorage(Container.GetBlockBlobReference(String.Concat(_root, path)), _absoluteRoot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,9 +155,12 @@ namespace Orchard.Azure {
|
||||
try {
|
||||
if (!Container.DirectoryExists(String.Concat(_root, path))) {
|
||||
CreateFolder(path);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// return false to be consistent with FileSystemProvider's implementation
|
||||
return false;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
@@ -173,6 +173,14 @@ namespace Orchard.Azure {
|
||||
|
||||
// Creating a virtually hidden file to make the directory an existing concept
|
||||
CreateFile(Combine(path, FolderEntry));
|
||||
|
||||
int lastIndex;
|
||||
while ((lastIndex = path.LastIndexOf('/')) > 0) {
|
||||
path = path.Substring(0, lastIndex);
|
||||
if(!Container.DirectoryExists(String.Concat(_root, path))) {
|
||||
CreateFile(Combine(path, FolderEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,6 +259,15 @@ namespace Orchard.Azure {
|
||||
throw new ArgumentException("File " + path + " already exists");
|
||||
}
|
||||
|
||||
// create all folder entries in the hierarchy
|
||||
int lastIndex;
|
||||
var localPath = path;
|
||||
while ((lastIndex = localPath.LastIndexOf('/')) > 0) {
|
||||
localPath = localPath.Substring(0, lastIndex);
|
||||
var folder = Container.GetBlockBlobReference(String.Concat(_root, Combine(localPath, FolderEntry)));
|
||||
folder.OpenWrite().Dispose();
|
||||
}
|
||||
|
||||
var blob = Container.GetBlockBlobReference(String.Concat(_root, path));
|
||||
blob.OpenWrite().Dispose(); // force file creation
|
||||
return new AzureBlobFileStorage(blob, _absoluteRoot);
|
||||
@@ -266,7 +283,7 @@ namespace Orchard.Azure {
|
||||
}
|
||||
|
||||
private class AzureBlobFileStorage : IStorageFile {
|
||||
private readonly CloudBlockBlob _blob;
|
||||
private CloudBlockBlob _blob;
|
||||
private readonly string _rootPath;
|
||||
|
||||
public AzureBlobFileStorage(CloudBlockBlob blob, string rootPath) {
|
||||
@@ -302,6 +319,15 @@ namespace Orchard.Azure {
|
||||
return _blob.OpenWrite();
|
||||
}
|
||||
|
||||
public Stream CreateFile() {
|
||||
// as opposed to the File System implementation, if nothing is done on the stream
|
||||
// the file will be emptied, because Azure doesn't implement FileMode.Truncate
|
||||
_blob.DeleteIfExists();
|
||||
_blob = _blob.Container.GetBlockBlobReference(_blob.Uri.ToString());
|
||||
_blob.OpenWrite().Dispose(); // force file creation
|
||||
|
||||
return OpenWrite();
|
||||
}
|
||||
}
|
||||
|
||||
private class AzureBlobFolderStorage : IStorageFolder {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Microsoft.WindowsAzure;
|
||||
using System.IO;
|
||||
using Microsoft.WindowsAzure;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.FileSystems.Media;
|
||||
|
||||
@@ -12,12 +13,31 @@ namespace Orchard.Azure.FileSystems.Media {
|
||||
public AzureBlobStorageProvider(ShellSettings shellSettings, CloudStorageAccount storageAccount) : base("media", shellSettings.Name, false, storageAccount) { }
|
||||
|
||||
|
||||
public bool TrySaveStream(string path, System.IO.Stream inputStream) {
|
||||
throw new System.NotImplementedException();
|
||||
public bool TrySaveStream(string path, Stream inputStream) {
|
||||
try {
|
||||
SaveStream(path, inputStream);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SaveStream(string path, System.IO.Stream inputStream) {
|
||||
throw new System.NotImplementedException();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SaveStream(string path, Stream inputStream) {
|
||||
// Create the file.
|
||||
// The CreateFile method will map the still relative path
|
||||
var file = CreateFile(path);
|
||||
|
||||
using(var outputStream = file.OpenWrite()) {
|
||||
var buffer = new byte[8192];
|
||||
for (;;) {
|
||||
var length = inputStream.Read(buffer, 0, buffer.Length);
|
||||
if (length <= 0)
|
||||
break;
|
||||
outputStream.Write(buffer, 0, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -151,6 +151,7 @@ Scenario: I should not be able to reuse an existing username or email
|
||||
Then I should see "User with that username and/or email already exists."
|
||||
|
||||
@management
|
||||
@ignore
|
||||
Scenario: I should be able to remove an existing user
|
||||
Given I have installed Orchard
|
||||
When I go to "admin/users"
|
||||
|
198
src/Orchard.Specs/Users.feature.cs
generated
198
src/Orchard.Specs/Users.feature.cs
generated
@@ -438,17 +438,19 @@ this.ScenarioSetup(scenarioInfo);
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I should be able to remove an existing user")]
|
||||
[NUnit.Framework.CategoryAttribute("management")]
|
||||
[NUnit.Framework.IgnoreAttribute()]
|
||||
public virtual void IShouldBeAbleToRemoveAnExistingUser()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should be able to remove an existing user", new string[] {
|
||||
"management"});
|
||||
#line 154
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
"management",
|
||||
"ignore"});
|
||||
#line 155
|
||||
testRunner.Given("I have installed Orchard");
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 156
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 157
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 158
|
||||
#line 159
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table13 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -466,13 +468,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table13.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 159
|
||||
#line 160
|
||||
testRunner.And("I fill in", ((string)(null)), table13);
|
||||
#line 165
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 166
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 167
|
||||
testRunner.And("I am redirected");
|
||||
#line 168
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table14 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -481,19 +483,19 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table14.AddRow(new string[] {
|
||||
"Options.Search",
|
||||
"user1"});
|
||||
#line 169
|
||||
#line 170
|
||||
testRunner.When("I fill in", ((string)(null)), table14);
|
||||
#line 172
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 173
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 174
|
||||
testRunner.When("I follow \"Delete\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 175
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.When("I follow \"Delete\"");
|
||||
#line 176
|
||||
testRunner.Then("I should see \"User user1 deleted\"");
|
||||
testRunner.And("I am redirected");
|
||||
#line 177
|
||||
testRunner.Then("I should see \"User user1 deleted\"");
|
||||
#line 178
|
||||
testRunner.And("I should not see \"<a[^>]*>user1</a>\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
@@ -506,13 +508,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should not be able to filter users by name", new string[] {
|
||||
"filtering"});
|
||||
#line 180
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 181
|
||||
testRunner.Given("I have installed Orchard");
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 182
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 183
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 184
|
||||
#line 185
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table15 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -530,13 +532,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table15.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 185
|
||||
#line 186
|
||||
testRunner.And("I fill in", ((string)(null)), table15);
|
||||
#line 191
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 192
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 193
|
||||
testRunner.And("I am redirected");
|
||||
#line 194
|
||||
#line 195
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -554,15 +556,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table16.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 195
|
||||
#line 196
|
||||
testRunner.And("I fill in", ((string)(null)), table16);
|
||||
#line 201
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 202
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 203
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I am redirected");
|
||||
#line 204
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 205
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table17 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -571,15 +573,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table17.AddRow(new string[] {
|
||||
"Options.Search",
|
||||
"user1"});
|
||||
#line 205
|
||||
#line 206
|
||||
testRunner.When("I fill in", ((string)(null)), table17);
|
||||
#line 208
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 209
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 210
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 211
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
#line 212
|
||||
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table18 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -588,15 +590,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table18.AddRow(new string[] {
|
||||
"Options.Search",
|
||||
"user1@domain.com"});
|
||||
#line 212
|
||||
#line 213
|
||||
testRunner.When("I fill in", ((string)(null)), table18);
|
||||
#line 215
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 216
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 217
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 218
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
#line 219
|
||||
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table19 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -605,15 +607,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table19.AddRow(new string[] {
|
||||
"Options.Search",
|
||||
"@domain.com"});
|
||||
#line 219
|
||||
#line 220
|
||||
testRunner.When("I fill in", ((string)(null)), table19);
|
||||
#line 222
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 223
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 224
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 225
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
#line 226
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
@@ -626,13 +628,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should be able to filter users by status", new string[] {
|
||||
"filtering"});
|
||||
#line 228
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 229
|
||||
testRunner.Given("I have installed Orchard");
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 230
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 231
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 232
|
||||
#line 233
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table20 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -650,13 +652,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table20.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 233
|
||||
#line 234
|
||||
testRunner.And("I fill in", ((string)(null)), table20);
|
||||
#line 239
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 240
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 241
|
||||
testRunner.And("I am redirected");
|
||||
#line 242
|
||||
#line 243
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table21 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -674,15 +676,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table21.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 243
|
||||
#line 244
|
||||
testRunner.And("I fill in", ((string)(null)), table21);
|
||||
#line 249
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 250
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 251
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I am redirected");
|
||||
#line 252
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 253
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table22 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -691,17 +693,17 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table22.AddRow(new string[] {
|
||||
"Options.Search",
|
||||
"user1"});
|
||||
#line 253
|
||||
#line 254
|
||||
testRunner.When("I fill in", ((string)(null)), table22);
|
||||
#line 256
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 257
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 258
|
||||
testRunner.When("I follow \"Disable\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 259
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.When("I follow \"Disable\"");
|
||||
#line 260
|
||||
testRunner.And("I am redirected");
|
||||
#line 261
|
||||
testRunner.Then("I should see \"User user1 disabled\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table23 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -710,15 +712,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table23.AddRow(new string[] {
|
||||
"Options.Filter",
|
||||
"Pending"});
|
||||
#line 261
|
||||
#line 262
|
||||
testRunner.When("I fill in", ((string)(null)), table23);
|
||||
#line 264
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 265
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 266
|
||||
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 267
|
||||
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||
#line 268
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table24 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -727,15 +729,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table24.AddRow(new string[] {
|
||||
"Options.Filter",
|
||||
"EmailPending"});
|
||||
#line 268
|
||||
#line 269
|
||||
testRunner.When("I fill in", ((string)(null)), table24);
|
||||
#line 271
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 272
|
||||
testRunner.Then("I should not see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 273
|
||||
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||
testRunner.Then("I should not see \"<a[^>]*>user1</a>\"");
|
||||
#line 274
|
||||
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||
#line 275
|
||||
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table25 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -744,15 +746,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table25.AddRow(new string[] {
|
||||
"Options.Filter",
|
||||
"Approved"});
|
||||
#line 275
|
||||
#line 276
|
||||
testRunner.When("I fill in", ((string)(null)), table25);
|
||||
#line 278
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 279
|
||||
testRunner.Then("I should not see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 280
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
testRunner.Then("I should not see \"<a[^>]*>user1</a>\"");
|
||||
#line 281
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
#line 282
|
||||
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table26 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -761,15 +763,15 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table26.AddRow(new string[] {
|
||||
"Options.Filter",
|
||||
"All"});
|
||||
#line 282
|
||||
#line 283
|
||||
testRunner.When("I fill in", ((string)(null)), table26);
|
||||
#line 285
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 286
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
testRunner.And("I hit \"Filter\"");
|
||||
#line 287
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||
#line 288
|
||||
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||
#line 289
|
||||
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
@@ -782,13 +784,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should not be able to add users with invalid email addresses", new string[] {
|
||||
"email"});
|
||||
#line 290
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 291
|
||||
testRunner.Given("I have installed Orchard");
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 292
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 293
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 294
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table27 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -806,11 +808,11 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table27.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 294
|
||||
#line 295
|
||||
testRunner.And("I fill in", ((string)(null)), table27);
|
||||
#line 300
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 301
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 302
|
||||
testRunner.Then("I should see \"You must specify a valid email address.\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
@@ -823,13 +825,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should be able to add users with valid email addresses", new string[] {
|
||||
"email"});
|
||||
#line 303
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 304
|
||||
testRunner.Given("I have installed Orchard");
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 305
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 306
|
||||
testRunner.When("I go to \"admin/users\"");
|
||||
#line 307
|
||||
testRunner.And("I follow \"Add a new user\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table28 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
@@ -847,13 +849,13 @@ this.ScenarioSetup(scenarioInfo);
|
||||
table28.AddRow(new string[] {
|
||||
"ConfirmPassword",
|
||||
"a12345!"});
|
||||
#line 307
|
||||
#line 308
|
||||
testRunner.And("I fill in", ((string)(null)), table28);
|
||||
#line 313
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 314
|
||||
testRunner.And("I am redirected");
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 315
|
||||
testRunner.And("I am redirected");
|
||||
#line 316
|
||||
testRunner.Then("I should see \"User created\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
@@ -39,6 +41,7 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
private ISessionFactory _sessionFactory;
|
||||
private ISession _session;
|
||||
private IContainer _container;
|
||||
private CultureInfo _currentCulture;
|
||||
|
||||
|
||||
public class TestSessionLocator : ISessionLocator {
|
||||
@@ -55,6 +58,7 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void InitFixture() {
|
||||
_currentCulture = Thread.CurrentThread.CurrentCulture;
|
||||
var databaseFileName = System.IO.Path.GetTempFileName();
|
||||
_sessionFactory = DataUtility.CreateSessionFactory(
|
||||
databaseFileName,
|
||||
@@ -66,7 +70,7 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TermFixture() {
|
||||
|
||||
Thread.CurrentThread.CurrentCulture = _currentCulture;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
@@ -122,5 +126,18 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
Assert.That(username, Is.EqualTo("foo"));
|
||||
Assert.That(validateByUtc, Is.GreaterThan(_clock.UtcNow));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VerifyUserUnicityTurkishTest() {
|
||||
CultureInfo turkishCulture = new CultureInfo("tr-TR");
|
||||
Thread.CurrentThread.CurrentCulture = turkishCulture;
|
||||
|
||||
// Create user lower case
|
||||
_membershipService.CreateUser(new CreateUserParams("admin", "66554321", "foo@bar.com", "", "", true));
|
||||
_container.Resolve<IOrchardServices>().ContentManager.Flush();
|
||||
|
||||
// Verify unicity with upper case which with turkish coallition would yeld admin with an i without the dot and therefore generate a different user name
|
||||
Assert.That(_userService.VerifyUserUnicity("ADMIN", "differentfoo@bar.com"), Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -129,6 +129,15 @@ namespace Orchard.Tests.Storage {
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldCreateFolders() {
|
||||
Directory.Delete(_folderPath, true);
|
||||
_storageProvider.CreateFolder("foo/bar/baz");
|
||||
Assert.That(_storageProvider.ListFolders("").Count(), Is.EqualTo(1));
|
||||
Assert.That(_storageProvider.ListFolders("foo").Count(), Is.EqualTo(1));
|
||||
Assert.That(_storageProvider.ListFolders("foo/bar").Count(), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RenameFolderTakesShortPathWithAnyKindOfSlash() {
|
||||
Assert.That(GetFolder(@"SubFolder1/SubSubFolder1"), Is.Not.Null);
|
||||
|
@@ -10,7 +10,7 @@ using Orchard.Recipes.Models;
|
||||
namespace Orchard.Recipes.Services {
|
||||
public class RecipeJournalManager : IRecipeJournal {
|
||||
private readonly IStorageProvider _storageProvider;
|
||||
private readonly string _recipeJournalFolder = "RecipeJournal" + Path.DirectorySeparatorChar;
|
||||
private const string RecipeJournalFolder = "RecipeJournal";
|
||||
private const string WebConfig =
|
||||
@"
|
||||
<configuration>
|
||||
@@ -92,10 +92,10 @@ namespace Orchard.Recipes.Services {
|
||||
|
||||
private IStorageFile GetJournalFile(string executionId) {
|
||||
IStorageFile journalFile;
|
||||
var journalPath = Path.Combine(_recipeJournalFolder, executionId);
|
||||
var journalPath = _storageProvider.Combine(RecipeJournalFolder, executionId);
|
||||
try {
|
||||
if (_storageProvider.TryCreateFolder(_recipeJournalFolder)) {
|
||||
var webConfigPath = Path.Combine(_recipeJournalFolder, "web.config");
|
||||
if (_storageProvider.TryCreateFolder(RecipeJournalFolder)) {
|
||||
var webConfigPath = _storageProvider.Combine(RecipeJournalFolder, "web.config");
|
||||
var webConfigFile = _storageProvider.CreateFile(webConfigPath);
|
||||
WriteWebConfig(webConfigFile);
|
||||
}
|
||||
@@ -121,10 +121,9 @@ namespace Orchard.Recipes.Services {
|
||||
|
||||
private static void WriteJournal(IStorageFile journalFile, XElement journal) {
|
||||
string content = journal.ToString();
|
||||
using (var stream = journalFile.OpenWrite()) {
|
||||
using (var stream = journalFile.CreateFile()) {
|
||||
using (var tw = new StreamWriter(stream)) {
|
||||
tw.Write(content);
|
||||
stream.SetLength(stream.Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -48,7 +48,7 @@ namespace Orchard.Roles.Services {
|
||||
for (var adjustmentLimiter = 0; adjustmentLimiter != 3; ++adjustmentLimiter) {
|
||||
if (!context.Granted && context.User != null) {
|
||||
if (!String.IsNullOrEmpty(_workContextAccessor.GetContext().CurrentSite.SuperUser) &&
|
||||
String.Equals(context.User.UserName, _workContextAccessor.GetContext().CurrentSite.SuperUser, StringComparison.OrdinalIgnoreCase)) {
|
||||
String.Equals(context.User.UserName, _workContextAccessor.GetContext().CurrentSite.SuperUser, StringComparison.Ordinal)) {
|
||||
context.Granted = true;
|
||||
}
|
||||
}
|
||||
|
@@ -241,11 +241,11 @@ namespace Orchard.Users.Controllers {
|
||||
}
|
||||
else {
|
||||
// also update the Super user if this is the renamed account
|
||||
if (String.Equals(Services.WorkContext.CurrentSite.SuperUser, previousName, StringComparison.OrdinalIgnoreCase)) {
|
||||
if (String.Equals(Services.WorkContext.CurrentSite.SuperUser, previousName, StringComparison.Ordinal)) {
|
||||
_siteService.GetSiteSettings().As<SiteSettingsPart>().SuperUser = editModel.UserName;
|
||||
}
|
||||
|
||||
user.NormalizedUserName = editModel.UserName.ToLower();
|
||||
user.NormalizedUserName = editModel.UserName.ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +264,7 @@ namespace Orchard.Users.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Delete(int id) {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
||||
return new HttpUnauthorizedResult();
|
||||
@@ -271,10 +272,10 @@ namespace Orchard.Users.Controllers {
|
||||
var user = Services.ContentManager.Get<IUser>(id);
|
||||
|
||||
if (user != null) {
|
||||
if (String.Equals(Services.WorkContext.CurrentSite.SuperUser, user.UserName, StringComparison.OrdinalIgnoreCase)) {
|
||||
if (String.Equals(Services.WorkContext.CurrentSite.SuperUser, user.UserName, StringComparison.Ordinal)) {
|
||||
Services.Notifier.Error(T("The Super user can't be removed. Please disable this account or specify another Super user account"));
|
||||
}
|
||||
else if (String.Equals(Services.WorkContext.CurrentUser.UserName, user.UserName, StringComparison.OrdinalIgnoreCase)) {
|
||||
else if (String.Equals(Services.WorkContext.CurrentUser.UserName, user.UserName, StringComparison.Ordinal)) {
|
||||
Services.Notifier.Error(T("You can't remove your own account. Please log in with another account"));
|
||||
}
|
||||
else{
|
||||
@@ -322,7 +323,7 @@ namespace Orchard.Users.Controllers {
|
||||
var user = Services.ContentManager.Get<IUser>(id);
|
||||
|
||||
if (user != null) {
|
||||
if (String.Equals(Services.WorkContext.CurrentUser.UserName, user.UserName, StringComparison.OrdinalIgnoreCase)) {
|
||||
if (String.Equals(Services.WorkContext.CurrentUser.UserName, user.UserName, StringComparison.Ordinal)) {
|
||||
Services.Notifier.Error(T("You can't disable your own account. Please log in with another account"));
|
||||
}
|
||||
else {
|
||||
|
@@ -49,7 +49,7 @@ namespace Orchard.Users.Services {
|
||||
|
||||
user.Record.UserName = createUserParams.Username;
|
||||
user.Record.Email = createUserParams.Email;
|
||||
user.Record.NormalizedUserName = createUserParams.Username.ToLower();
|
||||
user.Record.NormalizedUserName = createUserParams.Username.ToLowerInvariant();
|
||||
user.Record.HashAlgorithm = "SHA1";
|
||||
SetPassword(user.Record, createUserParams.Password);
|
||||
|
||||
@@ -97,13 +97,13 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
|
||||
public IUser GetUser(string username) {
|
||||
var lowerName = username == null ? "" : username.ToLower();
|
||||
var lowerName = username == null ? "" : username.ToLowerInvariant();
|
||||
|
||||
return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
|
||||
}
|
||||
|
||||
public IUser ValidateUser(string userNameOrEmail, string password) {
|
||||
var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLower();
|
||||
var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLowerInvariant();
|
||||
|
||||
var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
|
||||
|
||||
|
@@ -37,7 +37,7 @@ namespace Orchard.Users.Services {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public bool VerifyUserUnicity(string userName, string email) {
|
||||
string normalizedUserName = userName.ToLower();
|
||||
string normalizedUserName = userName.ToLowerInvariant();
|
||||
|
||||
if (_contentManager.Query<UserPart, UserPartRecord>()
|
||||
.Where(user =>
|
||||
@@ -51,7 +51,7 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
|
||||
public bool VerifyUserUnicity(int id, string userName, string email) {
|
||||
string normalizedUserName = userName.ToLower();
|
||||
string normalizedUserName = userName.ToLowerInvariant();
|
||||
|
||||
if (_contentManager.Query<UserPart, UserPartRecord>()
|
||||
.Where(user =>
|
||||
@@ -115,7 +115,7 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
|
||||
public bool SendLostPasswordEmail(string usernameOrEmail, Func<string, string> createUrl) {
|
||||
var lowerName = usernameOrEmail.ToLower();
|
||||
var lowerName = usernameOrEmail.ToLowerInvariant();
|
||||
var user = _contentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName || u.Email == lowerName).List().FirstOrDefault();
|
||||
|
||||
if (user != null) {
|
||||
|
@@ -69,7 +69,7 @@
|
||||
</td>
|
||||
<td>
|
||||
@Html.ActionLink(T("Edit").ToString(), "Edit", new { entry.User.Id }) |
|
||||
@Html.ActionLink(T("Delete").ToString(), "Delete", new { entry.User.Id }) |
|
||||
@Html.ActionLink(T("Delete").ToString(), "Delete", new { entry.User.Id}, new { itemprop = "RemoveUrl UnsafeUrl" }) |
|
||||
@if (entry.User.RegistrationStatus == UserStatus.Pending) {
|
||||
@Html.ActionLink(T("Approve").ToString(), "Approve", new { entry.User.Id })
|
||||
} else {
|
||||
|
@@ -135,8 +135,18 @@ namespace Orchard.FileSystems.Media {
|
||||
/// <param name="path">The relative path to the folder to be created.</param>
|
||||
/// <returns>True if success; False otherwise.</returns>
|
||||
public bool TryCreateFolder(string path) {
|
||||
try { CreateFolder(path); }
|
||||
catch { return false; }
|
||||
try {
|
||||
// prevent unnecessary exception
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(MapStorage(path));
|
||||
if (directoryInfo.Exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CreateFolder(path);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -250,8 +260,12 @@ namespace Orchard.FileSystems.Media {
|
||||
/// <param name="inputStream">The stream to be saved.</param>
|
||||
/// <returns>True if success; False otherwise.</returns>
|
||||
public bool TrySaveStream(string path, Stream inputStream) {
|
||||
try { SaveStream(path, inputStream); }
|
||||
catch { return false; }
|
||||
try {
|
||||
SaveStream(path, inputStream);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -334,6 +348,10 @@ namespace Orchard.FileSystems.Media {
|
||||
return new FileStream(_fileInfo.FullName, FileMode.Open, FileAccess.ReadWrite);
|
||||
}
|
||||
|
||||
public Stream CreateFile() {
|
||||
return new FileStream(_fileInfo.FullName, FileMode.Truncate, FileAccess.ReadWrite);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@@ -18,5 +18,11 @@ namespace Orchard.FileSystems.Media {
|
||||
/// Creates a stream for writing to the file.
|
||||
/// </summary>
|
||||
Stream OpenWrite();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a stream for writing to the file, and truncates the existing content.
|
||||
/// </summary>
|
||||
Stream CreateFile();
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user