From 408779759c3708e2ed60b520dba0af275b505f27 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 11 Nov 2020 14:55:30 +0800 Subject: [PATCH] Introduce OrderCancellationAuthorizationHandler Move order creation permission check to BasicOrderCancellationAuthorizationHandler Resolve #105 --- common.props | 2 +- .../Orders/EShopOrdersApplicationModule.cs | 1 + ...icOrderCancellationAuthorizationHandler.cs | 60 +++++++++++++++++++ .../BasicOrderCreationAuthorizationHandler.cs | 15 +++++ .../EShop/Orders/Orders/OrderAppService.cs | 16 ++--- .../OrderCancellationAuthorizationHandler.cs | 22 +++++++ .../EShop/Orders/Orders/OrderOperation.cs | 3 +- 7 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCancellationAuthorizationHandler.cs create mode 100644 modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderCancellationAuthorizationHandler.cs diff --git a/common.props b/common.props index 91a6f4d2..b70851c1 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 1.5.0 + 1.6.0 $(NoWarn);CS1591 true EasyAbp Team diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/EShopOrdersApplicationModule.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/EShopOrdersApplicationModule.cs index 6f6cad8a..25c8d856 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/EShopOrdersApplicationModule.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/EShopOrdersApplicationModule.cs @@ -23,6 +23,7 @@ namespace EasyAbp.EShop.Orders public override void PreConfigureServices(ServiceConfigurationContext context) { context.Services.AddSingleton(); + context.Services.AddSingleton(); } public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCancellationAuthorizationHandler.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCancellationAuthorizationHandler.cs new file mode 100644 index 00000000..5c254624 --- /dev/null +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCancellationAuthorizationHandler.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Orders.Authorization; +using EasyAbp.EShop.Stores.StoreOwners; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Users; + +namespace EasyAbp.EShop.Orders.Orders +{ + public class BasicOrderCancellationAuthorizationHandler : OrderCancellationAuthorizationHandler + { + private readonly IStoreOwnerStore _storeOwnerStore; + private readonly IPermissionChecker _permissionChecker; + private readonly ICurrentUser _currentUser; + + public BasicOrderCancellationAuthorizationHandler( + IStoreOwnerStore storeOwnerStore, + IPermissionChecker permissionChecker, + ICurrentUser currentUser) + { + _storeOwnerStore = storeOwnerStore; + _permissionChecker = permissionChecker; + _currentUser = currentUser; + } + + protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, + OrderOperationAuthorizationRequirement requirement, Order resource) + { + if (!await _permissionChecker.IsGrantedAsync(OrdersPermissions.Orders.Cancel)) + { + context.Fail(); + return; + } + + if (!resource.IsPaid()) + { + context.Succeed(requirement); + return; + } + + if (resource.CustomerUserId != _currentUser.GetId()) + { + if (!await _permissionChecker.IsGrantedAsync(OrdersPermissions.Orders.Manage)) + { + context.Fail(); + return; + } + + + if (await _storeOwnerStore.IsStoreOwnerAsync(resource.StoreId, _currentUser.GetId()) || + await _permissionChecker.IsGrantedAsync(OrdersPermissions.Orders.CrossStore)) + { + context.Succeed(requirement); + return; + } + } + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCreationAuthorizationHandler.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCreationAuthorizationHandler.cs index 441e79de..bb857ce5 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCreationAuthorizationHandler.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/BasicOrderCreationAuthorizationHandler.cs @@ -2,18 +2,33 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using EasyAbp.EShop.Orders.Authorization; using EasyAbp.EShop.Orders.Orders.Dtos; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; using Microsoft.AspNetCore.Authorization; +using Volo.Abp.Authorization.Permissions; namespace EasyAbp.EShop.Orders.Orders { public class BasicOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler { + private readonly IPermissionChecker _permissionChecker; + + public BasicOrderCreationAuthorizationHandler(IPermissionChecker permissionChecker) + { + _permissionChecker = permissionChecker; + } + protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource) { + if (!await _permissionChecker.IsGrantedAsync(OrdersPermissions.Orders.Create)) + { + context.Fail(); + return; + } + if (!await IsProductsPublishedAsync(resource.Input, resource.ProductDictionary)) { context.Fail(); diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderAppService.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderAppService.cs index 403bce43..fb426531 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderAppService.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderAppService.cs @@ -19,7 +19,6 @@ namespace EasyAbp.EShop.Orders.Orders public class OrderAppService : MultiStoreCrudAppService, IOrderAppService { - protected override string CreatePolicyName { get; set; } = OrdersPermissions.Orders.Create; protected override string GetPolicyName { get; set; } = OrdersPermissions.Orders.Manage; protected override string GetListPolicyName { get; set; } = OrdersPermissions.Orders.Manage; protected override string CrossStorePolicyName { get; set; } = OrdersPermissions.Orders.CrossStore; @@ -83,8 +82,6 @@ namespace EasyAbp.EShop.Orders.Orders public override async Task CreateAsync(CreateOrderDto input) { - await CheckCreatePolicyAsync(); - // Todo: Check if the store is open. var productDict = await GetProductDictionaryAsync(input.OrderLines.Select(dto => dto.ProductId).ToList(), @@ -170,17 +167,14 @@ namespace EasyAbp.EShop.Orders.Orders return await MapToGetOutputDtoAsync(order); } - [Authorize(OrdersPermissions.Orders.Cancel)] public virtual async Task CancelAsync(Guid id, CancelOrderInput input) { var order = await GetEntityByIdAsync(id); - - if (order.IsPaid() || order.CustomerUserId != CurrentUser.GetId()) - { - await AuthorizationService.CheckAsync(OrdersPermissions.Orders.Manage); - - // Todo: Check if current user is an admin of the store. - } + + await AuthorizationService.CheckAsync( + order, + new OrderOperationAuthorizationRequirement(OrderOperation.Cancellation) + ); order = await _orderManager.CancelAsync(order, input.CancellationReason); diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderCancellationAuthorizationHandler.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderCancellationAuthorizationHandler.cs new file mode 100644 index 00000000..d54ea086 --- /dev/null +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderCancellationAuthorizationHandler.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; + +namespace EasyAbp.EShop.Orders.Orders +{ + public abstract class OrderCancellationAuthorizationHandler : AuthorizationHandler + { + protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OrderOperationAuthorizationRequirement requirement, + Order resource) + { + if (requirement.OrderOperation != OrderOperation.Cancellation) + { + return; + } + + await HandleOrderCreationAsync(context, requirement, resource); + } + + protected abstract Task HandleOrderCreationAsync(AuthorizationHandlerContext context, + OrderOperationAuthorizationRequirement requirement, Order resource); + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderOperation.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderOperation.cs index ac057098..d1ed8a6f 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderOperation.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderOperation.cs @@ -5,6 +5,7 @@ namespace EasyAbp.EShop.Orders.Orders [Flags] public enum OrderOperation { - Creation = 0 + Creation = 1, + Cancellation = 2 } } \ No newline at end of file