From c2b78c05d7a5ad21486e3181c3faf375022f3906 Mon Sep 17 00:00:00 2001 From: Marcin Haba Date: Sun, 3 Jan 2016 17:07:32 +0100 Subject: [PATCH] baculum: Tweak add comments --- gui/baculum/protected/Class/BaculumAPI.php | 200 +++++++++++++++--- gui/baculum/protected/Class/BaculumPage.php | 105 +++++++-- .../protected/Class/ConfigurationManager.php | 14 +- 3 files changed, 263 insertions(+), 56 deletions(-) diff --git a/gui/baculum/protected/Class/BaculumAPI.php b/gui/baculum/protected/Class/BaculumAPI.php index 0ed249aede..74998c8cc6 100644 --- a/gui/baculum/protected/Class/BaculumAPI.php +++ b/gui/baculum/protected/Class/BaculumAPI.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2015 Marcin Haba + * Copyright (C) 2013-2016 Marcin Haba * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -23,23 +23,59 @@ Prado::using('System.Exceptions.TException'); Prado::using('Application.Class.Errors'); -abstract class BaculumAPI extends TPage -{ +/** + * Abstract module from which inherits each of API module. + * The module contains methods that are common for all API pages. + * + * @author Marcin Haba + */ +abstract class BaculumAPI extends TPage { + + /** + * Storing output from API commands in numeric array. + */ protected $output; + + /** + * Storing error from API commands as integer value. + */ protected $error; + /** + * Storing currently used Director name for bconsole commands. + */ protected $director; + /** + * Web interface User name that sent request to API. + * Null value means administrator, any other value means normal user + * (non-admin user). + */ protected $user; /** - * Actions methods. + * Action methods. */ + + // get elements const GET_METHOD = 'GET'; + + // create new elemenet const POST_METHOD = 'POST'; + + // update elements const PUT_METHOD = 'PUT'; + + // delete element const DELETE_METHOD = 'DELETE'; + /** + * Get request, login user and do request action. + * + * @access public + * @param mixed $params onInit action params + * @return none + */ public function onInit($params) { parent::onInit($params); /* @@ -48,20 +84,36 @@ abstract class BaculumAPI extends TPage */ $db = new ActiveRecord(); $db->getDbConnection(); + + // set Director to bconsole execution $this->director = isset($this->Request['director']) ? $this->Request['director'] : null; + /** + * User and password are obligatory for each request. Otherwise authorization + * error takes place. + * Password is provided in hashed form. + */ $user = isset($_SERVER['HTTP_X_BACULUM_USER']) ? $_SERVER['HTTP_X_BACULUM_USER']: null; - $pwd = isset($_SERVER['HTTP_X_BACULUM_PWD']) ? $_SERVER['HTTP_X_BACULUM_PWD']: null; - if(!is_null($user) && !is_null($pwd)) { - $logged = $this->Application->getModule('users')->loginUser($user, $pwd); + $pwd_hash = isset($_SERVER['HTTP_X_BACULUM_PWD']) ? $_SERVER['HTTP_X_BACULUM_PWD']: null; + if (!is_null($user) && !is_null($pwd_hash)) { + // try to log in user + $logged = $this->getModule('users')->loginUser($user, $pwd_hash); if ($logged === true) { + /* + * User and password are valid. + * Log in action finished successfuly. + * Now check if logged in user is admin or normal user. + * Admin value is null. Normal user value is string with the user name. + */ $this->user = ($this->User->getIsAdmin() === false) ? $user : null; } else { + // Invalid credentials. Authorization error. $this->output = AuthorizationError::MSG_ERROR_AUTHORIZATION_TO_WEBGUI_PROBLEM; $this->error = AuthorizationError::ERROR_AUTHORIZATION_TO_WEBGUI_PROBLEM; return; } } else { + // Not provided user or password. Authorization error. $this->output = AuthorizationError::MSG_ERROR_AUTHORIZATION_TO_WEBGUI_PROBLEM; $this->error = AuthorizationError::ERROR_AUTHORIZATION_TO_WEBGUI_PROBLEM; return; @@ -72,7 +124,13 @@ abstract class BaculumAPI extends TPage try { $this->put(); } catch(TDbException $e) { - $this->Application->getModule('logging')->log(__FUNCTION__, $e, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__); + $this->getModule('logging')->log( + __FUNCTION__, + $e, + Logging::CATEGORY_APPLICATION, + __FILE__, + __LINE__ + ); $this->output = DatabaseError::MSG_ERROR_DB_CONNECTION_PROBLEM; $this->error = DatabaseError::ERROR_DB_CONNECTION_PROBLEM; } @@ -82,7 +140,13 @@ abstract class BaculumAPI extends TPage try { $this->get(); } catch(TDbException $e) { - $this->Application->getModule('logging')->log(__FUNCTION__, $e, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__); + $this->getModule('logging')->log( + __FUNCTION__, + $e, + Logging::CATEGORY_APPLICATION, + __FILE__, + __LINE__ + ); $this->output = DatabaseError::MSG_ERROR_DB_CONNECTION_PROBLEM; $this->error = DatabaseError::ERROR_DB_CONNECTION_PROBLEM; } @@ -92,7 +156,13 @@ abstract class BaculumAPI extends TPage try { $this->post(); } catch(TDbException $e) { - $this->Application->getModule('logging')->log(__FUNCTION__, $e, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__); + $this->getModule('logging')->log( + __FUNCTION__, + $e, + Logging::CATEGORY_APPLICATION, + __FILE__, + __LINE__ + ); $this->output = DatabaseError::MSG_ERROR_DB_CONNECTION_PROBLEM; $this->error = DatabaseError::ERROR_DB_CONNECTION_PROBLEM; } @@ -102,7 +172,13 @@ abstract class BaculumAPI extends TPage try { $this->delete(); } catch(TDbException $e) { - $this->Application->getModule('logging')->log(__FUNCTION__, $e, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__); + $this->getModule('logging')->log( + __FUNCTION__, + $e, + Logging::CATEGORY_APPLICATION, + __FILE__, + __LINE__ + ); $this->output = DatabaseError::MSG_ERROR_DB_CONNECTION_PROBLEM; $this->error = DatabaseError::ERROR_DB_CONNECTION_PROBLEM; } @@ -111,59 +187,131 @@ abstract class BaculumAPI extends TPage } } + /** + * Get request result data and pack it in JSON format. + * JSON values are: { + * "output": (list) output values + * "error" : (integer) result exit code (0 - OK, non-zero - error) + * + * @access private + * @return string JSON value with output and error values + */ private function getOutput() { $output = array('output' => $this->output, 'error' => $this->error); - return json_encode($output); + $json = json_encode($output); + return $json; } + /** + * Return action result which was realized in onInit() method. + * On standard output is printed JSON value with request results. + * + * @access public + * @param mixed $params onInit action params + * @return none + */ public function onLoad($params) { parent::onLoad($params); echo $this->getOutput(); } + /** + * Each of API module should have get() method defined. + * Designed to getting data from API. + * + * @access protected + * @return none + */ abstract protected function get(); + /** + * Changing/updating values via API. + * + * @access private + * @return none + */ private function put() { $id = isset($this->Request['id']) ? $this->Request['id'] : null; - if(is_array($this->Request['update']) && count($this->Request['update']) > 0) { + + /** + * Check if it is possible to read PUT method data. + * Note that some clients sends data in PUT request as PHP input stream which + * is not possible to read by $_REQUEST data. From this reason, when is + * not possible to ready by superglobal $_REQUEST variable, then is try to + * read PUT data by PHP input stream. + */ + if (is_array($this->Request['update']) && count($this->Request['update']) > 0) { + // $_REQUEST available to read $params = (object)$this->Request['update']; $this->set($id, $params); } else { + // no possibility to read data from $_REQUEST. Try to load from input stream. $inputstr = file_get_contents("php://input"); + + /** + * Read using chunks for case large updates (over 1000 values). + * Otherwise max_input_vars limitation in php.ini can be reached (usually + * set to 1000 variables) + * @see http://php.net/manual/en/info.configuration.php#ini.max-input-vars + */ $chunks = explode('&', $inputstr); - $responseData = array(); + + $response_data = array(); for($i = 0; $iset($id, $params); } else { - $this->set($id, array()); //@TOVERIFY - //$this->output = GenericError::MSG_ERROR_INVALID_COMMAND; - //$this->error = GenericError::ERROR_INVALID_COMMAND; + /** + * This case should never occur because it means that there is + * given nothing to update. + */ + $this->set($id, array()); } } } - + + /** + * Creating new elements. + * + * @access private + * @return none + */ private function post() { - if(is_array($this->Request['create']) && count($this->Request['create']) > 0) { + if (is_array($this->Request['create']) && count($this->Request['create']) > 0) { $params = (object)$this->Request['create']; $this->create($params); } } + /** + * Deleting element by element ID. + * + * @access private + * @return none + */ private function delete() { - if(isset($this->Request['id'])) { + if (isset($this->Request['id'])) { $id = intval($this->Request['id']); $this->remove($id); } } + /** + * Shortcut method for getting application modules instances by + * module name. + * + * @access public + * @param string $name application module name + * @return object module class instance + */ public function getModule($name) { return $this->Application->getModule($name); } diff --git a/gui/baculum/protected/Class/BaculumPage.php b/gui/baculum/protected/Class/BaculumPage.php index d0eda6896f..a6043dc17d 100644 --- a/gui/baculum/protected/Class/BaculumPage.php +++ b/gui/baculum/protected/Class/BaculumPage.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2015 Marcin Haba + * Copyright (C) 2013-2016 Marcin Haba * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -19,19 +19,34 @@ * * Bacula(R) is a registered trademark of Kern Sibbald. */ - -class BaculumPage extends TPage -{ + +/** + * Base pages module. + * The module contains methods that are common for all pages (wizards, main + * page and error pages). + * + * @author Marcin Haba + */ +class BaculumPage extends TPage { public function onPreInit($param) { parent::onPreInit($param); - $configuration = $this->getModule('configuration'); $this->Application->getGlobalization()->Culture = $this->getLanguage(); - $this->setPrefixForSubdir(); + $this->setURLPrefixForSubdir(); } + /** + * Get curently set language short name (for example: en, pl). + * If language short name is not set in session then the language value + * is taken from Baculum config file, saved in session and returned. + * If the language setting is set in session, then the value from + * session is returned. + * + * @access public + * @return string currently set language short name + */ public function getLanguage() { - if(isset($_SESSION['language']) && !empty($_SESSION['language'])) { + if (isset($_SESSION['language']) && !empty($_SESSION['language'])) { $language = $_SESSION['language']; } else { $language = $this->getModule('configuration')->getLanguage(); @@ -40,40 +55,84 @@ class BaculumPage extends TPage return $language; } + /** + * Shortcut method for getting application modules instances by + * module name. + * + * @access public + * @param string $name application module name + * @return object module class instance + */ public function getModule($name) { return $this->Application->getModule($name); } - public function goToPage($pagePath,$getParameters = null) { - $this->Response->redirect($this->Service->constructUrl($pagePath,$getParameters,false)); + /** + * Redirection to a page. + * Page name is given in PRADO notation with "dot", for example: (Home.SomePage). + * + * @access public + * @param string $page_name page name to redirect + * @param array $params HTTP GET method parameters in associative array + * @return none + */ + public function goToPage($page_name, $params = null) { + $url = $this->Service->constructUrl($page_name, $params, false); + $this->Response->redirect($url); } - public function goToDefaultPage($getParameters = null) { - $this->goToPage($this->Service->DefaultPage, $getParameters); + /** + * Redirection to default page defined in application config. + * + * @access public + * @param array $params HTTP GET method parameters in associative array + * @return none + */ + public function goToDefaultPage($params = null) { + $this->goToPage($this->Service->DefaultPage, $params); } - public function setPrefixForSubdir() { - $fullDocumentRoot = preg_replace('#(\/)$#', '', $this->getFullDocumentRoot()); - $urlPrefix = str_replace($fullDocumentRoot, '', APPLICATION_DIRECTORY); - if(!empty($urlPrefix)) { - $this->Application->getModule('friendly-url')->setUrlPrefix($urlPrefix); + /** + * Set prefix when Baculum is running in document root subdirectory. + * For example: + * web server document root: /var/www/ + * Baculum directory /var/www/baculum/ + * URL prefix: /baculum/ + * In this case to base url is added '/baculum/' such as: + * http://localhost:9095/baculum/ + * + * @access private + * @return none + */ + private function setURLPrefixForSubdir() { + $full_document_root = preg_replace('#(\/)$#', '', $this->getFullDocumentRoot()); + $url_prefix = str_replace($full_document_root, '', APPLICATION_DIRECTORY); + if (!empty($url_prefix)) { + $this->Application->getModule('friendly-url')->setUrlPrefix($url_prefix); } } + /** + * Get full document root directory path. + * Symbolic links in document root path are translated to full paths. + * + * @access private + * return string full document root directory path + */ private function getFullDocumentRoot() { - $rootDir = array(); + $root_dir = array(); $dirs = explode('/', $_SERVER['DOCUMENT_ROOT']); for($i = 0; $i < count($dirs); $i++) { - $documentRootPart = implode('/', $rootDir) . '/' . $dirs[$i]; - if(is_link($documentRootPart)) { - $rootDir = array(readlink($documentRootPart)); + $document_root_part = implode('/', $root_dir) . '/' . $dirs[$i]; + if (is_link($document_root_part)) { + $root_dir = array(readlink($document_root_part)); } else { - $rootDir[] = $dirs[$i]; + $root_dir[] = $dirs[$i]; } } - $rootDir = implode('/', $rootDir); - return $rootDir; + $root_dir = implode('/', $root_dir); + return $root_dir; } } ?> diff --git a/gui/baculum/protected/Class/ConfigurationManager.php b/gui/baculum/protected/Class/ConfigurationManager.php index db22b11468..7995754a58 100644 --- a/gui/baculum/protected/Class/ConfigurationManager.php +++ b/gui/baculum/protected/Class/ConfigurationManager.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2015 Marcin Haba + * Copyright (C) 2013-2016 Marcin Haba * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -28,7 +28,7 @@ Prado::using('Application.Class.Miscellaneous'); * read/write application config and usersfiles, get application language * and others. * - * @author Marcin Haba + * @author Marcin Haba */ class ConfigurationManager extends TModule { @@ -209,7 +209,7 @@ class ConfigurationManager extends TModule * @return boolean true if user saved successfully, otherwise false */ public function setUsersConfig($user, $password, $firstUsage = false, $oldUser = null) { - if($firstUsage === true) { + if ($firstUsage === true) { $this->clearUsersConfig(); } @@ -224,15 +224,15 @@ class ConfigurationManager extends TModule $allUsers[$user] = $password; } - if(!is_null($oldUser) && $oldUser !== $user) { + if (!is_null($oldUser) && $oldUser !== $user) { // delete old username with password from configuration file - if(array_key_exists($oldUser, $allUsers)) { + if (array_key_exists($oldUser, $allUsers)) { unset($allUsers[$oldUser]); } } // add new user if does not exist - if($userExists === false) { + if ($userExists === false) { $allUsers[$user] = $password; } @@ -255,7 +255,7 @@ class ConfigurationManager extends TModule $users = file($usersFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); for($i = 0; $i < count($users); $i++) { - if(preg_match("/^(?P\S+)\:(?P\S+)$/", $users[$i], $match) === 1) { + if (preg_match("/^(?P\S+)\:(?P\S+)$/", $users[$i], $match) === 1) { $allUsers[$match['user']] = $match['hash']; } } -- 2.39.2