Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move GenerateOrderGuidAsync to IOrderProcessingService #7469

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Libraries/Nop.Services/Orders/IOrderProcessingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,10 @@ public partial interface IOrderProcessingService
/// <param name="recurringPayment">Recurring payment</param>
/// <returns>A task that represents the asynchronous operation</returns>
Task<int> GetCyclesRemainingAsync(RecurringPayment recurringPayment);

/// <summary>
/// Generate an order GUID
/// </summary>
/// <param name="processPaymentRequest">Process payment request</param>
Task GenerateOrderGuidAsync(ProcessPaymentRequest processPaymentRequest);
}
37 changes: 37 additions & 0 deletions src/Libraries/Nop.Services/Orders/OrderProcessingService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Globalization;
using Microsoft.AspNetCore.Http;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain.Catalog;
Expand All @@ -14,6 +15,7 @@
using Nop.Core.Domain.Tax;
using Nop.Core.Domain.Vendors;
using Nop.Core.Events;
using Nop.Core.Http.Extensions;
using Nop.Services.Affiliates;
using Nop.Services.Catalog;
using Nop.Services.Common;
Expand Down Expand Up @@ -53,6 +55,7 @@ public partial class OrderProcessingService : IOrderProcessingService
protected readonly IEventPublisher _eventPublisher;
protected readonly IGenericAttributeService _genericAttributeService;
protected readonly IGiftCardService _giftCardService;
protected readonly IHttpContextAccessor _httpContextAccessor;
protected readonly ILanguageService _languageService;
protected readonly ILocalizationService _localizationService;
protected readonly ILogger _logger;
Expand Down Expand Up @@ -105,6 +108,7 @@ public OrderProcessingService(CurrencySettings currencySettings,
IEventPublisher eventPublisher,
IGenericAttributeService genericAttributeService,
IGiftCardService giftCardService,
IHttpContextAccessor httpContextAccessor,
ILanguageService languageService,
ILocalizationService localizationService,
ILogger logger,
Expand Down Expand Up @@ -153,6 +157,7 @@ public OrderProcessingService(CurrencySettings currencySettings,
_eventPublisher = eventPublisher;
_genericAttributeService = genericAttributeService;
_giftCardService = giftCardService;
_httpContextAccessor = httpContextAccessor;
_languageService = languageService;
_localizationService = localizationService;
_logger = logger;
Expand Down Expand Up @@ -3231,6 +3236,38 @@ public virtual async Task<int> GetCyclesRemainingAsync(RecurringPayment recurrin
return result;
}

/// <summary>
/// Generate an order GUID
/// </summary>
/// <param name="processPaymentRequest">Process payment request</param>
public virtual async Task GenerateOrderGuidAsync(ProcessPaymentRequest processPaymentRequest)
{
if (processPaymentRequest == null)
return;

//we should use the same GUID for multiple payment attempts
//this way a payment gateway can prevent security issues such as credit card brute-force attacks
//in order to avoid any possible limitations by payment gateway we reset GUID periodically
var previousPaymentRequest = await _httpContextAccessor.HttpContext.Session.GetAsync<ProcessPaymentRequest>("OrderPaymentInfo");
if (_paymentSettings.RegenerateOrderGuidInterval > 0 &&
previousPaymentRequest != null &&
previousPaymentRequest.OrderGuidGeneratedOnUtc.HasValue)
{
var interval = DateTime.UtcNow - previousPaymentRequest.OrderGuidGeneratedOnUtc.Value;
if (interval.TotalSeconds < _paymentSettings.RegenerateOrderGuidInterval)
{
processPaymentRequest.OrderGuid = previousPaymentRequest.OrderGuid;
processPaymentRequest.OrderGuidGeneratedOnUtc = previousPaymentRequest.OrderGuidGeneratedOnUtc;
}
}

if (processPaymentRequest.OrderGuid == Guid.Empty)
{
processPaymentRequest.OrderGuid = Guid.NewGuid();
processPaymentRequest.OrderGuidGeneratedOnUtc = DateTime.UtcNow;
}
}

#endregion

#region Nested class
Expand Down
6 changes: 0 additions & 6 deletions src/Libraries/Nop.Services/Payments/IPaymentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,4 @@ public partial interface IPaymentService
/// <param name="order">Order</param>
/// <returns>Serialized CustomValues CustomValues</returns>
Dictionary<string, object> DeserializeCustomValues(Order order);

/// <summary>
/// Generate an order GUID
/// </summary>
/// <param name="processPaymentRequest">Process payment request</param>
Task GenerateOrderGuidAsync(ProcessPaymentRequest processPaymentRequest);
}
37 changes: 0 additions & 37 deletions src/Libraries/Nop.Services/Payments/PaymentService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System.Xml;
using System.Xml.Serialization;
using Microsoft.AspNetCore.Http;
using Nop.Core;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Payments;
using Nop.Core.Http.Extensions;
using Nop.Services.Catalog;
using Nop.Services.Customers;

Expand All @@ -18,7 +16,6 @@ public partial class PaymentService : IPaymentService
#region Fields

protected readonly ICustomerService _customerService;
protected readonly IHttpContextAccessor _httpContextAccessor;
protected readonly IPaymentPluginManager _paymentPluginManager;
protected readonly IPriceCalculationService _priceCalculationService;
protected readonly PaymentSettings _paymentSettings;
Expand All @@ -29,14 +26,12 @@ public partial class PaymentService : IPaymentService
#region Ctor

public PaymentService(ICustomerService customerService,
IHttpContextAccessor httpContextAccessor,
IPaymentPluginManager paymentPluginManager,
IPriceCalculationService priceCalculationService,
PaymentSettings paymentSettings,
ShoppingCartSettings shoppingCartSettings)
{
_customerService = customerService;
_httpContextAccessor = httpContextAccessor;
_paymentPluginManager = paymentPluginManager;
_priceCalculationService = priceCalculationService;
_paymentSettings = paymentSettings;
Expand Down Expand Up @@ -415,37 +410,5 @@ public virtual Dictionary<string, object> DeserializeCustomValues(Order order)
return [];
}

/// <summary>
/// Generate an order GUID
/// </summary>
/// <param name="processPaymentRequest">Process payment request</param>
public virtual async Task GenerateOrderGuidAsync(ProcessPaymentRequest processPaymentRequest)
{
if (processPaymentRequest == null)
return;

//we should use the same GUID for multiple payment attempts
//this way a payment gateway can prevent security issues such as credit card brute-force attacks
//in order to avoid any possible limitations by payment gateway we reset GUID periodically
var previousPaymentRequest = await _httpContextAccessor.HttpContext.Session.GetAsync<ProcessPaymentRequest>("OrderPaymentInfo");
if (_paymentSettings.RegenerateOrderGuidInterval > 0 &&
previousPaymentRequest != null &&
previousPaymentRequest.OrderGuidGeneratedOnUtc.HasValue)
{
var interval = DateTime.UtcNow - previousPaymentRequest.OrderGuidGeneratedOnUtc.Value;
if (interval.TotalSeconds < _paymentSettings.RegenerateOrderGuidInterval)
{
processPaymentRequest.OrderGuid = previousPaymentRequest.OrderGuid;
processPaymentRequest.OrderGuidGeneratedOnUtc = previousPaymentRequest.OrderGuidGeneratedOnUtc;
}
}

if (processPaymentRequest.OrderGuid == Guid.Empty)
{
processPaymentRequest.OrderGuid = Guid.NewGuid();
processPaymentRequest.OrderGuidGeneratedOnUtc = DateTime.UtcNow;
}
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ public static bool IsConnected(PayPalCommerceSettings settings)
if (paymentRequest is null || order is null)
{
paymentRequest = new();
await _paymentService.GenerateOrderGuidAsync(paymentRequest);
await _orderProcessingService.GenerateOrderGuidAsync(paymentRequest);
}
var orderGuid = paymentRequest.OrderGuid.ToString();

Expand Down
8 changes: 4 additions & 4 deletions src/Presentation/Nop.Web/Controllers/CheckoutController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ public virtual async Task<IActionResult> EnterPaymentInfo(IFormCollection form)
//get payment info
var paymentInfo = await paymentMethod.GetPaymentInfoAsync(form);
//set previous order GUID (if exists)
await _paymentService.GenerateOrderGuidAsync(paymentInfo);
await _orderProcessingService.GenerateOrderGuidAsync(paymentInfo);

//session save
await HttpContext.Session.SetAsync("OrderPaymentInfo", paymentInfo);
Expand Down Expand Up @@ -1307,7 +1307,7 @@ public virtual async Task<IActionResult> ConfirmOrder(bool captchaValid)

processPaymentRequest = new ProcessPaymentRequest();
}
await _paymentService.GenerateOrderGuidAsync(processPaymentRequest);
await _orderProcessingService.GenerateOrderGuidAsync(processPaymentRequest);
processPaymentRequest.StoreId = store.Id;
processPaymentRequest.CustomerId = customer.Id;
processPaymentRequest.PaymentMethodSystemName = await _genericAttributeService.GetAttributeAsync<string>(customer,
Expand Down Expand Up @@ -1972,7 +1972,7 @@ public virtual async Task<IActionResult> OpcSavePaymentInfo(IFormCollection form
//get payment info
var paymentInfo = await paymentMethod.GetPaymentInfoAsync(form);
//set previous order GUID (if exists)
await _paymentService.GenerateOrderGuidAsync(paymentInfo);
await _orderProcessingService.GenerateOrderGuidAsync(paymentInfo);

//session save
await HttpContext.Session.SetAsync("OrderPaymentInfo", paymentInfo);
Expand Down Expand Up @@ -2058,7 +2058,7 @@ public virtual async Task<IActionResult> OpcConfirmOrder(bool captchaValid)

processPaymentRequest = new ProcessPaymentRequest();
}
await _paymentService.GenerateOrderGuidAsync(processPaymentRequest);
await _orderProcessingService.GenerateOrderGuidAsync(processPaymentRequest);
processPaymentRequest.StoreId = store.Id;
processPaymentRequest.CustomerId = customer.Id;
processPaymentRequest.PaymentMethodSystemName = await _genericAttributeService.GetAttributeAsync<string>(customer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Payments;
using Nop.Core.Domain.Shipping;
using Nop.Core.Http.Extensions;
using Nop.Data;
using Nop.Services.Orders;
using Nop.Services.Payments;
using Nop.Tests.Nop.Services.Tests.Payments;
using NUnit.Framework;

Expand All @@ -15,12 +18,14 @@ public class OrderProcessingServiceTests : ServiceTest
{
private IOrderService _orderService;
private IOrderProcessingService _orderProcessingService;
private IHttpContextAccessor _httpContextAccessor;

[OneTimeSetUp]
public void SetUp()
{
_orderService = GetService<IOrderService>();
_orderProcessingService = GetService<IOrderProcessingService>();
_httpContextAccessor = GetService<IHttpContextAccessor>();
}

[OneTimeTearDown]
Expand All @@ -34,6 +39,29 @@ public async Task TearDown()
await GetService<IRepository<RecurringPayment>>().TruncateAsync();
}

[Test]
public async Task CanGenerateOrderGuid()
{
var request = new ProcessPaymentRequest();
request.OrderGuid.Should().Be(Guid.Empty);
await _orderProcessingService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().NotBe(Guid.Empty);
var oldGuid = request.OrderGuid;
await _orderProcessingService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().Be(oldGuid);
request = new ProcessPaymentRequest();
await _orderProcessingService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().NotBe(oldGuid);
oldGuid = request.OrderGuid;
ArgumentNullException.ThrowIfNull(_httpContextAccessor.HttpContext);
await _httpContextAccessor.HttpContext.Session.SetAsync("OrderPaymentInfo", request);
await _orderProcessingService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().Be(oldGuid);
request = new ProcessPaymentRequest();
await _orderProcessingService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().Be(oldGuid);
}

[Test]
public void EnsureOrderCanOnlyBeCancelledWhenOrderStatusIsNotCanCelledYet()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Nop.Core.Domain.Orders;
using Nop.Core.Http.Extensions;
using Nop.Services.Payments;
using NUnit.Framework;

Expand All @@ -12,37 +10,12 @@ public class PaymentServiceTests : ServiceTest
{
private IPaymentPluginManager _paymentPluginManager;
private IPaymentService _paymentService;
private IHttpContextAccessor _httpContextAccessor;

[OneTimeSetUp]
public void SetUp()
{
_paymentService = GetService<IPaymentService>();
_paymentPluginManager = GetService<IPaymentPluginManager>();
_httpContextAccessor = GetService<IHttpContextAccessor>();
}

[Test]
public async Task CanGenerateOrderGuid()
{
var request = new ProcessPaymentRequest();
request.OrderGuid.Should().Be(Guid.Empty);
await _paymentService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().NotBe(Guid.Empty);
var oldGuid = request.OrderGuid;
await _paymentService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().Be(oldGuid);
request = new ProcessPaymentRequest();
await _paymentService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().NotBe(oldGuid);
oldGuid = request.OrderGuid;
ArgumentNullException.ThrowIfNull(_httpContextAccessor.HttpContext);
await _httpContextAccessor.HttpContext.Session.SetAsync("OrderPaymentInfo", request);
await _paymentService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().Be(oldGuid);
request = new ProcessPaymentRequest();
await _paymentService.GenerateOrderGuidAsync(request);
request.OrderGuid.Should().Be(oldGuid);
}

[Test]
Expand Down