Created
July 16, 2012 10:11
-
-
Save repomaa/3121927 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$host = 'localhost'; | |
$user = 'bla'; | |
$pass = 'bla'; | |
$db = 'opendiet'; | |
if (isset($_POST['api_key'])) | |
$api_key = $_POST['api_key']; | |
else | |
send_error_response('You need to provide your api key'); | |
if (isset($_POST['api_sig'])) | |
$api_sig = $_POST['api_sig']; | |
else | |
send_error_response('You need sign your calls'); | |
if (isset($_POST['session'])) | |
$session = $_POST['session']; | |
if (isset($_POST['request'])) | |
$request = $_POST['request']; | |
else | |
send_error_response('You have to provide a request'); | |
try { | |
$conn = new PDO('mysql:host='.$host.';dbname='.$db.';charset=UTF-8', $user, $pass); | |
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
} catch (PDOException $ex) { | |
send_error_response('Failed to connect to MySQL: ' . $ex->getMessage()); | |
} | |
if(!check_sig()) | |
send_error_response('Invalid signature'); | |
if($request === 'update' || $request === 'add') { | |
if(!isset($session)) | |
send_error_response('You need to provide a session for write calls'); | |
else if(!checkSession($_POST['api_key'], $_POST['session'])) | |
send_error_response("Invalid session"); | |
} | |
process_response(); | |
function process_response() { | |
global $request, $api_key, $conn; | |
switch($request) { | |
case 'auth': | |
$token = uniqid(); | |
try { | |
$stmt = $conn->prepare("UPDATE applications SET token = ? WHERE api_key = ?"); | |
$stmt->execute(array($token, $api_key)); | |
send_token_response($token); | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
break; | |
case 'session': | |
if(isset($_POST['token'])) | |
session($_POST['token']); | |
else | |
send_error_response('You have to provide a token in order to obtain a session'); | |
break; | |
case 'check_session': | |
if(isset($_POST['session']) && checkSession($api_key, $_POST['session'])) | |
send_session_response($_POST['session']); | |
else send_error_response('Invalid session'); | |
break; | |
case 'search': | |
if(isset($_POST['query'])) | |
search($_POST['query']); | |
else | |
send_error_response('You have to provide a search query for the food you are looking for'); | |
break; | |
case 'update': | |
if(isset($_POST['id'])) { | |
update($_POST['id']); | |
} | |
else | |
send_error_response("You have to provide a valid integer >= 0 as the parameter id for update"); | |
break; | |
case 'add': | |
if(isset($_POST['data'])) | |
add($_POST['data']); | |
else | |
send_error_response("You did not provide any data to add"); | |
break; | |
default: | |
send_error_response('Undefined request'); | |
} | |
} | |
function send_token_response($token) { | |
global $api_key; | |
$data = array('api_key'=>$api_key,'token'=>$token); | |
send_json_response($data); | |
} | |
function send_session_response($session) { | |
global $api_key; | |
$data = array('api_key'=>$api_key,'session'=>$session); | |
send_json_response($data); | |
} | |
function add($data) { | |
global $api_key, $conn; | |
$data = json_decode($data, true); | |
if(count($data) != 9) | |
send_error_response("You have to provide all information for the food"); | |
$data['name'] = trim($data['name']); | |
$hash = md5($data['name'] . $data['category'] . $data['brand']); | |
try { | |
$stmt = $conn->prepare("SELECT * FROM food WHERE hash = ?"); | |
$stmt->execute(array($hash)); | |
if(count($stmt->fetchAll(PDO::FETCH_ASSOC)) > 0) | |
send_error_response("A food extactly like this already exists. Please use update"); | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
try { | |
$stmt = $conn->prepare("INSERT INTO food (name, carbs, fat, protein, alcohol, serving, serving_type, category, api_key, hash, brand) | |
VALUES(:name, :carbs, :fat, :protein, :alcohol, :serving, :serving_type, :category, :api_key, :hash, :brand)"); | |
foreach ($data as $key=>$value) { | |
if($key === 'serving_type' || $key === 'category') | |
$stmt->bindValue(':'.$key, $value, PDO::PARAM_INT); | |
else | |
$stmt->bindValue(':'.$key, strval($value), PDO::PARAM_STR); | |
} | |
$stmt->bindValue(':api_key', $api_key); | |
$stmt->bindValue(':hash', $hash); | |
$stmt->debugDumpParams(); | |
$stmt->execute(); | |
send_ok_response(); | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
} | |
function update($id) { | |
$whitelist = array("name","carbs","fat","protein","alcohol","serving","serving_type","category","brand"); | |
global $api_key, $conn; | |
if(!ctype_digit($id)) | |
send_error_response("You have to provide a valid integer >= 0 as the parameter id for update"); | |
$query = "UPDATE food SET "; | |
if(!isset($_POST['data'])) | |
send_error_response("You have to provide data that should be updated"); | |
$data = json_decode($_POST['data'], true); | |
foreach ($data as $key=>$value) { | |
if(!in_array($key, $whitelist)) | |
send_error_response($key . "isn't a valid key"); | |
$query .= $key . ' = :' . $key . ' , '; | |
} | |
$query .= "api_key = :api_key WHERE id = :id"; | |
$stmt = $conn->prepare($query); | |
$stmt->bindValue(':api_key', $api_key, PDO::PARAM_STR); | |
$stmt->bindValue(':id', $id, PDO::PARAM_INT); | |
try { | |
$stmt = $conn->prepare($query); | |
foreach ($data as $key=>$value) { | |
if($key === 'serving_type' || $key === 'category') | |
$stmt->bindValue(':' . $key, $value, PDO::PARAM_INT); | |
else | |
$stmt->bindValue(':' . $key, $value, PDO::PARAM_STR); | |
echo($key . ", "); | |
} | |
echo($count); | |
$stmt->debugDumpParams(); | |
$stmt->execute(); | |
send_ok_response(); | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
} | |
function send_ok_response() { | |
die("All ok"); | |
} | |
function session($token) { | |
global $api_key, $conn; | |
try { | |
$stmt = $conn->prepare("SELECT token FROM applications WHERE api_key = ?"); | |
$stmt->execute(array($api_key)); | |
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); | |
if(count($rows)!= 1) | |
send_error_response('Internal server error'); | |
if($token !== $rows[0]['token']) | |
send_error_response('Invalid token'); | |
$session = str_replace('.', 'f', uniqid('', true)); | |
$query = "UPDATE applications SET token = null"; | |
$conn->exec($query); | |
$stmt = $conn->prepare("INSERT INTO sessions (api_key, session) VALUES (?, ?)"); | |
$stmt->execute(array($api_key, $session)); | |
send_session_response($session); | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
} | |
function search($query) { | |
global $conn; | |
$search_query = strtolower(trim($query)); | |
$search_keywords = explode(' ', $search_query); | |
if(count($search_keywords) < 1) | |
send_error_response('You have to provide a search query for the food you are looking for'); | |
$prepared_query = "SELECT * FROM food WHERE "; | |
$params = array(); | |
for($i=0; $i < count($search_keywords); $i++) { | |
$prepared_query .= "LCASE(name) LIKE ? "; | |
if(($i + 1) < count($search_keywords)) | |
$prepared_query .= "OR "; | |
$search_keywords[$i] = '%' . $search_keywords[$i] . '%'; | |
} | |
$prepared_query .= "ORDER BY name"; | |
try { | |
$stmt =$conn->prepare($prepared_query); | |
$stmt->execute($search_keywords); | |
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); | |
send_search_response($rows); | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
} | |
function send_json_response($data) { | |
header('Content-type : application/json'); | |
echo json_encode($data); | |
} | |
function send_search_response($result) { | |
send_json_response($result); | |
} | |
function check_sig() { | |
global $api_key, $api_sig, $conn; | |
$sorted_parms = $_POST; | |
ksort($sorted_parms); | |
$parm_string = ''; | |
foreach ($sorted_parms as $key=>$value) | |
if($key !== 'api_sig') | |
$parm_string .= $key.$value; | |
if(!preg_match("/^[a-f0-9]{23}$/", $api_key)) | |
send_error_response('Invalid api key format'); | |
try { | |
$stmt = $conn->prepare("SELECT api_secret FROM applications WHERE api_key = ?"); | |
$stmt->execute(array($api_key)); | |
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); | |
if(count($rows) != 1 || empty($rows[0]['api_secret'])) | |
send_error_response('Internal server error'); | |
$parm_string .= $rows[0]['api_secret']; | |
$hash = md5($parm_string); | |
return $hash === $api_sig; | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
} | |
function send_error_response ($message) { | |
header("HTTP/1.0 400 Bad Request"); | |
die($message); | |
} | |
function checkSession($api_key, $session) { | |
global $conn; | |
try { | |
$stmt = $conn->prepare("SELECT api_key FROM sessions WHERE session = ?"); | |
$stmt->execute(array($session)); | |
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); | |
for($i = 0; $i < count($rows); $i++) { | |
if($rows[$i]['api_key'] === $api_key) | |
return true; | |
} | |
} catch (PDOException $ex) { | |
send_error_response("MySQL error: " . $ex->getMessage()); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment