Skip to content
Browse files

Add nonces and one function signing

- Sign function now adds a randomly generated nonce value if one is
  provided in the passed in array.
- Convenience function added to perform signing with one method call.
- nonce generation function is stubbable
- Updated unit tests.
  • Loading branch information...
1 parent 19d976c commit ee32bc4c09065e03e90937b6a864e508c3aa6b3f @Sturmanator Sturmanator committed with isaachall Mar 6, 2012
Showing with 40 additions and 13 deletions.
  1. +25 −3 lib/recurly/recurly_js.php
  2. +15 −10 test/recurly/recurlyjs_test.php
View
28 lib/recurly/recurly_js.php
@@ -22,16 +22,32 @@ function __construct($data)
$this->data = $data;
}
- # Create a signature with the protected data
- public function sign()
+ // Create a signature with the protected data
+ public function get_signature()
{
$this->data['timestamp'] = $this->utc_timestamp();
+
+ if (!in_array('nonce', $this->data)) {
+ $this->data['nonce'] = $this->get_nonce();
+ }
+
ksort($this->data);
$queryString = http_build_query($this->data, null, '&');
return Recurly_js::_hash($queryString) . "|" . $queryString;
}
- # Lookup the result of a Recurly.js operation
+ // Convenience function providing parity between this and the other libraries.
+ // get_signature() is implemented as a non-static method for ease of testing.
+ //
+ // TODO - Eliminate $type arg in favor of using static keyword for stubbing
+ // if we ever drop PHP < 5.3.
+ public static function sign($data, $type = "Recurly_js")
+ {
+ $rjs = new $type($data);
+ return $rjs->get_signature();
+ }
+
+ // Lookup the result of a Recurly.js operation
public static function getResult($token, $client = null)
{
$uri = Recurly_Client::PATH_RECURLY_JS_RESULT . '/' . rawurlencode($token);
@@ -52,4 +68,10 @@ protected function utc_timestamp()
{
return time();
}
+
+ // In its own function so it can be stubbed for testing
+ protected function get_nonce()
+ {
+ return uniqid();
+ }
}
View
25 test/recurly/recurlyjs_test.php
@@ -5,6 +5,10 @@ class Recurly_jsMock extends Recurly_js {
function utc_timestamp() {
return 1330452000;
}
+
+ function get_nonce() {
+ return "1234567890ABC";
+ }
}
class Recurly_RecurlyjsTestCase extends UnitTestCase {
@@ -17,28 +21,29 @@ function tearDown() {
}
function testSignSimple() {
- $recurly_js = new Recurly_jsMock(array(
+ $signature = Recurly_jsMock::sign(array(
'account' => array('account_code' => '123')
- ));
- $signature = $recurly_js->sign();
+ ), "Recurly_jsMock");
- $this->assertEqual($signature, "de21d9ef754772de103be467f58ddb0cb5ebb8f6|account%5Baccount_code%5D=123&timestamp=1330452000");
+ $this->assertEqual($signature, "e4bbe0671c8154f82b6a96cf2b13307d839e6ad6|" .
+ "account%5Baccount_code%5D=123&nonce=1234567890ABC&timestamp=1330452000");
}
function testSignComplex() {
- $recurly_js = new Recurly_jsMock(array(
+ $signature = Recurly_jsMock::sign(array(
'account' => array('account_code' => '123'),
'plan_code' => 'gold',
'add_ons' => array(
array('add_on_code'=>'extra','quantity'=>5),
array('add_on_code'=>'bonus','quantity'=>2)
),
'quantity' => 1
- ));
- $signature = $recurly_js->sign();
+ ), "Recurly_jsMock");
- $this->assertEqual($signature, "e31ed714b041968c1685f3427d4d2b247c8ff3e9|account%5Baccount_code%5D=123&add_ons%5B0%5D%5Badd_on_code%5D=extra&" .
- "add_ons%5B0%5D%5Bquantity%5D=5&add_ons%5B1%5D%5Badd_on_code%5D=bonus&add_ons%5B1%5D%5Bquantity%5D=2&" .
- "plan_code=gold&quantity=1&timestamp=1330452000");
+ $this->assertEqual($signature, "af31773205811350017ed1d05e5b2f7d303417d8|" .
+ "account%5Baccount_code%5D=123&add_ons%5B0%5D%5Badd_on_code%5D=extra&ad" .
+ "d_ons%5B0%5D%5Bquantity%5D=5&add_ons%5B1%5D%5Badd_on_code%5D=bonus&add" .
+ "_ons%5B1%5D%5Bquantity%5D=2&nonce=1234567890ABC&plan_code=gold&quantit" .
+ "y=1&timestamp=1330452000");
}
}

0 comments on commit ee32bc4

Please sign in to comment.
Something went wrong with that request. Please try again.