diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/ShopifyRequestVerifyException.java b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/ShopifyRequestVerifyException.java deleted file mode 100644 index c72e75060..000000000 --- a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/ShopifyRequestVerifyException.java +++ /dev/null @@ -1,7 +0,0 @@ -package au.com.royalpay.payment.manage.shopify.auth.domain; - -public class ShopifyRequestVerifyException extends RuntimeException{ - public ShopifyRequestVerifyException(String message) { - super(message); - } -} diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/exception/ShopifyRequestVerifyException.java b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/exception/ShopifyRequestVerifyException.java new file mode 100644 index 000000000..6aa717dcb --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/exception/ShopifyRequestVerifyException.java @@ -0,0 +1,11 @@ +package au.com.royalpay.payment.manage.shopify.auth.domain.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.UNAUTHORIZED) +public class ShopifyRequestVerifyException extends RuntimeException{ + public ShopifyRequestVerifyException(String message) { + super(message); + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/service/ShopifyRequestValidator.java b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/service/ShopifyRequestValidator.java index b3b6ec49f..cf90d7473 100644 --- a/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/service/ShopifyRequestValidator.java +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/auth/domain/service/ShopifyRequestValidator.java @@ -27,4 +27,8 @@ public class ShopifyRequestValidator { .append("×tamp=").append(timestamp); return HmacVerificationUtil.hmacSHA256(message.toString(),clientSecret,hmac); } + + public boolean verify(String message, String hmac) { + return HmacVerificationUtil.hmacSHA256(message,clientSecret,hmac); + } } 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 c8e61b2e3..f4443d1ce 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 @@ -1,9 +1,9 @@ package au.com.royalpay.payment.manage.shopify.auth.web; -import au.com.royalpay.payment.manage.shopify.auth.domain.ShopifyRequestVerifyException; import au.com.royalpay.payment.manage.shopify.auth.domain.application.ShopifyMerchantAuthApplication; import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyCommonParameter; 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.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.exceptions.BadRequestException; @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.view.RedirectView; +import javax.servlet.http.HttpServletResponse; import java.util.regex.Pattern; @Controller @@ -39,9 +40,10 @@ public class ShopifyAuthTemplateController { * @return */ @GetMapping("/auth") - public RedirectView shopifyStorePermission(@RequestParam("shop") String shop, - @RequestParam("hmac") String hmac, - @RequestParam("timestamp") String timestamp) { + public String shopifyStorePermission(@RequestParam("shop") String shop, + @RequestParam("hmac") String hmac, + @RequestParam("timestamp") String timestamp, + HttpServletResponse response) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) { throw new BadRequestException("Parameter shop is invalid."); } @@ -49,7 +51,8 @@ public class ShopifyAuthTemplateController { throw new ShopifyRequestVerifyException("This request parameters is invalid"); } ShopifyPermissionURL shopifyPermissionURL = shopifyMerchantAuthApplication.getShopifyPermissionUrl(shop); - return new RedirectView(shopifyPermissionURL.getUrl()); + response.setHeader("content-security-policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com"); + return "redirect:" + shopifyPermissionURL.getUrl(); } /** @@ -69,7 +72,8 @@ public class ShopifyAuthTemplateController { @RequestParam("host") String host, @RequestParam("state") String state, @RequestParam("shop") String shop, - @RequestParam("timestamp") String timestamp) { + @RequestParam("timestamp") String timestamp, + HttpServletResponse response) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) { throw new ShopifyRequestVerifyException("Parameter shop is invalid."); @@ -93,6 +97,7 @@ public class ShopifyAuthTemplateController { } String redirectUri = PlatformEnvironment.getEnv().concatUrl("/auth.html#/shopify/login?code=" + code + "&hmac=" + hmac + "&host=" + host + "&state=" + state + "&shop=" + shop + "×tamp=" + timestamp); + response.setHeader("content-security-policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com"); return new RedirectView(redirectUri); } 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 255158085..0b620a206 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 @@ -1,16 +1,19 @@ package au.com.royalpay.payment.manage.shopify.hooks; +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.hooks.command.ShopifyCustomerRedactCommand; import au.com.royalpay.payment.manage.shopify.hooks.command.ShopifyCustomerRequestCommand; 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 com.alibaba.fastjson.JSON; +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.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; @Slf4j @RestController @@ -20,35 +23,50 @@ public class ShopifyWebhooksController { @Autowired private ShopifyStoreService shopifyStoreService; + @Autowired + private ShopifyRequestValidator shopifyRequestValidator; + /** * 推送顾客信息查询请求 * - * @param command */ @PostMapping("/customer/request") - public void customerRequest(ShopifyCustomerRequestCommand command) { - log.warn(JSON.toJSONString(command)); + public void customerRequest(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac, + HttpServletRequest request) { + String requestBody = ShopifyHttpUtils.getRequestBody(request); + if (!shopifyRequestValidator.verify(requestBody, hmac)) { + throw new ShopifyRequestVerifyException("Unauthorized"); + } + ShopifyCustomerRequestCommand shopifyCustomerRequestCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRequestCommand.class); } /** * 擦除顾客信息消息通知 * - * @param command */ @PostMapping("/customer/erasure") - public void customerRedact(ShopifyCustomerRedactCommand command) { - log.warn(JSON.toJSONString(command)); + public void customerRedact(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac, + HttpServletRequest request) { + String requestBody = ShopifyHttpUtils.getRequestBody(request); + if (!shopifyRequestValidator.verify(requestBody, hmac)) { + throw new ShopifyRequestVerifyException("Unauthorized"); + } + ShopifyCustomerRedactCommand shopifyCustomerRedactCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRedactCommand.class); } /** * shopify店铺卸载payment app事件 * - * @param command */ @PostMapping("/shop/erasure") - public void shopRedact(ShopifyShopRedactCommand command) { - log.warn(JSON.toJSONString(command)); - ShopifyStore shopifyShop = shopifyStoreService.getByShopifyShop(command.getShop_domain()); + public void shopRedact(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac, + HttpServletRequest request) { + String requestBody = ShopifyHttpUtils.getRequestBody(request); + 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/ShopifyHttpUtils.java b/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyHttpUtils.java new file mode 100644 index 000000000..6e82a1643 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/shopify/support/ShopifyHttpUtils.java @@ -0,0 +1,33 @@ +package au.com.royalpay.payment.manage.shopify.support; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; + +public class ShopifyHttpUtils { + + public static String getRequestBody(HttpServletRequest request) { + BufferedReader br = null; + StringBuilder sb = new StringBuilder(""); + try { + br = request.getReader(); + String str; + while ((str = br.readLine()) != null) { + sb.append(str); + } + br.close(); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return sb.toString(); + } +}