Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php |
— | — | @@ -153,6 +153,7 @@ |
154 | 154 | // The submitted data is valid, so process it |
155 | 155 | //increase the count of attempts |
156 | 156 | ++$data['numAttempt']; |
| 157 | + wfRunHooks( 'PayflowGatewayValidate', array( &$this, &$data )) ; |
157 | 158 | $this->fnPayflowProcessTransaction( $data, $payflow_data ); |
158 | 159 | } |
159 | 160 | } else { |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/HTTPBase.php |
— | — | @@ -0,0 +1,434 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* HTTPBase.php |
| 5 | + * |
| 6 | + * Copyright (C) 2008 MaxMind, Inc. |
| 7 | + * |
| 8 | + * This library is free software; you can redistribute it and/or |
| 9 | + * modify it under the terms of the GNU Lesser General Public |
| 10 | + * License as published by the Free Software Foundation; either |
| 11 | + * version 2.1 of the License, or (at your option) any later version. |
| 12 | + * |
| 13 | + * This library is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | + * Lesser General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU Lesser General Public |
| 19 | + * License along with this library; if not, write to the Free Software |
| 20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | + */ |
| 22 | + |
| 23 | +class HTTPBase{ |
| 24 | + var $server; |
| 25 | + var $numservers; |
| 26 | + var $url; |
| 27 | + var $queries; |
| 28 | + var $allowed_fields; |
| 29 | + var $num_allowed_fields; |
| 30 | + var $outputstr; |
| 31 | + var $isSecure; |
| 32 | + var $timeout; |
| 33 | + var $debug; |
| 34 | + var $check_field; |
| 35 | + var $wsIpaddrRefreshTimeout; |
| 36 | + var $wsIpaddrCacheFile; |
| 37 | + var $useDNS; |
| 38 | + var $ipstr; |
| 39 | + function HTTPBase() { |
| 40 | + $this->isSecure = 0; |
| 41 | + $this->debug = 0; |
| 42 | + $this->timeout = 0; |
| 43 | + $this->check_field = "score"; |
| 44 | + $this->wsIpaddrRefreshTimeout = 18000; |
| 45 | + $this->wsIpaddrCacheFile = $this->_getTempDir()."/maxmind.ws.cache"; |
| 46 | + if ($this->debug == 1) { |
| 47 | + print "wsIpaddrRefreshTimeout: " . $this->wsIpaddrRefreshTimeout . "\n"; |
| 48 | + print "wsIpaddrCacheFile: " . $this->wsIpaddrCacheFile . "\n"; |
| 49 | + print "useDNS: " . $this->useDNS . "\n"; |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + // this function sets the checked field |
| 54 | + function set_check_field($f) { |
| 55 | + $check_field = $f; |
| 56 | + } |
| 57 | + |
| 58 | + // this function sets the allowed fields |
| 59 | + function set_allowed_fields($i) { |
| 60 | + $this->allowed_fields = $i; |
| 61 | + $this->num_allowed_fields = count($i); |
| 62 | + } |
| 63 | + |
| 64 | + //this function queries the servers |
| 65 | + function query() { |
| 66 | + //query every server in the list |
| 67 | + if (!$this->useDNS){ |
| 68 | + $ipstr = $this->readIpAddressFromCache(); |
| 69 | + if ($this->debug == 1){ |
| 70 | + print "using ip addresses, IPs are " . $ipstr . "\n"; |
| 71 | + } |
| 72 | + } |
| 73 | + // query every server using its ip address |
| 74 | + // if there was success reading the ip addresses |
| 75 | + // from the web or the cache file |
| 76 | + if ($ipstr) { |
| 77 | + $ipaddr = explode(";",$ipstr); |
| 78 | + $numipaddr = count($ipaddr); |
| 79 | + for ($i = 0;$i < $numipaddr;$i++){ |
| 80 | + $result = $this->querySingleServer($ipaddr[$i]); |
| 81 | + if ($this->debug == 1) { |
| 82 | + print "ip address: " . $ipaddr[$i] . "\n"; |
| 83 | + print "result: " . $result . "\n"; |
| 84 | + } |
| 85 | + if ($result) { |
| 86 | + return $result; |
| 87 | + } |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + // query every server using its domain name |
| 92 | + for ($i = 0; $i < $this->numservers; $i++ ) { |
| 93 | + $result = $this->querySingleServer($this->server[$i]); |
| 94 | + if ($this->debug == 1) { |
| 95 | + print "server: " . $this->server[$i] . "\nresult: " . $result . "\n"; |
| 96 | + } |
| 97 | + if ($result) { |
| 98 | + return $result; |
| 99 | + } |
| 100 | + } |
| 101 | + return 0; |
| 102 | + } |
| 103 | + |
| 104 | + // this function takes a input hash and stores it in the hash named queries |
| 105 | + function input($vars) { |
| 106 | + $numinputkeys = count($vars); // get the number of keys in the input hash |
| 107 | + $inputkeys = array_keys($vars); // get a array of keys in the input hash |
| 108 | + for ($i = 0; $i < $numinputkeys; $i++) { |
| 109 | + $key = $inputkeys[$i]; |
| 110 | + if ($this->allowed_fields[$key] == 1) { |
| 111 | + //if key is a allowed field then store it in |
| 112 | + //the hash named queries |
| 113 | + $this->queries[$key] = urlencode($this->filter_field($key, $vars[$key])); |
| 114 | + } else { |
| 115 | + print "invalid input $key - perhaps misspelled field?"; |
| 116 | + return 0; |
| 117 | + } |
| 118 | + } |
| 119 | + $this->queries["clientAPI"] = $this->API_VERSION; |
| 120 | + } |
| 121 | + |
| 122 | + //sub-class should override this if it needs to filter inputs |
| 123 | + function filter_field($key, $value) { |
| 124 | + return $value; |
| 125 | + } |
| 126 | + |
| 127 | + //this function returns the output from the server |
| 128 | + function output() { |
| 129 | + return $this->outputstr; |
| 130 | + } |
| 131 | + |
| 132 | + // write the ip Addresses and the time right now to |
| 133 | + // the cache file |
| 134 | + function writeIpAddressToCache($filename,$ipstr) { |
| 135 | + $datetime = time(); |
| 136 | + $fh = fopen($this->wsIpaddrCacheFile,'w'); |
| 137 | + fwrite($fh,$ipstr . "\n"); |
| 138 | + fwrite($fh,$datetime . "\n"); |
| 139 | + fclose($fh); |
| 140 | + if ($this->debug == 1) { |
| 141 | + print "writing ip address to cache\n"; |
| 142 | + print "ip str: " . $ipstr . "\n"; |
| 143 | + print "date time: " . $datetime . "\n"; |
| 144 | + } |
| 145 | + } |
| 146 | + |
| 147 | + function readIpAddressFromCache() { |
| 148 | + // if the cache file exists then |
| 149 | + // read the ip addresses and the time |
| 150 | + // IPs were cached |
| 151 | + if (file_exists($this->wsIpaddrCacheFile)) { |
| 152 | + $fh = fopen($this->wsIpaddrCacheFile,'r'); |
| 153 | + $ipstr = fgets($fh,1024); |
| 154 | + $ipstr = rtrim($ipstr); |
| 155 | + $datetime = fgets($fh,1024); |
| 156 | + $datetime = rtrim($datetime); |
| 157 | + fclose($fh); |
| 158 | + } |
| 159 | + |
| 160 | + // if the ip addresses expired or don't exist then |
| 161 | + // get them from the web and write |
| 162 | + // them to the cache file |
| 163 | + if (((time() - $datetime) > $this->wsIpaddrRefreshTimeout) | (!$ipstr)) { |
| 164 | + $tryIpstr = $this->readIpAddressFromWeb(); |
| 165 | + if ($tryIpstr) { |
| 166 | + $ipstr = $tryIpstr; |
| 167 | + } else { |
| 168 | + if ($this->debug == 1){ |
| 169 | + print "Warning, unable to get ws_ipaddr from www.maxmind.com\n"; |
| 170 | + } |
| 171 | + } |
| 172 | + // we write to cache whether or not we were able to get $tryIpStr, since |
| 173 | + // in case DNS goes down, we don't want to check app/ws_ipaddr over and over |
| 174 | + $this->writeIpAddressToCache($this->wsIpaddrCacheFile,$ipstr); |
| 175 | + } |
| 176 | + if ($this->debug == 1){ |
| 177 | + print "reading ip address from cache\n"; |
| 178 | + print "ip str: " . $ipstr . "\n"; |
| 179 | + print "date time: " . $datetime . "\n"; |
| 180 | + } |
| 181 | + //return the ip addresses |
| 182 | + return $ipstr; |
| 183 | + } |
| 184 | + |
| 185 | + function readIpAddressFromWeb() { |
| 186 | + //check if the curl module exists |
| 187 | + $url = "http://www.maxmind.com/app/ws_ipaddr"; |
| 188 | + if (extension_loaded('curl')) { |
| 189 | + // open curl |
| 190 | + $ch = curl_init(); |
| 191 | + |
| 192 | + // set curl options |
| 193 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
| 194 | + curl_setopt($ch, CURLOPT_URL, $url); |
| 195 | + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); |
| 196 | + |
| 197 | + //get the content |
| 198 | + $content = curl_exec($ch); |
| 199 | + $content = rtrim($content); |
| 200 | + if ($this->debug == 1) { |
| 201 | + print "using curl\n"; |
| 202 | + } |
| 203 | + } else { |
| 204 | + // we using HTTP without curl |
| 205 | + |
| 206 | + // parse the url to get |
| 207 | + // host, path and query |
| 208 | + $url3 = parse_url($url); |
| 209 | + $host = $url3["host"]; |
| 210 | + $path = $url3["path"]; |
| 211 | + |
| 212 | + // open the connection |
| 213 | + $fp = fsockopen ($host, 80, $errno, $errstr, $this->timeout); |
| 214 | + if ($fp) { |
| 215 | + // send the request |
| 216 | + fputs ($fp, "GET $path HTTP/1.0\nHost: " . $host . "\n\n"); |
| 217 | + while (!feof($fp)) { |
| 218 | + $buf .= fgets($fp, 128); |
| 219 | + } |
| 220 | + $lines = split("\n", $buf); |
| 221 | + // get the content |
| 222 | + $content = $lines[count($lines)-1]; |
| 223 | + //close the connection |
| 224 | + fclose($fp); |
| 225 | + } |
| 226 | + if ($this->debug == 1) { |
| 227 | + print "using fsockopen\n"; |
| 228 | + } |
| 229 | + } |
| 230 | + if ($this->debug == 1) { |
| 231 | + print "readIpAddressFromWeb found ip addresses: " . $content . "\n"; |
| 232 | + } |
| 233 | + // TODO fix regexp so that it checks if it only has IP addresses |
| 234 | + if (ereg ("([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})",$content)) { |
| 235 | + return $content; |
| 236 | + } |
| 237 | + return ""; |
| 238 | + } |
| 239 | + |
| 240 | + // this function queries a single server |
| 241 | + function querySingleServer($server) { |
| 242 | + // check if we using the Secure HTTPS proctol |
| 243 | + if ($this->isSecure == 1) { |
| 244 | + $scheme = "https://"; // Secure HTTPS proctol |
| 245 | + } else { |
| 246 | + $scheme = "http://"; // Regular HTTP proctol |
| 247 | + } |
| 248 | + |
| 249 | + // build a query string from the hash called queries |
| 250 | + $numquerieskeys = count($this->queries); // get the number of keys in the hash called queries |
| 251 | + $querieskeys = array_keys($this->queries); // get a array of keys in the hash called queries |
| 252 | + if ($this->debug == 1) { |
| 253 | + print "number of query keys " + $numquerieskeys + "\n"; |
| 254 | + } |
| 255 | + |
| 256 | + $query_string = ""; |
| 257 | + |
| 258 | + for ($i = 0; $i < $numquerieskeys; $i++) { |
| 259 | + //for each element in the hash called queries |
| 260 | + //append the key and value of the element to the query string |
| 261 | + $key = $querieskeys[$i]; |
| 262 | + $value = $this->queries[$key]; |
| 263 | + //encode the key and value before adding it to the string |
| 264 | + //$key = urlencode($key); |
| 265 | + //$value = urlencode($value); |
| 266 | + if ($this->debug == 1) { |
| 267 | + print " query key " . $key . " query value " . $value . "\n"; |
| 268 | + } |
| 269 | + $query_string = $query_string . $key . "=" . $value; |
| 270 | + if ($i < $numquerieskeys - 1) { |
| 271 | + $query_string = $query_string . "&"; |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + $content = ""; |
| 276 | + |
| 277 | + //check if the curl module exists |
| 278 | + if (extension_loaded('curl')) { |
| 279 | + //use curl |
| 280 | + if ($this->debug == 1) { |
| 281 | + print "using curl\n"; |
| 282 | + } |
| 283 | + |
| 284 | + //open curl |
| 285 | + $ch = curl_init(); |
| 286 | + |
| 287 | + $url = $scheme . $server . "/" . $this->url; |
| 288 | + |
| 289 | + //set curl options |
| 290 | + if ($this->debug == 1){ |
| 291 | + print "url " . $url . "\n"; |
| 292 | + } |
| 293 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
| 294 | + curl_setopt($ch, CURLOPT_URL, $url); |
| 295 | + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); |
| 296 | + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0); |
| 297 | + |
| 298 | + //this option lets you store the result in a string |
| 299 | + curl_setopt($ch, CURLOPT_POST, 1); |
| 300 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); |
| 301 | + |
| 302 | + //get the content |
| 303 | + $content = curl_exec($ch); |
| 304 | + |
| 305 | + // For some reason curl_errno returns an error even when function works |
| 306 | + // Until we figure this out, will ignore curl errors - (not good i know) |
| 307 | +// $e = curl_errno($ch);//get error or sucess |
| 308 | + |
| 309 | +// if (($e == 1) & ($this->isSecure == 1)) { |
| 310 | + // HTTPS does not work print error message |
| 311 | +// print "error: this version of curl does not support HTTPS try build curl with SSL or specify \$ccfs->isSecure = 0\n"; |
| 312 | +// } |
| 313 | +// if ($e > 0) { |
| 314 | + //we get a error msg print it |
| 315 | +// print "Received error message $e from curl: " . curl_error($ch) . "\n"; |
| 316 | +// return 0; |
| 317 | +// } |
| 318 | + //close curl |
| 319 | + curl_close($ch); |
| 320 | + } else { |
| 321 | + //curl does not exist |
| 322 | + //use the fsockopen function, |
| 323 | + //the fgets function and the fclose function |
| 324 | + if ($this->debug == 1) { |
| 325 | + print "using fsockopen for querySingleServer\n"; |
| 326 | + } |
| 327 | + |
| 328 | + $url = $scheme . $server . "/" . $this->url . "?" . $query_string; |
| 329 | + if ($this->debug == 1) { |
| 330 | + print "url " . $url . " " . "\n"; |
| 331 | + } |
| 332 | + |
| 333 | + //now check if we are using regular HTTP |
| 334 | + if ($this->isSecure == 0) { |
| 335 | + //we using regular HTTP |
| 336 | + |
| 337 | + //parse the url to get |
| 338 | + //host, path and query |
| 339 | + $url3 = parse_url($url); |
| 340 | + $host = $url3["host"]; |
| 341 | + $path = $url3["path"]; |
| 342 | + $query = $url3["query"]; |
| 343 | + |
| 344 | + //open the connection |
| 345 | + $fp = fsockopen ($host, 80, $errno, $errstr, $this->timeout); |
| 346 | + if ($fp) { |
| 347 | + //send the request |
| 348 | + $post = "POST $path HTTP/1.0\nHost: " . $host . "\nContent-type: application/x-www-form-urlencoded\nUser-Agent: Mozilla 4.0\nContent-length: " . strlen($query) . "\nConnection: close\n\n$query"; |
| 349 | + fputs ($fp, $post); |
| 350 | + while (!feof($fp)) { |
| 351 | + $buf .= fgets($fp, 128); |
| 352 | + } |
| 353 | + $lines = split("\n", $buf); |
| 354 | + // get the content |
| 355 | + $content = $lines[count($lines)-1]; |
| 356 | + //close the connection |
| 357 | + fclose($fp); |
| 358 | + } else { |
| 359 | + return 0; |
| 360 | + } |
| 361 | + } else { |
| 362 | + //secure HTTPS requires CURL |
| 363 | + print "error: you need to install curl if you want secure HTTPS or specify the variable to be $ccfs->isSecure = 0"; |
| 364 | + return 0; |
| 365 | + } |
| 366 | + } |
| 367 | + |
| 368 | + if ($this->debug == 1) { |
| 369 | + print "content = " . $content . "\n"; |
| 370 | + } |
| 371 | + // get the keys and values from |
| 372 | + // the string content and store them |
| 373 | + // the hash named outputstr |
| 374 | + |
| 375 | + // split content into pairs containing both |
| 376 | + // the key and the value |
| 377 | + $keyvaluepairs = explode(";",$content); |
| 378 | + |
| 379 | + //get the number of key and value pairs |
| 380 | + $numkeyvaluepairs = count($keyvaluepairs); |
| 381 | + |
| 382 | + //for each pair store key and value into the |
| 383 | + //hash named outputstr |
| 384 | + $this->outputstr = array(); |
| 385 | + for ($i = 0; $i < $numkeyvaluepairs; $i++) { |
| 386 | + //split the pair into a key and a value |
| 387 | + list($key,$value) = explode("=",$keyvaluepairs[$i]); |
| 388 | + if ($this->debug == 1) { |
| 389 | + print " output " . $key . " = " . $value . "\n"; |
| 390 | + } |
| 391 | + //store the key and the value into the |
| 392 | + //hash named outputstr |
| 393 | + $this->outputstr[$key] = $value; |
| 394 | + } |
| 395 | + //check if outputstr has the score if outputstr does not have |
| 396 | + //the score return 0 |
| 397 | + if ($this->outputstr[$this->check_field] == "") { |
| 398 | + return 0; |
| 399 | + } |
| 400 | + //one other way to do it |
| 401 | + //if (!array_key_exists("score",$this->outputstr)) { |
| 402 | + // return 0; |
| 403 | + //} |
| 404 | + return 1; |
| 405 | + } |
| 406 | + |
| 407 | + function _getTempDir() { |
| 408 | + if (ini_get('upload_tmp_dir')) { |
| 409 | + return ini_get('upload_tmp_dir'); |
| 410 | + } |
| 411 | + |
| 412 | + if (substr(PHP_OS, 0, 3) != 'WIN') { |
| 413 | + return '/tmp'; |
| 414 | + } |
| 415 | + |
| 416 | + if (isset($_ENV['TMP'])) { |
| 417 | + return $_ENV['TMP']; |
| 418 | + } |
| 419 | + |
| 420 | + if (isset($_ENV['TEMP'])) { |
| 421 | + return $_ENV['TEMP']; |
| 422 | + } |
| 423 | + |
| 424 | + if (is_dir('c:\\windows\\temp')) { |
| 425 | + return 'c:\\windows\\temp'; |
| 426 | + } |
| 427 | + |
| 428 | + if (is_dir('c:\\winnt\\temp')) { |
| 429 | + return 'c:\\winnt\\temp'; |
| 430 | + } |
| 431 | + |
| 432 | + return '.'; |
| 433 | + } |
| 434 | +} |
| 435 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/Example.php |
— | — | @@ -0,0 +1,87 @@ |
| 2 | +#!/usr/bin/php -q |
| 3 | +<?php |
| 4 | +require("CreditCardFraudDetection.php"); |
| 5 | + |
| 6 | +// Create a new CreditCardFraudDetection object |
| 7 | +$ccfs = new CreditCardFraudDetection; |
| 8 | + |
| 9 | +// Set inputs and store them in a hash |
| 10 | +// See http://www.maxmind.com/app/ccv for more details on the input fields |
| 11 | + |
| 12 | +// Enter your license key here (Required) |
| 13 | +$h["license_key"] = "XBCKSF4gnHA7"; |
| 14 | + |
| 15 | +// Required fields |
| 16 | +$h["i"] = "24.24.24.24"; // set the client ip address |
| 17 | +$h["city"] = "New York"; // set the billing city |
| 18 | +$h["region"] = "NY"; // set the billing state |
| 19 | +$h["postal"] = "11434"; // set the billing zip code |
| 20 | +$h["country"] = "US"; // set the billing country |
| 21 | + |
| 22 | +// Recommended fields |
| 23 | +$h["domain"] = "yahoo.com"; // Email domain |
| 24 | +$h["bin"] = "549099"; // bank identification number |
| 25 | +$h["forwardedIP"] = "24.24.24.25"; // X-Forwarded-For or Client-IP HTTP Header |
| 26 | +// CreditCardFraudDetection.php will take |
| 27 | +// MD5 hash of e-mail address passed to emailMD5 if it detects '@' in the string |
| 28 | +$h["emailMD5"] = "Adeeb@Hackstyle.com"; |
| 29 | +// CreditCardFraudDetection.php will take the MD5 hash of the username/password if the length of the string is not 32 |
| 30 | +$h["usernameMD5"] = "test_carder_username"; |
| 31 | +$h["passwordMD5"] = "test_carder_password"; |
| 32 | + |
| 33 | +// Optional fields |
| 34 | +$h["binName"] = "MBNA America Bank"; // bank name |
| 35 | +$h["binPhone"] = "800-421-2110"; // bank customer service phone number on back of credit card |
| 36 | +$h["custPhone"] = "212-242"; // Area-code and local prefix of customer phone number |
| 37 | +$h["requested_type"] = "premium"; // Which level (free, city, premium) of CCFD to use |
| 38 | +$h["shipAddr"] = "145-50 157TH STREET"; // Shipping Address |
| 39 | +$h["shipCity"] = "Jamaica"; // the City to Ship to |
| 40 | +$h["shipRegion"] = "NY"; // the Region to Ship to |
| 41 | +$h["shipPostal"] = "11434"; // the Postal Code to Ship to |
| 42 | +$h["shipCountry"] = "US"; // the country to Ship to |
| 43 | + |
| 44 | +$h["txnID"] = "1234"; // Transaction ID |
| 45 | +$h["sessionID"] = "abcd9876"; // Session ID |
| 46 | + |
| 47 | +$h["accept_language"] = "de-de"; |
| 48 | +$h["user_agent"] = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; de-de) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1"; |
| 49 | + |
| 50 | +// If you want to disable Secure HTTPS or don't have Curl and OpenSSL installed |
| 51 | +// uncomment the next line |
| 52 | +// $ccfs->isSecure = 0; |
| 53 | + |
| 54 | +// set the timeout to be five seconds |
| 55 | +$ccfs->timeout = 5; |
| 56 | + |
| 57 | +// uncomment to turn on debugging |
| 58 | +// $ccfs->debug = 1; |
| 59 | + |
| 60 | +// how many seconds to cache the ip addresses |
| 61 | +// $ccfs->wsIpaddrRefreshTimeout = 3600*5; |
| 62 | + |
| 63 | +// file to store the ip address for minfraud3.maxmind.com, minfraud1.maxmind.com and minfraud2.maxmind.com |
| 64 | +// $ccfs->wsIpaddrCacheFile = "/tmp/maxmind.ws.cache"; |
| 65 | + |
| 66 | +// if useDNS is 1 then use DNS, otherwise use ip addresses directly |
| 67 | +$ccfs->useDNS = 0; |
| 68 | + |
| 69 | +$ccfs->isSecure = 0; |
| 70 | + |
| 71 | +// next we set up the input hash |
| 72 | +$ccfs->input($h); |
| 73 | + |
| 74 | +// then we query the server |
| 75 | +$ccfs->query(); |
| 76 | + |
| 77 | +// then we get the result from the server |
| 78 | +$h = $ccfs->output(); |
| 79 | + |
| 80 | +// then finally we print out the result |
| 81 | +$outputkeys = array_keys($h); |
| 82 | +$numoutputkeys = count($h); |
| 83 | +for ($i = 0; $i < $numoutputkeys; $i++) { |
| 84 | + $key = $outputkeys[$i]; |
| 85 | + $value = $h[$key]; |
| 86 | + print $key . " = " . $value . "\n"; |
| 87 | +} |
| 88 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/LocationVerification.php |
— | — | @@ -0,0 +1,50 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* LocationVerification.php |
| 5 | + * |
| 6 | + * Copyright (C) 2005 MaxMind LLC |
| 7 | + * |
| 8 | + * This library is free software; you can redistribute it and/or |
| 9 | + * modify it under the terms of the GNU Lesser General Public |
| 10 | + * License as published by the Free Software Foundation; either |
| 11 | + * version 2.1 of the License, or (at your option) any later version. |
| 12 | + * |
| 13 | + * This library is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | + * Lesser General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU Lesser General Public |
| 19 | + * License along with this library; if not, write to the Free Software |
| 20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | + */ |
| 22 | + |
| 23 | +require_once ("HTTPBase.php"); |
| 24 | +class LocationVerification extends HTTPBase { |
| 25 | + var $server; |
| 26 | + var $numservers; |
| 27 | + var $API_VERSION; |
| 28 | + |
| 29 | + function LocationVerification() { |
| 30 | + $this->HTTPBase(); |
| 31 | + $this->isSecure = 1; // use HTTPS by default |
| 32 | + |
| 33 | + //set the allowed_fields hash |
| 34 | + $this->allowed_fields["i"] = 1; |
| 35 | + $this->allowed_fields["city"] = 1; |
| 36 | + $this->allowed_fields["region"] = 1; |
| 37 | + $this->allowed_fields["postal"] = 1; |
| 38 | + $this->allowed_fields["country"] = 1; |
| 39 | + $this->allowed_fields["license_key"] = 1; |
| 40 | + $this->num_allowed_fields = count($this->allowed_fields); |
| 41 | + |
| 42 | + //set the url of the web service |
| 43 | + $this->url = "app/locvr"; |
| 44 | + $this->check_field = "distance"; |
| 45 | + |
| 46 | + $this->server = array("www.maxmind.com", "www2.maxmind.com"); |
| 47 | + $this->numservers = count($this->server); |
| 48 | + $this->API_VERSION = 'PHP/1.4'; |
| 49 | + } |
| 50 | +} |
| 51 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/Example_locv.php |
— | — | @@ -0,0 +1,54 @@ |
| 2 | +#!/usr/bin/php -q |
| 3 | +<?php |
| 4 | +require("LocationVerification.php"); |
| 5 | + |
| 6 | +//first we create a new CreditCardFraudDetection object |
| 7 | +$locv = new LocationVerification; |
| 8 | + |
| 9 | +//Enter your license key here |
| 10 | +$h["license_key"] = "XBCKSF4gnHA7"; |
| 11 | + |
| 12 | +// Set inputs and store them in a hash |
| 13 | + |
| 14 | +// Required fields |
| 15 | +$h["i"] = "24.24.24.24"; // set the client ip address |
| 16 | +$h["city"] = "New York"; // set the billing city |
| 17 | +$h["region"] = "NY"; // set the billing state |
| 18 | +$h["postal"] = "10011"; // set the billing zip code |
| 19 | +$h["country"] = "US"; // set the billing country |
| 20 | + |
| 21 | +// If you want to disable Secure HTTPS or don't have Curl and OpenSSL installed |
| 22 | +// uncomment the next line |
| 23 | +// $locv->isSecure = 0; |
| 24 | + |
| 25 | +// how many seconds to cache the ip addresses |
| 26 | +$locv->wsIpaddrRefreshTimeout = 3600*5; |
| 27 | +// file to store the ip address |
| 28 | +$locv->wsIpaddrCacheFile = "/tmp/maxmind.ws.cache"; |
| 29 | +// if useDNS is 1 then use DNS, otherwise use ip addresses directly |
| 30 | +// $locv->useDNS = 1; |
| 31 | + |
| 32 | +// set the time out to be five seconds |
| 33 | +$locv->timeout = 5; |
| 34 | + |
| 35 | +// uncomment to turn on debugging |
| 36 | +$locv->debug = 1; |
| 37 | + |
| 38 | +// next we set up the input hash |
| 39 | +$locv->input($h); |
| 40 | + |
| 41 | +// then we query the server |
| 42 | +$locv->query(); |
| 43 | + |
| 44 | +// then we get the result from the server |
| 45 | +$h = $locv->output(); |
| 46 | + |
| 47 | +// then finally we print out the result |
| 48 | +$outputkeys = array_keys($h); |
| 49 | +$numoutputkeys = count($h); |
| 50 | +for ($i = 0; $i < $numoutputkeys; $i++) { |
| 51 | + $key = $outputkeys[$i]; |
| 52 | + $value = $h[$key]; |
| 53 | + print $key . " = " . $value . "\n"; |
| 54 | +} |
| 55 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/COPYING |
— | — | @@ -0,0 +1,504 @@ |
| 2 | + GNU LESSER GENERAL PUBLIC LICENSE |
| 3 | + Version 2.1, February 1999 |
| 4 | + |
| 5 | + Copyright (C) 1991, 1999 Free Software Foundation, Inc. |
| 6 | + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 7 | + Everyone is permitted to copy and distribute verbatim copies |
| 8 | + of this license document, but changing it is not allowed. |
| 9 | + |
| 10 | +[This is the first released version of the Lesser GPL. It also counts |
| 11 | + as the successor of the GNU Library Public License, version 2, hence |
| 12 | + the version number 2.1.] |
| 13 | + |
| 14 | + Preamble |
| 15 | + |
| 16 | + The licenses for most software are designed to take away your |
| 17 | +freedom to share and change it. By contrast, the GNU General Public |
| 18 | +Licenses are intended to guarantee your freedom to share and change |
| 19 | +free software--to make sure the software is free for all its users. |
| 20 | + |
| 21 | + This license, the Lesser General Public License, applies to some |
| 22 | +specially designated software packages--typically libraries--of the |
| 23 | +Free Software Foundation and other authors who decide to use it. You |
| 24 | +can use it too, but we suggest you first think carefully about whether |
| 25 | +this license or the ordinary General Public License is the better |
| 26 | +strategy to use in any particular case, based on the explanations below. |
| 27 | + |
| 28 | + When we speak of free software, we are referring to freedom of use, |
| 29 | +not price. Our General Public Licenses are designed to make sure that |
| 30 | +you have the freedom to distribute copies of free software (and charge |
| 31 | +for this service if you wish); that you receive source code or can get |
| 32 | +it if you want it; that you can change the software and use pieces of |
| 33 | +it in new free programs; and that you are informed that you can do |
| 34 | +these things. |
| 35 | + |
| 36 | + To protect your rights, we need to make restrictions that forbid |
| 37 | +distributors to deny you these rights or to ask you to surrender these |
| 38 | +rights. These restrictions translate to certain responsibilities for |
| 39 | +you if you distribute copies of the library or if you modify it. |
| 40 | + |
| 41 | + For example, if you distribute copies of the library, whether gratis |
| 42 | +or for a fee, you must give the recipients all the rights that we gave |
| 43 | +you. You must make sure that they, too, receive or can get the source |
| 44 | +code. If you link other code with the library, you must provide |
| 45 | +complete object files to the recipients, so that they can relink them |
| 46 | +with the library after making changes to the library and recompiling |
| 47 | +it. And you must show them these terms so they know their rights. |
| 48 | + |
| 49 | + We protect your rights with a two-step method: (1) we copyright the |
| 50 | +library, and (2) we offer you this license, which gives you legal |
| 51 | +permission to copy, distribute and/or modify the library. |
| 52 | + |
| 53 | + To protect each distributor, we want to make it very clear that |
| 54 | +there is no warranty for the free library. Also, if the library is |
| 55 | +modified by someone else and passed on, the recipients should know |
| 56 | +that what they have is not the original version, so that the original |
| 57 | +author's reputation will not be affected by problems that might be |
| 58 | +introduced by others. |
| 59 | + |
| 60 | + Finally, software patents pose a constant threat to the existence of |
| 61 | +any free program. We wish to make sure that a company cannot |
| 62 | +effectively restrict the users of a free program by obtaining a |
| 63 | +restrictive license from a patent holder. Therefore, we insist that |
| 64 | +any patent license obtained for a version of the library must be |
| 65 | +consistent with the full freedom of use specified in this license. |
| 66 | + |
| 67 | + Most GNU software, including some libraries, is covered by the |
| 68 | +ordinary GNU General Public License. This license, the GNU Lesser |
| 69 | +General Public License, applies to certain designated libraries, and |
| 70 | +is quite different from the ordinary General Public License. We use |
| 71 | +this license for certain libraries in order to permit linking those |
| 72 | +libraries into non-free programs. |
| 73 | + |
| 74 | + When a program is linked with a library, whether statically or using |
| 75 | +a shared library, the combination of the two is legally speaking a |
| 76 | +combined work, a derivative of the original library. The ordinary |
| 77 | +General Public License therefore permits such linking only if the |
| 78 | +entire combination fits its criteria of freedom. The Lesser General |
| 79 | +Public License permits more lax criteria for linking other code with |
| 80 | +the library. |
| 81 | + |
| 82 | + We call this license the "Lesser" General Public License because it |
| 83 | +does Less to protect the user's freedom than the ordinary General |
| 84 | +Public License. It also provides other free software developers Less |
| 85 | +of an advantage over competing non-free programs. These disadvantages |
| 86 | +are the reason we use the ordinary General Public License for many |
| 87 | +libraries. However, the Lesser license provides advantages in certain |
| 88 | +special circumstances. |
| 89 | + |
| 90 | + For example, on rare occasions, there may be a special need to |
| 91 | +encourage the widest possible use of a certain library, so that it becomes |
| 92 | +a de-facto standard. To achieve this, non-free programs must be |
| 93 | +allowed to use the library. A more frequent case is that a free |
| 94 | +library does the same job as widely used non-free libraries. In this |
| 95 | +case, there is little to gain by limiting the free library to free |
| 96 | +software only, so we use the Lesser General Public License. |
| 97 | + |
| 98 | + In other cases, permission to use a particular library in non-free |
| 99 | +programs enables a greater number of people to use a large body of |
| 100 | +free software. For example, permission to use the GNU C Library in |
| 101 | +non-free programs enables many more people to use the whole GNU |
| 102 | +operating system, as well as its variant, the GNU/Linux operating |
| 103 | +system. |
| 104 | + |
| 105 | + Although the Lesser General Public License is Less protective of the |
| 106 | +users' freedom, it does ensure that the user of a program that is |
| 107 | +linked with the Library has the freedom and the wherewithal to run |
| 108 | +that program using a modified version of the Library. |
| 109 | + |
| 110 | + The precise terms and conditions for copying, distribution and |
| 111 | +modification follow. Pay close attention to the difference between a |
| 112 | +"work based on the library" and a "work that uses the library". The |
| 113 | +former contains code derived from the library, whereas the latter must |
| 114 | +be combined with the library in order to run. |
| 115 | + |
| 116 | + GNU LESSER GENERAL PUBLIC LICENSE |
| 117 | + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
| 118 | + |
| 119 | + 0. This License Agreement applies to any software library or other |
| 120 | +program which contains a notice placed by the copyright holder or |
| 121 | +other authorized party saying it may be distributed under the terms of |
| 122 | +this Lesser General Public License (also called "this License"). |
| 123 | +Each licensee is addressed as "you". |
| 124 | + |
| 125 | + A "library" means a collection of software functions and/or data |
| 126 | +prepared so as to be conveniently linked with application programs |
| 127 | +(which use some of those functions and data) to form executables. |
| 128 | + |
| 129 | + The "Library", below, refers to any such software library or work |
| 130 | +which has been distributed under these terms. A "work based on the |
| 131 | +Library" means either the Library or any derivative work under |
| 132 | +copyright law: that is to say, a work containing the Library or a |
| 133 | +portion of it, either verbatim or with modifications and/or translated |
| 134 | +straightforwardly into another language. (Hereinafter, translation is |
| 135 | +included without limitation in the term "modification".) |
| 136 | + |
| 137 | + "Source code" for a work means the preferred form of the work for |
| 138 | +making modifications to it. For a library, complete source code means |
| 139 | +all the source code for all modules it contains, plus any associated |
| 140 | +interface definition files, plus the scripts used to control compilation |
| 141 | +and installation of the library. |
| 142 | + |
| 143 | + Activities other than copying, distribution and modification are not |
| 144 | +covered by this License; they are outside its scope. The act of |
| 145 | +running a program using the Library is not restricted, and output from |
| 146 | +such a program is covered only if its contents constitute a work based |
| 147 | +on the Library (independent of the use of the Library in a tool for |
| 148 | +writing it). Whether that is true depends on what the Library does |
| 149 | +and what the program that uses the Library does. |
| 150 | + |
| 151 | + 1. You may copy and distribute verbatim copies of the Library's |
| 152 | +complete source code as you receive it, in any medium, provided that |
| 153 | +you conspicuously and appropriately publish on each copy an |
| 154 | +appropriate copyright notice and disclaimer of warranty; keep intact |
| 155 | +all the notices that refer to this License and to the absence of any |
| 156 | +warranty; and distribute a copy of this License along with the |
| 157 | +Library. |
| 158 | + |
| 159 | + You may charge a fee for the physical act of transferring a copy, |
| 160 | +and you may at your option offer warranty protection in exchange for a |
| 161 | +fee. |
| 162 | + |
| 163 | + 2. You may modify your copy or copies of the Library or any portion |
| 164 | +of it, thus forming a work based on the Library, and copy and |
| 165 | +distribute such modifications or work under the terms of Section 1 |
| 166 | +above, provided that you also meet all of these conditions: |
| 167 | + |
| 168 | + a) The modified work must itself be a software library. |
| 169 | + |
| 170 | + b) You must cause the files modified to carry prominent notices |
| 171 | + stating that you changed the files and the date of any change. |
| 172 | + |
| 173 | + c) You must cause the whole of the work to be licensed at no |
| 174 | + charge to all third parties under the terms of this License. |
| 175 | + |
| 176 | + d) If a facility in the modified Library refers to a function or a |
| 177 | + table of data to be supplied by an application program that uses |
| 178 | + the facility, other than as an argument passed when the facility |
| 179 | + is invoked, then you must make a good faith effort to ensure that, |
| 180 | + in the event an application does not supply such function or |
| 181 | + table, the facility still operates, and performs whatever part of |
| 182 | + its purpose remains meaningful. |
| 183 | + |
| 184 | + (For example, a function in a library to compute square roots has |
| 185 | + a purpose that is entirely well-defined independent of the |
| 186 | + application. Therefore, Subsection 2d requires that any |
| 187 | + application-supplied function or table used by this function must |
| 188 | + be optional: if the application does not supply it, the square |
| 189 | + root function must still compute square roots.) |
| 190 | + |
| 191 | +These requirements apply to the modified work as a whole. If |
| 192 | +identifiable sections of that work are not derived from the Library, |
| 193 | +and can be reasonably considered independent and separate works in |
| 194 | +themselves, then this License, and its terms, do not apply to those |
| 195 | +sections when you distribute them as separate works. But when you |
| 196 | +distribute the same sections as part of a whole which is a work based |
| 197 | +on the Library, the distribution of the whole must be on the terms of |
| 198 | +this License, whose permissions for other licensees extend to the |
| 199 | +entire whole, and thus to each and every part regardless of who wrote |
| 200 | +it. |
| 201 | + |
| 202 | +Thus, it is not the intent of this section to claim rights or contest |
| 203 | +your rights to work written entirely by you; rather, the intent is to |
| 204 | +exercise the right to control the distribution of derivative or |
| 205 | +collective works based on the Library. |
| 206 | + |
| 207 | +In addition, mere aggregation of another work not based on the Library |
| 208 | +with the Library (or with a work based on the Library) on a volume of |
| 209 | +a storage or distribution medium does not bring the other work under |
| 210 | +the scope of this License. |
| 211 | + |
| 212 | + 3. You may opt to apply the terms of the ordinary GNU General Public |
| 213 | +License instead of this License to a given copy of the Library. To do |
| 214 | +this, you must alter all the notices that refer to this License, so |
| 215 | +that they refer to the ordinary GNU General Public License, version 2, |
| 216 | +instead of to this License. (If a newer version than version 2 of the |
| 217 | +ordinary GNU General Public License has appeared, then you can specify |
| 218 | +that version instead if you wish.) Do not make any other change in |
| 219 | +these notices. |
| 220 | + |
| 221 | + Once this change is made in a given copy, it is irreversible for |
| 222 | +that copy, so the ordinary GNU General Public License applies to all |
| 223 | +subsequent copies and derivative works made from that copy. |
| 224 | + |
| 225 | + This option is useful when you wish to copy part of the code of |
| 226 | +the Library into a program that is not a library. |
| 227 | + |
| 228 | + 4. You may copy and distribute the Library (or a portion or |
| 229 | +derivative of it, under Section 2) in object code or executable form |
| 230 | +under the terms of Sections 1 and 2 above provided that you accompany |
| 231 | +it with the complete corresponding machine-readable source code, which |
| 232 | +must be distributed under the terms of Sections 1 and 2 above on a |
| 233 | +medium customarily used for software interchange. |
| 234 | + |
| 235 | + If distribution of object code is made by offering access to copy |
| 236 | +from a designated place, then offering equivalent access to copy the |
| 237 | +source code from the same place satisfies the requirement to |
| 238 | +distribute the source code, even though third parties are not |
| 239 | +compelled to copy the source along with the object code. |
| 240 | + |
| 241 | + 5. A program that contains no derivative of any portion of the |
| 242 | +Library, but is designed to work with the Library by being compiled or |
| 243 | +linked with it, is called a "work that uses the Library". Such a |
| 244 | +work, in isolation, is not a derivative work of the Library, and |
| 245 | +therefore falls outside the scope of this License. |
| 246 | + |
| 247 | + However, linking a "work that uses the Library" with the Library |
| 248 | +creates an executable that is a derivative of the Library (because it |
| 249 | +contains portions of the Library), rather than a "work that uses the |
| 250 | +library". The executable is therefore covered by this License. |
| 251 | +Section 6 states terms for distribution of such executables. |
| 252 | + |
| 253 | + When a "work that uses the Library" uses material from a header file |
| 254 | +that is part of the Library, the object code for the work may be a |
| 255 | +derivative work of the Library even though the source code is not. |
| 256 | +Whether this is true is especially significant if the work can be |
| 257 | +linked without the Library, or if the work is itself a library. The |
| 258 | +threshold for this to be true is not precisely defined by law. |
| 259 | + |
| 260 | + If such an object file uses only numerical parameters, data |
| 261 | +structure layouts and accessors, and small macros and small inline |
| 262 | +functions (ten lines or less in length), then the use of the object |
| 263 | +file is unrestricted, regardless of whether it is legally a derivative |
| 264 | +work. (Executables containing this object code plus portions of the |
| 265 | +Library will still fall under Section 6.) |
| 266 | + |
| 267 | + Otherwise, if the work is a derivative of the Library, you may |
| 268 | +distribute the object code for the work under the terms of Section 6. |
| 269 | +Any executables containing that work also fall under Section 6, |
| 270 | +whether or not they are linked directly with the Library itself. |
| 271 | + |
| 272 | + 6. As an exception to the Sections above, you may also combine or |
| 273 | +link a "work that uses the Library" with the Library to produce a |
| 274 | +work containing portions of the Library, and distribute that work |
| 275 | +under terms of your choice, provided that the terms permit |
| 276 | +modification of the work for the customer's own use and reverse |
| 277 | +engineering for debugging such modifications. |
| 278 | + |
| 279 | + You must give prominent notice with each copy of the work that the |
| 280 | +Library is used in it and that the Library and its use are covered by |
| 281 | +this License. You must supply a copy of this License. If the work |
| 282 | +during execution displays copyright notices, you must include the |
| 283 | +copyright notice for the Library among them, as well as a reference |
| 284 | +directing the user to the copy of this License. Also, you must do one |
| 285 | +of these things: |
| 286 | + |
| 287 | + a) Accompany the work with the complete corresponding |
| 288 | + machine-readable source code for the Library including whatever |
| 289 | + changes were used in the work (which must be distributed under |
| 290 | + Sections 1 and 2 above); and, if the work is an executable linked |
| 291 | + with the Library, with the complete machine-readable "work that |
| 292 | + uses the Library", as object code and/or source code, so that the |
| 293 | + user can modify the Library and then relink to produce a modified |
| 294 | + executable containing the modified Library. (It is understood |
| 295 | + that the user who changes the contents of definitions files in the |
| 296 | + Library will not necessarily be able to recompile the application |
| 297 | + to use the modified definitions.) |
| 298 | + |
| 299 | + b) Use a suitable shared library mechanism for linking with the |
| 300 | + Library. A suitable mechanism is one that (1) uses at run time a |
| 301 | + copy of the library already present on the user's computer system, |
| 302 | + rather than copying library functions into the executable, and (2) |
| 303 | + will operate properly with a modified version of the library, if |
| 304 | + the user installs one, as long as the modified version is |
| 305 | + interface-compatible with the version that the work was made with. |
| 306 | + |
| 307 | + c) Accompany the work with a written offer, valid for at |
| 308 | + least three years, to give the same user the materials |
| 309 | + specified in Subsection 6a, above, for a charge no more |
| 310 | + than the cost of performing this distribution. |
| 311 | + |
| 312 | + d) If distribution of the work is made by offering access to copy |
| 313 | + from a designated place, offer equivalent access to copy the above |
| 314 | + specified materials from the same place. |
| 315 | + |
| 316 | + e) Verify that the user has already received a copy of these |
| 317 | + materials or that you have already sent this user a copy. |
| 318 | + |
| 319 | + For an executable, the required form of the "work that uses the |
| 320 | +Library" must include any data and utility programs needed for |
| 321 | +reproducing the executable from it. However, as a special exception, |
| 322 | +the materials to be distributed need not include anything that is |
| 323 | +normally distributed (in either source or binary form) with the major |
| 324 | +components (compiler, kernel, and so on) of the operating system on |
| 325 | +which the executable runs, unless that component itself accompanies |
| 326 | +the executable. |
| 327 | + |
| 328 | + It may happen that this requirement contradicts the license |
| 329 | +restrictions of other proprietary libraries that do not normally |
| 330 | +accompany the operating system. Such a contradiction means you cannot |
| 331 | +use both them and the Library together in an executable that you |
| 332 | +distribute. |
| 333 | + |
| 334 | + 7. You may place library facilities that are a work based on the |
| 335 | +Library side-by-side in a single library together with other library |
| 336 | +facilities not covered by this License, and distribute such a combined |
| 337 | +library, provided that the separate distribution of the work based on |
| 338 | +the Library and of the other library facilities is otherwise |
| 339 | +permitted, and provided that you do these two things: |
| 340 | + |
| 341 | + a) Accompany the combined library with a copy of the same work |
| 342 | + based on the Library, uncombined with any other library |
| 343 | + facilities. This must be distributed under the terms of the |
| 344 | + Sections above. |
| 345 | + |
| 346 | + b) Give prominent notice with the combined library of the fact |
| 347 | + that part of it is a work based on the Library, and explaining |
| 348 | + where to find the accompanying uncombined form of the same work. |
| 349 | + |
| 350 | + 8. You may not copy, modify, sublicense, link with, or distribute |
| 351 | +the Library except as expressly provided under this License. Any |
| 352 | +attempt otherwise to copy, modify, sublicense, link with, or |
| 353 | +distribute the Library is void, and will automatically terminate your |
| 354 | +rights under this License. However, parties who have received copies, |
| 355 | +or rights, from you under this License will not have their licenses |
| 356 | +terminated so long as such parties remain in full compliance. |
| 357 | + |
| 358 | + 9. You are not required to accept this License, since you have not |
| 359 | +signed it. However, nothing else grants you permission to modify or |
| 360 | +distribute the Library or its derivative works. These actions are |
| 361 | +prohibited by law if you do not accept this License. Therefore, by |
| 362 | +modifying or distributing the Library (or any work based on the |
| 363 | +Library), you indicate your acceptance of this License to do so, and |
| 364 | +all its terms and conditions for copying, distributing or modifying |
| 365 | +the Library or works based on it. |
| 366 | + |
| 367 | + 10. Each time you redistribute the Library (or any work based on the |
| 368 | +Library), the recipient automatically receives a license from the |
| 369 | +original licensor to copy, distribute, link with or modify the Library |
| 370 | +subject to these terms and conditions. You may not impose any further |
| 371 | +restrictions on the recipients' exercise of the rights granted herein. |
| 372 | +You are not responsible for enforcing compliance by third parties with |
| 373 | +this License. |
| 374 | + |
| 375 | + 11. If, as a consequence of a court judgment or allegation of patent |
| 376 | +infringement or for any other reason (not limited to patent issues), |
| 377 | +conditions are imposed on you (whether by court order, agreement or |
| 378 | +otherwise) that contradict the conditions of this License, they do not |
| 379 | +excuse you from the conditions of this License. If you cannot |
| 380 | +distribute so as to satisfy simultaneously your obligations under this |
| 381 | +License and any other pertinent obligations, then as a consequence you |
| 382 | +may not distribute the Library at all. For example, if a patent |
| 383 | +license would not permit royalty-free redistribution of the Library by |
| 384 | +all those who receive copies directly or indirectly through you, then |
| 385 | +the only way you could satisfy both it and this License would be to |
| 386 | +refrain entirely from distribution of the Library. |
| 387 | + |
| 388 | +If any portion of this section is held invalid or unenforceable under any |
| 389 | +particular circumstance, the balance of the section is intended to apply, |
| 390 | +and the section as a whole is intended to apply in other circumstances. |
| 391 | + |
| 392 | +It is not the purpose of this section to induce you to infringe any |
| 393 | +patents or other property right claims or to contest validity of any |
| 394 | +such claims; this section has the sole purpose of protecting the |
| 395 | +integrity of the free software distribution system which is |
| 396 | +implemented by public license practices. Many people have made |
| 397 | +generous contributions to the wide range of software distributed |
| 398 | +through that system in reliance on consistent application of that |
| 399 | +system; it is up to the author/donor to decide if he or she is willing |
| 400 | +to distribute software through any other system and a licensee cannot |
| 401 | +impose that choice. |
| 402 | + |
| 403 | +This section is intended to make thoroughly clear what is believed to |
| 404 | +be a consequence of the rest of this License. |
| 405 | + |
| 406 | + 12. If the distribution and/or use of the Library is restricted in |
| 407 | +certain countries either by patents or by copyrighted interfaces, the |
| 408 | +original copyright holder who places the Library under this License may add |
| 409 | +an explicit geographical distribution limitation excluding those countries, |
| 410 | +so that distribution is permitted only in or among countries not thus |
| 411 | +excluded. In such case, this License incorporates the limitation as if |
| 412 | +written in the body of this License. |
| 413 | + |
| 414 | + 13. The Free Software Foundation may publish revised and/or new |
| 415 | +versions of the Lesser General Public License from time to time. |
| 416 | +Such new versions will be similar in spirit to the present version, |
| 417 | +but may differ in detail to address new problems or concerns. |
| 418 | + |
| 419 | +Each version is given a distinguishing version number. If the Library |
| 420 | +specifies a version number of this License which applies to it and |
| 421 | +"any later version", you have the option of following the terms and |
| 422 | +conditions either of that version or of any later version published by |
| 423 | +the Free Software Foundation. If the Library does not specify a |
| 424 | +license version number, you may choose any version ever published by |
| 425 | +the Free Software Foundation. |
| 426 | + |
| 427 | + 14. If you wish to incorporate parts of the Library into other free |
| 428 | +programs whose distribution conditions are incompatible with these, |
| 429 | +write to the author to ask for permission. For software which is |
| 430 | +copyrighted by the Free Software Foundation, write to the Free |
| 431 | +Software Foundation; we sometimes make exceptions for this. Our |
| 432 | +decision will be guided by the two goals of preserving the free status |
| 433 | +of all derivatives of our free software and of promoting the sharing |
| 434 | +and reuse of software generally. |
| 435 | + |
| 436 | + NO WARRANTY |
| 437 | + |
| 438 | + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO |
| 439 | +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. |
| 440 | +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR |
| 441 | +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY |
| 442 | +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE |
| 443 | +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 444 | +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE |
| 445 | +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME |
| 446 | +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
| 447 | + |
| 448 | + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN |
| 449 | +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY |
| 450 | +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU |
| 451 | +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR |
| 452 | +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE |
| 453 | +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING |
| 454 | +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A |
| 455 | +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF |
| 456 | +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
| 457 | +DAMAGES. |
| 458 | + |
| 459 | + END OF TERMS AND CONDITIONS |
| 460 | + |
| 461 | + How to Apply These Terms to Your New Libraries |
| 462 | + |
| 463 | + If you develop a new library, and you want it to be of the greatest |
| 464 | +possible use to the public, we recommend making it free software that |
| 465 | +everyone can redistribute and change. You can do so by permitting |
| 466 | +redistribution under these terms (or, alternatively, under the terms of the |
| 467 | +ordinary General Public License). |
| 468 | + |
| 469 | + To apply these terms, attach the following notices to the library. It is |
| 470 | +safest to attach them to the start of each source file to most effectively |
| 471 | +convey the exclusion of warranty; and each file should have at least the |
| 472 | +"copyright" line and a pointer to where the full notice is found. |
| 473 | + |
| 474 | + <one line to give the library's name and a brief idea of what it does.> |
| 475 | + Copyright (C) <year> <name of author> |
| 476 | + |
| 477 | + This library is free software; you can redistribute it and/or |
| 478 | + modify it under the terms of the GNU Lesser General Public |
| 479 | + License as published by the Free Software Foundation; either |
| 480 | + version 2.1 of the License, or (at your option) any later version. |
| 481 | + |
| 482 | + This library is distributed in the hope that it will be useful, |
| 483 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 484 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 485 | + Lesser General Public License for more details. |
| 486 | + |
| 487 | + You should have received a copy of the GNU Lesser General Public |
| 488 | + License along with this library; if not, write to the Free Software |
| 489 | + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 490 | + |
| 491 | +Also add information on how to contact you by electronic and paper mail. |
| 492 | + |
| 493 | +You should also get your employer (if you work as a programmer) or your |
| 494 | +school, if any, to sign a "copyright disclaimer" for the library, if |
| 495 | +necessary. Here is a sample; alter the names: |
| 496 | + |
| 497 | + Yoyodyne, Inc., hereby disclaims all copyright interest in the |
| 498 | + library `Frob' (a library for tweaking knobs) written by James Random Hacker. |
| 499 | + |
| 500 | + <signature of Ty Coon>, 1 April 1990 |
| 501 | + Ty Coon, President of Vice |
| 502 | + |
| 503 | +That's all there is to it! |
| 504 | + |
| 505 | + |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/Changes |
— | — | @@ -0,0 +1,42 @@ |
| 2 | +Revision history for MaxMind CreditCardFraudDetection PHP API |
| 3 | +1.49 Februar 19th 2009 |
| 4 | + - Add minfraud3.maxmind.com to the server list ( Boris Zentner ) |
| 5 | +1.48 October 3th 2008 |
| 6 | + - Add new optional fields user_agent and accept_language for CCFD requests ( Boris Zentner ) |
| 7 | + |
| 8 | +1.47 April 25th 2008 |
| 9 | + - Changed license from GPL to LGPL |
| 10 | + |
| 11 | +1.46 October 4th 2007 |
| 12 | + - Replaced www.maxmind.com and www2.maxmind.com with minfraud1.maxmind.com and minfraud2.maxmind.com |
| 13 | + |
| 14 | +1.43 October 3rd 2006 |
| 15 | + - Added support for new input fields, usernameMD5 and passwordMD5 |
| 16 | + - Changed require ("HTTPBase.php") to require_once ("HTTPBase.php") |
| 17 | + in case both CCFD and Telephone Verification files are used (Mike Mallinson) |
| 18 | + |
| 19 | +1.4 August 8th 2005 |
| 20 | + - Added support for Telephone Verification |
| 21 | + - Use POST method instead of GET method, fixes bug where query string |
| 22 | + was truncated |
| 23 | + - Added support for bypassing DNS using IP addresses |
| 24 | + - Added shipCity shipRegion shipPostal shipCountry to list of input fields |
| 25 | + |
| 26 | +1.3 February 9th 2005 |
| 27 | + - Added requested_type, forwardedIP, emailMD5, shipAddr, |
| 28 | + txnID, sessionID to list of input fields |
| 29 | + - Added LocationVerification.php |
| 30 | + - Replaced global variables with class fields (David Recordon) |
| 31 | + |
| 32 | +1.2 July 2nd 2004 |
| 33 | + - Added binName, binPhone, custPhone to list of input fields |
| 34 | + |
| 35 | +1.1 June 8th 2004 |
| 36 | + - Replaced h1 and h2 servers with www and www2 (all ending with maxmind.com) |
| 37 | + - Fixed URL encoding bug |
| 38 | + - Fixed curl code |
| 39 | + - Added debug and timeout options |
| 40 | + - Failover if score field not set |
| 41 | + |
| 42 | +1.0 May 5st 2004 |
| 43 | + - original version |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/CreditCardFraudDetection.php |
— | — | @@ -0,0 +1,83 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* CreditCardFraudDetection.php |
| 5 | + * |
| 6 | + * Copyright (C) 2008 MaxMind, Inc. |
| 7 | + * |
| 8 | + * This library is free software; you can redistribute it and/or |
| 9 | + * modify it under the terms of the GNU Lesser General Public |
| 10 | + * License as published by the Free Software Foundation; either |
| 11 | + * version 2.1 of the License, or (at your option) any later version. |
| 12 | + * |
| 13 | + * This library is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | + * Lesser General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU Lesser General Public |
| 19 | + * License along with this library; if not, write to the Free Software |
| 20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | + */ |
| 22 | + |
| 23 | +require_once ("HTTPBase.php"); |
| 24 | +class CreditCardFraudDetection extends HTTPBase { |
| 25 | + var $server; |
| 26 | + var $numservers; |
| 27 | + var $API_VERSION; |
| 28 | + |
| 29 | + function CreditCardFraudDetection() { |
| 30 | + $this->HTTPBase(); |
| 31 | + $this->isSecure = 1; // use HTTPS by default |
| 32 | + |
| 33 | + //set the allowed_fields hash |
| 34 | + $this->allowed_fields["i"] = 1; |
| 35 | + $this->allowed_fields["domain"] = 1; |
| 36 | + $this->allowed_fields["city"] = 1; |
| 37 | + $this->allowed_fields["region"] = 1; |
| 38 | + $this->allowed_fields["postal"] = 1; |
| 39 | + $this->allowed_fields["country"] = 1; |
| 40 | + $this->allowed_fields["bin"] = 1; |
| 41 | + $this->allowed_fields["binName"] = 1; |
| 42 | + $this->allowed_fields["binPhone"] = 1; |
| 43 | + $this->allowed_fields["custPhone"] = 1; |
| 44 | + $this->allowed_fields["license_key"] = 1; |
| 45 | + $this->allowed_fields["requested_type"] = 1; |
| 46 | + $this->allowed_fields["forwardedIP"] = 1; |
| 47 | + $this->allowed_fields["emailMD5"] = 1; |
| 48 | + $this->allowed_fields["shipAddr"] = 1; |
| 49 | + $this->allowed_fields["shipCity"] = 1; |
| 50 | + $this->allowed_fields["shipRegion"] = 1; |
| 51 | + $this->allowed_fields["shipPostal"] = 1; |
| 52 | + $this->allowed_fields["shipCountry"] = 1; |
| 53 | + $this->allowed_fields["txnID"] = 1; |
| 54 | + $this->allowed_fields["sessionID"] = 1; |
| 55 | + $this->allowed_fields["usernameMD5"] = 1; |
| 56 | + $this->allowed_fields["passwordMD5"] = 1; |
| 57 | + $this->allowed_fields["user_agent"] = 1; |
| 58 | + $this->allowed_fields["accept_language"] = 1; |
| 59 | + |
| 60 | + |
| 61 | + $this->num_allowed_fields = count($this->allowed_fields); |
| 62 | + |
| 63 | + //set the url of the web service |
| 64 | + $this->url = "app/ccv2r"; |
| 65 | + $this->check_field = "score"; |
| 66 | + $this->server = array("minfraud3.maxmind.com", "minfraud1.maxmind.com", "minfraud2.maxmind.com"); |
| 67 | + $this->numservers = count($this->server); |
| 68 | + $this->API_VERSION = 'PHP/1.49'; |
| 69 | + } |
| 70 | + |
| 71 | + function filter_field($key, $value) { |
| 72 | + if ($key == 'emailMD5'){ |
| 73 | + if (ereg('\@',$value)){ |
| 74 | + return md5(strtolower($value)); |
| 75 | + } |
| 76 | + } else if ($key == 'usernameMD5' || $key == 'passwordMD5') { |
| 77 | + if (strlen($value) != 32) { |
| 78 | + return md5(strtolower($value)); |
| 79 | + } |
| 80 | + } |
| 81 | + return $value; |
| 82 | + } |
| 83 | +} |
| 84 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/Example_telv.php |
— | — | @@ -0,0 +1,54 @@ |
| 2 | +#!/usr/bin/php -q |
| 3 | +<?php |
| 4 | +require("TelephoneVerification.php"); |
| 5 | + |
| 6 | +$tv = new TelephoneVerification; |
| 7 | + |
| 8 | +// Set inputs and store them in a hash |
| 9 | +// See http://www.maxmind.com/app/telephone_form for more details on the input fields |
| 10 | + |
| 11 | +// Enter your license key here |
| 12 | +// $h["l"] = "YOUR_LICENSE_KEY_HERE"; |
| 13 | + |
| 14 | +// Enter your telephone number here |
| 15 | +// $h["phone"] = "YOUR_TELEPHONE_NUMBER_HERE"; |
| 16 | + |
| 17 | +// $h["verify_code"] = "5783"; |
| 18 | + |
| 19 | +// If you want to disable Secure HTTPS or don't have Curl and OpenSSL installed |
| 20 | +// uncomment the next line |
| 21 | +// $tv->isSecure = 0; |
| 22 | + |
| 23 | +//set the time out to be 30 seconds |
| 24 | +$tv->timeout = 30; |
| 25 | + |
| 26 | +//uncomment to turn on debugging |
| 27 | +// $tv->debug = 1; |
| 28 | + |
| 29 | +//how many seconds the cache the ip addresses |
| 30 | +$ccfs->wsIpaddrRefreshTimeout = 3600*5; |
| 31 | + |
| 32 | +//where to store the ip address |
| 33 | +$ccfs->wsIpaddrCacheFile = "/tmp/maxmind.ws.cache"; |
| 34 | + |
| 35 | +// if useDNS is 1 then use DNS, otherwise use ip addresses directly |
| 36 | +$ccfs->useDNS = 0; |
| 37 | + |
| 38 | +// next we set up the input hash to be passed to the server |
| 39 | +$tv->input($h); |
| 40 | + |
| 41 | +// then we query the server |
| 42 | +$tv->query(); |
| 43 | + |
| 44 | +// then we get the result from the server |
| 45 | +$h = $tv->output(); |
| 46 | + |
| 47 | +//then finally we print out the result |
| 48 | +$outputkeys = array_keys($h); |
| 49 | +$numoutputkeys = count($h); |
| 50 | +for ($i = 0; $i < $numoutputkeys; $i++) { |
| 51 | + $key = $outputkeys[$i]; |
| 52 | + $value = $h[$key]; |
| 53 | + print $key . " = " . $value . "\n"; |
| 54 | +} |
| 55 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/TelephoneVerification.php |
— | — | @@ -0,0 +1,26 @@ |
| 2 | +<?php |
| 3 | +require_once ("HTTPBase.php"); |
| 4 | +class TelephoneVerification extends HTTPBase { |
| 5 | + var $server; |
| 6 | + var $numservers; |
| 7 | + var $API_VERSION; |
| 8 | + function TelephoneVerification(){ |
| 9 | + $this->HTTPBase(); |
| 10 | + $this->isSecure = 1; // use HTTPS by default |
| 11 | + |
| 12 | + //set the allowed_fields hash |
| 13 | + $this->allowed_fields["l"] = 1; |
| 14 | + $this->allowed_fields["phone"] = 1; |
| 15 | + $this->allowed_fields["verify_code"] = 1; |
| 16 | + $this->num_allowed_fields = count($this->allowed_fields); |
| 17 | + |
| 18 | + //set the url of the web service |
| 19 | + $this->url = "app/telephone_http"; |
| 20 | + $this->check_field = "refid"; |
| 21 | + $this->server = array("www.maxmind.com", "www2.maxmind.com"); |
| 22 | + $this->numservers = count($this->server); |
| 23 | + $this->API_VERSION = 'PHP/1.4'; |
| 24 | + $this->timeout = 30; |
| 25 | + } |
| 26 | +} |
| 27 | +?> |
Index: trunk/extensions/DonationInterface/minfraud/ccfd/README |
— | — | @@ -0,0 +1,63 @@ |
| 2 | +Maxmind Credit Card Fraud Detection Service PHP API Version 1.49 |
| 3 | + |
| 4 | +=============== |
| 5 | +Example scripts |
| 6 | + |
| 7 | +See Example.php for complete example how to use this API with the CCFD service. |
| 8 | +See Example_telv.php for complete example how to use this API with the Telephone Verification service. |
| 9 | +See Example_locv.php for complete example how to use this API with the Location Verification service. |
| 10 | +These scripts can be run from the shell. |
| 11 | + |
| 12 | +================================== |
| 13 | +API Documentation for CCFD service |
| 14 | + |
| 15 | +$ccfs = new CreditCardFraudDetection; |
| 16 | + This creates a new CreditCardFraudDetection object |
| 17 | + |
| 18 | +$ccfs->isSecure |
| 19 | + If isSecure is set to 0 then it uses regular HTTP. |
| 20 | + If isSecure is set to 1 then it uses Secure HTTPS (requires Curl PHP binding) |
| 21 | + |
| 22 | +$ccfs->input($hash) |
| 23 | + Takes a hash and uses it as input for the server. |
| 24 | + See http://www.maxmind.com/app/ccv for details on input fields. |
| 25 | + |
| 26 | +$ccfs->query(); |
| 27 | + Queries the server with the fields passed to the input method |
| 28 | + and stores the output. |
| 29 | + |
| 30 | +$hash = $ccfs->output(); |
| 31 | + Returns the output from the server. |
| 32 | + See http://www.maxmind.com/app/ccv for details on output fields. |
| 33 | + |
| 34 | +============ |
| 35 | +Secure HTTPS |
| 36 | + |
| 37 | +If you want secure HTTPS then you need to have |
| 38 | +the Curl PHP binding, the curl libary and the OpenSSL libary. |
| 39 | + |
| 40 | +You can download the curl libary at |
| 41 | +http://curl.haxx.se/download.html |
| 42 | +http://curl.haxx.se/docs/install.html for installation details |
| 43 | + |
| 44 | +If you do not have curl PHP binding then you should install it. |
| 45 | +See the web page |
| 46 | +http://curl.haxx.se/libcurl/php/install.html for details |
| 47 | + |
| 48 | +It is recommended that you install these packages in this order |
| 49 | +install the OpenSSL libary first |
| 50 | +then install the Curl libary second |
| 51 | +then install the Curl PHP binding last |
| 52 | + |
| 53 | +Secure HTTPS is off by default. |
| 54 | +If you have the Curl PHP binding, the Curl libary |
| 55 | +and the OpenSSL libary then you can turn on Secure HTTPS |
| 56 | +by setting: |
| 57 | +$ccfs->isSecure = 1; |
| 58 | +where $ccfs is the CreditCardFraudDetection object. |
| 59 | + |
| 60 | +=============================== |
| 61 | +Copyright (c) 2008, MaxMind, Inc |
| 62 | + |
| 63 | +All rights reserved. This package is licensed under the LGPL. For details see |
| 64 | +the COPYING file. |
Index: trunk/extensions/DonationInterface/minfraud/tests/minfraudTest.php |
— | — | @@ -0,0 +1,158 @@ |
| 2 | +<?php |
| 3 | +require_once "PHPUnit/Framework.php"; |
| 4 | + |
| 5 | +class minfraudTest extends PHPUnit_Framework_TestCase |
| 6 | +{ |
| 7 | + protected function setUp() { |
| 8 | + require_once( __FILE__ . '/../../minfraud.php'); |
| 9 | + global $wgMinFraudLog; |
| 10 | + $wgMinFraudLog = dirname(__FILE__) . "/test_log"; |
| 11 | + $license_key = 'XBCKSF4gnHA7'; |
| 12 | + $this->fixture = new MinFraud( $license_key ); |
| 13 | + } |
| 14 | + |
| 15 | + protected function tearDown() { |
| 16 | + global $wgMinFraudLog; |
| 17 | + unlink( $wgMinFraudLog ); |
| 18 | + } |
| 19 | + |
| 20 | + public function testCcfdInstance() { |
| 21 | + $ccfd_instance_test = $this->fixture->get_ccfd() instanceof CreditCardFraudDetection; |
| 22 | + $this->assertTrue( $ccfd_instance_test ); |
| 23 | + } |
| 24 | + |
| 25 | + /** |
| 26 | + * @dataProvider queryDataProvider |
| 27 | + */ |
| 28 | + public function testBuildQuery( $data ) { |
| 29 | + $query = $this->fixture->build_query( $data ); |
| 30 | + $this->assertArrayHasKey( "i", $query ); |
| 31 | + $this->assertArrayHasKey( "user_agent", $query ); |
| 32 | + $this->assertArrayHasKey( "city", $query ); |
| 33 | + $this->assertArrayHasKey( "region", $query ); |
| 34 | + $this->assertArrayHasKey( "postal", $query ); |
| 35 | + $this->assertArrayHasKey( "country", $query ); |
| 36 | + $this->assertArrayHasKey( "domain", $query ); |
| 37 | + $this->assertArrayHasKey( "emailMD5", $query ); |
| 38 | + $this->assertArrayHasKey( "bin", $query ); |
| 39 | + $this->assertArrayHasKey( "txnID", $query ); |
| 40 | + $this->assertArrayNotHasKey( "foo", $query ); //make sure we're not adding extraneous info |
| 41 | + $this->assertNotContains( "@", $query[ 'domain' ] ); //make sure we're only getting domains from email addresses |
| 42 | + $this->assertEquals( 6, strlen( $query[ 'bin' ] )); //make sure our bin is 6 digits long |
| 43 | + } |
| 44 | + |
| 45 | + public function queryDataProvider() { |
| 46 | + $data = array( |
| 47 | + array( |
| 48 | + array( |
| 49 | + "city" => 'san francisco', |
| 50 | + "state" => 'ca', |
| 51 | + "zip" => '94104', |
| 52 | + "country" => 'US', |
| 53 | + "email" => 'test@example.com', |
| 54 | + "card_num" => "378282246310005", |
| 55 | + "contribution_tracking_id" => "banana", |
| 56 | + "foo" => "bar" |
| 57 | + ) |
| 58 | + ) |
| 59 | + ); |
| 60 | + return $data; |
| 61 | + } |
| 62 | + |
| 63 | + /** |
| 64 | + * @dataProvider queryDataProvider |
| 65 | + */ |
| 66 | +/* public function testQueryMinfraud( $data ) { |
| 67 | + $query = $this->fixture->build_query( $data ); |
| 68 | + $this->fixture->query_minfraud( $query ); |
| 69 | + $this->assertType( 'array', $this->fixture->minfraud_response ); |
| 70 | + }*/ |
| 71 | + |
| 72 | + /** |
| 73 | + * @dataProvider hashValidateFalseData |
| 74 | + */ |
| 75 | + public function testValidateMinfraudHashFalse( $data ) { |
| 76 | + $this->assertFalse( $this->fixture->validate_minfraud_hash( $data )); |
| 77 | + } |
| 78 | + |
| 79 | + public function hashValidateFalseData() { |
| 80 | + return array( |
| 81 | + array( |
| 82 | + array(), |
| 83 | + array( 'license_key' => 'a' ), |
| 84 | + array( |
| 85 | + 'license_key' => 'a', |
| 86 | + 'i' => 'a', |
| 87 | + ), |
| 88 | + array( |
| 89 | + 'license_key' => 'a', |
| 90 | + 'i' => 'a', |
| 91 | + 'city' => 'a' |
| 92 | + ), |
| 93 | + array( |
| 94 | + 'license_key' => 'a', |
| 95 | + 'i' => 'a', |
| 96 | + 'city' => 'a', |
| 97 | + 'region' => 'a' |
| 98 | + ), |
| 99 | + array( |
| 100 | + 'license_key' => 'a', |
| 101 | + 'i' => 'a', |
| 102 | + 'city' => 'a', |
| 103 | + 'region' => 'a', |
| 104 | + 'postal' => 'a', |
| 105 | + ), |
| 106 | + array( |
| 107 | + 'license_key' => 'a', |
| 108 | + 'country' => 'a', |
| 109 | + ) |
| 110 | + ) |
| 111 | + ); |
| 112 | + } |
| 113 | + |
| 114 | + /** |
| 115 | + * @dataProvider hashValidateTrueData |
| 116 | + */ |
| 117 | + public function testValidateMinfraudHashTrue( $data ) { |
| 118 | + $this->assertTrue( $this->fixture->validate_minfraud_hash( $data )); |
| 119 | + } |
| 120 | + |
| 121 | + public function hashValidateTrueData() { |
| 122 | + return array( |
| 123 | + array( |
| 124 | + array( |
| 125 | + 'license_key' => 'a', |
| 126 | + 'i' => 'a', |
| 127 | + 'city' => 'a', |
| 128 | + 'region' => 'a', |
| 129 | + 'postal' => 'a', |
| 130 | + 'country' => 'a' |
| 131 | + ) |
| 132 | + ) |
| 133 | + ); |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * @dataProvider determineActionsData |
| 138 | + */ |
| 139 | + public function testDetermineActions( $risk_score, $action_ranges, $expected ) { |
| 140 | + $this->fixture->action_ranges = $action_ranges; |
| 141 | + $this->assertEquals( $expected, $this->fixture->determine_actions( $risk_score )); |
| 142 | + } |
| 143 | + |
| 144 | + public function determineActionsData() { |
| 145 | + 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')) |
| 149 | + ); |
| 150 | + } |
| 151 | + |
| 152 | + public function testLogging() { |
| 153 | + global $wgMinFraudLog; |
| 154 | + $this->fixture->log( "foo" ); |
| 155 | + $new_fh = fopen( $wgMinFraudLog, 'r' ); |
| 156 | + $this->assertEquals("foo\n", fread( $new_fh, filesize( $wgMinFraudLog ) )); |
| 157 | + fclose( $new_fh ); |
| 158 | + } |
| 159 | +} |
Index: trunk/extensions/DonationInterface/minfraud/minfraud.il8n.php |
Index: trunk/extensions/DonationInterface/minfraud/minfraud.php |
— | — | @@ -0,0 +1,223 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class MinFraud { |
| 5 | + |
| 6 | + /** |
| 7 | + * Full response from minFraud |
| 8 | + * @var public array |
| 9 | + */ |
| 10 | + public $minfraud_response = NULL; |
| 11 | + |
| 12 | + /** |
| 13 | + * License key for minfraud |
| 14 | + * @var public string |
| 15 | + */ |
| 16 | + public $minfraud_license_key = NULL; |
| 17 | + |
| 18 | + /** |
| 19 | + * File handle for log file |
| 20 | + * @var public |
| 21 | + */ |
| 22 | + public $log_fh = NULL; |
| 23 | + |
| 24 | + /** |
| 25 | + * User-definable riskScore ranges for actions to take |
| 26 | + * @var public array |
| 27 | + */ |
| 28 | + public $action_ranges = array( |
| 29 | + 'process' => array( 0, 100 ), |
| 30 | + 'review' => array( -1, -1 ), |
| 31 | + 'challenge' => array( -1, -1 ), |
| 32 | + 'reject' => array( -1, -1 ), |
| 33 | + ); |
| 34 | + |
| 35 | + function __construct( $license_key = NULL ) { |
| 36 | + require_once( __FILE__ . "/../ccfd/CreditCardFraudDetection.php" ); |
| 37 | + |
| 38 | + global $wgMinFraudLicenseKey, $wgMinFraudActionRanges, $wgMinFraudLog; |
| 39 | + |
| 40 | + // set the minfraud license key, go no further if we don't have it |
| 41 | + if ( !$license_key && !$wgMinFraudLicenseKey ) { |
| 42 | + throw new Exception( "minFraud license key required but not present." ); |
| 43 | + } |
| 44 | + $this->minfraud_license_key = ( $license_key ) ? $license_key : $wgMinFraudLicenseKey; |
| 45 | + |
| 46 | + if ( isset( $wgMinFraudActionRanges )) $this->action_ranges = $wgMinFraudActionRanges; |
| 47 | + |
| 48 | + $log_file = ( $wgMinFraudLog ) ? $wgMinFraudLog : "/var/log/mw/minfraud"; |
| 49 | + $this->prepare_log_file( $log_file ); |
| 50 | + } |
| 51 | + |
| 52 | + /** |
| 53 | + * Query minFraud with the transaction, set actions to take and make a log entry |
| 54 | + * |
| 55 | + * Accessible via $wgHooks[ 'PayflowGatewayValidate' ] |
| 56 | + * @param object PayflowPro Gateway object |
| 57 | + * @param array The array of data generated from an attempted transaction |
| 58 | + */ |
| 59 | + public function validate( &$pfp_gateway_object, $data ) { |
| 60 | + $minfraud_hash = $this->build_query( $data ); |
| 61 | + $this->query_minfraud( $minfraud_hash ); |
| 62 | + $pfp_gateway_object->actions = $this->determine_actions( $this->minfraud_response[ 'riskScore' ] ); |
| 63 | + $log_message = '"'. date('c') . '"'; |
| 64 | + $log_message .= "\t" . '"' . $data[ 'contribution_tracking_id' ] . '"'; |
| 65 | + $log_message .= "\t" . '"' . $data[ 'comment' ] . '"'; |
| 66 | + $log_message .= "\t" . '"' . $data[ 'amount' ] . ' ' . $data[ 'currency' ] . '"'; |
| 67 | + $log_message .= "\t" . '"' . serialize( $minfraud_hash ) . '"'; |
| 68 | + $log_message .= "\t" . '"' . serialize( $this->minfraud_response ) . '"'; |
| 69 | + $log_message .= "\t" . '"' . serialize( $pfp_gateway_object->actions ) . '"'; |
| 70 | + $this->log( $log_message ); |
| 71 | + return TRUE; |
| 72 | + } |
| 73 | + |
| 74 | + /** |
| 75 | + * Get instance of CreditCardFraudDetection |
| 76 | + * @return object |
| 77 | + */ |
| 78 | + public function get_ccfd() { |
| 79 | + if ( !$this->ccfd ) { |
| 80 | + $this->ccfd = new CreditCardFraudDetection; |
| 81 | + } |
| 82 | + return $this->ccfd; |
| 83 | + } |
| 84 | + |
| 85 | + /** |
| 86 | + * Builds minfraud query hash from user input |
| 87 | + * @return array containing hash for minfraud query |
| 88 | + */ |
| 89 | + public function build_query( array $data ) { |
| 90 | + // mapping of data keys -> minfraud hash keys |
| 91 | + $map = array( |
| 92 | + "city" => "city", |
| 93 | + "region" => "state", |
| 94 | + "postal" => "zip", |
| 95 | + "country" => "country", |
| 96 | + "domain" => "email", |
| 97 | + "emailMD5" => "email", |
| 98 | + "bin" => "card_num", |
| 99 | + "txnID" => "contribution_tracking_id" |
| 100 | + ); |
| 101 | + |
| 102 | + // minfraud license key |
| 103 | + $minfraud_hash[ "license_key" ] = $this->minfraud_license_key; |
| 104 | + |
| 105 | + // user's IP address |
| 106 | + $minfraud_hash[ "i" ] = $_SERVER[ 'REMOTE_ADDR' ]; |
| 107 | + |
| 108 | + // user's user agent |
| 109 | + $minfraud_hash[ "user_agent" ] = $_SERVER[ 'HTTP_USER_AGENT' ]; |
| 110 | + |
| 111 | + // loop through the map and add pertinent values from $data to the hash |
| 112 | + foreach ( $map as $key => $value ) { |
| 113 | + |
| 114 | + // do some data processing to clean up values for minfraud |
| 115 | + switch ( $key ) { |
| 116 | + case "domain": // get just the domain from the email address |
| 117 | + $newdata[ $value ] = substr( strstr( $data[ $value ], '@' ), 1 ); |
| 118 | + break; |
| 119 | + case "bin": // get just the first 6 digits from CC# |
| 120 | + $newdata[ $value ] = substr( $data[ $value ], 0, 6 ); |
| 121 | + break; |
| 122 | + default: |
| 123 | + $newdata[ $value ] = $data[ $value ]; |
| 124 | + } |
| 125 | + |
| 126 | + $minfraud_hash[ $key ] = $newdata[ $value ]; |
| 127 | + } |
| 128 | + |
| 129 | + return $minfraud_hash; |
| 130 | + } |
| 131 | + |
| 132 | + /** |
| 133 | + * Perform the min fraud query and capture the response |
| 134 | + */ |
| 135 | + public function query_minfraud( array $minfraud_hash ) { |
| 136 | + $this->get_ccfd()->input( $minfraud_hash ); |
| 137 | + $this->get_ccfd()->query(); |
| 138 | + $this->minfraud_response = $this->get_ccfd()->output(); |
| 139 | + } |
| 140 | + |
| 141 | + /** |
| 142 | + * Validates the minfraud_hash for minimum required fields |
| 143 | + * |
| 144 | + * This is a pretty dumb validator. It just checks to see if |
| 145 | + * there is a value for a required field and if its length is > 0 |
| 146 | + * |
| 147 | + * @param array $minfraud_hash which is the hash you would pass to |
| 148 | + * minfraud in a query |
| 149 | + * @result bool |
| 150 | + */ |
| 151 | + public function validate_minfraud_hash( array $minfraud_hash ) { |
| 152 | + // array of minfraud required fields |
| 153 | + $reqd_fields = array( |
| 154 | + 'license_key', |
| 155 | + 'i', |
| 156 | + 'city', |
| 157 | + 'region', |
| 158 | + 'postal', |
| 159 | + 'country' |
| 160 | + ); |
| 161 | + |
| 162 | + foreach ( $reqd_fields as $reqd_field ) { |
| 163 | + if ( !isset( $minfraud_hash[ $reqd_field ] ) || |
| 164 | + strlen( $minfraud_hash[ $reqd_field ] ) < 1 ) { |
| 165 | + return FALSE; |
| 166 | + } |
| 167 | + } |
| 168 | + |
| 169 | + return TRUE; |
| 170 | + } |
| 171 | + |
| 172 | + /** |
| 173 | + * Determine the actions for the processor to take |
| 174 | + * |
| 175 | + * Determined based on predefined riskScore ranges for |
| 176 | + * a given action. It is possible to return multiple |
| 177 | + * ranges. |
| 178 | + * @param float risk score (returned from minFraud) |
| 179 | + * @return array of actions to be taken |
| 180 | + */ |
| 181 | + public function determine_actions( $risk_score ) { |
| 182 | + $actions = array(); |
| 183 | + foreach ( $this->action_ranges as $action => $range ) { |
| 184 | + if ( $risk_score >= $range[0] && $risk_score <= $range[1] ) { |
| 185 | + $actions[] = $action; |
| 186 | + } |
| 187 | + } |
| 188 | + return $actions; |
| 189 | + } |
| 190 | + |
| 191 | + /** |
| 192 | + * Prepares a log file |
| 193 | + * |
| 194 | + * @param string path to log file |
| 195 | + * @return resource Pointer for the log file |
| 196 | + */ |
| 197 | + protected function prepare_log_file( $log_file ) { |
| 198 | + $this->log_fh = fopen( $log_file, 'a+' ); |
| 199 | + } |
| 200 | + |
| 201 | + /** |
| 202 | + * Writes message to a log file |
| 203 | + * |
| 204 | + * If a log file does not exist and could not be created, |
| 205 | + * do nothing. |
| 206 | + * @fixme Perhaps lack of log file can be handled better, |
| 207 | + * or maybe it doesn't matter? |
| 208 | + * @param string The message to log |
| 209 | + */ |
| 210 | + public function log( $msg ) { |
| 211 | + if ( !$this->log_fh ) { |
| 212 | + return; |
| 213 | + } |
| 214 | + $msg .= "\n"; |
| 215 | + fwrite( $this->log_fh, $msg ); |
| 216 | + } |
| 217 | + |
| 218 | + /** |
| 219 | + * Close the open log file handler if it's open |
| 220 | + */ |
| 221 | + public function __destruct() { |
| 222 | + if ( $this->log_fh ) fclose( $this->log_fh ); |
| 223 | + } |
| 224 | +} |