Skip to content

Commit

Permalink
Merge branch 'issue-4591-Two-stages-enable-SSL' into develop
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/Presentation/Nop.Web.Framework/Migrations/UpgradeTo460/LocalizationMigration.cs
  • Loading branch information
exileDev committed Jul 29, 2022
2 parents ac8cf73 + fc35742 commit 6f3c8b8
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
Expand Up @@ -279,6 +279,12 @@ public override void Up()
["Checkout.VatNumber.Disabled"] = "VAT number can be entered (on the <a href=\"{0}\">customer info page</a>) and used only after registration",
["Checkout.VatNumber.Warning"] = "VAT number is {0}",

//#4591
["Admin.Configuration.Stores.Fields.SslEnabled"] = "SSL",
["Admin.Configuration.Stores.Fields.SslEnabled.Hint"] = "SSL (Secure Socket Layer) is the standard security technology for establishing an encrypted connection between a web server and the browser. This ensures that all data exchanged between web server and browser arrives unchanged.",
["Admin.Configuration.Stores.Ssl.Enable"] = "Enable SSL",
["Admin.Configuration.Stores.Ssl.Disable"] = "Disable SSL",
["Admin.Configuration.Stores.Ssl.Updated"] = "The SSL setting has been successfully changed. Do not forget to synchronize the store URL with the current HTTP protocol.",
}, languageId).Wait();

#endregion
Expand Down
@@ -1,8 +1,11 @@
using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting;
using Nop.Core;
using Nop.Data;

Expand All @@ -18,12 +21,24 @@ public sealed class HttpsRequirementAttribute : TypeFilterAttribute
/// <summary>
/// Create instance of the filter attribute
/// </summary>
public HttpsRequirementAttribute() : base(typeof(HttpsRequirementFilter))
/// <param name="ignore">Whether to ignore the execution of filter actions</param>
public HttpsRequirementAttribute(bool ignore = false) : base(typeof(HttpsRequirementFilter))
{
IgnoreFilter = ignore;
Arguments = new object[] { ignore };
}

#endregion

#region Properties

/// <summary>
/// Gets a value indicating whether to ignore the execution of filter actions
/// </summary>
public bool IgnoreFilter { get; }

#endregion

#region Nested filter

