r70846 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r70845‎ | r70846 | r70847 >
Date:01:11, 11 August 2010
Author:awjrichards
Status:ok
Tags:
Comment:
Removed the ability to have multiple actions on a transaction - it was overengineered
Added a hashing mechanism in minfraud code that will allows us to track whether or not a transaction has already gone through minFraud validation
Updated minfraud tests
Modified paths:
  • /trunk/extensions/DonationInterface/payflowpro_gateway/extras/minfraud/minfraud.php (modified) (history)
  • /trunk/extensions/DonationInterface/payflowpro_gateway/extras/minfraud/tests/minfraudTest.php (modified) (history)
  • /trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php
@@ -3,7 +3,7 @@
44 class PayflowProGateway extends UnlistedSpecialPage {
55
66 /**
7 - * Defines the action(s) to take on a PFP transaction.
 7+ * Defines the action to take on a PFP transaction.
88 *
99 * Possible values include 'process', 'challenge',
1010 * 'review', 'reject'. These values can be set during
@@ -12,9 +12,9 @@
1313 * Hooks are exposed to handle the differet actions.
1414 *
1515 * Defaults to 'process'.
16 - * @var array
 16+ * @var string
1717 */
18 - public $actions = array( 'process' );
 18+ public $action = NULL;
1919
2020 /**
2121 * Constructor - set up the new special page
Index: trunk/extensions/DonationInterface/payflowpro_gateway/extras/minfraud/tests/minfraudTest.php
@@ -8,7 +8,7 @@
99 global $wgMinFraudLog;
1010 $wgMinFraudLog = dirname(__FILE__) . "/test_log";
1111 $license_key = 'XBCKSF4gnHA7';
12 - $this->fixture = new MinFraud( $license_key );
 12+ $this->fixture = new PayflowProGateway_Extras_MinFraud( $license_key );
1313 }
1414
1515 protected function tearDown() {
@@ -137,14 +137,13 @@
138138 */
139139 public function testDetermineActions( $risk_score, $action_ranges, $expected ) {
140140 $this->fixture->action_ranges = $action_ranges;
141 - $this->assertEquals( $expected, $this->fixture->determine_actions( $risk_score ));
 141+ $this->assertEquals( $expected, $this->fixture->determine_action( $risk_score ));
142142 }
143143
144144 public function determineActionsData() {
145145 return array(
146 - array( '0.1', array( 'process' => array(0, 100)), array('process')),
147 - array( '75.04', array( 'process' => array(0, 50), 'reject' => array( '50.01', '100')), array('reject')),
148 - array( '15', array( 'process' => array(0, 50), 'review' => array(10, 20)), array('process','review'))
 146+ array( '0.1', array( 'process' => array(0, 100)), 'process'),
 147+ array( '75.04', array( 'process' => array(0, 50), 'reject' => array( '50.01', '100')), 'reject'),
149148 );
150149 }
151150
@@ -155,4 +154,33 @@
156155 $this->assertEquals("foo\n", fread( $new_fh, filesize( $wgMinFraudLog ) ));
157156 fclose( $new_fh );
158157 }
 158+
 159+ public function testGenerateHash() {
 160+ global $wgMinFraudSalt;
 161+ $wgMinFraudSalt = 'salt';
 162+ $this->assertEquals( '5a9ee1e4a15adbf03b3ef9f7baa6caffa9f6bcd72c736498f045c073e57753e7b244bc97fe82b075eabd80778a4d56eb14406e9a1ac4b13737b2c3fd8c3717e8', $this->fixture->generate_hash( 'foo' ));
 163+ }
 164+
 165+ public function testCompareHash() {
 166+ global $wgMinFraudSalt;
 167+ $wgMinFraudSalt = 'salt';
 168+ $this->assertTrue( $this->fixture->compare_hash('5a9ee1e4a15adbf03b3ef9f7baa6caffa9f6bcd72c736498f045c073e57753e7b244bc97fe82b075eabd80778a4d56eb14406e9a1ac4b13737b2c3fd8c3717e8', 'foo'));
 169+ $this->assertFalse( $this->fixture->compare_hash('5a9ee1e4a15adbf03b3ef9f7baa6caffa9f6bcd72c736498f045c073e57753e7b244bc97fe82b075eabd80778a4d56eb14406e9a1ac4b13737b2c3fd8c3717e8', 'bar'));
 170+ }
 171+
 172+ public function testBypassMinfraud() {
 173+ global $wgMinFraudSalt;
 174+ $wgMinFraudSalt = 'salt';
 175+ $data = array(
 176+ 'action' => '4bd7857c851039d1e07a434800fe752c6bd99aec61c325aef460441be1b95c3ab5236e43c8d06f41d77715dbd3cf94e679b86422ec3204f00ad433501e5005e9',
 177+ 'data_hash' => '8a42092df24db59b67ab2c6408e00553de93e79dc0d77467f5b91501a392cff99922a0b24f9d0cc5853ae874bbc79c20eb22814ce3a912d743d4137b1f795ac3',
 178+ 'foo'
 179+ );
 180+ $this->assertTrue( $this->fixture->bypass_minfraud( &$this->fixture, &$data ));
 181+ $this->assertEquals( 'challenge', $this->fixture->action );
 182+ $this->assertEquals( '8a42092df24db59b67ab2c6408e00553de93e79dc0d77467f5b91501a392cff99922a0b24f9d0cc5853ae874bbc79c20eb22814ce3a912d743d4137b1f795ac3', $data[ 'data_hash' ]);
 183+
 184+ $data[] = 'bar';
 185+ $this->assertFalse( $this->fixture->bypass_minfraud( &$this->fixture, &$data ));
 186+ }
