From eb5ed56488d9b973fc3d4297c8bbef21637f63eb Mon Sep 17 00:00:00 2001 From: ycfxx Date: Wed, 9 Feb 2022 14:21:02 +0800 Subject: [PATCH] upgrade shopify response Content-Security-Policy --- .../payment/manage/WebConfiguration.java | 7 +++ .../web/ShopifyAuthTemplateController.java | 17 +++----- .../hooks/ShopifyWebhooksController.java | 15 ++++--- .../shopify/support/ShopifyEndpoint.java | 9 ++++ .../ShopifyRequestInfoInterceptor.java | 43 +++++++++++++++++++ 5 files changed, 73 insertions(+), 18 deletions(-) create mode 100644 src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyEndpoint.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyRequestInfoInterceptor.java diff --git a/src/main/java/au/com/royalpay/payment/manage/WebConfiguration.java b/src/main/java/au/com/royalpay/payment/manage/WebConfiguration.java index 70ea18c86..c5a511f1e 100644 --- a/src/main/java/au/com/royalpay/payment/manage/WebConfiguration.java +++ b/src/main/java/au/com/royalpay/payment/manage/WebConfiguration.java @@ -1,6 +1,8 @@ package au.com.royalpay.payment.manage; import au.com.royalpay.payment.manage.permission.manager.ManagerUserInterceptor; +import au.com.royalpay.payment.manage.shopify.support.ShopifyRequestInfoInterceptor; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -15,10 +17,15 @@ public class WebConfiguration implements WebMvcConfigurer { @Resource private ManagerUserInterceptor managerUserInterceptor; + @Bean + public ShopifyRequestInfoInterceptor shopifyRequestInfoInterceptor() { + return new ShopifyRequestInfoInterceptor(); + } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(managerUserInterceptor).order(1); + registry.addInterceptor(shopifyRequestInfoInterceptor()); } diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/web/ShopifyAuthTemplateController.java b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/web/ShopifyAuthTemplateController.java index 5b6dc3969..c57b68a81 100644 --- a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/web/ShopifyAuthTemplateController.java +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/web/ShopifyAuthTemplateController.java @@ -5,17 +5,14 @@ import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyCommonPa import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyPermissionURL; import au.com.royalpay.payment.manage.shopify.auth.domain.exception.ShopifyRequestVerifyException; import au.com.royalpay.payment.manage.shopify.auth.domain.service.ShopifyRequestValidator; +import au.com.royalpay.payment.manage.shopify.support.ShopifyEndpoint; import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.exceptions.BadRequestException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.view.RedirectView; +import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletResponse; import java.util.regex.Pattern; @Controller @@ -40,11 +37,10 @@ public class ShopifyAuthTemplateController { * @return */ @GetMapping("/auth") + @ShopifyEndpoint public String shopifyStorePermission(@RequestParam("shop") String shop, @RequestParam("hmac") String hmac, - @RequestParam("timestamp") String timestamp, - HttpServletResponse response) { - response.setHeader("Content-Security-Policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com"); + @RequestParam("timestamp") String timestamp) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) { throw new BadRequestException("Parameter shop is invalid."); } @@ -67,14 +63,13 @@ public class ShopifyAuthTemplateController { * @return */ @GetMapping("/auth/back") + @ShopifyEndpoint public String shopifyStoreAuthRedirect(@RequestParam("code") String code, @RequestParam("hmac") String hmac, @RequestParam("host") String host, @RequestParam("state") String state, @RequestParam("shop") String shop, - @RequestParam("timestamp") String timestamp, - HttpServletResponse response) { - response.setHeader("Content-Security-Policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com"); + @RequestParam("timestamp") String timestamp) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) { throw new ShopifyRequestVerifyException("Parameter shop is invalid."); } diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/hooks/ShopifyWebhooksController.java b/src/main/java/au/com/royalpay/payment/manage/shopify/hooks/ShopifyWebhooksController.java index 18f56d8e7..493c61d22 100644 --- a/src/main/java/au/com/royalpay/payment/manage/shopify/hooks/ShopifyWebhooksController.java +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/hooks/ShopifyWebhooksController.java @@ -7,11 +7,11 @@ import au.com.royalpay.payment.manage.shopify.hooks.command.ShopifyCustomerReque import au.com.royalpay.payment.manage.shopify.hooks.command.ShopifyShopRedactCommand; import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore; import au.com.royalpay.payment.manage.shopify.store.domain.service.ShopifyStoreService; +import au.com.royalpay.payment.manage.shopify.support.ShopifyEndpoint; import au.com.royalpay.payment.manage.shopify.support.ShopifyHttpUtils; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; @@ -33,15 +33,15 @@ public class ShopifyWebhooksController { * */ @PostMapping("/customer/request") + @ShopifyEndpoint public void customerRequest(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac, HttpServletRequest request, HttpServletResponse response) { String requestBody = ShopifyHttpUtils.getRequestBody(request); - ShopifyCustomerRequestCommand shopifyCustomerRequestCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRequestCommand.class); - response.setHeader("Content-Security-Policy", "frame-ancestors https://" + shopifyCustomerRequestCommand.getShop_domain() + ".myshopify.com https://admin.shopify.com"); if (!shopifyRequestValidator.verify(requestBody, hmac)) { throw new ShopifyRequestVerifyException("Unauthorized"); } + ShopifyCustomerRequestCommand shopifyCustomerRequestCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRequestCommand.class); } /** @@ -49,15 +49,16 @@ public class ShopifyWebhooksController { * */ @PostMapping("/customer/erasure") + @ShopifyEndpoint public void customerRedact(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac, HttpServletRequest request, HttpServletResponse response) { String requestBody = ShopifyHttpUtils.getRequestBody(request); - ShopifyCustomerRedactCommand shopifyCustomerRedactCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRedactCommand.class); - response.setHeader("Content-Security-Policy", "frame-ancestors https://" + shopifyCustomerRedactCommand.getShop_domain() + ".myshopify.com https://admin.shopify.com"); if (!shopifyRequestValidator.verify(requestBody, hmac)) { throw new ShopifyRequestVerifyException("Unauthorized"); } + + ShopifyCustomerRedactCommand shopifyCustomerRedactCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRedactCommand.class); } /** @@ -65,16 +66,16 @@ public class ShopifyWebhooksController { * */ @PostMapping("/shop/erasure") + @ShopifyEndpoint public void shopRedact(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac, HttpServletRequest request, HttpServletResponse response) { String requestBody = ShopifyHttpUtils.getRequestBody(request); - ShopifyShopRedactCommand shopifyShopRedactCommand = JSONObject.parseObject(requestBody, ShopifyShopRedactCommand.class); - response.setHeader("Content-Security-Policy", "frame-ancestors https://" + shopifyShopRedactCommand.getShop_domain() + ".myshopify.com https://admin.shopify.com"); if (!shopifyRequestValidator.verify(requestBody, hmac)) { throw new ShopifyRequestVerifyException("Unauthorized"); } + ShopifyShopRedactCommand shopifyShopRedactCommand = JSONObject.parseObject(requestBody, ShopifyShopRedactCommand.class); ShopifyStore shopifyShop = shopifyStoreService.getByShopifyShop(shopifyShopRedactCommand.getShop_domain()); if (shopifyShop == null) { return; diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyEndpoint.java b/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyEndpoint.java new file mode 100644 index 000000000..f80fd004b --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyEndpoint.java @@ -0,0 +1,9 @@ +package au.com.royalpay.payment.manage.shopify.support; + +import java.lang.annotation.*; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface ShopifyEndpoint { +} diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyRequestInfoInterceptor.java b/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyRequestInfoInterceptor.java new file mode 100644 index 000000000..2a5858f83 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyRequestInfoInterceptor.java @@ -0,0 +1,43 @@ +package au.com.royalpay.payment.manage.shopify.support; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.http.HttpMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +public class ShopifyRequestInfoInterceptor extends HandlerInterceptorAdapter { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + Method method = ((HandlerMethod) handler).getMethod(); + + if(HttpMethod.GET.matches(request.getMethod())) { + if (AnnotatedElementUtils.isAnnotated(method, ShopifyEndpoint.class)) { + String shop = request.getParameter("shop"); + if (StringUtils.isNotBlank(shop)) { + response.addHeader("Content-Security-Policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com"); + } + } + } + + if (HttpMethod.POST.matches(request.getMethod())) { + if (AnnotatedElementUtils.isAnnotated(method, ShopifyEndpoint.class)) { + String requestBody = ShopifyHttpUtils.getRequestBody(request); + JSONObject body = JSONObject.parseObject(requestBody); + String shop = body.getString("shop_domain"); + if (StringUtils.isNotBlank(shop)) { + response.addHeader("Content-Security-Policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com"); + } + } + } + + return super.preHandle(request, response, handler); + } + +}