From cebab00a027c2b6ad6e36d5dea4e2ac1d2eb99d9 Mon Sep 17 00:00:00 2001 From: Jason Swenski Date: Tue, 15 Dec 2015 01:56:36 -0700 Subject: [PATCH] Fixing the fact that getInvoice(id,PUBLIC_NO_TOKEN) was actually still signing the requests and therefore not actually using the public API. This doesn't work in some cases because the /invoice endpoint doesn't support some facades. Also refactors some of the parameter building to off-the-shelf apache commons methods --- .gitignore | 8 ++ src/main/java/controller/BitPay.java | 124 +++++++++++---------------- 2 files changed, 59 insertions(+), 73 deletions(-) diff --git a/.gitignore b/.gitignore index e169f73..f1277e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +.DS_Store +.classpath +.project +.settings/ +bin/.gitignore +lib/.DS_Store +pom.xml +target/ locals/ *.key java-bitpay-client.xml diff --git a/src/main/java/controller/BitPay.java b/src/main/java/controller/BitPay.java index 2d6c289..11a050e 100644 --- a/src/main/java/controller/BitPay.java +++ b/src/main/java/controller/BitPay.java @@ -14,8 +14,10 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.bitcoinj.core.ECKey; @@ -381,14 +383,13 @@ public class BitPay { */ public Invoice getInvoice(String invoiceId, String token) throws BitPayException { - Hashtable parameters = this.getParams(); - - parameters.put("token", token); - - HttpResponse response = this.get("invoices/" + invoiceId, parameters); + final List params = new ArrayList(); + params.add(new BasicNameValuePair("token", token)); + + boolean requireSignature = !PUBLIC_NO_TOKEN.equals(token); + HttpResponse response = this.get("invoices/" + invoiceId, params, requireSignature); Invoice i; - try { i = new ObjectMapper().readValue(this.responseToJsonString(response), Invoice.class); } catch (JsonProcessingException e) { @@ -409,13 +410,13 @@ public class BitPay { */ public List getInvoices(String dateStart, String dateEnd) throws BitPayException { - Hashtable parameters = this.getParams(); + + final List params = new ArrayList(); + params.add(new BasicNameValuePair("token", this.getAccessToken(FACADE_MERCHANT))); + params.add(new BasicNameValuePair("dateStart", dateStart)); + params.add(new BasicNameValuePair("dateEnd", dateEnd)); - parameters.put("token", this.getAccessToken(FACADE_MERCHANT)); - parameters.put("dateStart", dateStart); - parameters.put("dateEnd", dateEnd); - - HttpResponse response = this.get("invoices", parameters); + HttpResponse response = this.get("invoices", params); List invoices; @@ -510,17 +511,17 @@ public class BitPay { * @throws BitPayException */ public boolean cancelRefundRequest(Invoice invoice, String refundId) throws BitPayException - { - Refund refund = this.getRefund(invoice, refundId); - if (refund == null) - { - throw new BitPayException("Error - refundId is not associated with specified invoice"); - } + { + Refund refund = this.getRefund(invoice, refundId); + if (refund == null) + { + throw new BitPayException("Error - refundId is not associated with specified invoice"); + } - Hashtable parameters = this.getParams(); - parameters.put("token", refund.getToken()); - - HttpResponse response = this.delete("invoices/" + invoice.getId() + "/refunds/" + refundId, parameters); + final List params = new ArrayList(); + params.add(new BasicNameValuePair("token", refund.getToken())); + + HttpResponse response = this.delete("invoices/" + invoice.getId() + "/refunds/" + refundId, params); String result = this.responseToJsonString(response); return (result.equals("\"Success\"")); @@ -536,11 +537,10 @@ public class BitPay { public Refund getRefund(Invoice invoice, String refundId) throws BitPayException { Refund refund = new Refund(); - Hashtable parameters = this.getParams(); - - parameters.put("token", invoice.getToken()); - - HttpResponse response = this.get("invoices/" + invoice.getId() + "/refunds/" + refundId, parameters); + + final List params = new ArrayList(); + params.add(new BasicNameValuePair("token", invoice.getToken())); + HttpResponse response = this.get("invoices/" + invoice.getId() + "/refunds/" + refundId, params); ObjectMapper mapper = new ObjectMapper(); @@ -564,11 +564,10 @@ public class BitPay { public List getAllRefunds(Invoice invoice) throws BitPayException { List refunds; - Hashtable parameters = this.getParams(); - - parameters.put("token", invoice.getToken()); - - HttpResponse response = this.get("invoices/" + invoice.getId() + "/refunds", parameters); + final List params = new ArrayList(); + params.add(new BasicNameValuePair("token", invoice.getToken())); + + HttpResponse response = this.get("invoices/" + invoice.getId() + "/refunds", params); try { refunds = Arrays.asList(new ObjectMapper().readValue(this.responseToJsonString(response), Refund[].class)); @@ -686,23 +685,22 @@ public class BitPay { { this.clearAccessTokenCache(); - Hashtable parameters = this.getParams(); - - parameters.put("id", this.getIdentity()); - - HttpResponse response = this.get("tokens", parameters); + final List params = new ArrayList(); + params.add(new BasicNameValuePair("id", this.getIdentity())); + + HttpResponse response = this.get("tokens", params); _tokenCache = responseToTokenCache(response); return _tokenCache.size(); } - - private Hashtable getParams() - { - return new Hashtable(); + + + private HttpResponse get(String uri, List parameters) throws BitPayException { + return get(uri, parameters, true); } - private HttpResponse get(String uri, Hashtable parameters) throws BitPayException + private HttpResponse get(String uri, List parameters, boolean signatureRequired) throws BitPayException { try { @@ -710,23 +708,14 @@ public class BitPay { HttpGet get = new HttpGet(fullURL); if (parameters != null) { - fullURL += "?"; - - for (String key : parameters.keySet()) { - fullURL += key + "=" + parameters.get(key) + "&"; - } - - fullURL = fullURL.substring(0,fullURL.length() - 1); - - get.setURI(new URI(fullURL)); - - String signature = KeyUtils.sign(_ecKey, fullURL); - - get.addHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO); - get.addHeader("x-accept-version", BITPAY_API_VERSION); - get.addHeader("x-signature", signature); + get.setURI(new URI(fullURL+URLEncodedUtils.format(parameters, "UTF-8"))); + } + if(signatureRequired) { + get.addHeader("x-signature", KeyUtils.sign(_ecKey, fullURL)); get.addHeader("x-identity", KeyUtils.bytesToHex(_ecKey.getPubKey())); } + get.addHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO); + get.addHeader("x-accept-version", BITPAY_API_VERSION); return _httpClient.execute(get); @@ -752,9 +741,7 @@ public class BitPay { post.setEntity(new ByteArrayEntity(json.getBytes("UTF8"))); if (signatureRequired) { - String signature = KeyUtils.sign(_ecKey, _baseUrl + uri + json); - - post.addHeader("x-signature", signature); + post.addHeader("x-signature", KeyUtils.sign(_ecKey, _baseUrl + uri + json)); post.addHeader("x-identity", KeyUtils.bytesToHex(_ecKey.getPubKey())); } @@ -783,7 +770,7 @@ public class BitPay { return this.post(uri, json, true); } - private HttpResponse delete(String uri, Hashtable parameters) throws BitPayException + private HttpResponse delete(String uri, List parameters) throws BitPayException { try { @@ -791,21 +778,12 @@ public class BitPay { HttpDelete delete = new HttpDelete(fullURL); if (parameters != null) { - fullURL += "?"; - - for (String key : parameters.keySet()) { - fullURL += key + "=" + parameters.get(key) + "&"; - } - - fullURL = fullURL.substring(0,fullURL.length() - 1); - - delete.setURI(new URI(fullURL)); - - String signature = KeyUtils.sign(_ecKey, fullURL); + + delete.setURI(new URI(fullURL+URLEncodedUtils.format(parameters, "UTF-8"))); delete.addHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO); delete.addHeader("x-accept-version", BITPAY_API_VERSION); - delete.addHeader("x-signature", signature); + delete.addHeader("x-signature", KeyUtils.sign(_ecKey, fullURL)); delete.addHeader("x-identity", KeyUtils.bytesToHex(_ecKey.getPubKey())); }