]> git.sur5r.net Git - bacula/bacula/commitdiff
baculum: Tweak add comments
authorMarcin Haba <marcin.haba@bacula.pl>
Thu, 31 Dec 2015 08:15:58 +0000 (09:15 +0100)
committerMarcin Haba <marcin.haba@bacula.pl>
Thu, 31 Dec 2015 08:15:58 +0000 (09:15 +0100)
gui/baculum/index.php
gui/baculum/protected/Class/API.php
gui/baculum/protected/Class/ConfigurationManager.php
gui/baculum/protected/Init.php
gui/baculum/protected/application.xml

index 683acb7efcd9382ea16002ffc106a541a10946e3..d70df07e089149ddde1b4cabbe911dc442cb9bc9 100644 (file)
  *
  * Bacula(R) is a registered trademark of Kern Sibbald.
  */
+
+/*
+ * Constant is used to localize always valid document root directory
+ * Using for placing Baculum files in document root subdirectory
+ */
 define('APPLICATION_DIRECTORY', __DIR__);
 
 require_once('./protected/Init.php');
 require_once('./framework/prado.php');
 
+// Start application
 $application=new TApplication;
 $application->run();
 ?>
index b04df4540787a42ac09bebba84f3bb22e35b7d09..9f631fd1f0f8e2af3b3f367763ba80dbf1772be1 100644 (file)
 
 Prado::using('Application.Class.Errors');
 