159187 }
Index: trunk/extensions/DonationInterface/payflowpro_gateway/extras/minfraud/minfraud.php
@@ -55,10 +55,19 @@
5656 * @param object PayflowPro Gateway object
5757 * @param array The array of data generated from an attempted transaction
5858 */
59 - public function validate( &$pfp_gateway_object, $data ) {
 59+ public function validate( &$pfp_gateway_object, &$data ) {
 60+ // see if we can bypass minfraud
 61+ if ( $this->bypass_minfraud( $pfp_gateway_object, &$data )) return TRUE;
 62+
6063 $minfraud_hash = $this->build_query( $data );
6164 $this->query_minfraud( $minfraud_hash );
62 - $pfp_gateway_object->actions = $this->determine_actions( $this->minfraud_response[ 'riskScore' ] );
 65+ $pfp_gateway_object->action = $this->determine_action( $this->minfraud_response[ 'riskScore' ] );
 66+
 67+ // reset the data hash and the action
 68+ if ( isset( $data[ 'data_hash' ] )) unset( $data[ 'data_hash' ] );
 69+ if ( isset( $data[ 'action' ] )) unset( $data[ 'action' ] );
 70+ $data[ 'data_hash' ] = $this->genereate_hash( serialize( $data ));
 71+ $data[ 'action' ] = $this->genereate_hash( $pfp_gateway_object->action );
6372
6473 // log the message if the user has specified a log file
6574 if ( $this->log_fh ) {
@@ -76,6 +85,46 @@
7786 }
7887
7988 /**
 89+ * Check to see if we can bypass minFraud check
 90+ *
 91+ * The first time a user hits the submission form, a hash of the full data array plus a
 92+ * hashed action name are injected to the data. This allows us to track the transaction's
 93+ * status. If a valid hash of the data is present and a valid action is present, we can
 94+ * assume the transaction has already gone through the minFraud check and can be passed
 95+ * on to the appropriate action.
 96+ *
 97+ * @param object $pfp_gateway_object The PayflowPro gateway object
 98+ * @param array $data The array of data from the form submission
 99+ * @return bool
 100+ */
 101+ public function bypass_minfraud( &$pfp_gateway_object, &$data ) {
 102+ // if the data bits data_hash and action are not set, we need to hit minFraud
 103+ if ( isset( $data[ 'data_hash' ] ) && isset( $data[ 'action' ] )) {
 104+ $data_hash = $data[ 'data_hash' ]; // the data hash passed in by the form submission
 105+ $action_hash = $data[ 'action' ]; // a hash of the action to take passed in by the form submission
 106+
 107+ // unset these values from the data aray since they are not part of the overall data hash
 108+ unset( $data[ 'data_hash' ] );
 109+ unset( $data[ 'action' ] );
 110+ // compare the data hash to make sure it's legit
 111+ if ( $this->compare_hash( $data_hash, serialize( $data ))) {
 112+ $data[ 'data_hash' ] = $data_hash;
 113+
 114+ // check to see if we have a valid action set for us to bypass minfraud
 115+ $actions = array( 'process', 'challenge', 'review', 'reject' );
 116+ foreach ( $actions as $action ) {
 117+ if ( $this->compare_hash( $action_hash, $action )) {
 118+ // set the action that should be taken
 119+ $pfp_gateway_object->action = $action;
 120+ return TRUE;
 121+ }
 122+ }
 123+ }
 124+ }
 125+ return FALSE;
 126+ }
 127+
 128+ /**
80129 * Get instance of CreditCardFraudDetection
81130 * @return object
82131 */
@@ -123,8 +172,8 @@
124173 case "bin": // get just the first 6 digits from CC#
125174 $newdata[ $value ] = substr( $data[ $value ], 0, 6 );
126175 break;
127 - default:
128 - $newdata[ $value ] = $data[ $value ];
 176+ default:
 177+ $newdata[ $value ] = $data[ $value ];
129178 }
130179
131180 $minfraud_hash[ $key ] = $newdata[ $value ];
@@ -174,22 +223,20 @@
175224 }
176225
177226 /**
178 - * Determine the actions for the processor to take
 227+ * Determine the action for the processor to take
179228 *
180229 * Determined based on predefined riskScore ranges for
181 - * a given action. It is possible to return multiple
182 - * ranges.
 230+ * a given action.
183231 * @param float risk score (returned from minFraud)
184232 * @return array of actions to be taken
185233 */
186 - public function determine_actions( $risk_score ) {
 234+ public function determine_action( $risk_score ) {
187235 $actions = array();
188236 foreach ( $this->action_ranges as $action => $range ) {
189237 if ( $risk_score >= $range[0] && $risk_score <= $range[1] ) {
190 - $actions[] = $action;
 238+ return $action;
191239 }
192240 }
193 - return $actions;
194241 }
195242
196243 /**
@@ -220,6 +267,29 @@
221268 }
222269
223270 /**
 271+ * Generate a hash of some data
 272+ * @param string the data to hash
 273+ * @return string The hash of the data
 274+ */
 275+ public function generate_hash( $data ) {
 276+ global $wgMinFraudSalt;
 277+ return hash( "sha512", $wgMinFraudSalt . $data );
 278+ }
 279+
 280+ /**
 281+ * Compare a hash to the hash of some given data
 282+ * @param string $hash A given hash
 283+ * @param strin $data The data to hash and compare to $hash
 284+ * @return bool
 285+ */
 286+ public function compare_hash( $hash, $data ) {
 287+ if ( $hash == $this->generate_hash( $data )) {
 288+ return TRUE;
 289+ }
 290+ return FALSE;
 291+ }
 292+
 293+ /**
224294 * Close the open log file handler if it's open
225295 */
226296 public function __destruct() {

Status & tagging log