]> git.sur5r.net Git - bacula/bacula/blobdiff - gui/baculum/protected/Class/BaculumAPI.php
baculum: Tweak add comments
[bacula/bacula] / gui / baculum / protected / Class / BaculumAPI.php
index 0ed249aede9d6c4d6abb0cafa2c17ba70bebd1e7..74998c8cc60023ae805f61d31c342b00036baf48 100644 (file)
@@ -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
 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 <marcin.haba@bacula.pl>
+ */
+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; $i<count($chunks); $i++) {
-                               parse_str($chunks[$i], $responseEl);
-                               if(is_array($responseEl) && array_key_exists('update', $responseEl) && is_array($responseEl['update'])) {
-                                       $key = key($responseEl['update']);
-                                       $responseData['update'][$key] = $responseEl['update'][$key];
+                               // if chunks would not be used, then here occurs reach max_input_vars limit
+                               parse_str($chunks[$i], $response_el);
+                               if (is_array($response_el) && array_key_exists('update', $response_el) && is_array($response_el['update'])) {
+                                       $key = key($response_el['update']);
+                                       $response_data['update'][$key] = $response_el['update'][$key];
                                }
                        }
-                       if(is_array($responseData) && array_key_exists('update', $responseData)) {
-                               $params = (object)$responseData['update'];
+                       if (is_array($response_data) && array_key_exists('update', $response_data)) {
+                               $params = (object)$response_data['update'];
                                $this->set($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);
        }