upgrade shopify webhook check

master
ycfxx 3 years ago
parent 1f8846a25a
commit a8bc6dfc62

@ -1,7 +0,0 @@
package au.com.royalpay.payment.manage.shopify.auth.domain;
public class ShopifyRequestVerifyException extends RuntimeException{
public ShopifyRequestVerifyException(String message) {
super(message);
}
}

@ -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);
}
}

@ -27,4 +27,8 @@ public class ShopifyRequestValidator {
.append("&timestamp=").append(timestamp); .append("&timestamp=").append(timestamp);
return HmacVerificationUtil.hmacSHA256(message.toString(),clientSecret,hmac); return HmacVerificationUtil.hmacSHA256(message.toString(),clientSecret,hmac);
} }
public boolean verify(String message, String hmac) {
return HmacVerificationUtil.hmacSHA256(message,clientSecret,hmac);
}
} }

@ -1,9 +1,9 @@
package au.com.royalpay.payment.manage.shopify.auth.web; 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.application.ShopifyMerchantAuthApplication;
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyCommonParameter; 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.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.auth.domain.service.ShopifyRequestValidator;
import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import au.com.royalpay.payment.tools.exceptions.BadRequestException; 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.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.HttpServletResponse;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@Controller @Controller
@ -39,9 +40,10 @@ public class ShopifyAuthTemplateController {
* @return * @return
*/ */
@GetMapping("/auth") @GetMapping("/auth")
public RedirectView shopifyStorePermission(@RequestParam("shop") String shop, public String shopifyStorePermission(@RequestParam("shop") String shop,
@RequestParam("hmac") String hmac, @RequestParam("hmac") String hmac,
@RequestParam("timestamp") String timestamp) { @RequestParam("timestamp") String timestamp,
HttpServletResponse response) {
if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) {
throw new BadRequestException("Parameter shop is invalid."); throw new BadRequestException("Parameter shop is invalid.");
} }
@ -49,7 +51,8 @@ public class ShopifyAuthTemplateController {
throw new ShopifyRequestVerifyException("This request parameters is invalid"); throw new ShopifyRequestVerifyException("This request parameters is invalid");
} }
ShopifyPermissionURL shopifyPermissionURL = shopifyMerchantAuthApplication.getShopifyPermissionUrl(shop); 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("host") String host,
@RequestParam("state") String state, @RequestParam("state") String state,
@RequestParam("shop") String shop, @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)) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) {
throw new ShopifyRequestVerifyException("Parameter shop is invalid."); 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 + "&timestamp=" + timestamp); String redirectUri = PlatformEnvironment.getEnv().concatUrl("/auth.html#/shopify/login?code=" + code + "&hmac=" + hmac + "&host=" + host + "&state=" + state + "&shop=" + shop + "&timestamp=" + timestamp);
response.setHeader("content-security-policy", "frame-ancestors https://" + shop + ".myshopify.com https://admin.shopify.com");
return new RedirectView(redirectUri); return new RedirectView(redirectUri);
} }

@ -1,16 +1,19 @@
package au.com.royalpay.payment.manage.shopify.hooks; 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.ShopifyCustomerRedactCommand;
import au.com.royalpay.payment.manage.shopify.hooks.command.ShopifyCustomerRequestCommand; 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.hooks.command.ShopifyShopRedactCommand;
import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore; 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.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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest;
@Slf4j @Slf4j
@RestController @RestController
@ -20,35 +23,50 @@ public class ShopifyWebhooksController {
@Autowired @Autowired
private ShopifyStoreService shopifyStoreService; private ShopifyStoreService shopifyStoreService;
@Autowired
private ShopifyRequestValidator shopifyRequestValidator;
/** /**
* *
* *
* @param command
*/ */
@PostMapping("/customer/request") @PostMapping("/customer/request")
public void customerRequest(ShopifyCustomerRequestCommand command) { public void customerRequest(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac,
log.warn(JSON.toJSONString(command)); 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") @PostMapping("/customer/erasure")
public void customerRedact(ShopifyCustomerRedactCommand command) { public void customerRedact(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac,
log.warn(JSON.toJSONString(command)); HttpServletRequest request) {
String requestBody = ShopifyHttpUtils.getRequestBody(request);
if (!shopifyRequestValidator.verify(requestBody, hmac)) {
throw new ShopifyRequestVerifyException("Unauthorized");
}
ShopifyCustomerRedactCommand shopifyCustomerRedactCommand = JSONObject.parseObject(requestBody, ShopifyCustomerRedactCommand.class);
} }
/** /**
* shopifypayment app * shopifypayment app
* *
* @param command
*/ */
@PostMapping("/shop/erasure") @PostMapping("/shop/erasure")
public void shopRedact(ShopifyShopRedactCommand command) { public void shopRedact(@RequestHeader("X-Shopify-Hmac-SHA256") String hmac,
log.warn(JSON.toJSONString(command)); HttpServletRequest request) {
ShopifyStore shopifyShop = shopifyStoreService.getByShopifyShop(command.getShop_domain()); 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) { if (shopifyShop == null) {
return; return;
} }

@ -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();
}
}
Loading…
Cancel
Save