Skip to content

Instantly share code, notes, and snippets.

@repomaa
Created July 16, 2012 10:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save repomaa/3121927 to your computer and use it in GitHub Desktop.
Save repomaa/3121927 to your computer and use it in GitHub Desktop.
<?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