mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Merge branch 'dev' into feature/recipesteps
This commit is contained in:
@@ -4,6 +4,10 @@ Orchard is a free, open source, community-focused Content Management System buil
|
|||||||
|
|
||||||
[](https://gitter.im/OrchardCMS/Orchard?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/OrchardCMS/Orchard?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
|
You can try it for free on [Dotnest.com](https://dotnest.com) or on Microsoft Azure by clicking on this button
|
||||||
|
|
||||||
|
[](https://ms.portal.azure.com/#create/OutercurveFoundation.OrchardCMS.0.5.9)
|
||||||
|
|
||||||
## About The Orchard Project
|
## About The Orchard Project
|
||||||
|
|
||||||
#### Please visit our website at http://orchardproject.net for the most current information about this project.
|
#### Please visit our website at http://orchardproject.net for the most current information about this project.
|
||||||
|
|||||||
@@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
public const string ShellSettingsStorageConnectionStringSettingName = "Orchard.Azure.Settings.StorageConnectionString";
|
public const string ShellSettingsStorageConnectionStringSettingName = "Orchard.Azure.Settings.StorageConnectionString";
|
||||||
public const string ShellSettingsContainerName = "sites"; // Container names must be lower case.
|
public const string ShellSettingsContainerNameSettingName = "Orchard.Azure.Settings.ContainerName";
|
||||||
|
public const string ShellSettingsDefaultContainerName = "sites"; // Container names must be lower case.
|
||||||
public const string ShellSettingsFileName = "Settings.txt";
|
public const string ShellSettingsFileName = "Settings.txt";
|
||||||
|
|
||||||
public const string MediaStorageFeatureName = "Orchard.Azure.Media";
|
public const string MediaStorageFeatureName = "Orchard.Azure.Media";
|
||||||
public const string MediaStorageStorageConnectionStringSettingName = "Orchard.Azure.Media.StorageConnectionString";
|
public const string MediaStorageStorageConnectionStringSettingName = "Orchard.Azure.Media.StorageConnectionString";
|
||||||
public const string MediaStorageRootFolderPathSettingName = "Orchard.Azure.Media.RootFolderPath";
|
public const string MediaStorageRootFolderPathSettingName = "Orchard.Azure.Media.RootFolderPath";
|
||||||
public const string MediaStorageContainerName = "media"; // Container names must be lower case.
|
public const string MediaStorageContainerNameSettingName = "Orchard.Azure.Media.ContainerName";
|
||||||
|
public const string MediaStorageDefaultContainerName = "media"; // Container names must be lower case.
|
||||||
public const string MediaStoragePublicHostName = "Orchard.Azure.Media.StoragePublicHostName";
|
public const string MediaStoragePublicHostName = "Orchard.Azure.Media.StoragePublicHostName";
|
||||||
|
|
||||||
public const string OutputCacheFeatureName = "Orchard.Azure.OutputCache";
|
public const string OutputCacheFeatureName = "Orchard.Azure.OutputCache";
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ namespace Orchard.Azure.Services.Environment.Configuration {
|
|||||||
private readonly IShellSettingsManagerEventHandler _events;
|
private readonly IShellSettingsManagerEventHandler _events;
|
||||||
|
|
||||||
public AzureBlobShellSettingsManager(IMimeTypeProvider mimeTypeProvider, IShellSettingsManagerEventHandler events) {
|
public AzureBlobShellSettingsManager(IMimeTypeProvider mimeTypeProvider, IShellSettingsManagerEventHandler events) {
|
||||||
_fileSystem = new AzureFileSystem(CloudConfigurationManager.GetSetting(Constants.ShellSettingsStorageConnectionStringSettingName), Constants.ShellSettingsContainerName, String.Empty, true, mimeTypeProvider);
|
var connectionString = CloudConfigurationManager.GetSetting(Constants.ShellSettingsStorageConnectionStringSettingName);
|
||||||
|
var containerName = CloudConfigurationManager.GetSetting(Constants.ShellSettingsContainerNameSettingName);
|
||||||
|
if (String.IsNullOrEmpty(containerName))
|
||||||
|
containerName = Constants.ShellSettingsDefaultContainerName;
|
||||||
|
_fileSystem = new AzureFileSystem(connectionString, containerName, String.Empty, true, mimeTypeProvider);
|
||||||
_events = events;
|
_events = events;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,15 @@ namespace Orchard.Azure.Services.FileSystems.Media {
|
|||||||
[OrchardSuppressDependency("Orchard.FileSystems.Media.FileSystemStorageProvider")]
|
[OrchardSuppressDependency("Orchard.FileSystems.Media.FileSystemStorageProvider")]
|
||||||
public class AzureBlobStorageProvider : AzureFileSystem, IStorageProvider {
|
public class AzureBlobStorageProvider : AzureFileSystem, IStorageProvider {
|
||||||
|
|
||||||
public AzureBlobStorageProvider(ShellSettings shellSettings, IMimeTypeProvider mimeTypeProvider, IPlatformConfigurationAccessor pca)
|
public AzureBlobStorageProvider(
|
||||||
: this(pca.GetSetting(Constants.MediaStorageStorageConnectionStringSettingName, shellSettings.Name, null),
|
ShellSettings shellSettings,
|
||||||
Constants.MediaStorageContainerName,
|
IMimeTypeProvider mimeTypeProvider,
|
||||||
pca.GetSetting(Constants.MediaStorageRootFolderPathSettingName, shellSettings.Name, null) ?? shellSettings.Name,
|
IPlatformConfigurationAccessor platformConfigurationAccessor)
|
||||||
|
: this(platformConfigurationAccessor.GetSetting(Constants.MediaStorageStorageConnectionStringSettingName, shellSettings.Name, null),
|
||||||
|
platformConfigurationAccessor.GetSetting(Constants.MediaStorageContainerNameSettingName, shellSettings.Name, null) ?? Constants.MediaStorageDefaultContainerName,
|
||||||
|
platformConfigurationAccessor.GetSetting(Constants.MediaStorageRootFolderPathSettingName, shellSettings.Name, null) ?? shellSettings.Name,
|
||||||
mimeTypeProvider,
|
mimeTypeProvider,
|
||||||
pca.GetSetting(Constants.MediaStoragePublicHostName, shellSettings.Name, null))
|
platformConfigurationAccessor.GetSetting(Constants.MediaStoragePublicHostName, shellSettings.Name, null))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
(function($) {
|
(function($) {
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("select.recipe").change(function() { // class="recipe" on the select element
|
$("select.recipe").change(function() { // class="recipe" on the select element
|
||||||
var description = $(this).find(":selected").attr("recipedescription"); // reads the html attribute of the selected option
|
var description = $(this).find(":selected").data("recipe-description"); // reads the html attribute of the selected option
|
||||||
$("#recipedescription").text(description); // make the contents of <div id="recipe-description"></div> be the escaped description string
|
$("#recipedescription").text(description); // make the contents of <div id="recipe-description"></div> be the escaped description string
|
||||||
});
|
});
|
||||||
$(".data").find('input[name=DatabaseProvider]:checked').click();
|
$(".data").find('input[name=DatabaseProvider]:checked').click();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@model Orchard.Setup.ViewModels.SetupViewModel
|
@model Orchard.Setup.ViewModels.SetupViewModel
|
||||||
|
@using Orchard.Recipes.Models;
|
||||||
@{
|
@{
|
||||||
Script.Require("jQuery");
|
Script.Require("jQuery");
|
||||||
Script.Require("ShapesBase");
|
Script.Require("ShapesBase");
|
||||||
@@ -8,6 +9,18 @@
|
|||||||
var groupedRecipes = Model.Recipes.Where(x => !String.IsNullOrWhiteSpace(x.Category)).GroupBy(x => x.Category);
|
var groupedRecipes = Model.Recipes.Where(x => !String.IsNullOrWhiteSpace(x.Category)).GroupBy(x => x.Category);
|
||||||
var unspecifiedCategoryRecipes = Model.Recipes.Where(x => String.IsNullOrWhiteSpace(x.Category)).ToList();
|
var unspecifiedCategoryRecipes = Model.Recipes.Where(x => String.IsNullOrWhiteSpace(x.Category)).ToList();
|
||||||
}
|
}
|
||||||
|
@helper RenderRecipeOptions(IEnumerable<Recipe> recipes) {
|
||||||
|
foreach (var recipe in recipes) {
|
||||||
|
var optionAttributes = new RouteValueDictionary {
|
||||||
|
{ "data-recipe-description", recipe.Description }
|
||||||
|
};
|
||||||
|
if (Model.Recipe == null && recipe.Name == "Default") {
|
||||||
|
optionAttributes["selected"] = "selected";
|
||||||
|
}
|
||||||
|
@Html.SelectOption(Model.Recipe, recipe.Name, recipe.Name, optionAttributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
<h1>@Html.TitleForPage(T("Get Started").ToString())</h1>
|
<h1>@Html.TitleForPage(T("Get Started").ToString())</h1>
|
||||||
|
|
||||||
@using (Html.BeginFormAntiForgeryPost()) {
|
@using (Html.BeginFormAntiForgeryPost()) {
|
||||||
@@ -83,17 +96,13 @@ if (!Model.DatabaseIsPreconfigured) {
|
|||||||
if (groupedRecipes.Count() > 1) {
|
if (groupedRecipes.Count() > 1) {
|
||||||
<optgroup label="@recipeGroup.Key"></optgroup>
|
<optgroup label="@recipeGroup.Key"></optgroup>
|
||||||
}
|
}
|
||||||
foreach (var recipe in recipeGroup.OrderBy(x => x.Name)) {
|
@RenderRecipeOptions(recipeGroup.OrderBy(x => x.Name))
|
||||||
@Html.SelectOption(Model.Recipe, recipe.Name, recipe.Name, new { recipedescription = recipe.Description })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@if (unspecifiedCategoryRecipes.Any()) {
|
@if (unspecifiedCategoryRecipes.Any()) {
|
||||||
if (groupedRecipes.Any()) {
|
if (groupedRecipes.Any()) {
|
||||||
<optgroup label="@T("Unspecified")"></optgroup>
|
<optgroup label="@T("Unspecified")"></optgroup>
|
||||||
}
|
}
|
||||||
foreach (var recipe in unspecifiedCategoryRecipes.OrderBy(x => x.Name)) {
|
@RenderRecipeOptions(unspecifiedCategoryRecipes.OrderBy(x => x.Name))
|
||||||
@Html.SelectOption(Model.Recipe, recipe.Name, recipe.Name, new { recipedescription = recipe.Description })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ using System.Collections.Generic;
|
|||||||
using Orchard.Services;
|
using Orchard.Services;
|
||||||
using System.Web.Helpers;
|
using System.Web.Helpers;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
|
using Orchard.Environment.Extensions;
|
||||||
|
|
||||||
namespace Orchard.Users.Services {
|
namespace Orchard.Users.Services {
|
||||||
|
[OrchardSuppressDependency("Orchard.Security.NullMembershipService")]
|
||||||
public class MembershipService : IMembershipService {
|
public class MembershipService : IMembershipService {
|
||||||
private const string PBKDF2 = "PBKDF2";
|
private const string PBKDF2 = "PBKDF2";
|
||||||
private const string DefaultHashAlgorithm = PBKDF2;
|
private const string DefaultHashAlgorithm = PBKDF2;
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ namespace Orchard.Mvc.Html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MvcHtmlString SelectOption<T>(this HtmlHelper html, T currentValue, T optionValue, string text, object htmlAttributes) {
|
public static MvcHtmlString SelectOption<T>(this HtmlHelper html, T currentValue, T optionValue, string text, object htmlAttributes) {
|
||||||
|
return SelectOption(html, optionValue, object.Equals(optionValue, currentValue), text, new RouteValueDictionary(htmlAttributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MvcHtmlString SelectOption<T>(this HtmlHelper html, T currentValue, T optionValue, string text, RouteValueDictionary htmlAttributes) {
|
||||||
return SelectOption(html, optionValue, object.Equals(optionValue, currentValue), text, htmlAttributes);
|
return SelectOption(html, optionValue, object.Equals(optionValue, currentValue), text, htmlAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +64,10 @@ namespace Orchard.Mvc.Html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MvcHtmlString SelectOption(this HtmlHelper html, object optionValue, bool selected, string text, object htmlAttributes) {
|
public static MvcHtmlString SelectOption(this HtmlHelper html, object optionValue, bool selected, string text, object htmlAttributes) {
|
||||||
|
return SelectOption(html, optionValue, selected, text, new RouteValueDictionary(htmlAttributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MvcHtmlString SelectOption(this HtmlHelper html, object optionValue, bool selected, string text, RouteValueDictionary htmlAttributes) {
|
||||||
var builder = new TagBuilder("option");
|
var builder = new TagBuilder("option");
|
||||||
|
|
||||||
if (optionValue != null)
|
if (optionValue != null)
|
||||||
@@ -71,7 +79,7 @@ namespace Orchard.Mvc.Html {
|
|||||||
builder.SetInnerText(text);
|
builder.SetInnerText(text);
|
||||||
|
|
||||||
if (htmlAttributes != null) {
|
if (htmlAttributes != null) {
|
||||||
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
|
builder.MergeAttributes(htmlAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal));
|
return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal));
|
||||||
|
|||||||
@@ -181,6 +181,7 @@
|
|||||||
<Compile Include="Localization\Services\ILocalizationStreamParser.cs" />
|
<Compile Include="Localization\Services\ILocalizationStreamParser.cs" />
|
||||||
<Compile Include="Localization\Services\LocalizationStreamParser.cs" />
|
<Compile Include="Localization\Services\LocalizationStreamParser.cs" />
|
||||||
<Compile Include="Security\ISslSettingsProvider.cs" />
|
<Compile Include="Security\ISslSettingsProvider.cs" />
|
||||||
|
<Compile Include="Security\NullMembershipService.cs" />
|
||||||
<Compile Include="Security\Providers\DefaultSslSettingsProvider.cs" />
|
<Compile Include="Security\Providers\DefaultSslSettingsProvider.cs" />
|
||||||
<Compile Include="Security\Providers\DefaultMembershipValidationService.cs" />
|
<Compile Include="Security\Providers\DefaultMembershipValidationService.cs" />
|
||||||
<Compile Include="StaticHttpContextScope.cs" />
|
<Compile Include="StaticHttpContextScope.cs" />
|
||||||
|
|||||||
30
src/Orchard/Security/NullMembershipService.cs
Normal file
30
src/Orchard/Security/NullMembershipService.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Orchard.Security {
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a default implementation of <c>IMembershipService</c> used only for dependency resolution
|
||||||
|
/// in a setup context. No members on this implementation will ever be called; at the time when this
|
||||||
|
/// interface is actually used in a tenant, another implementation is assumed to have suppressed it.
|
||||||
|
/// </summary>
|
||||||
|
public class NullMembershipService : IMembershipService {
|
||||||
|
public IUser CreateUser(CreateUserParams createUserParams) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MembershipSettings GetSettings() {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUser GetUser(string username) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPassword(IUser user, string password) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUser ValidateUser(string userNameOrEmail, string password) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,16 +3,18 @@ using System.Web;
|
|||||||
using System.Web.Security;
|
using System.Web.Security;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.Mvc;
|
using Orchard.Mvc;
|
||||||
using Orchard.Mvc.Extensions;
|
using Orchard.Mvc.Extensions;
|
||||||
using Orchard.Services;
|
using Orchard.Services;
|
||||||
|
using Orchard.Utility.Extensions;
|
||||||
|
|
||||||
namespace Orchard.Security.Providers {
|
namespace Orchard.Security.Providers {
|
||||||
public class FormsAuthenticationService : IAuthenticationService {
|
public class FormsAuthenticationService : IAuthenticationService {
|
||||||
|
private const int _cookieVersion = 3;
|
||||||
|
|
||||||
private readonly ShellSettings _settings;
|
private readonly ShellSettings _settings;
|
||||||
private readonly IClock _clock;
|
private readonly IClock _clock;
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IMembershipService _membershipService;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
private readonly ISslSettingsProvider _sslSettingsProvider;
|
private readonly ISslSettingsProvider _sslSettingsProvider;
|
||||||
private readonly IMembershipValidationService _membershipValidationService;
|
private readonly IMembershipValidationService _membershipValidationService;
|
||||||
@@ -23,13 +25,13 @@ namespace Orchard.Security.Providers {
|
|||||||
public FormsAuthenticationService(
|
public FormsAuthenticationService(
|
||||||
ShellSettings settings,
|
ShellSettings settings,
|
||||||
IClock clock,
|
IClock clock,
|
||||||
IContentManager contentManager,
|
IMembershipService membershipService,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
ISslSettingsProvider sslSettingsProvider,
|
ISslSettingsProvider sslSettingsProvider,
|
||||||
IMembershipValidationService membershipValidationService) {
|
IMembershipValidationService membershipValidationService) {
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_clock = clock;
|
_clock = clock;
|
||||||
_contentManager = contentManager;
|
_membershipService = membershipService;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
_sslSettingsProvider = sslSettingsProvider;
|
_sslSettingsProvider = sslSettingsProvider;
|
||||||
_membershipValidationService = membershipValidationService;
|
_membershipValidationService = membershipValidationService;
|
||||||
@@ -46,11 +48,12 @@ namespace Orchard.Security.Providers {
|
|||||||
public void SignIn(IUser user, bool createPersistentCookie) {
|
public void SignIn(IUser user, bool createPersistentCookie) {
|
||||||
var now = _clock.UtcNow.ToLocalTime();
|
var now = _clock.UtcNow.ToLocalTime();
|
||||||
|
|
||||||
// the cookie user data is {userId};{tenant}
|
// The cookie user data is "{userName.Base64};{tenant}".
|
||||||
var userData = String.Concat(Convert.ToString(user.Id), ";", _settings.Name);
|
// The username is encoded to Base64 to prevent collisions with the ';' seprarator.
|
||||||
|
var userData = String.Concat(user.UserName.ToBase64(), ";", _settings.Name);
|
||||||
|
|
||||||
var ticket = new FormsAuthenticationTicket(
|
var ticket = new FormsAuthenticationTicket(
|
||||||
1 /*version*/,
|
_cookieVersion,
|
||||||
user.UserName,
|
user.UserName,
|
||||||
now,
|
now,
|
||||||
now.Add(ExpirationTimeSpan),
|
now.Add(ExpirationTimeSpan),
|
||||||
@@ -121,29 +124,28 @@ namespace Orchard.Security.Providers {
|
|||||||
var formsIdentity = (FormsIdentity)httpContext.User.Identity;
|
var formsIdentity = (FormsIdentity)httpContext.User.Identity;
|
||||||
var userData = formsIdentity.Ticket.UserData ?? "";
|
var userData = formsIdentity.Ticket.UserData ?? "";
|
||||||
|
|
||||||
// the cookie user data is {userId};{tenant}
|
// The cookie user data is {userName.Base64};{tenant}.
|
||||||
var userDataSegments = userData.Split(';');
|
var userDataSegments = userData.Split(';');
|
||||||
|
|
||||||
if (userDataSegments.Length < 2) {
|
if (userDataSegments.Length < 2) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userDataId = userDataSegments[0];
|
var userDataName = userDataSegments[0];
|
||||||
var userDataTenant = userDataSegments[1];
|
var userDataTenant = userDataSegments[1];
|
||||||
|
|
||||||
|
try {
|
||||||
|
userDataName = userDataName.FromBase64();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!String.Equals(userDataTenant, _settings.Name, StringComparison.Ordinal)) {
|
if (!String.Equals(userDataTenant, _settings.Name, StringComparison.Ordinal)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int userId;
|
_signedInUser = _membershipService.GetUser(userDataName);
|
||||||
if (!int.TryParse(userDataId, out userId)) {
|
|
||||||
Logger.Error("User id not a parsable integer");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: this issues a sql query for each authenticated request
|
|
||||||
_signedInUser = _contentManager.Get(userId).As<IUser>();
|
|
||||||
|
|
||||||
if (_signedInUser == null || !_membershipValidationService.CanAuthenticateWithCookie(_signedInUser)) {
|
if (_signedInUser == null || !_membershipValidationService.CanAuthenticateWithCookie(_signedInUser)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user