From 1e54a1a2d6695963c3be9b06d5a48655526fe5a0 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sun, 26 May 2013 19:33:19 +0200 Subject: [PATCH 1/3] initial commit of a working API page --- public/include/classes/user.class.php | 13 ++++++ public/include/pages/api.inc.php | 57 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 public/include/pages/api.inc.php diff --git a/public/include/classes/user.class.php b/public/include/classes/user.class.php index d54b2da5..a8067a17 100644 --- a/public/include/classes/user.class.php +++ b/public/include/classes/user.class.php @@ -225,6 +225,19 @@ class User { return false; } + /** + * Check API key for authentication + * @param key string API key hash + * @return bool + **/ + public function checkApiKey($key) { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare("SELECT api_key FROM $this->table WHERE api_key = ?"); + if ($this->checkStmt($stmt) && $stmt->bind_param("s", $key) && $stmt->execute() && $stmt->bind_result($api_key) && $stmt->fetch()) + return $key === $api_key; + return false; + } + private function checkUserPassword($username, $password) { $this->debug->append("STA " . __METHOD__, 4); $user = array(); diff --git a/public/include/pages/api.inc.php b/public/include/pages/api.inc.php new file mode 100644 index 00000000..23332c3a --- /dev/null +++ b/public/include/pages/api.inc.php @@ -0,0 +1,57 @@ +checkApiKey($_REQUEST['api_key'])) { + header("HTTP/1.1 401 Unauthorized"); + die(); +} + +// Fetch data from litecoind +if ($bitcoin->can_connect() === true){ + if (!$dDifficulty = $memcache->get('dDifficulty')) { + $dDifficulty = $bitcoin->query('getdifficulty'); + $memcache->set('dDifficulty', $dDifficulty); + } + if (!$iBlock = $memcache->get('iBlock')) { + $iBlock = $bitcoin->query('getblockcount'); + $memcache->set('iBlock', $iBlock); + } +} else { + $iDifficulty = 1; + $iBlock = 0; + $_SESSION['POPUP'][] = array('CONTENT' => 'Unable to connect to pushpool service: ' . $bitcoin->can_connect(), 'TYPE' => 'errormsg'); +} + +// Grab the last 10 blocks found +$iLimit = 10; +$aBlocksFoundData = $statistics->getBlocksFound($iLimit); +$aBlockData = $aBlocksFoundData[0]; + +// Estimated time to find the next block +$iCurrentPoolHashrate = $statistics->getCurrentHashrate(); +// Time in seconds, not hours, using modifier in smarty to translate +$iEstTime = $dDifficulty * pow(2,32) / ($iCurrentPoolHashrate * 1000); + +// Time since last block +$now = new DateTime( "now" ); +if (!empty($aBlockData)) { + $dTimeSinceLast = ($now->getTimestamp() - $aBlockData['time']); +} else { + $dTimeSinceLast = 0; +} + +$aData = array( + 'est_time' => $iEstTime, + 'time_last' => $dTimeSinceLast, + 'blocks_found' => $aBlocksFoundData, + 'cur_block' => $iBlock, + 'last_block' => $aBlockData['height'], + 'difficulty' => $iDifficulty, +); + +$supress_master = 1; +echo json_encode($aData); +?> From d4331ed8dcfc5d8f75bc8932029f7e12e9a3258f Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Tue, 28 May 2013 10:50:16 +0200 Subject: [PATCH 2/3] Adding more actions for API page * getblockcount * getblocksfound (with limit support) * getcurrentworkers * getdifficulty * getestimatedtime * getpoolhashrate * getpoolsharerate * gettimesincelastblock --- public/include/autoloader.inc.php | 1 + public/include/classes/bitcoin.class.php | 3 -- .../include/classes/bitcoinwrapper.class.php | 37 +++++++++++++++++++ .../include/pages/api/getblockcount.inc.php | 24 ++++++++++++ .../include/pages/api/getblocksfound.inc.php | 20 ++++++++++ .../pages/api/getcurrentworkers.inc.php | 15 ++++++++ .../include/pages/api/getdifficulty.inc.php | 25 +++++++++++++ .../pages/api/getestimatedtime.inc.php | 18 +++++++++ .../include/pages/api/getpoolhashrate.inc.php | 15 ++++++++ .../pages/api/getpoolsharerate.inc.php | 15 ++++++++ .../pages/api/gettimesincelastblock.inc.php | 26 +++++++++++++ 11 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 public/include/classes/bitcoinwrapper.class.php create mode 100644 public/include/pages/api/getblockcount.inc.php create mode 100644 public/include/pages/api/getblocksfound.inc.php create mode 100644 public/include/pages/api/getcurrentworkers.inc.php create mode 100644 public/include/pages/api/getdifficulty.inc.php create mode 100644 public/include/pages/api/getestimatedtime.inc.php create mode 100644 public/include/pages/api/getpoolhashrate.inc.php create mode 100644 public/include/pages/api/getpoolsharerate.inc.php create mode 100644 public/include/pages/api/gettimesincelastblock.inc.php diff --git a/public/include/autoloader.inc.php b/public/include/autoloader.inc.php index 0da83b59..0671a34e 100644 --- a/public/include/autoloader.inc.php +++ b/public/include/autoloader.inc.php @@ -3,6 +3,7 @@ require_once(CLASS_DIR . '/debug.class.php'); require_once(CLASS_DIR . '/bitcoin.class.php'); require_once(CLASS_DIR . '/statscache.class.php'); +require_once(CLASS_DIR . '/bitcoinwrapper.class.php'); require_once(INCLUDE_DIR . '/database.inc.php'); require_once(INCLUDE_DIR . '/smarty.inc.php'); // Load classes that need the above as dependencies diff --git a/public/include/classes/bitcoin.class.php b/public/include/classes/bitcoin.class.php index 9a901be6..fa88d415 100644 --- a/public/include/classes/bitcoin.class.php +++ b/public/include/classes/bitcoin.class.php @@ -898,6 +898,3 @@ class BitcoinClient extends jsonrpc_client { return $this->query("getaddressesbyaccount", $account); } } - -// Auto-load this class -$bitcoin = new BitcoinClient($config['wallet']['type'], $config['wallet']['username'], $config['wallet']['password'], $config['wallet']['host']); diff --git a/public/include/classes/bitcoinwrapper.class.php b/public/include/classes/bitcoinwrapper.class.php new file mode 100644 index 00000000..7231c252 --- /dev/null +++ b/public/include/classes/bitcoinwrapper.class.php @@ -0,0 +1,37 @@ +type = $type; + $this->username = $username; + $this->password = $password; + $this->host = $host; + $this->memcache = $memcache; + return parent::__construct($this->type, $this->username, $this->password, $this->host); + } + /** + * Wrap variouns methods to add caching + **/ + public function getblockcount() { + if ($data = $this->memcache->get(__FUNCTION__)) return $data; + return $this->memcache->setCache(__FUNCTION__, parent::getblockcount()); + } + public function getdifficulty() { + if ($data = $this->memcache->get(__FUNCTION__)) return $data; + return $this->memcache->setCache(__FUNCTION__, parent::getdifficulty()); + } + public function getestimatedtime($iCurrentPoolHashrate) { + if ($iCurrentPoolHashrate == 0) return 0; + if ($data = $this->memcache->get(__FUNCTION__)) return $data; + $dDifficulty = parent::getdifficulty(); + return $this->memcache->setCache(__FUNCTION__, $dDifficulty * pow(2,32) / $iCurrentPoolHashrate); + } +} + +// Load this wrapper +$bitcoin = new BitcoinWrapper($config['wallet']['type'], $config['wallet']['username'], $config['wallet']['password'], $config['wallet']['host'], $memcache); diff --git a/public/include/pages/api/getblockcount.inc.php b/public/include/pages/api/getblockcount.inc.php new file mode 100644 index 00000000..f3a6779f --- /dev/null +++ b/public/include/pages/api/getblockcount.inc.php @@ -0,0 +1,24 @@ +checkApiKey($_REQUEST['api_key']); + +if ($bitcoin->can_connect() === true){ + if (!$iBlock = $memcache->get('iBlock')) { + $iBlock = $bitcoin->query('getblockcount'); + $memcache->set('iBlock', $iBlock); + } +} else { + $iBlock = 0; +} + +// Output JSON format +echo json_encode(array('getblockcount' => $iBlock)); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/getblocksfound.inc.php b/public/include/pages/api/getblocksfound.inc.php new file mode 100644 index 00000000..67cd6ab7 --- /dev/null +++ b/public/include/pages/api/getblocksfound.inc.php @@ -0,0 +1,20 @@ +checkApiKey($_REQUEST['api_key']); + +// Set a sane limit, overwrite with URL parameter +$iLimit = 10; +if (@$_REQUEST['limit']) + $iLimit = $_REQUEST['limit']; + +// Output JSON format +echo json_encode(array('getblocksfound' => $statistics->getBlocksFound($iLimit))); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/getcurrentworkers.inc.php b/public/include/pages/api/getcurrentworkers.inc.php new file mode 100644 index 00000000..2f0a3241 --- /dev/null +++ b/public/include/pages/api/getcurrentworkers.inc.php @@ -0,0 +1,15 @@ +checkApiKey($_REQUEST['api_key']); + +// Output JSON format +echo json_encode(array('getcurrentworkers' => $worker->getCountAllActiveWorkers())); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/getdifficulty.inc.php b/public/include/pages/api/getdifficulty.inc.php new file mode 100644 index 00000000..60c0f111 --- /dev/null +++ b/public/include/pages/api/getdifficulty.inc.php @@ -0,0 +1,25 @@ +checkApiKey($_REQUEST['api_key']); + +// Fetch data from litecoind +if ($bitcoin->can_connect() === true){ + if (!$dDifficulty = $memcache->get('dDifficulty')) { + $memcache->set('dDifficulty', $dDifficulty); + $dDifficulty = $bitcoin->query('getdifficulty'); + } +} else { + $iDifficulty = 1; +} + +// Output JSON format +echo json_encode(array('getdifficulty' => $dDifficulty)); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/getestimatedtime.inc.php b/public/include/pages/api/getestimatedtime.inc.php new file mode 100644 index 00000000..6bc76881 --- /dev/null +++ b/public/include/pages/api/getestimatedtime.inc.php @@ -0,0 +1,18 @@ +checkApiKey($_REQUEST['api_key']); + +// Estimated time to find the next block +$iCurrentPoolHashrate = $statistics->getCurrentHashrate() * 1000; + +// Output JSON format +echo json_encode(array('getestimatedtime' => $bitcoin->getestimatedtime($iCurrentPoolHashrate))); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/getpoolhashrate.inc.php b/public/include/pages/api/getpoolhashrate.inc.php new file mode 100644 index 00000000..996d1ce2 --- /dev/null +++ b/public/include/pages/api/getpoolhashrate.inc.php @@ -0,0 +1,15 @@ +checkApiKey($_REQUEST['api_key']); + +// Output JSON format +echo json_encode(array('getpoolhashrate' => $statistics->getCurrentHashrate())); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/getpoolsharerate.inc.php b/public/include/pages/api/getpoolsharerate.inc.php new file mode 100644 index 00000000..980c0ba3 --- /dev/null +++ b/public/include/pages/api/getpoolsharerate.inc.php @@ -0,0 +1,15 @@ +checkApiKey($_REQUEST['api_key']); + +// Output JSON format +echo json_encode(array('getpoolsharerate' => $statistics->getCurrentShareRate())); + +// Supress master template +$supress_master = 1; +?> diff --git a/public/include/pages/api/gettimesincelastblock.inc.php b/public/include/pages/api/gettimesincelastblock.inc.php new file mode 100644 index 00000000..f80c55ce --- /dev/null +++ b/public/include/pages/api/gettimesincelastblock.inc.php @@ -0,0 +1,26 @@ +checkApiKey($_REQUEST['api_key']); + +// Fetch our last block found +$aBlocksFoundData = $statistics->getBlocksFound(1); + +// Time since last block +$now = new DateTime( "now" ); +if (!empty($aBlocksFoundData)) { + $dTimeSinceLast = ($now->getTimestamp() - $aBlocksFoundData[0]['time']); +} else { + $dTimeSinceLast = 0; +} + +// Output JSON format +echo json_encode(array('gettimesincelastblock' => $dTimeSinceLast)); + +// Supress master template +$supress_master = 1; +?> From f4a423556247b48951938cd679d0ba4a1f90fee5 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Tue, 28 May 2013 10:55:29 +0200 Subject: [PATCH 3/3] remove generic api page --- public/include/pages/api.inc.php | 53 +++----------------------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/public/include/pages/api.inc.php b/public/include/pages/api.inc.php index 23332c3a..3b4d3858 100644 --- a/public/include/pages/api.inc.php +++ b/public/include/pages/api.inc.php @@ -4,54 +4,9 @@ if (!defined('SECURITY')) die('Hacking attempt'); -if (!$user->checkApiKey($_REQUEST['api_key'])) { - header("HTTP/1.1 401 Unauthorized"); - die(); -} +// Check for valid API key +$user->checkApiKey($_REQUEST['api_key']); -// Fetch data from litecoind -if ($bitcoin->can_connect() === true){ - if (!$dDifficulty = $memcache->get('dDifficulty')) { - $dDifficulty = $bitcoin->query('getdifficulty'); - $memcache->set('dDifficulty', $dDifficulty); - } - if (!$iBlock = $memcache->get('iBlock')) { - $iBlock = $bitcoin->query('getblockcount'); - $memcache->set('iBlock', $iBlock); - } -} else { - $iDifficulty = 1; - $iBlock = 0; - $_SESSION['POPUP'][] = array('CONTENT' => 'Unable to connect to pushpool service: ' . $bitcoin->can_connect(), 'TYPE' => 'errormsg'); -} - -// Grab the last 10 blocks found -$iLimit = 10; -$aBlocksFoundData = $statistics->getBlocksFound($iLimit); -$aBlockData = $aBlocksFoundData[0]; - -// Estimated time to find the next block -$iCurrentPoolHashrate = $statistics->getCurrentHashrate(); -// Time in seconds, not hours, using modifier in smarty to translate -$iEstTime = $dDifficulty * pow(2,32) / ($iCurrentPoolHashrate * 1000); - -// Time since last block -$now = new DateTime( "now" ); -if (!empty($aBlockData)) { - $dTimeSinceLast = ($now->getTimestamp() - $aBlockData['time']); -} else { - $dTimeSinceLast = 0; -} - -$aData = array( - 'est_time' => $iEstTime, - 'time_last' => $dTimeSinceLast, - 'blocks_found' => $aBlocksFoundData, - 'cur_block' => $iBlock, - 'last_block' => $aBlockData['height'], - 'difficulty' => $iDifficulty, -); - -$supress_master = 1; -echo json_encode($aData); +header('HTTP/1.1 400 Bad Request'); +die('400 Bad Request'); ?>