+/**
+ * Internal API client module.
+ *
+ * @author Marcin Haba
+ */
 class API extends TModule {
 
+       /**
+        * API version (used in HTTP header)
+        */
        const API_VERSION = '0.1';
 
+       /**
+        * Store configuration data from settings file
+        * @access protected
+        */
        protected $appCfg;
 
+       /**
+        * These errors are allowed in API response and they do not cause
+        * disturb application working (no direction to error page)
+        * @access private
+        */
        private $allowedErrors = array(
                GenericError::ERROR_NO_ERRORS,
                BconsoleError::ERROR_INVALID_COMMAND,
                PoolError::ERROR_NO_VOLUMES_IN_POOL_TO_UPDATE
        );
 
-       private function getConnection() {
+       /**
+        * Get connection request handler.
+        * For data requests is used cURL interface.
+        * @access public
+        * @return resource connection handler on success, false on errors
+        */
+       public function getConnection() {
                $ch = curl_init();
+               $userpwd = sprintf('%s:%s', $this->appCfg['baculum']['login'], $this->appCfg['baculum']['password']);
+               curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
+               curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=' . md5(session_id()));
-               curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
-               curl_setopt($ch, CURLOPT_USERPWD, $this->appCfg['baculum']['login'] . ':' . $this->appCfg['baculum']['password']);
                return $ch;
        }
 
+       /**
+        * Get API specific headers used in HTTP requests.
+        * @access private
+        * @return API specific headers
+        */
        private function getAPIHeaders() {
                $headers = array(
                        'X-Baculum-API: ' . self::API_VERSION,
@@ -55,29 +84,61 @@ class API extends TModule {
                return $headers;
        }
 
+       /**
+        * Initializes API module (framework module constructor)
+        * @access public
+        * @param TXmlElement $config API module configuration
+        */
        public function init($config) {
                $this->initSessionCache();
                $this->appCfg = $this->Application->getModule('configuration')->getApplicationConfig();
        }
 
+       /**
+        * Get URL to use by internal API client's request.
+        * @access private
+        * @return string URL to internal API server
+        */
        private function getURL() {
                $protocol = !empty($_SERVER['HTTPS']) ? 'https' : 'http';
                $host = $_SERVER['SERVER_NAME'];
                $port = $_SERVER['SERVER_PORT'];
+
+               // support for document root subdirectory
                $urlPrefix = $this->Application->getModule('friendly-url')->getUrlPrefix();
+
                $url = sprintf('%s://%s:%d%s/', $protocol, $host, $port, $urlPrefix);
                return $url;
        }
 
-       private function setParamsToUrl(&$url) {
-               $url .= (preg_match('/\?/', $url) === 1 ? '&' : '?' ) . 'director=' . ((array_key_exists('director', $_SESSION)) ? $_SESSION['director'] : '');
-               $this->Application->getModule('logging')->log(__FUNCTION__, PHP_EOL . PHP_EOL . 'EXECUTE URL ==> ' . $url . ' <==' . PHP_EOL . PHP_EOL, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__);
+       /**
+        * Set URL parameters and prepare URL to request send.
+        * @access private
+        * @param string &$url reference to URL string variable
+        */
+       private function setUrlParams(&$url) {
+               $url .= (preg_match('/\?/', $url) === 1 ? '&' : '?');
+               $url .= 'director=';
+               if (array_key_exists('director', $_SESSION)) {
+                       $url .= $_SESSION['director'];
+               }
+
+               $this->Application->getModule('logging')->log(
+                       __FUNCTION__,
+                       PHP_EOL . PHP_EOL . 'EXECUTE URL ==> ' . $url . ' <==' . PHP_EOL . PHP_EOL,
+                       Logging::CATEGORY_APPLICATION,
+                       __FILE__,
+                       __LINE__
+               );
        }
 
        /**
-        * API REQUESTS METHODS (get, set, create, delete)
+        * Internal API GET request.
+        * @access public
+        * @param array $params GET params to send in request
+        * @param bool $use_cache if true then try to use session cache, if false then always use fresh data
+        * @return object stdClass with request result as two properties: 'output' and 'error'
         */
-
        public function get(array $params, $use_cache = false) {
                $cached = null;
                $ret = null;
@@ -88,7 +149,7 @@ class API extends TModule {
                        $ret = $cached;
                } else {
                        $url = $this->getURL() . implode('/', $params);
-                       $this->setParamsToUrl($url);
+                       $this->setUrlParams($url);
                        $ch = $this->getConnection();
                        curl_setopt($ch, CURLOPT_URL, $url);
                        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getAPIHeaders());
@@ -102,14 +163,24 @@ class API extends TModule {
                return $ret;
        }
 
+       /**
+        * Internal API SET request.
+        * @access public
+        * @param array $params GET params to send in request
+        * @param array $options POST params to send in request
+        * @return object stdClass with request result as two properties: 'output' and 'error'
+        */
        public function set(array $params, array $options) {
                $url = $this->getURL() . implode('/', $params);
-               $this->setParamsToUrl($url);
+               $this->setUrlParams($url);
                $data = http_build_query(array('update' => $options));
                $ch = $this->getConnection();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
-               curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($this->getAPIHeaders(), array('X-HTTP-Method-Override: PUT', 'Content-Length: ' . strlen($data), 'Expect:')));
+               curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge(
+                       $this->getAPIHeaders(),
+                       array('X-HTTP-Method-Override: PUT', 'Content-Length: ' . strlen($data), 'Expect:')
+               ));
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                $result = curl_exec($ch);
@@ -117,9 +188,16 @@ class API extends TModule {
                return $this->preParseOutput($result);
        }
 
+       /**
+        * Internal API CREATE request.
+        * @access public
+        * @param array $params GET params to send in request
+        * @param array $options POST params to send in request
+        * @return object stdClass with request result as two properties: 'output' and 'error'
+        */
        public function create(array $params, array $options) {
                $url = $this->getURL() . implode('/', $params);
-               $this->setParamsToUrl($url);
+               $this->setUrlParams($url);
                $data = http_build_query(array('create' => $options));
                $ch = $this->getConnection();
                curl_setopt($ch, CURLOPT_URL, $url);
@@ -131,9 +209,15 @@ class API extends TModule {
                return $this->preParseOutput($result);
        }
 
+       /**
+        * Internal API REMOVE request.
+        * @access public
+        * @param array $params GET params to send in request
+        * @return object stdClass with request result as two properties: 'output' and 'error'
+        */
        public function remove(array $params) {
                $url = $this->getURL() . implode('/', $params);
-               $this->setParamsToUrl($url);
+               $this->setUrlParams($url);
                $ch = $this->getConnection();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
@@ -143,10 +227,28 @@ class API extends TModule {
                return $this->preParseOutput($result);
        }
 
+       /**
+        * Initially parse and prepare every Internal API response.
+        * If a error occurs then redirect to appropriate error page.
+        * @access private
+        * @param string $result response output as JSON string (not object yet)
+        * @return object stdClass parsed response with two top level properties 'output' and 'error'
+        */
        private function preParseOutput($result) {
-               $this->Application->getModule('logging')->log(__FUNCTION__, $result, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__);
+               // first write log with that what comes
+               $this->Application->getModule('logging')->log(
+                       __FUNCTION__,
+                       $result,
+                       Logging::CATEGORY_APPLICATION,
+                       __FILE__,
+                       __LINE__
+               );
+
+               // decode JSON to object
                $resource = json_decode($result);
+
                $error = null;
+
                if(is_object($resource) && property_exists($resource, 'error')) {
                        if(!in_array($resource->error, $this->allowedErrors)) {
                                $error = $resource->error;
@@ -155,10 +257,24 @@ class API extends TModule {
                        $error = AuthorizationError::ERROR_AUTHORIZATION_TO_WEBGUI_PROBLEM;
                }
 
-               $this->Application->getModule('logging')->log(__FUNCTION__, $resource, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__);
+               $this->Application->getModule('logging')->log(
+                       __FUNCTION__,
+                       $resource,
+                       Logging::CATEGORY_APPLICATION,
+                       __FILE__,
+                       __LINE__
+               );
+
+               // if other than allowed errors exist then show error page (redirect)
                if(!is_null($error)) {
                        // Note! Redirection to error page takes place here.
-                       $this->Response->redirect($this->Service->constructUrl('BaculumError',array('error' => $error), false));
+                       $this->Response->redirect(
+                               $this->Service->constructUrl(
+                                       'BaculumError',
+                                       array('error' => $error),
+                                       false
+                               )
+                       );
                }
 
                return $resource;
index caa1bdd6f6cf56fe84ae385ec4566c9e12fa16e0..b5692817bb5de9554adea1793c505579a668d526 100644 (file)
 
 Prado::using('Application.Class.Miscellaneous');
 
+/**
+ * Manage application configuration.
+ * Module is responsible for get/set application config data like:
+ * read/write application config and usersfiles, get application language
+ * and others.
+ *
+ * @author Marcin Haba
+ */
 class ConfigurationManager extends TModule
 {
 
        /**
-        * Location o application configuration file.
+        * Application config file path
         */
        const CONFIG_FILE = 'Application.Data.settings';
 
@@ -36,32 +44,39 @@ class ConfigurationManager extends TModule
        const USERS_FILE = 'Application.Data.baculum';
 
        /**
-        * PostgreSQL default params.
+        * PostgreSQL default params
         */
        const PGSQL = 'pgsql';
        const PGSQL_NAME = 'PostgreSQL';
        const PGSQL_PORT = 5432;
 
        /**
-        * MySQL default params.
+        * MySQL default params
         */
        const MYSQL = 'mysql';
        const MYSQL_NAME = 'MySQL';
        const MYSQL_PORT = 3306;
 
        /**
-        * SQLite default params.
+        * SQLite default params
         */
        const SQLITE = 'sqlite';
        const SQLITE_NAME = 'SQLite';
        const SQLITE_PORT = null;
 
        /**
-        * Default language for application.
+        * Default application language
         */
        const DEFAULT_LANGUAGE = 'en';
 
+       /**
+        * Get database name by database type (short name).
+        * @access public
+        * @param string $type database type ('pgsql', 'mysql' ...)
+        * @return mixed database name or null if database name not found
+        */
        public function getDbNameByType($type) {
+               $type = (string) $type;
                switch($type) {
                        case self::PGSQL: $dbName = self::PGSQL_NAME; break;
                        case self::MYSQL: $dbName = self::MYSQL_NAME; break;
@@ -71,34 +86,46 @@ class ConfigurationManager extends TModule
                return $dbName;
        }
 
-       public function getPostgreSQLType() {
-               return self::PGSQL;
-       }
-
-       public function getMySQLType() {
-               return self::MYSQL;
-       }
-
-       public function getSQLiteType() {
-               return self::SQLITE;
-       }
-
+       /**
+        * Check if given database type is PostgreSQL type.
+        * @access public
+        * @param string $type database type ('pgsql', 'mysql' ...)
+        * @return boolean true if database type is PostgreSQL, otherwise false
+        */
        public function isPostgreSQLType($type) {
                return ($type === self::PGSQL);
        }
 
+       /**
+        * Check if given database type is MySQL type.
+        * @access public
+        * @param string $type database type ('pgsql', 'mysql' ...)
+        * @return boolean true if database type is MySQL, otherwise false
+        */
        public function isMySQLType($type) {
                return ($type === self::MYSQL);
        }
 
+       /**
+        * Check if given database type is SQLite type.
+        * @access public
+        * @param string $type database type ('sqlite', 'mysql' ...)
+        * @return boolean true if database type is SQLite, otherwise false
+        */
        public function isSQLiteType($type) {
                return ($type === self::SQLITE);
        }
 
+       /**
+        * Get currently set application language short name.
+        * If no language set then default language is taken.
+        * @access public
+        * @return string lanuage short name
+        */
        public function getLanguage() {
                $language = self::DEFAULT_LANGUAGE;
                if ($this->isApplicationConfig() === true) {
-                       $config = $this->getApplicationConfig();
+                       $config = self::getApplicationConfig();
                        if (array_key_exists('lang', $config['baculum'])) {
                                $language = $config['baculum']['lang'];
                        }
@@ -106,13 +133,8 @@ class ConfigurationManager extends TModule
                return $language;
        }
 
-       public function setLanguage($language) {
-               
-       }
-
        /**
-        * Saving application configuration.
-        * 
+        * Save application configuration.
         * @access public
         * @param array $config structure of config file params
         * @return boolean true if config save is successfully, false if config save is failure
@@ -123,8 +145,7 @@ class ConfigurationManager extends TModule
        }
 
        /**
-        * Getting application configuration.
-        * 
+        * Get application configuration.
         * @access public
         * @return array application configuration
         */
@@ -134,8 +155,7 @@ class ConfigurationManager extends TModule
        }
 
        /**
-        * Checking if application configuration file exists.
-        * 
+        * Check if application configuration file exists.
         * @access public
         * @return boolean true if file exists, otherwise false
         */
@@ -143,20 +163,20 @@ class ConfigurationManager extends TModule
                return file_exists(Prado::getPathOfNamespace(self::CONFIG_FILE, '.conf'));
        }
 
+       /**
+        * Get encrypted password to use in HTTP Basic auth.
+        *
+        * @access public
+        * @param string $password plain text password
+        * @return string encrypted password
+        */
        public function getCryptedPassword($password) {
                $enc_pwd = crypt($password, base64_encode($password));
                return $enc_pwd;
        }
 
        /**
-        * Saving user to users configuration file.
-        *
-        * NOTE!
-        * So far by webGUI is possible to set one user.
-        * For more users and restricted consoles, there is need to modify
-        * users and passwords file.
-        *
-        * TODO: Support for more than one user setting on webGUI.
+        * Save user to users configuration file.
         *
         * @access public
         * @param string $user username
@@ -166,13 +186,13 @@ class ConfigurationManager extends TModule
         * @return boolean true if user saved successfully, otherwise false
         */
        public function setUsersConfig($user, $password, $firstUsage = false, $oldUser = null) {
-               $allUsers = $this->getAllUsers();
-               $password = $this->getCryptedPassword($password);
-
                if($firstUsage === true) {
                        $this->clearUsersConfig();
                }
 
+               $allUsers = $this->getAllUsers();
+               $password = $this->getCryptedPassword($password);
+
                $userExists = array_key_exists($user, $allUsers);
 
 
@@ -197,6 +217,14 @@ class ConfigurationManager extends TModule
                return $result;
        }
 
+       /**
+        * Read all users from HTTP Basic users file.
+        * Returned value is associative array with usernames as keys
+        * and encrypted passwords as values.
+        *
+        * @access public
+        * @return array users/passwords list
+        */
        public function getAllUsers() {
                $allUsers = array();
                if ($this->isUsersConfig() === true) {
@@ -212,6 +240,15 @@ class ConfigurationManager extends TModule
                return $allUsers;
        }
 
+       /**
+        * Save HTTP Basic users file.
+        * Given parameter is associative array with usernames as keys
+        * and encrypted passwords as values.
+        *
+        * @access public
+        * @param array $allUsers users/passwords list
+        * @return boolean true if users file saved successfully, otherwise false
+        */
        public function saveUserConfig($allUsers) {
                $users = array();
                foreach ($allUsers as $user => $pwd) {
@@ -226,6 +263,15 @@ class ConfigurationManager extends TModule
                return $result;
        }
 
+       /**
+        * Remove single user from HTTP Basic users file.
+        * Note, this method saves config file if username was existed
+        * before removing.
+        *
+        * @access public
+        * @param string $username user name to remove
+        * @return boolean true if users file saved successfully, otherwise false
+        */
        public function removeUser($username) {
                $result = false;
                $allUsers = $this->getAllUsers();
@@ -237,8 +283,7 @@ class ConfigurationManager extends TModule
        }
 
        /**
-        * Checking if users configuration file exists.
-        *
+        * Check if users configuration file exists.
         * @access public
         * @return boolean true if file exists, otherwise false
         */
@@ -248,22 +293,44 @@ class ConfigurationManager extends TModule
 
        /**
         * Clear all content of users file.
-        *
-        * @access private
+        * @access public
         * @return boolean true if file cleared successfully, otherwise false
         */
-       private function clearUsersConfig() {
+       public function clearUsersConfig() {
                $usersFile = Prado::getPathOfNamespace(self::USERS_FILE, '.users');
                $result = file_put_contents($usersFile, '') !== false;
                return $result;
        }
 
+       /**
+        * Log in as specific user.
+        *
+        * Note, usually after this method call there required is using exit() just
+        * after method execution. Otherwise the HTTP redirection may be canceled on some
+        * web servers.
+        *
+        * @access public
+        * @param string $http_protocol 'http' or 'https' value
+        * @param string $host hostname without port, for example: my.own.host or localhost
+        * @param integer $port port number on which listens web server
+        * @param string $user user name to log in
+        * @param string $string plain text user's password
+        * @return none
+        */
        public function switchToUser($http_protocol, $host, $port, $user, $password) {
                $urlPrefix = $this->Application->getModule('friendly-url')->getUrlPrefix();
                $location = sprintf("%s://%s:%s@%s:%d%s", $http_protocol, $user, $password, $host, $port, $urlPrefix);
                header("Location: $location");
        }
 
+       /**
+        * Get (pseudo)random string.
+        *
+        * Useful for log out user from HTTP Basic auth by providing random password.
+        *
+        * @access public
+        * @return string random 62 characters string from range [a-zA-Z0-9]
+        */
        public function getRandomString() {
                $characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                $rand_string = str_shuffle($characters);
index d3627030a2d937f071e731a3475a66ba56275f0b..f7a5f1c67958695dc7b3b3035157618d039f92d4 100644 (file)
@@ -31,11 +31,23 @@ if (!ini_get('date.timezone')) {
        date_default_timezone_set($timezone);
 }
 
-// Support for web servers which do not provide direct info about HTTP Basic auth to PHP superglobal $_SERVER array.
-if(!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']) && isset($_SERVER['HTTP_AUTHORIZATION'])) {
-    list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
+/*
+ * Support for web servers (for example Lighttpd) which do not provide direct
+ * info about HTTP Basic auth to PHP superglobal $_SERVER array.
+ */
+if (!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW']) && isset($_SERVER['HTTP_AUTHORIZATION'])) {
+       /*
+        * Substring 'Basic ' from  HTTP authorization header
+        * Example 'Basic YWRtaW46YWRtaW4=' becomes 'YWRtaW46YWRtaW4='
+        */
+       $encoded_credentials = substr($_SERVER['HTTP_AUTHORIZATION'], 6);
+       $decoded_credentials = base64_decode($encoded_credentials);
+
+       // initialize required auth superglobal $_SERVER array
+       list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', $decoded_credentials);
 }
 
+// Check requirements and if are some needed then show requirements page
 require_once('./protected/Pages/Requirements.php');
 new Requirements(dirname(__DIR__));
 
index c1aea2b934ea3c18a7745eb899448a12e5558335..7f4c77477b8d97b086f865f68f43b2b286879275 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application id="baculum" mode="Normal">
        <paths>
-               <using namespace="Application.Class.*" />
                <using namespace="System.Data.ActiveRecord.*" />
                <using namespace="System.I18N.*" />
+               <using namespace="Application.Class.*" />
                <using namespace="Application.Portlets.BButton" />
                <using namespace="Application.Portlets.BActiveButton" />
        </paths>