mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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,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;
|
||||
|
Reference in New Issue
Block a user