/// <summary>
Expand All @@ -33,17 +48,21 @@ private class HttpsRequirementFilter : IAsyncAuthorizationFilter
{
#region Fields

private readonly bool _ignoreFilter;
private readonly IStoreContext _storeContext;
private readonly IWebHelper _webHelper;
private readonly IWebHostEnvironment _webHostEnvironment;

#endregion

#region Ctor

public HttpsRequirementFilter(IStoreContext storeContext, IWebHelper webHelper)
public HttpsRequirementFilter(bool ignoreFilter, IStoreContext storeContext, IWebHelper webHelper, IWebHostEnvironment webHostEnvironment)
{
_ignoreFilter = ignoreFilter;
_storeContext = storeContext;
_webHelper = webHelper;
_webHostEnvironment = webHostEnvironment;
}

#endregion
Expand All @@ -70,18 +89,31 @@ private async Task CheckHttpsRequirementAsync(AuthorizationFilterContext context
if (!DataSettingsManager.IsDatabaseInstalled())
return;

//check whether this filter has been overridden for the action
var actionFilter = context.ActionDescriptor.FilterDescriptors
.Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
.Select(filterDescriptor => filterDescriptor.Filter)
.OfType<HttpsRequirementAttribute>()
.FirstOrDefault();

if (actionFilter?.IgnoreFilter ?? _ignoreFilter)
return;

var store = await _storeContext.GetCurrentStoreAsync();

//whether current connection is secured
var currentConnectionSecured = _webHelper.IsCurrentConnectionSecured();

//link caching can cause unstable behavior in development environments, when we use permanent redirects
var isPermanent = !_webHostEnvironment.IsDevelopment();

//page should be secured, so redirect (permanent) to HTTPS version of page
if (store.SslEnabled && !currentConnectionSecured)
context.Result = new RedirectResult(_webHelper.GetThisPageUrl(true, true), true);
context.Result = new RedirectResult(_webHelper.GetThisPageUrl(true, true), isPermanent);

//page shouldn't be secured, so redirect (permanent) to HTTP version of page
if (!store.SslEnabled && currentConnectionSecured)
context.Result = new RedirectResult(_webHelper.GetThisPageUrl(true, false), true);
context.Result = new RedirectResult(_webHelper.GetThisPageUrl(true, false), isPermanent);
}

#endregion
Expand Down
Expand Up @@ -9604,10 +9604,10 @@
<Value>Please provide a name.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Fields.SslEnabled">
<Value>SSL enabled</Value>
<Value>SSL</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Fields.SslEnabled.Hint">
<Value>Check if your store will be SSL secured. SSL (Secure Socket Layer) is the standard security technology for establishing an encrypted connection between a web server and the browser. This ensures that all data exchanged between web server and browser arrives unchanged.</Value>
<Value>SSL (Secure Socket Layer) is the standard security technology for establishing an encrypted connection between a web server and the browser. This ensures that all data exchanged between web server and browser arrives unchanged.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Fields.SslEnabled.Hint2">
<Value>WARNING: Do not enable it until you have SSL certificate installed on the server.</Value>
Expand All @@ -9621,6 +9621,15 @@
<LocaleResource Name="Admin.Configuration.Stores.Fields.Url.Required">
<Value>Please provide a store URL.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Ssl.Disable">
<Value>Disable SSL</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Ssl.Enable">
<Value>Enable SSL</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Ssl.Updated">
<Value>The SSL setting has been successfully changed. Do not forget to synchronize the store URL with the current HTTP protocol.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Configuration.Stores.Updated">
<Value>The store has been updated successfully.</Value>
</LocaleResource>
Expand Down
Expand Up @@ -33,6 +33,7 @@ public partial class StoreController : BaseAdminController
private readonly IStoreModelFactory _storeModelFactory;
private readonly IStoreService _storeService;
private readonly IGenericAttributeService _genericAttributeService;
private readonly IWebHelper _webHelper;
private readonly IWorkContext _workContext;

#endregion
Expand All @@ -48,6 +49,7 @@ public partial class StoreController : BaseAdminController
IStoreModelFactory storeModelFactory,
IStoreService storeService,
IGenericAttributeService genericAttributeService,
IWebHelper webHelper,
IWorkContext workContext)
{
_customerActivityService = customerActivityService;
Expand All @@ -59,6 +61,7 @@ public partial class StoreController : BaseAdminController
_storeModelFactory = storeModelFactory;
_storeService = storeService;
_genericAttributeService = genericAttributeService;
_webHelper = webHelper;
_workContext = workContext;

}
Expand Down Expand Up @@ -151,6 +154,31 @@ public virtual async Task<IActionResult> Create(StoreModel model, bool continueE
return View(model);
}

[HttpsRequirement(true)]
public virtual async Task<IActionResult> SetStoreSslByCurrentRequestScheme(int id)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageStores))
return AccessDeniedView();

//try to get a store with the specified id
var store = await _storeService.GetStoreByIdAsync(id);
if (store == null)
return RedirectToAction("List");

var value = _webHelper.IsCurrentConnectionSecured();

if (store.SslEnabled != value)
{
store.SslEnabled = value;
await _storeService.UpdateStoreAsync(store);

_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Configuration.Stores.Ssl.Updated"));
}

return RedirectToAction("Edit", new { id = id });
}

[HttpsRequirement(true)]
public virtual async Task<IActionResult> Edit(int id, bool showtour = false)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageStores))
Expand Down
Expand Up @@ -61,7 +61,12 @@
<nop-label asp-for="SslEnabled" />
</div>
<div class="col-md-9">
<nop-editor asp-for="SslEnabled" />
<a class="btn bg-olive"
asp-protocol="@(Model.SslEnabled ? Uri.UriSchemeHttp : Uri.UriSchemeHttps)"
asp-action="SetStoreSslByCurrentRequestScheme"
asp-route-id="@Model.Id">
@(Model.SslEnabled ? T("Admin.Configuration.Stores.Ssl.Disable") : T("Admin.Configuration.Stores.Ssl.Enable"))
</a>
<div><em>@T("Admin.Configuration.Stores.Fields.SslEnabled.Hint2")</em></div>
<span asp-validation-for="SslEnabled"></span>
</div>
Expand Down

0 comments on commit 6f3c8b8

Please sign in to comment.