mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
Merge dev -> perf
--HG-- branch : perf
This commit is contained in:
@@ -154,6 +154,7 @@
|
||||
<Compile Include="Themes\Services\ThemeServiceTests.cs" />
|
||||
<Compile Include="Users\Controllers\AccountControllerTests.cs" />
|
||||
<Compile Include="Users\Services\UserServiceTests.cs" />
|
||||
<Compile Include="Users\ShellSettingsUtility.cs" />
|
||||
<Compile Include="Values.cs" />
|
||||
<Compile Include="Users\Controllers\AdminControllerTests.cs" />
|
||||
<Compile Include="Users\Services\MembershipServiceTests.cs" />
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
@@ -26,20 +27,19 @@ using Orchard.Messaging.Events;
|
||||
using Orchard.Messaging.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Permissions;
|
||||
using Orchard.Security.Providers;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.UI.Notify;
|
||||
using Orchard.Users.Controllers;
|
||||
using Orchard.Users.Handlers;
|
||||
using Orchard.Users.Models;
|
||||
using Orchard.Users.Services;
|
||||
using Orchard.Users.ViewModels;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Core.Settings.Services;
|
||||
using Orchard.Tests.Messaging;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Core.Settings.Models;
|
||||
using Orchard.Core.Settings.Handlers;
|
||||
using Orchard.Messaging.Models;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Orchard.Tests.Modules.Users.Controllers {
|
||||
@@ -74,11 +74,14 @@ namespace Orchard.Tests.Modules.Users.Controllers {
|
||||
builder.RegisterType<StubExtensionManager>().As<IExtensionManager>();
|
||||
builder.RegisterType<SiteSettingsPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<RegistrationSettingsPartHandler>().As<IContentHandler>();
|
||||
|
||||
builder.RegisterInstance(new Mock<INotifier>().Object);
|
||||
builder.RegisterInstance(new Mock<IContentDisplay>().Object);
|
||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
||||
builder.RegisterType<Signals>().As<ISignals>();
|
||||
builder.RegisterInstance(new ShellSettings { Name = "Alpha", RequestUrlHost = "wiki.example.com", RequestUrlPrefix = "~/foo" });
|
||||
|
||||
builder.RegisterType<DefaultEncryptionService>().As<IEncryptionService>();
|
||||
builder.RegisterInstance(ShellSettingsUtility.CreateEncryptionEnabled());
|
||||
|
||||
_authorizer = new Mock<IAuthorizer>();
|
||||
builder.RegisterInstance(_authorizer.Object);
|
||||
|
@@ -26,6 +26,7 @@ using Orchard.Messaging.Events;
|
||||
using Orchard.Messaging.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Permissions;
|
||||
using Orchard.Security.Providers;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.UI.Notify;
|
||||
using Orchard.Users.Controllers;
|
||||
@@ -69,7 +70,8 @@ namespace Orchard.Tests.Modules.Users.Controllers {
|
||||
builder.RegisterInstance(new Mock<IContentDisplay>().Object);
|
||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
||||
builder.RegisterType<Signals>().As<ISignals>();
|
||||
builder.RegisterInstance(new ShellSettings { Name = "Alpha", RequestUrlHost = "wiki.example.com", RequestUrlPrefix = "~/foo" });
|
||||
builder.RegisterType<DefaultEncryptionService>().As<IEncryptionService>();
|
||||
builder.RegisterInstance(ShellSettingsUtility.CreateEncryptionEnabled());
|
||||
|
||||
_authorizer = new Mock<IAuthorizer>();
|
||||
builder.RegisterInstance(_authorizer.Object);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Web.Security;
|
||||
using System.Xml.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
@@ -21,6 +20,7 @@ using Orchard.Environment.Extensions;
|
||||
using Orchard.Messaging.Events;
|
||||
using Orchard.Messaging.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Providers;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Tests.Utility;
|
||||
using Orchard.Users.Handlers;
|
||||
@@ -96,7 +96,9 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
builder.RegisterType<DefaultShapeFactory>().As<IShapeFactory>();
|
||||
builder.RegisterType<StubExtensionManager>().As<IExtensionManager>();
|
||||
builder.RegisterType<DefaultContentDisplay>().As<IContentDisplay>();
|
||||
builder.RegisterInstance(new ShellSettings { Name = "Alpha", RequestUrlHost = "wiki.example.com", RequestUrlPrefix = "~/foo" });
|
||||
|
||||
builder.RegisterType<DefaultEncryptionService>().As<IEncryptionService>();
|
||||
builder.RegisterInstance(ShellSettingsUtility.CreateEncryptionEnabled());
|
||||
|
||||
_session = _sessionFactory.OpenSession();
|
||||
builder.RegisterInstance(new TestSessionLocator(_session)).As<ISessionLocator>();
|
||||
@@ -121,25 +123,5 @@ namespace Orchard.Tests.Modules.Users.Services {
|
||||
Assert.That(username, Is.EqualTo("foo"));
|
||||
Assert.That(validateByUtc, Is.GreaterThan(_clock.UtcNow));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NonceShouldNotBeUsedOnAnotherTenant() {
|
||||
var user = _membershipService.CreateUser(new CreateUserParams("foo", "66554321", "foo@bar.com", "", "", true));
|
||||
var nonce = _userService.CreateNonce(user, new TimeSpan(1, 0, 0));
|
||||
|
||||
Assert.That(nonce, Is.Not.Empty);
|
||||
|
||||
string username;
|
||||
DateTime validateByUtc;
|
||||
|
||||
_container.Resolve<ShellSettings>().Name = "Beta";
|
||||
|
||||
var result = _userService.DecryptNonce(nonce, out username, out validateByUtc);
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
Assert.That(username, Is.EqualTo("foo"));
|
||||
Assert.That(validateByUtc, Is.GreaterThan(_clock.UtcNow));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
27
src/Orchard.Tests.Modules/Users/ShellSettingsUtility.cs
Normal file
27
src/Orchard.Tests.Modules/Users/ShellSettingsUtility.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Tests.Modules.Users {
|
||||
public class ShellSettingsUtility {
|
||||
public static ShellSettings CreateEncryptionEnabled() {
|
||||
// generate random keys for encryption
|
||||
var key = new byte[32];
|
||||
var iv = new byte[16];
|
||||
using ( var random = new RNGCryptoServiceProvider() ) {
|
||||
random.GetBytes(key);
|
||||
random.GetBytes(iv);
|
||||
}
|
||||
|
||||
return new ShellSettings {
|
||||
Name = "Alpha",
|
||||
RequestUrlHost = "wiki.example.com",
|
||||
RequestUrlPrefix = "~/foo",
|
||||
EncryptionAlgorithm = "AES",
|
||||
EncryptionKey = key.ToHexString(),
|
||||
EncryptionIV = iv.ToHexString()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -58,11 +58,47 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
VerifyShapeType("Views/Items", "Content-MyType.Edit", "Content_Edit__MyType");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultItemsContentTemplate2() {
|
||||
VerifyShapeType("Views", "Content", "Content");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImplicitSpecializationOfItemsContentTemplate2() {
|
||||
VerifyShapeType("Views", "MyType", "MyType");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExplicitSpecializationOfItemsContentTemplate2() {
|
||||
VerifyShapeType("Views", "Content-MyType", "Content__MyType");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContentItemDisplayTypes2() {
|
||||
VerifyShapeType("Views", "Content", "Content");
|
||||
VerifyShapeType("Views", "Content.Summary", "Content_Summary");
|
||||
VerifyShapeType("Views", "Content.Edit", "Content_Edit");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExplicitSpecializationMixedWithDisplayTypes2() {
|
||||
VerifyShapeType("Views", "Content-MyType", "Content__MyType");
|
||||
VerifyShapeType("Views", "Content-MyType.Summary", "Content_Summary__MyType");
|
||||
VerifyShapeType("Views", "Content-MyType.Edit", "Content_Edit__MyType");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MultipleDotsAreNormalizedToUnderscore() {
|
||||
VerifyShapeType("Views/Parts", "Common.Body", "Parts_Common_Body");
|
||||
VerifyShapeType("Views/Parts", "Common.Body.Summary", "Parts_Common_Body_Summary");
|
||||
VerifyShapeType("Views/Parts", "Localization.ContentTranslations.Summary", "Parts_Localization_ContentTranslations_Summary");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MultipleDotsAreNormalizedToUnderscore2() {
|
||||
VerifyShapeType("Views", "Parts.Common.Body", "Parts_Common_Body");
|
||||
VerifyShapeType("Views", "Parts.Common.Body.Summary", "Parts_Common_Body_Summary");
|
||||
VerifyShapeType("Views", "Parts.Localization.ContentTranslations.Summary", "Parts_Localization_ContentTranslations_Summary");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Descriptors.ResourceBindingStrategy;
|
||||
using Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
|
||||
namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
[TestFixture]
|
||||
public class StylesheetBindingStrategyTests : ContainerTestBase {
|
||||
private ShellDescriptor _descriptor;
|
||||
private IList<FeatureDescriptor> _features;
|
||||
private TestViewEngine _testViewEngine;
|
||||
private TestVirtualPathProvider _testVirtualPathProvider;
|
||||
|
||||
|
||||
protected override void Register(Autofac.ContainerBuilder builder) {
|
||||
_descriptor = new ShellDescriptor { };
|
||||
_testViewEngine = new TestViewEngine();
|
||||
_testVirtualPathProvider = new TestVirtualPathProvider();
|
||||
|
||||
builder.Register(ctx => _descriptor);
|
||||
builder.RegisterType<StylesheetBindingStrategy>().As<IShapeTableProvider>();
|
||||
builder.RegisterInstance(_testViewEngine).As<IShapeTemplateViewEngine>();
|
||||
builder.RegisterInstance(_testVirtualPathProvider).As<IVirtualPathProvider>();
|
||||
|
||||
var extensionManager = new Mock<IExtensionManager>();
|
||||
builder.Register(ctx => extensionManager);
|
||||
builder.Register(ctx => extensionManager.Object);
|
||||
}
|
||||
|
||||
public class TestViewEngine : Dictionary<string, object>, IShapeTemplateViewEngine {
|
||||
public IEnumerable<string> DetectTemplateFileNames(IEnumerable<string> fileNames) {
|
||||
return fileNames;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestVirtualPathProvider : IVirtualPathProvider {
|
||||
public string Combine(params string[] paths) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string ToAppRelative(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string MapPath(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool FileExists(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Stream OpenFile(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public StreamWriter CreateText(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Stream CreateFile(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public DateTime GetFileLastWriteTimeUtc(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CreateDirectory(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetDirectoryName(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListFiles(string path) {
|
||||
return new List<string> {"~/Modules/Alpha/Styles/AlphaStyle.css"};
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListDirectories(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Resolve(ILifetimeScope container) {
|
||||
_features = new List<FeatureDescriptor>();
|
||||
|
||||
container.Resolve<Mock<IExtensionManager>>()
|
||||
.Setup(em => em.AvailableFeatures())
|
||||
.Returns(_features);
|
||||
}
|
||||
|
||||
void AddFeature(string name, params string[] dependencies) {
|
||||
var featureDescriptor = new FeatureDescriptor {
|
||||
Id = name,
|
||||
Dependencies = dependencies,
|
||||
Extension = new ExtensionDescriptor {
|
||||
Id = name,
|
||||
Location = "~/Modules"
|
||||
}
|
||||
};
|
||||
featureDescriptor.Extension.Features = new[] { featureDescriptor };
|
||||
|
||||
_features.Add(featureDescriptor);
|
||||
}
|
||||
|
||||
void AddEnabledFeature(string name, params string[] dependencies) {
|
||||
AddFeature(name, dependencies);
|
||||
_descriptor.Features = _descriptor.Features.Concat(new[] { new ShellFeature { Name = name } });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TemplateResolutionWorks() {
|
||||
AddEnabledFeature("Alpha");
|
||||
|
||||
_testViewEngine.Add("~/Modules/Alpha/Styles/AlphaShape.css", null);
|
||||
var strategy = _container.Resolve<IShapeTableProvider>();
|
||||
|
||||
IList<ShapeAlterationBuilder> alterationBuilders = new List<ShapeAlterationBuilder>();
|
||||
var builder = new ShapeTableBuilder(alterationBuilders,null);
|
||||
strategy.Discover(builder);
|
||||
var alterations = alterationBuilders.Select(alterationBuilder=>alterationBuilder.Build());
|
||||
|
||||
Assert.That(alterations.Any(alteration => alteration.ShapeType == "Style"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -58,7 +58,7 @@ namespace Orchard.Tests.Environment.Configuration {
|
||||
_appDataFolder.CreateFile("Sites\\Default\\Settings.txt", "Name: Default\r\nDataProvider: SqlCe\r\nDataConnectionString: something else");
|
||||
|
||||
IShellSettingsManager loader = new ShellSettingsManager(_appDataFolder, new Mock<IShellSettingsManagerEventHandler>().Object);
|
||||
var foo = new ShellSettings { Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux" };
|
||||
var foo = new ShellSettings {Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux"};
|
||||
|
||||
Assert.That(loader.LoadSettings().Count(), Is.EqualTo(1));
|
||||
loader.SaveSettings(foo);
|
||||
@@ -69,5 +69,19 @@ namespace Orchard.Tests.Environment.Configuration {
|
||||
Assert.That(text, Is.StringContaining("Bar"));
|
||||
Assert.That(text, Is.StringContaining("Quux"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EncryptionSettingsAreStoredAndReadable() {
|
||||
IShellSettingsManager loader = new ShellSettingsManager(_appDataFolder, new Mock<IShellSettingsManagerEventHandler>().Object);
|
||||
var foo = new ShellSettings { Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux", EncryptionAlgorithm = "AES", EncryptionKey = "ABCDEFG", EncryptionIV= "HIJKL" };
|
||||
loader.SaveSettings(foo);
|
||||
Assert.That(loader.LoadSettings().Count(), Is.EqualTo(1));
|
||||
|
||||
var settings = loader.LoadSettings().First();
|
||||
|
||||
Assert.That(settings.EncryptionAlgorithm, Is.EqualTo("AES"));
|
||||
Assert.That(settings.EncryptionKey, Is.EqualTo("ABCDEFG"));
|
||||
Assert.That(settings.EncryptionIV, Is.EqualTo("HIJKL"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -212,6 +212,7 @@
|
||||
<Compile Include="DisplayManagement\DefaultDisplayManagerTests.cs" />
|
||||
<Compile Include="ContainerTestBase.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\BasicShapeTemplateHarvesterTests.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\StylesheetBindingStrategyTests.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\DefaultShapeTableManagerTests.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\InMemoryWebSiteFolder.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\PlacementFileParserTests.cs" />
|
||||
@@ -244,6 +245,7 @@
|
||||
<Compile Include="Mvc\Routes\ShellRouteTests.cs" />
|
||||
<Compile Include="Mvc\Routes\UrlPrefixTests.cs" />
|
||||
<Compile Include="Records\BigRecord.cs" />
|
||||
<Compile Include="Security\DefaultEncryptionServiceTests.cs" />
|
||||
<Compile Include="Stubs\InMemoryWebSiteFolder.cs" />
|
||||
<Compile Include="Stubs\StubHttpContextAccessor.cs" />
|
||||
<Compile Include="Stubs\StubWorkContextAccessor.cs" />
|
||||
|
53
src/Orchard.Tests/Security/DefaultEncryptionServiceTests.cs
Normal file
53
src/Orchard.Tests/Security/DefaultEncryptionServiceTests.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Providers;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Tests.Security {
|
||||
[TestFixture]
|
||||
public class DefaultEncryptionServiceTests {
|
||||
private IContainer container;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
|
||||
var key = new byte[32];
|
||||
var iv = new byte[16];
|
||||
using ( var random = new RNGCryptoServiceProvider() ) {
|
||||
random.GetBytes(key);
|
||||
random.GetBytes(iv);
|
||||
}
|
||||
|
||||
var shellSettings = new ShellSettings {
|
||||
Name = "Foo",
|
||||
DataProvider = "Bar",
|
||||
DataConnectionString = "Quux",
|
||||
EncryptionAlgorithm = "AES",
|
||||
EncryptionKey = key.ToHexString(),
|
||||
EncryptionIV = iv.ToHexString()
|
||||
};
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterInstance(shellSettings);
|
||||
builder.RegisterType<DefaultEncryptionService>().As<IEncryptionService>();
|
||||
container = builder.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanEncodeAndDecodeData() {
|
||||
var encryptionService = container.Resolve<IEncryptionService>();
|
||||
|
||||
var secretData = Encoding.Unicode.GetBytes("this is secret data");
|
||||
var encrypted = encryptionService.Encode(secretData);
|
||||
var decrypted = encryptionService.Decode(encrypted);
|
||||
|
||||
Assert.That(encrypted, Is.Not.EqualTo(decrypted));
|
||||
Assert.That(decrypted, Is.EqualTo(secretData));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -16,7 +16,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
public class BodyPartDriver : ContentPartDriver<BodyPart> {
|
||||
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
|
||||
|
||||
private const string TemplateName = "Parts/Common.Body";
|
||||
private const string TemplateName = "Parts.Common.Body";
|
||||
|
||||
public BodyPartDriver(IOrchardServices services, IEnumerable<IHtmlFilter> htmlFilters) {
|
||||
_htmlFilters = htmlFilters;
|
||||
|
@@ -83,7 +83,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
}
|
||||
|
||||
return ContentShape("Parts_Common_Owner_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Common.Owner", Model: model, Prefix: Prefix));
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.Owner", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
DriverResult ContainerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -112,7 +112,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
}
|
||||
|
||||
return ContentShape("Parts_Common_Container_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Common.Container", Model: model, Prefix: Prefix));
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.Container", Model: model, Prefix: Prefix));
|
||||
}
|
||||
}
|
||||
}
|
@@ -22,7 +22,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, TextField field, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Common_Text_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Fields/Common.Text.Edit", Model: field, Prefix: GetPrefix(field, part)));
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Fields.Common.Text.Edit", Model: field, Prefix: GetPrefix(field, part)));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, TextField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
|
@@ -1 +0,0 @@
|
||||
@model Orchard.Core.Common.ViewModels.BodyDisplayViewModel
|
@@ -0,0 +1 @@
|
||||
|
@@ -28,7 +28,7 @@ namespace Orchard.Core.Navigation.Drivers {
|
||||
return null;
|
||||
|
||||
return ContentShape("Parts_Navigation_Menu_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Navigation.Menu.Edit", Model: part, Prefix: Prefix));
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Navigation.Menu.Edit", Model: part, Prefix: Prefix));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(MenuPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
|
@@ -231,19 +231,19 @@
|
||||
<Content Include="Common\Module.txt" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyTypePartSettings.cshtml" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyPartSettings.cshtml" />
|
||||
<Content Include="Common\Views\Fields\Common.Text.cshtml" />
|
||||
<Content Include="Common\Views\Parts\Common.Body.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\Parts\Common.Metadata.cshtml" />
|
||||
<Content Include="Common\Views\Parts\Common.Metadata.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\Fields.Common.Text.cshtml" />
|
||||
<Content Include="Common\Views\Parts.Common.Body.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\Parts.Common.Metadata.cshtml" />
|
||||
<Content Include="Common\Views\Parts.Common.Metadata.SummaryAdmin.cshtml" />
|
||||
<Content Include="Containers\Module.txt" />
|
||||
<Content Include="Contents\Views\Admin\Create.cshtml" />
|
||||
<Content Include="Contents\Views\Admin\Edit.cshtml" />
|
||||
<Content Include="Contents\Views\Admin\List.cshtml" />
|
||||
<Content Include="Feeds\Views\Feed.cshtml" />
|
||||
<Content Include="Contents\Views\Parts\Contents.Publish.cshtml" />
|
||||
<Content Include="Contents\Views\Parts\Contents.Publish.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Fields\Common.Text.Edit.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Container.cshtml" />
|
||||
<Content Include="Contents\Views\Parts.Contents.Publish.cshtml" />
|
||||
<Content Include="Contents\Views\Parts.Contents.Publish.SummaryAdmin.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Fields.Common.Text.Edit.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts.Common.Container.cshtml" />
|
||||
<Content Include="Common\Views\Body.Editor.cshtml" />
|
||||
<Content Include="Contents\Module.txt" />
|
||||
<Content Include="Contents\Views\Admin\CreatableTypeList.cshtml" />
|
||||
@@ -252,12 +252,12 @@
|
||||
<Content Include="Reports\Views\Admin\Index.cshtml" />
|
||||
<Content Include="Routable\Module.txt" />
|
||||
<Content Include="Routable\Scripts\jquery.slugify.js" />
|
||||
<Content Include="Routable\Views\EditorTemplates\Parts\Routable.RoutePart.cshtml" />
|
||||
<Content Include="Routable\Views\EditorTemplates\Parts.Routable.RoutePart.cshtml" />
|
||||
<Content Include="Settings\Module.txt" />
|
||||
<Content Include="Settings\Styles\admin.css" />
|
||||
<Content Include="Settings\Views\Admin\Index.cshtml" />
|
||||
<Content Include="Settings\Views\Admin\Culture.cshtml" />
|
||||
<Content Include="Contents\Views\Items\Content.Edit.cshtml" />
|
||||
<Content Include="Contents\Views\Content.Edit.cshtml" />
|
||||
<Content Include="Routable\Placement.info" />
|
||||
<Content Include="Settings\Placement.info" />
|
||||
<Content Include="Settings\Views\DisplayTemplates\CurrentCulture.cshtml" />
|
||||
@@ -279,7 +279,7 @@
|
||||
<Content Include="Shapes\Views\Message.cshtml" />
|
||||
<Content Include="Shapes\Views\NotFound.cshtml" />
|
||||
<Content Include="XmlRpc\Module.txt" />
|
||||
<Content Include="Settings\Views\EditorTemplates\Parts\Settings.SiteSettingsPart.cshtml" />
|
||||
<Content Include="Settings\Views\EditorTemplates\Parts.Settings.SiteSettingsPart.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Orchard\Orchard.Framework.csproj">
|
||||
@@ -294,9 +294,9 @@
|
||||
<Content Include="Common\Views\Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\Parts\Common.Body.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Body.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Owner.cshtml" />
|
||||
<Content Include="Common\Views\Parts.Common.Body.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts.Common.Body.cshtml" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts.Common.Owner.cshtml" />
|
||||
<Content Include="Feeds\Module.txt" />
|
||||
<Content Include="Navigation\Module.txt" />
|
||||
<Content Include="Scheduling\Module.txt" />
|
||||
@@ -306,11 +306,11 @@
|
||||
<Content Include="Dashboard\Views\Admin\Index.cshtml" />
|
||||
<Content Include="HomePage\Module.txt" />
|
||||
<Content Include="Navigation\Views\Admin\Index.cshtml" />
|
||||
<Content Include="Navigation\Views\EditorTemplates\Parts\Navigation.Menu.Edit.cshtml" />
|
||||
<Content Include="Navigation\Views\EditorTemplates\Parts.Navigation.Menu.Edit.cshtml" />
|
||||
<Content Include="Navigation\Views\Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\Parts\Common.Body.Summary.cshtml" />
|
||||
<Content Include="Common\Views\Parts.Common.Body.Summary.cshtml" />
|
||||
<Content Include="Dashboard\Views\Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -320,8 +320,8 @@
|
||||
<Content Include="Contents\Views\Web.config" />
|
||||
<Content Include="Routable\Views\Web.config" />
|
||||
<Content Include="Reports\Views\Web.config" />
|
||||
<Content Include="Contents\Views\Items\Content.cshtml" />
|
||||
<Content Include="Contents\Views\Items\Content.SummaryAdmin.cshtml" />
|
||||
<Content Include="Contents\Views\Content.cshtml" />
|
||||
<Content Include="Contents\Views\Content.SummaryAdmin.cshtml" />
|
||||
<Content Include="Shapes\Views\Document.cshtml" />
|
||||
<Content Include="Shapes\Views\User.cshtml" />
|
||||
<Content Include="Shapes\Views\Header.cshtml" />
|
||||
@@ -330,17 +330,17 @@
|
||||
<Content Include="Shapes\Views\MenuItem.cshtml" />
|
||||
<Content Include="Shapes\Views\Web.config" />
|
||||
<Content Include="Common\Placement.info" />
|
||||
<Content Include="Common\Views\Parts\Common.Metadata.Summary.cshtml" />
|
||||
<Content Include="Common\Views\Parts.Common.Metadata.Summary.cshtml" />
|
||||
<Content Include="Contents\Placement.info">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Contents\Views\Content.ControlWrapper.cshtml" />
|
||||
<Content Include="Contents\Views\Item\Display.cshtml" />
|
||||
<Content Include="Navigation\Placement.info" />
|
||||
<Content Include="Routable\Views\Parts\RoutableTitle.cshtml" />
|
||||
<Content Include="Routable\Views\Parts.RoutableTitle.cshtml" />
|
||||
<Content Include="Routable\Views\Item\Display.cshtml" />
|
||||
<Content Include="Routable\Views\Routable.HomePage.cshtml" />
|
||||
<Content Include="Contents\Views\Items\Content.Summary.cshtml" />
|
||||
<Content Include="Contents\Views\Content.Summary.cshtml" />
|
||||
<Content Include="Shapes\Views\Pager.cshtml" />
|
||||
<Content Include="Contents\Views\Content.SaveButton.cshtml" />
|
||||
<Content Include="Contents\Views\Content.PublishButton.cshtml" />
|
||||
@@ -363,13 +363,13 @@
|
||||
<Content Include="Containers\Views\DefinitionTemplates\ContainerPartSettings.cshtml" />
|
||||
<Content Include="Containers\Views\DefinitionTemplates\ContainerTypePartSettings.cshtml" />
|
||||
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
|
||||
<Content Include="Containers\Views\Parts\ContainerWidget.cshtml" />
|
||||
<Content Include="Containers\Views\Parts.ContainerWidget.cshtml" />
|
||||
<Content Include="Containers\Views\EditorTemplates\CustomProperties.cshtml" />
|
||||
<Content Include="Routable\Views\Parts\RoutableTitle_Summary.cshtml" />
|
||||
<Content Include="Routable\Views\Parts\RoutableTitle_SummaryAdmin.cshtml" />
|
||||
<Content Include="Routable\Views\Parts.RoutableTitle_Summary.cshtml" />
|
||||
<Content Include="Routable\Views\Parts.RoutableTitle_SummaryAdmin.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Containers\Views\Parts\Container.Contained.SummaryAdmin.cshtml" />
|
||||
<Content Include="Containers\Views\Parts.Container.Contained.SummaryAdmin.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
|
@@ -30,7 +30,7 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
private const string TemplateName = "Parts/Routable.RoutePart";
|
||||
private const string TemplateName = "Parts.Routable.RoutePart";
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
|
@@ -40,7 +40,7 @@ namespace Orchard.Core.Settings.Drivers {
|
||||
};
|
||||
|
||||
return ContentShape("Parts_Settings_SiteSettingsPart",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Settings.SiteSettingsPart", Model: model, Prefix: Prefix));
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Settings.SiteSettingsPart", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(SiteSettingsPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -65,7 +65,7 @@ namespace Orchard.Core.Settings.Drivers {
|
||||
}
|
||||
|
||||
return ContentShape("Parts_Settings_SiteSettingsPart",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Settings.SiteSettingsPart", Model: model, Prefix: Prefix));
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Settings.SiteSettingsPart", Model: model, Prefix: Prefix));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -8,6 +9,8 @@ using System.Web.Mvc;
|
||||
using System.Web.Mvc.Html;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Descriptors.ResourceBindingStrategy;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Settings;
|
||||
using Orchard.UI;
|
||||
using Orchard.UI.Resources;
|
||||
@@ -19,11 +22,20 @@ using Orchard.Utility.Extensions;
|
||||
namespace Orchard.Core.Shapes {
|
||||
public class CoreShapes : IShapeTableProvider {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public CoreShapes(IWorkContextAccessor workContextAccessor) {
|
||||
public CoreShapes(IWorkContextAccessor workContextAccessor, IHttpContextAccessor httpContextAccessor) {
|
||||
// needed to get CurrentSite.
|
||||
// note that injecting ISiteService here causes a stack overflow in AutoFac!
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
// not injected the usual way because this component is a 'static' dependency and RM is per-request
|
||||
private IResourceManager ResourceManager {
|
||||
get {
|
||||
return _workContextAccessor.GetContext(_httpContextAccessor.Current()).Resolve<IResourceManager>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Discover(ShapeTableBuilder builder) {
|
||||
@@ -82,6 +94,26 @@ namespace Orchard.Core.Shapes {
|
||||
list.ItemClasses = new List<string>();
|
||||
list.ItemAttributes = new Dictionary<string, string>();
|
||||
});
|
||||
|
||||
builder.Describe("Style")
|
||||
.OnDisplaying(displaying => {
|
||||
var resource = displaying.Shape;
|
||||
string url = resource.Url;
|
||||
string fileName = StylesheetBindingStrategy.GetAlternateShapeNameFromFileName(url);
|
||||
if (!string.IsNullOrEmpty(fileName)) {
|
||||
resource.Metadata.Alternates.Add("Style__" + fileName);
|
||||
}
|
||||
});
|
||||
|
||||
builder.Describe("Resource")
|
||||
.OnDisplaying(displaying => {
|
||||
var resource = displaying.Shape;
|
||||
string url = resource.Url;
|
||||
string fileName = StylesheetBindingStrategy.GetAlternateShapeNameFromFileName(url);
|
||||
if (!string.IsNullOrEmpty(fileName)) {
|
||||
resource.Metadata.Alternates.Add("Resource__" + fileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -159,51 +191,58 @@ namespace Orchard.Core.Shapes {
|
||||
#endregion
|
||||
|
||||
[Shape]
|
||||
public void HeadScripts(HtmlHelper Html, IResourceManager ResourceManager) {
|
||||
WriteResources(Html, _workContextAccessor.GetContext(Html.ViewContext).CurrentSite,
|
||||
ResourceManager, "script", ResourceLocation.Head, null);
|
||||
WriteLiteralScripts(Html, ResourceManager.GetRegisteredHeadScripts());
|
||||
public void HeadScripts(dynamic Display, TextWriter Output) {
|
||||
WriteResources(Display, Output, "script", ResourceLocation.Head, null);
|
||||
WriteLiteralScripts(Output, ResourceManager.GetRegisteredHeadScripts());
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void FootScripts(HtmlHelper Html, IResourceManager ResourceManager) {
|
||||
WriteResources(Html, _workContextAccessor.GetContext(Html.ViewContext).CurrentSite,
|
||||
ResourceManager, "script", null, ResourceLocation.Head);
|
||||
WriteLiteralScripts(Html, ResourceManager.GetRegisteredFootScripts());
|
||||
public void FootScripts(dynamic Display, TextWriter Output) {
|
||||
WriteResources(Display, Output, "script", null, ResourceLocation.Head);
|
||||
WriteLiteralScripts(Output, ResourceManager.GetRegisteredFootScripts());
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void Metas(HtmlHelper Html, IResourceManager ResourceManager) {
|
||||
public void Metas(TextWriter Output) {
|
||||
foreach (var meta in ResourceManager.GetRegisteredMetas()) {
|
||||
Html.ViewContext.Writer.WriteLine(meta.GetTag());
|
||||
Output.WriteLine(meta.GetTag());
|
||||
}
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void HeadLinks(HtmlHelper Html, IResourceManager ResourceManager) {
|
||||
public void HeadLinks(TextWriter Output) {
|
||||
foreach (var link in ResourceManager.GetRegisteredLinks()) {
|
||||
Html.ViewContext.Writer.WriteLine(link.GetTag());
|
||||
Output.WriteLine(link.GetTag());
|
||||
}
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void StylesheetLinks(HtmlHelper Html, IResourceManager ResourceManager) {
|
||||
WriteResources(Html, _workContextAccessor.GetContext(Html.ViewContext).CurrentSite,
|
||||
ResourceManager, "stylesheet", null, null);
|
||||
public void StylesheetLinks(dynamic Display, TextWriter Output) {
|
||||
WriteResources(Display, Output, "stylesheet", null, null);
|
||||
}
|
||||
|
||||
private static void WriteLiteralScripts(HtmlHelper html, IEnumerable<string> scripts) {
|
||||
[Shape]
|
||||
public void Style(TextWriter Output, ResourceDefinition Resource, string Url, string Condition) {
|
||||
UI.Resources.ResourceManager.WriteResource(Output, Resource, Url, Condition);
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void Resource(TextWriter Output, ResourceDefinition Resource, string Url, string Condition) {
|
||||
UI.Resources.ResourceManager.WriteResource(Output, Resource, Url, Condition);
|
||||
}
|
||||
|
||||
private static void WriteLiteralScripts(TextWriter output, IEnumerable<string> scripts) {
|
||||
if (scripts == null) {
|
||||
return;
|
||||
}
|
||||
var writer = html.ViewContext.Writer;
|
||||
foreach (string script in scripts) {
|
||||
writer.WriteLine(script);
|
||||
output.WriteLine(script);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteResources(HtmlHelper html, ISite site, IResourceManager rm, string resourceType, ResourceLocation? includeLocation, ResourceLocation? excludeLocation) {
|
||||
private void WriteResources(dynamic Display, TextWriter Output, string resourceType, ResourceLocation? includeLocation, ResourceLocation? excludeLocation) {
|
||||
bool debugMode;
|
||||
var site = _workContextAccessor.GetContext(_httpContextAccessor.Current()).CurrentSite;
|
||||
switch (site.ResourceDebugMode) {
|
||||
case ResourceDebugMode.Enabled:
|
||||
debugMode = true;
|
||||
@@ -213,26 +252,29 @@ namespace Orchard.Core.Shapes {
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(site.ResourceDebugMode == ResourceDebugMode.FromAppSetting, "Unknown ResourceDebugMode value.");
|
||||
debugMode = html.ViewContext.HttpContext.IsDebuggingEnabled;
|
||||
debugMode = _httpContextAccessor.Current().IsDebuggingEnabled;
|
||||
break;
|
||||
}
|
||||
var defaultSettings = new RequireSettings {
|
||||
DebugMode = debugMode,
|
||||
Culture = CultureInfo.CurrentUICulture.Name,
|
||||
};
|
||||
var requiredResources = rm.BuildRequiredResources(resourceType);
|
||||
var appPath = html.ViewContext.HttpContext.Request.ApplicationPath;
|
||||
var requiredResources = ResourceManager.BuildRequiredResources(resourceType);
|
||||
var appPath = _httpContextAccessor.Current().Request.ApplicationPath;
|
||||
foreach (var context in requiredResources.Where(r =>
|
||||
(includeLocation.HasValue ? r.Settings.Location == includeLocation.Value : true) &&
|
||||
(excludeLocation.HasValue ? r.Settings.Location != excludeLocation.Value : true))) {
|
||||
|
||||
var path = context.GetResourceUrl(defaultSettings, appPath);
|
||||
var condition = context.Settings.Condition;
|
||||
if (!string.IsNullOrEmpty(condition)) {
|
||||
html.ViewContext.Writer.WriteLine("<!--[if " + condition + "]>");
|
||||
IHtmlString result;
|
||||
if (resourceType == "stylesheet") {
|
||||
result = Display.Style(Url: path, Condition: condition, Resource: context.Resource);
|
||||
}
|
||||
html.ViewContext.Writer.WriteLine(context.GetTagBuilder(defaultSettings, appPath).ToString(context.Resource.TagRenderMode));
|
||||
if (!string.IsNullOrEmpty(condition)) {
|
||||
html.ViewContext.Writer.WriteLine("<![endif]-->");
|
||||
else {
|
||||
result = Display.Resource(Url: path, Condition: condition, Resource: context.Resource);
|
||||
}
|
||||
Output.Write(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
<select id="publishActions" name="@Html.NameOf(m => m.Options.BulkAction)">
|
||||
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.None, T("Choose action...").ToString())
|
||||
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Approve, T("Approve").ToString())
|
||||
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Pend, T("Pend").ToString())
|
||||
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Unapprove, T("Unapprove").ToString())
|
||||
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.MarkAsSpam, T("Mark as Spam").ToString())
|
||||
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Delete, T("Remove").ToString())
|
||||
</select>
|
||||
|
@@ -6,10 +6,8 @@ using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentTypes.Extensions;
|
||||
using Orchard.ContentTypes.ViewModels;
|
||||
using Orchard.Core.Contents.Extensions;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.ContentTypes.Services {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
@model IEnumerable<Orchard.ContentTypes.ViewModels.EditPartFieldViewModel
|
||||
@model IEnumerable<Orchard.ContentTypes.ViewModels.EditPartFieldViewModel>
|
||||
@if (Model.Any()) {
|
||||
<dl>@foreach (var field in Model) {
|
||||
var f = field;
|
||||
|
@@ -9,8 +9,8 @@
|
||||
var htmlFieldName = string.Format("Settings[{0}]", si++);
|
||||
// doesn't gen a similarly sanitized id as the other inputs...*/
|
||||
<label for="@ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName + ".Value")">@s.Key</label>
|
||||
Html.Hidden(htmlFieldName + ".Key", s.Key)
|
||||
Html.TextBox(htmlFieldName + ".Value", s.Value)
|
||||
Html.Hidden(htmlFieldName + ".Key", s.Key);
|
||||
Html.TextBox(htmlFieldName + ".Value", s.Value);
|
||||
}
|
||||
}
|
||||
</fieldset>
|
||||
|
@@ -1,14 +1,27 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Email.Models;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Security;
|
||||
|
||||
namespace Orchard.Email.Handlers {
|
||||
[UsedImplicitly]
|
||||
public class SmtpSettingsPartHandler : ContentHandler {
|
||||
public SmtpSettingsPartHandler(IRepository<SmtpSettingsPartRecord> repository) {
|
||||
private readonly IEncryptionService _encryptionService;
|
||||
|
||||
public SmtpSettingsPartHandler(IRepository<SmtpSettingsPartRecord> repository, IEncryptionService encryptionService) {
|
||||
_encryptionService = encryptionService;
|
||||
Filters.Add(new ActivatingFilter<SmtpSettingsPart>("Site"));
|
||||
Filters.Add(StorageFilter.For(repository));
|
||||
|
||||
OnLoaded<SmtpSettingsPart>(LazyLoadHandlers);
|
||||
}
|
||||
|
||||
void LazyLoadHandlers(LoadContentContext context, SmtpSettingsPart part) {
|
||||
part.PasswordField.Getter(() => String.IsNullOrWhiteSpace(part.Record.Password) ? String.Empty : Encoding.UTF8.GetString(_encryptionService.Decode(Convert.FromBase64String(part.Record.Password))));
|
||||
part.PasswordField.Setter(value => part.Record.Password = String.IsNullOrWhiteSpace(value) ? String.Empty : Convert.ToBase64String(_encryptionService.Encode(Encoding.UTF8.GetBytes(value))));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,14 +1,13 @@
|
||||
using System.Text;
|
||||
using System.Web.Security;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement;
|
||||
using System;
|
||||
using Orchard.ContentManagement.Utilities;
|
||||
|
||||
namespace Orchard.Email.Models {
|
||||
public class SmtpSettingsPart : ContentPart<SmtpSettingsPartRecord> {
|
||||
public bool IsValid() {
|
||||
return !String.IsNullOrWhiteSpace(Record.Host)
|
||||
&& Record.Port > 0
|
||||
&& !String.IsNullOrWhiteSpace(Record.Address);
|
||||
private readonly ComputedField<string> _password = new ComputedField<string>();
|
||||
|
||||
public ComputedField<string> PasswordField {
|
||||
get { return _password; }
|
||||
}
|
||||
|
||||
public string Address {
|
||||
@@ -42,8 +41,14 @@ namespace Orchard.Email.Models {
|
||||
}
|
||||
|
||||
public string Password {
|
||||
get { return String.IsNullOrWhiteSpace(Record.Password) ? String.Empty : Encoding.UTF8.GetString(MachineKey.Decode(Record.Password, MachineKeyProtection.All)); ; }
|
||||
set { Record.Password = String.IsNullOrWhiteSpace(value) ? String.Empty : MachineKey.Encode(Encoding.UTF8.GetBytes(value), MachineKeyProtection.All); }
|
||||
get { return _password.Value; }
|
||||
set { _password.Value = value; }
|
||||
}
|
||||
|
||||
public bool IsValid() {
|
||||
return !String.IsNullOrWhiteSpace(Record.Host)
|
||||
&& Record.Port > 0
|
||||
&& !String.IsNullOrWhiteSpace(Record.Address);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Web;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
@@ -29,6 +30,7 @@ using Orchard.Settings;
|
||||
using Orchard.Environment.State;
|
||||
using Orchard.Data.Migration;
|
||||
using Orchard.Themes.Services;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Orchard.Widgets.Models;
|
||||
using Orchard.Widgets;
|
||||
|
||||
@@ -118,6 +120,21 @@ namespace Orchard.Setup.Services {
|
||||
shellSettings.DataTablePrefix = context.DatabaseTablePrefix;
|
||||
}
|
||||
|
||||
#region Encryption Settings
|
||||
|
||||
// generate random keys for encryption
|
||||
var key = new byte[32];
|
||||
var iv = new byte[16];
|
||||
using ( var random = new RNGCryptoServiceProvider() ) {
|
||||
random.GetBytes(key);
|
||||
random.GetBytes(iv);
|
||||
}
|
||||
|
||||
shellSettings.EncryptionAlgorithm = "AES";
|
||||
shellSettings.EncryptionKey = key.ToHexString();
|
||||
shellSettings.EncryptionIV = iv.ToHexString();
|
||||
#endregion
|
||||
|
||||
var shellDescriptor = new ShellDescriptor {
|
||||
Features = context.EnabledFeatures.Select(name => new ShellFeature { Name = name })
|
||||
};
|
||||
|
@@ -25,13 +25,15 @@ namespace Orchard.Users.Services {
|
||||
private readonly IClock _clock;
|
||||
private readonly IMessageManager _messageManager;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IEncryptionService _encryptionService;
|
||||
|
||||
public UserService(IContentManager contentManager, IMembershipService membershipService, IClock clock, IMessageManager messageManager, ShellSettings shellSettings) {
|
||||
public UserService(IContentManager contentManager, IMembershipService membershipService, IClock clock, IMessageManager messageManager, ShellSettings shellSettings, IEncryptionService encryptionService) {
|
||||
_contentManager = contentManager;
|
||||
_membershipService = membershipService;
|
||||
_clock = clock;
|
||||
_messageManager = messageManager;
|
||||
_shellSettings = shellSettings;
|
||||
_encryptionService = encryptionService;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
@@ -66,24 +68,22 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
|
||||
public string CreateNonce(IUser user, TimeSpan delay) {
|
||||
// the tenant's name is added to the token to prevent cross-tenant requests
|
||||
var challengeToken = new XElement("n", new XAttribute("s", _shellSettings.Name), new XAttribute("un", user.UserName), new XAttribute("utc", _clock.UtcNow.ToUniversalTime().Add(delay).ToString(CultureInfo.InvariantCulture))).ToString();
|
||||
var data = Encoding.Unicode.GetBytes(challengeToken);
|
||||
return MachineKey.Encode(data, MachineKeyProtection.All);
|
||||
var challengeToken = new XElement("n", new XAttribute("un", user.UserName), new XAttribute("utc", _clock.UtcNow.ToUniversalTime().Add(delay).ToString(CultureInfo.InvariantCulture))).ToString();
|
||||
var data = Encoding.UTF8.GetBytes(challengeToken);
|
||||
return Convert.ToBase64String(_encryptionService.Encode(data));
|
||||
}
|
||||
|
||||
public bool DecryptNonce(string challengeToken, out string username, out DateTime validateByUtc) {
|
||||
public bool DecryptNonce(string nonce, out string username, out DateTime validateByUtc) {
|
||||
username = null;
|
||||
validateByUtc = _clock.UtcNow;
|
||||
|
||||
try {
|
||||
var data = MachineKey.Decode(challengeToken, MachineKeyProtection.All);
|
||||
var xml = Encoding.Unicode.GetString(data);
|
||||
var data = _encryptionService.Decode(Convert.FromBase64String(nonce));
|
||||
var xml = Encoding.UTF8.GetString(data);
|
||||
var element = XElement.Parse(xml);
|
||||
var tenant = element.Attribute("s").Value;
|
||||
username = element.Attribute("un").Value;
|
||||
validateByUtc = DateTime.Parse(element.Attribute("utc").Value, CultureInfo.InvariantCulture);
|
||||
return String.Equals(_shellSettings.Name, tenant, StringComparison.Ordinal) && _clock.UtcNow <= validateByUtc;
|
||||
return _clock.UtcNow <= validateByUtc;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
|
29
src/Orchard/ContentManagement/Utilities/ComputedField.cs
Normal file
29
src/Orchard/ContentManagement/Utilities/ComputedField.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace Orchard.ContentManagement.Utilities {
|
||||
public class ComputedField<T> {
|
||||
private Func<T> _getter;
|
||||
private Action<T> _setter;
|
||||
|
||||
public T Value {
|
||||
get { return GetValue(); }
|
||||
set { SetValue(value); }
|
||||
}
|
||||
|
||||
public void Getter(Func<T> loader) {
|
||||
_getter = loader;
|
||||
}
|
||||
|
||||
public void Setter(Action<T> setter) {
|
||||
_setter = setter;
|
||||
}
|
||||
|
||||
private T GetValue() {
|
||||
return _getter();
|
||||
}
|
||||
|
||||
private void SetValue(T value) {
|
||||
_setter(value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.UI.Resources;
|
||||
|
||||
namespace Orchard.DisplayManagement.Descriptors.ResourceBindingStrategy {
|
||||
// discovers .css files and turns them into Style__<filename> shapes.
|
||||
public class StylesheetBindingStrategy : IShapeTableProvider {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly ShellDescriptor _shellDescriptor;
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
private static readonly Regex _safeName = new Regex(@"[/:?#\[\]@!&'()*+,;=\s\""<>\.\-_]+", RegexOptions.Compiled);
|
||||
|
||||
public StylesheetBindingStrategy(IExtensionManager extensionManager, ShellDescriptor shellDescriptor, IVirtualPathProvider virtualPathProvider) {
|
||||
_extensionManager = extensionManager;
|
||||
_shellDescriptor = shellDescriptor;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
}
|
||||
|
||||
private static string SafeName(string name) {
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return String.Empty;
|
||||
return _safeName.Replace(name, String.Empty);
|
||||
}
|
||||
|
||||
public static string GetAlternateShapeNameFromFileName(string fileName) {
|
||||
if (fileName == null) {
|
||||
throw new ArgumentNullException("fileName");
|
||||
}
|
||||
string shapeName;
|
||||
if (Uri.IsWellFormedUriString(fileName, UriKind.Absolute)) {
|
||||
var uri = new Uri(fileName);
|
||||
shapeName = uri.Authority + "$" + uri.AbsolutePath + "$" + uri.Query;
|
||||
}
|
||||
else {
|
||||
shapeName = Path.GetFileNameWithoutExtension(fileName);
|
||||
}
|
||||
return SafeName(shapeName);
|
||||
}
|
||||
|
||||
private static IEnumerable<ExtensionDescriptor> Once(IEnumerable<FeatureDescriptor> featureDescriptors) {
|
||||
var once = new ConcurrentDictionary<string, object>();
|
||||
return featureDescriptors.Select(fd => fd.Extension).Where(ed => once.TryAdd(ed.Id, null)).ToList();
|
||||
}
|
||||
|
||||
public void Discover(ShapeTableBuilder builder) {
|
||||
var availableFeatures = _extensionManager.AvailableFeatures();
|
||||
var activeFeatures = availableFeatures.Where(FeatureIsEnabled);
|
||||
var activeExtensions = Once(activeFeatures);
|
||||
|
||||
var hits = activeExtensions.SelectMany(extensionDescriptor => {
|
||||
var basePath = Path.Combine(extensionDescriptor.Location, extensionDescriptor.Id).Replace(Path.DirectorySeparatorChar, '/');
|
||||
var virtualPath = Path.Combine(basePath, "Styles").Replace(Path.DirectorySeparatorChar, '/');
|
||||
var shapes = _virtualPathProvider.ListFiles(virtualPath)
|
||||
.Select(Path.GetFileName)
|
||||
.Where(fileName => string.Equals(Path.GetExtension(fileName), ".css", System.StringComparison.OrdinalIgnoreCase))
|
||||
.Select(cssFileName => new {
|
||||
fileName = Path.GetFileNameWithoutExtension(cssFileName),
|
||||
fileVirtualPath = Path.Combine(virtualPath, cssFileName).Replace(Path.DirectorySeparatorChar, '/'),
|
||||
shapeType = "Style__" + GetAlternateShapeNameFromFileName(cssFileName),
|
||||
extensionDescriptor
|
||||
});
|
||||
return shapes;
|
||||
});
|
||||
|
||||
foreach (var iter in hits) {
|
||||
var hit = iter;
|
||||
var featureDescriptors = hit.extensionDescriptor.Features.Where(fd => fd.Id == hit.extensionDescriptor.Id);
|
||||
foreach (var featureDescriptor in featureDescriptors) {
|
||||
builder.Describe(iter.shapeType)
|
||||
.From(new Feature {Descriptor = featureDescriptor})
|
||||
.BoundAs(
|
||||
hit.fileVirtualPath,
|
||||
shapeDescriptor => displayContext => {
|
||||
var shape = ((dynamic) displayContext.Value);
|
||||
var output = displayContext.ViewContext.Writer;
|
||||
ResourceDefinition resource = shape.Resource;
|
||||
string condition = shape.Condition;
|
||||
ResourceManager.WriteResource(output, resource, hit.fileVirtualPath, condition);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool FeatureIsEnabled(FeatureDescriptor fd) {
|
||||
return (DefaultExtensionTypes.IsTheme(fd.Extension.ExtensionType) && (fd.Id == "TheAdmin" || fd.Id == "SafeMode")) ||
|
||||
_shellDescriptor.Features.Any(sf => sf.Name == fd.Id);
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,6 +16,9 @@
|
||||
DataTablePrefix = settings.DataTablePrefix;
|
||||
RequestUrlHost = settings.RequestUrlHost;
|
||||
RequestUrlPrefix = settings.RequestUrlPrefix;
|
||||
EncryptionAlgorithm = settings.EncryptionAlgorithm;
|
||||
EncryptionKey = settings.EncryptionKey;
|
||||
EncryptionIV = settings.EncryptionIV;
|
||||
State = settings.State;
|
||||
}
|
||||
|
||||
@@ -28,6 +31,10 @@
|
||||
public string RequestUrlHost { get; set; }
|
||||
public string RequestUrlPrefix { get; set; }
|
||||
|
||||
public string EncryptionAlgorithm { get; set; }
|
||||
public string EncryptionKey { get; set; }
|
||||
public string EncryptionIV { get; set; }
|
||||
|
||||
public TenantState State { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -84,6 +84,15 @@ namespace Orchard.Environment.Configuration {
|
||||
case "RequestUrlPrefix":
|
||||
shellSettings.RequestUrlPrefix = settingFields[1];
|
||||
break;
|
||||
case "EncryptionAlgorithm":
|
||||
shellSettings.EncryptionAlgorithm = settingFields[1];
|
||||
break;
|
||||
case "EncryptionKey":
|
||||
shellSettings.EncryptionKey = settingFields[1];
|
||||
break;
|
||||
case "EncryptionIV":
|
||||
shellSettings.EncryptionIV = settingFields[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,14 +103,18 @@ namespace Orchard.Environment.Configuration {
|
||||
if (settings == null)
|
||||
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\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.DataProvider,
|
||||
settings.DataConnectionString ?? "null",
|
||||
settings.DataTablePrefix ?? "null",
|
||||
settings.RequestUrlHost ?? "null",
|
||||
settings.RequestUrlPrefix ?? "null",
|
||||
settings.State != null ? settings.State.ToString() : String.Empty);
|
||||
settings.State != null ? settings.State.ToString() : String.Empty,
|
||||
settings.EncryptionAlgorithm ?? "null",
|
||||
settings.EncryptionKey ?? "null",
|
||||
settings.EncryptionIV ?? "null"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ namespace Orchard.Environment {
|
||||
_stopping = false;
|
||||
var timer = new Timer();
|
||||
timer.Elapsed += CompileViews;
|
||||
timer.Interval = TimeSpan.FromMilliseconds(100).TotalMilliseconds;
|
||||
timer.Interval = TimeSpan.FromMilliseconds(1500).TotalMilliseconds;
|
||||
timer.AutoReset = false;
|
||||
timer.Start();
|
||||
}
|
||||
@@ -45,6 +45,8 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
private void CompileViews(object sender, ElapsedEventArgs elapsedEventArgs) {
|
||||
var totalTime = new Stopwatch();
|
||||
totalTime.Start();
|
||||
Logger.Information("Starting background compilation of views");
|
||||
((Timer)sender).Stop();
|
||||
|
||||
@@ -57,25 +59,30 @@ namespace Orchard.Environment {
|
||||
"~/Themes/SafeMode/Views",
|
||||
|
||||
// Homepage
|
||||
"~/Themes/TheThemeMachine/Views",
|
||||
"~/Core/Common/Views",
|
||||
"~/Core/Contents/Views",
|
||||
"~/Core/Routable/Views",
|
||||
"~/Core/Contents/Views",
|
||||
"~/Core/Common/Views",
|
||||
"~/Core/Settings/Views",
|
||||
"~/Core/Shapes/Views",
|
||||
"~/Core/Feeds/Views",
|
||||
"~/Modules/Orchard.Tags/Views",
|
||||
"~/Modules/Orchard.Widgets/Views",
|
||||
|
||||
// Dashboard
|
||||
"~/Core/Dashboard/Views",
|
||||
"~/Themes/TheAdmin/Views",
|
||||
|
||||
// Content Items
|
||||
"~/Modules/Orchard.PublishLater/Views",
|
||||
|
||||
// Content Types
|
||||
"~/Modules/Orchard.ContentTypes/Views",
|
||||
|
||||
// "Edit" homepage
|
||||
"~/Modules/TinyMce/Views",
|
||||
"~/Modules/Orchard.Tags/Views",
|
||||
"~/Core/Navigation/Views",
|
||||
|
||||
// Various other admin pages
|
||||
"~/Modules/Orchard.Modules/Views",
|
||||
"~/Core/Settings/Views",
|
||||
"~/Core/Containers/Views",
|
||||
"~/Modules/Orchard.Widgets/Views",
|
||||
"~/Modules/Orchard.Users/Views",
|
||||
"~/Modules/Orchard.Media/Views",
|
||||
"~/Modules/Orchard.Comments/Views",
|
||||
@@ -91,6 +98,7 @@ namespace Orchard.Environment {
|
||||
.DirectoriesToBrowse
|
||||
.SelectMany(folder => GetViewDirectories(folder, context.FileExtensionsToCompile));
|
||||
|
||||
int directoryCount = 0;
|
||||
foreach (var viewDirectory in directories) {
|
||||
if (_stopping) {
|
||||
if (Logger.IsEnabled(LogLevel.Information)) {
|
||||
@@ -104,8 +112,11 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
CompileDirectory(context, viewDirectory);
|
||||
directoryCount++;
|
||||
}
|
||||
Logger.Information("Ending background compilation of views");
|
||||
|
||||
totalTime.Stop();
|
||||
Logger.Information("Ending background compilation of views, {0} directories processed in {1} sec", directoryCount, totalTime.Elapsed.TotalSeconds);
|
||||
}
|
||||
|
||||
private void CompileDirectory(CompilationContext context, string viewDirectory) {
|
||||
@@ -118,7 +129,6 @@ namespace Orchard.Environment {
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
try {
|
||||
|
||||
var firstFile = _virtualPathProvider
|
||||
.ListFiles(viewDirectory)
|
||||
.Where(f => context.FileExtensionsToCompile.Any(e => f.EndsWith(e, StringComparison.OrdinalIgnoreCase)))
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -14,7 +15,7 @@ namespace Orchard.Logging {
|
||||
private readonly IDictionary<string, ILogger> _loggerCache;
|
||||
|
||||
public LoggingModule() {
|
||||
_loggerCache = new Dictionary<string, ILogger>();
|
||||
_loggerCache = new ConcurrentDictionary<string, ILogger>();
|
||||
}
|
||||
|
||||
protected override void Load(ContainerBuilder moduleBuilder) {
|
||||
@@ -78,7 +79,7 @@ namespace Orchard.Logging {
|
||||
else {
|
||||
var propertyValue = ctx.Resolve<ILogger>(new TypedParameter(typeof(Type), componentType));
|
||||
_loggerCache.Add(component, propertyValue);
|
||||
propertyInfo.SetValue(instance, propertyValue, null);
|
||||
propertyInfo.SetValue(instance, propertyValue, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -142,6 +142,8 @@
|
||||
<Compile Include="ContentManagement\DefaultContentDisplay.cs" />
|
||||
<Compile Include="ContentManagement\Drivers\ContentShapeResult.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\BuildShapeContext.cs" />
|
||||
<Compile Include="ContentManagement\Utilities\ComputedField.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ResourceBindingStrategy\StylesheetBindingStrategy.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeDescriptor.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeAlteration.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeAlterationBuilder.cs" />
|
||||
@@ -170,7 +172,9 @@
|
||||
<Compile Include="Mvc\IOrchardViewPage.cs" />
|
||||
<Compile Include="Mvc\Spooling\HtmlStringWriter.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\Razor\IRazorCompilationEvents.cs" />
|
||||
<Compile Include="Security\IEncryptionService.cs" />
|
||||
<Compile Include="Security\CurrentUserWorkContext.cs" />
|
||||
<Compile Include="Security\Providers\DefaultEncryptionService.cs" />
|
||||
<Compile Include="Settings\CurrentSiteWorkContext.cs" />
|
||||
<Compile Include="Settings\ResourceDebugMode.cs" />
|
||||
<Compile Include="Themes\ThemeManager.cs" />
|
||||
|
20
src/Orchard/Security/IEncryptionService.cs
Normal file
20
src/Orchard/Security/IEncryptionService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Orchard.Security {
|
||||
/// <summary>
|
||||
/// Provides encryption services adapted to securing tenant level information
|
||||
/// </summary>
|
||||
public interface IEncryptionService : ISingletonDependency {
|
||||
/// <summary>
|
||||
/// Decodes data that has been encrypted.
|
||||
/// </summary>
|
||||
/// <param name="encodedData">The encrypted data to decrypt.</param>
|
||||
/// <returns>A Byte[] array that represents the decrypted data.</returns>
|
||||
byte[] Decode(byte[] encodedData);
|
||||
|
||||
/// <summary>
|
||||
/// Encrypts data.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to encrypt.</param>
|
||||
/// <returns>The encrypted value.</returns>
|
||||
byte[] Encode(byte[] data);
|
||||
}
|
||||
}
|
62
src/Orchard/Security/Providers/DefaultEncryptionService.cs
Normal file
62
src/Orchard/Security/Providers/DefaultEncryptionService.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Security.Providers {
|
||||
public class DefaultEncryptionService : IEncryptionService {
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private const int SaltSize = 16;
|
||||
|
||||
public DefaultEncryptionService(ShellSettings shellSettings ) {
|
||||
_shellSettings = shellSettings;
|
||||
}
|
||||
|
||||
public byte[] Decode(byte[] encodedData) {
|
||||
using ( var ms = new MemoryStream() ) {
|
||||
using (var algorithm = CreateAlgorithm()) {
|
||||
using ( var cs = new CryptoStream(ms, algorithm.CreateDecryptor(), CryptoStreamMode.Write) ) {
|
||||
cs.Write(encodedData, 0, encodedData.Length);
|
||||
cs.FlushFinalBlock();
|
||||
}
|
||||
|
||||
// remove the salt part
|
||||
return ms.ToArray().Skip(SaltSize).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Encode(byte[] data) {
|
||||
var salt = new byte[SaltSize];
|
||||
|
||||
// generate a random salt to happend to encoded data
|
||||
using ( var random = new RNGCryptoServiceProvider() ) {
|
||||
random.GetBytes(salt);
|
||||
}
|
||||
using ( var ms = new MemoryStream() ) {
|
||||
using (var algorithm = CreateAlgorithm()) {
|
||||
using ( var cs = new CryptoStream(ms, algorithm.CreateEncryptor(), CryptoStreamMode.Write) ) {
|
||||
// append the salt to the data and encrypt
|
||||
var salted = salt.Concat(data).ToArray();
|
||||
cs.Write(salted, 0, salted.Length);
|
||||
cs.FlushFinalBlock();
|
||||
}
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SymmetricAlgorithm CreateAlgorithm() {
|
||||
var encryptionAlgorithm = SymmetricAlgorithm.Create(_shellSettings.EncryptionAlgorithm);
|
||||
|
||||
encryptionAlgorithm.Key = _shellSettings.EncryptionKey.ToByteArray();
|
||||
encryptionAlgorithm.IV = _shellSettings.EncryptionIV.ToByteArray();
|
||||
|
||||
return encryptionAlgorithm;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,20 +4,16 @@ using Orchard.Mvc.Filters;
|
||||
|
||||
namespace Orchard.UI.Resources {
|
||||
public class ResourceFilter : FilterProvider, IResultFilter {
|
||||
private readonly IResourceManager _resourceManager;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly dynamic _shapeFactory;
|
||||
|
||||
public ResourceFilter(
|
||||
IResourceManager resourceManager,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IShapeFactory shapeFactory) {
|
||||
_resourceManager = resourceManager;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_shapeFactory = shapeFactory;
|
||||
}
|
||||
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext filterContext) {
|
||||
// should only run on a full view rendering result
|
||||
if (!(filterContext.Result is ViewResult))
|
||||
@@ -26,11 +22,11 @@ namespace Orchard.UI.Resources {
|
||||
var ctx = _workContextAccessor.GetContext();
|
||||
var head = ctx.Layout.Head;
|
||||
var tail = ctx.Layout.Tail;
|
||||
head.Add(_shapeFactory.Metas().ResourceManager(_resourceManager));
|
||||
head.Add(_shapeFactory.HeadLinks().ResourceManager(_resourceManager));
|
||||
head.Add(_shapeFactory.StylesheetLinks().ResourceManager(_resourceManager));
|
||||
head.Add(_shapeFactory.HeadScripts().ResourceManager(_resourceManager));
|
||||
tail.Add(_shapeFactory.FootScripts().ResourceManager(_resourceManager));
|
||||
head.Add(_shapeFactory.Metas());
|
||||
head.Add(_shapeFactory.HeadLinks());
|
||||
head.Add(_shapeFactory.StylesheetLinks());
|
||||
head.Add(_shapeFactory.HeadScripts());
|
||||
tail.Add(_shapeFactory.FootScripts());
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext) {
|
||||
|
@@ -3,8 +3,10 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Autofac.Features.Metadata;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
@@ -40,6 +42,30 @@ namespace Orchard.UI.Resources {
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
private static TagBuilder GetTagBuilder(ResourceDefinition resource, string url) {
|
||||
var tagBuilder = new TagBuilder(resource.TagName);
|
||||
tagBuilder.MergeAttributes(resource.TagBuilder.Attributes);
|
||||
if (!String.IsNullOrEmpty(resource.FilePathAttributeName)) {
|
||||
if (!String.IsNullOrEmpty(url)) {
|
||||
if (VirtualPathUtility.IsAppRelative(url)) {
|
||||
url = VirtualPathUtility.ToAbsolute(url);
|
||||
}
|
||||
tagBuilder.MergeAttribute(resource.FilePathAttributeName, url, true);
|
||||
}
|
||||
}
|
||||
return tagBuilder;
|
||||
}
|
||||
|
||||
public static void WriteResource(TextWriter writer, ResourceDefinition resource, string url, string condition) {
|
||||
if (!string.IsNullOrEmpty(condition)) {
|
||||
writer.WriteLine("<!--[if " + condition + "]>");
|
||||
}
|
||||
writer.WriteLine(GetTagBuilder(resource, url).ToString(resource.TagRenderMode));
|
||||
if (!string.IsNullOrEmpty(condition)) {
|
||||
writer.WriteLine("<![endif]-->");
|
||||
}
|
||||
}
|
||||
|
||||
public ResourceManager(IEnumerable<Meta<IResourceManifestProvider>> resourceProviders) {
|
||||
_providers = resourceProviders;
|
||||
}
|
||||
|
@@ -6,11 +6,15 @@ namespace Orchard.UI.Resources {
|
||||
public ResourceDefinition Resource { get; set; }
|
||||
public RequireSettings Settings { get; set; }
|
||||
|
||||
public string GetResourceUrl(RequireSettings baseSettings, string appPath) {
|
||||
return Resource.ResolveUrl(baseSettings == null ? Settings : baseSettings.Combine(Settings), appPath);
|
||||
}
|
||||
|
||||
public TagBuilder GetTagBuilder(RequireSettings baseSettings, string appPath) {
|
||||
var tagBuilder = new TagBuilder(Resource.TagName);
|
||||
tagBuilder.MergeAttributes(Resource.TagBuilder.Attributes);
|
||||
if (!String.IsNullOrEmpty(Resource.FilePathAttributeName)) {
|
||||
var resolvedUrl = Resource.ResolveUrl(baseSettings == null ? Settings : baseSettings.Combine(Settings), appPath);
|
||||
var resolvedUrl = GetResourceUrl(baseSettings, appPath);
|
||||
if (!String.IsNullOrEmpty(resolvedUrl)) {
|
||||
tagBuilder.MergeAttribute(Resource.FilePathAttributeName, resolvedUrl, true);
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.Localization;
|
||||
|
||||
@@ -55,5 +56,16 @@ namespace Orchard.Utility.Extensions {
|
||||
? ""
|
||||
: Regex.Replace(text, @"(\r?\n)", replacement, RegexOptions.Singleline);
|
||||
}
|
||||
|
||||
public static string ToHexString(this byte[] bytes) {
|
||||
return BitConverter.ToString(bytes).Replace("-", "");
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(this string hex) {
|
||||
return Enumerable.Range(0, hex.Length).
|
||||
Where(x => 0 == x % 2).
|
||||
Select(x => Convert.ToByte(hex.Substring(x, 2), 16)).
|
||||
ToArray();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user