From: Artem Daniliants Date: Thu, 13 May 2010 19:13:47 +0000 (+0300) Subject: Refactored code and added additional features X-Git-Url: http://git.maemo.org/git/?p=speedfreak;a=commitdiff_plain;h=16692981b5e3265ac6734b84d91571e305b79d61 Refactored code and added additional features - Added avatar support - Added support for fetching list of all registered users - Added support for viewing user's profile - Modified database: added last_activity and description columns - Added support for last_activity (when user last contacted server) --- diff --git a/Server/application/config/api.php b/Server/application/config/api.php index a38951c..99b56a8 100644 --- a/Server/application/config/api.php +++ b/Server/application/config/api.php @@ -11,4 +11,14 @@ /* * Salt for hashing (should always be changed on deployment!) */ -$config['salf'] = 'klzdjkhI/&/567Û%#ÛgbnkBJHVTVjdhiuhdbmzcss-__FDHSYUWYUTUDGBZ'; \ No newline at end of file +$config['salf'] = 'klzdjkhI/&/567Û%#ÛgbnkBJHVTVjdhiuhdbmzcss-__FDHSYUWYUTUDGBZ'; + +/* + * Maximum filesize for avatar images (in bytes) + */ +$config['avatar_max_filesize'] = '102400'; + +/* + * Allowed image types for avatars + */ +$config['avatar_allowed_filetypes'] = array('image/jpeg'); \ No newline at end of file diff --git a/Server/application/config/upload.php b/Server/application/config/upload.php new file mode 100644 index 0000000..6861499 --- /dev/null +++ b/Server/application/config/upload.php @@ -0,0 +1,17 @@ + - * @copyright (c) 2010 Speed Freak team - * @license http://opensource.org/licenses/gpl-license.php GNU Public License - */ - -class Api_Controller extends Controller{ - - /* - * Default action when no parameters are given to controller - */ - public function index(){ - url::redirect(Kohana::config('api.default_redirect'),301); - } - - /* - * New user registration - */ - public function register(){ - $xml = $this->get_xml(); - try { - $user = new User_Model($xml->login, $xml->password, $xml->email); - echo "OK"; - } - catch (Exception $e) { - echo $e->getMessage() . "\n"; - die; - } - } - - /* - * Returns XML file supplied by client - */ - private function get_xml(){ - if (isset($_POST['xml'])){ - $xml = simplexml_load_string($_POST['xml']); - } - elseif (isset($_FILES['xml'])){ - $xml = simplexml_load_file($_FILES['xml']['tmp_name']); - } - else{ - header("HTTP/1.1 400 Bad Request"); - echo "Please supply required parameters"; - die; - } - return $xml; - } - - /* - * Check that supplied credentials are valid using basic authentication - * - */ - public function login(){ - if ($this->is_authorized()){ - print "OK"; - die; - } - else - $this->not_authorized(); - } - - /* - * Validate supplied credentials - */ - public function is_authorized(){ - if (isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])){ - $user = new User_Model(); - if ($user->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) - return true; - else - return false; - } - else - return false; - - } - - /* - * Display "You're not authorized error to client - * - * @todo Need to create function for generally displaying errors - */ - public function not_authorized(){ - header('HTTP/1.0 401 Unauthorized'); - print "Invalid credentials or not registered"; - die; - } - - /* - * Get categories list and output it as XML - * - */ - public function categories(){ - if ($this->is_authorized()){ - $view = new View('api/categories'); - $cat = new Category_Model(); - $view->categories=$cat->get_all(); - $view->render(true); - } - else - $this->not_authorized(); - } - - /* - * Get results - * - */ - public function results($category, $limit, $show_unit=false){ - $results = New Result_Model(); - $cat = New Category_Model(); - if ($cat->category_exists($category) AND $this->is_authorized() AND isset($limit)){ - $view = new View('api/results'); - $view->results = $results->get_results($category, $limit); - $view->show_unit=$show_unit; - $view->render(true); - } - else - $this->not_authorized(); - } - - /* - * Submit results to selected category - * - * @param string $category Category to which results are submitted - */ - public function update($category){ - $cat = New Category_Model(); - if ($cat->category_exists($category) AND $this->is_authorized()){ - $xml = $this->get_xml(); - $result = New Result_Model(); - if ($result->insert($category,$_SERVER['PHP_AUTH_USER'], $xml['value'])){ - print "OK"; - die; - } - else { - header("HTTP/1.1 400 Bad Request"); - echo "Invalid request"; - die; - } - } - else { - header("HTTP/1.0 404 Not Found"); - die('Category not found or not authorized'); - } - - } -} \ No newline at end of file diff --git a/Server/application/controllers/results.php b/Server/application/controllers/results.php new file mode 100644 index 0000000..71a63d3 --- /dev/null +++ b/Server/application/controllers/results.php @@ -0,0 +1,71 @@ + + * @copyright (c) 2010 Speed Freak team + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ + +class Results_Controller extends Controller{ + + /* + * Get categories list and output it as XML + * + */ + public function categories(){ + if (apiler::is_authorized()){ + $view = new View('api/categories'); + $cat = new Category_Model(); + $view->categories=$cat->get_all(); + $view->render(true); + } + else + apiler::not_authorized(); + } + + /* + * Get results + * + */ + public function list_results($category, $limit, $show_unit=false){ + $results = New Result_Model(); + $cat = New Category_Model(); + if ($cat->category_exists($category) AND apiler::is_authorized() AND isset($limit)){ + $view = new View('api/results'); + $view->results = $results->get_results($category, $limit); + $view->show_unit=$show_unit; + $view->render(true); + } + else + apiler::not_authorized(); + } + + /* + * Submit results to selected category + * + * @param string $category Category to which results are submitted + */ + public function update($category){ + $cat = New Category_Model(); + if ($cat->category_exists($category) AND apiler::is_authorized()){ + $xml = apiler::get_xml(); + $result = New Result_Model(); + if ($result->insert($category,$_SERVER['PHP_AUTH_USER'], $xml['value'])){ + print "OK"; + die; + } + else { + header("HTTP/1.1 400 Bad Request"); + echo "Invalid request"; + die; + } + } + else { + header("HTTP/1.0 404 Not Found"); + die('Category not found or not authorized'); + } + + } + +} \ No newline at end of file diff --git a/Server/application/controllers/users.php b/Server/application/controllers/users.php new file mode 100644 index 0000000..ee20517 --- /dev/null +++ b/Server/application/controllers/users.php @@ -0,0 +1,106 @@ + + * @copyright (c) 2010 Speed Freak team + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ + +class Users_Controller extends Controller{ + + + /** + * When no parameters are supplied visitor is redirected to project's website + * + * @access public + * @return void + */ + public function index(){ + url::redirect(Kohana::config('api.default_redirect'),301); + } + + + /** + * Register new user + * + * @access public + * @return string Returns "OK" string upon succession and error message otherwise + */ + public function register(){ + $xml = apiler::get_xml(); + try { + $user = new User_Model($xml->login, $xml->password, $xml->email, $xml->description); + $this->store_avatar($user->get_id($xml->login)); + echo "OK"; + } + catch (Exception $e) { + echo $e->getMessage() . "\n"; + die; + } + } + + + /** + * Display user's information + * + * @access public + * @param string Username that we wish to get information for + * @return string Returns information as XML or error message + */ + public function info($username){ + if (apiler::is_authorized()){ + $view = new View('api/user_info'); + $user = new User_Model(); + $view->user=$user->get_info($username); + if ($view->user==false) + die('User not found'); + if (file_exists(Kohana::config('upload.directory').'/'.$view->user->id.'.jpg')) + $view->avatar=url::site('static/uploads/avatars/'.$view->user->id.'.jpg', 'http'); + $view->render(true); + } + else + apiler::not_authorized(); + } + + + /** + * View all registered users + * + * @access public + * @return string Returns XML containing list of all users or error message + */ + public function list_all(){ + $users = new User_Model(); + $list = $users->list_all_users(); + $view = new View('api/user_list'); + $view->list = $list; + $view->render(true); + } + + + /** + * Check that supplied avatar is valid and store it + * + * @access private + * @param array $image Uploaded item found in $_FILES array + * @param integer $id User id that will be used as filename + * @return boolean Returns TRUE upon succession and FALSE otherwise + */ + private function store_avatar($id){ + if (isset($_FILES['avatar'])){ + $info = getimagesize($_FILES['avatar']['tmp_name']); + + if ($_FILES['avatar']['size']<=Kohana::config('api.avatar_max_filesize') AND in_array($info['mime'], Kohana::config('api.avatar_allowed_filetypes'))) + { + if (upload::save('avatar', $id.'.jpg')) + return True; + else + return False; + } + else + return False; + } + } + +} \ No newline at end of file diff --git a/Server/application/helpers/apiler.php b/Server/application/helpers/apiler.php new file mode 100644 index 0000000..d142785 --- /dev/null +++ b/Server/application/helpers/apiler.php @@ -0,0 +1,83 @@ + + * @copyright (c) 2010 Speed Freak team + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ + +class apiler_Core { + + /** + * Get XML either from POST variable or FILES variable + * + * @access private + * @static + * @return mixed Returns either SimpleXml object or outputs error along with HTTP 400 error + */ + public static function get_xml(){ + if (isset($_POST['xml'])){ + $xml = simplexml_load_string($_POST['xml']); + } + elseif (isset($_FILES['xml'])){ + $xml = simplexml_load_file($_FILES['xml']['tmp_name']); + } + else{ + header("HTTP/1.1 400 Bad Request"); + echo "Please supply required parameters"; + die; + } + return $xml; + } + + + /** + * Check if user is authorized + * + * @access public + * @static + * @return boolean Returns TRUE if authorized and FALSE otherwise + */ + public static function is_authorized(){ + if (isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])){ + $user = new User_Model(); + if ($user->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) + return true; + else + return false; + } + else + return false; + + } + + + /** + * Display "Unauthorized error" + * + * @access public + * @static + * @return string Prints error text + */ + public static function not_authorized(){ + header('HTTP/1.0 401 Unauthorized'); + print "Invalid credentials or not registered"; + die; + } + + /** + * Verify user's credentials + * + * @access public + * @return string Outputs "OK" or error + */ + public function login(){ + if ($this->is_authorized()){ + print "OK"; + die; + }else + $this->not_authorized(); + } + +} \ No newline at end of file diff --git a/Server/application/models/database_structure.sql b/Server/application/models/database_structure.sql index 7b2ed70..111c0e9 100644 --- a/Server/application/models/database_structure.sql +++ b/Server/application/models/database_structure.sql @@ -1,10 +1,10 @@ -# Sequel Pro dump -# Version 1630 +# Sequel Pro dump +# Version 2210 # http://code.google.com/p/sequel-pro # # Host: localhost (MySQL 5.1.37) # Database: speedfreak -# Generation Time: 2010-04-21 11:03:11 +0300 +# Generation Time: 2010-05-13 21:56:50 +0300 # ************************************************************ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; @@ -61,10 +61,12 @@ CREATE TABLE `users` ( `username` char(255) DEFAULT NULL, `password` char(255) DEFAULT NULL, `email` char(255) DEFAULT NULL, + `description` text, + `last_activity` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `login_unique` (`username`), UNIQUE KEY `email_unique` (`email`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/Server/application/models/user.php b/Server/application/models/user.php index 78ef8ca..0535789 100644 --- a/Server/application/models/user.php +++ b/Server/application/models/user.php @@ -17,7 +17,7 @@ class User_Model extends Model { * @param string $email Valid email address * @return bool Returns True if operation was successfull and exception otherwise */ - public function __construct($username='', $password='', $email=''){ + public function __construct($username='', $password='', $email='', $description=''){ // load database library into $this->db parent::__construct(); @@ -36,7 +36,7 @@ class User_Model extends Model { elseif ($this->user_exists($username, $email)) throw new Exception('User already exists (login or email matched)'); - if ($this->register($username, $password, $email)->valid()) + if ($this->register($username, $password, $email, $description)->valid()) return true; else return false; @@ -52,14 +52,14 @@ class User_Model extends Model { * @param string $email Valid email address * @return bool Returns True if operation was successfull and exception otherwise */ - private function register($username, $password, $email){ + private function register($username, $password, $email, $description){ // hash password $password = $this->hash($password); // @todo I can't seem to get query working when password binding has '' around it like others if ($this->user_exists($username, $email)==false) - return $this->db->query("INSERT into users SET username = '?', password = ?, email = '?'", - $username, $password, $email); + return $this->db->query("INSERT into users SET username = '?', password = ?, description='?', last_activity=NOW(), email = '?'", + $username, $password, $description, $email); else return false; } @@ -82,13 +82,23 @@ class User_Model extends Model { * @return bool Returns True if user exists and false otherwise */ private function user_exists($username, $email){ - if ($this->db->query("SELECT id FROM users WHERE username = '?' OR email = '?'", + if ($this->db->query("SELECT id FROM users WHERE username='?' OR email='?'", $username, $email)->count()>0) return true; else return false; } + + public function get_info($username){ + $result = $this->db->query("SELECT * FROM users WHERE username = ?", $username); + if ($result->count()>0) + return $result[0]; + else + return false; + } + + /* * Get user id * @@ -96,12 +106,26 @@ class User_Model extends Model { * @return integer|bool User id if successful or false */ public function get_id($username){ - $result = $this->db->query("SELECT id FROM users WHERE username = ?", $username); - if ($result->count()>0) + $result = $this->db->query("SELECT id FROM users WHERE username='?'", $username); + if ($result->count()>0) return $result[0]->id; else return false; } + + /** + * List all users found in database + * + * @access public + * @return boolean|object Returns object containing all users or false + */ + public function list_all_users(){ + $result = $this->db->query("SELECT * FROM users"); + if ($result->count()>0) + return $result; + else + return false; + } /* * Check if supplied credentials are valid diff --git a/Server/application/views/api/user_info.php b/Server/application/views/api/user_info.php new file mode 100644 index 0000000..598eed3 --- /dev/null +++ b/Server/application/views/api/user_info.php @@ -0,0 +1,3 @@ +'; ?> + + /> \ No newline at end of file diff --git a/Server/application/views/api/user_list.php b/Server/application/views/api/user_list.php new file mode 100644 index 0000000..261fb04 --- /dev/null +++ b/Server/application/views/api/user_list.php @@ -0,0 +1,8 @@ +'; ?> + +0) foreach($list as $user){ ?> + + /> + + + \ No newline at end of file