Skip to content
Snippets Groups Projects
SecurityControler.php 17.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • SNA's avatar
    SNA committed
    /*
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
    *    Copyright 2008-2015 Maarch
    
    SNA's avatar
    SNA committed
    *
    *  This file is part of Maarch Framework.
    *
    *   Maarch Framework is free software: you can redistribute it and/or modify
    *   it under the terms of the GNU General Public License as published by
    *   the Free Software Foundation, either version 3 of the License, or
    *   (at your option) any later version.
    *
    *   Maarch Framework is distributed in the hope that it will be useful,
    *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    *   GNU General Public License for more details.
    *
    *   You should have received a copy of the GNU General Public License
    *    along with Maarch Framework.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    /**
    
    * @brief  Contains the controler of the Security Object
    *
    *
    
    SNA's avatar
    SNA committed
    * @file
    * @author Claire Figueras <dev@maarch.org>
    * @date $date$
    * @version $Revision$
    * @ingroup core
    */
    
    // Loads the required class
    
    SNA's avatar
    SNA committed
        require_once 'core/core_tables.php';
        require_once 'core/class/class_db.php';
        require_once 'core/class/users_controler.php';
        require_once 'core/class/session_security_controler.php';
        require_once 'core/class/Security.php';
        if (! defined('_CLASSIFICATION_SCHEME_VIEW')) {
    
            define('_CLASSIFICATION_SCHEME_VIEW', 'mr_classification_scheme_view');
        }
    
    SNA's avatar
    SNA committed
    } catch (Exception $e) {
    
        functions::xecho($e->getMessage()) . ' // ';
    
    SNA's avatar
    SNA committed
    /**
    
    * @brief  Controler of the Security Object
    
    SNA's avatar
    SNA committed
    *
    *<ul>
    *  <li>Get an security object from an id</li>
    *  <li>Save in the database a security</li>
    
    *  <li>Manage the operation on the security table in the database
    
    SNA's avatar
    SNA committed
    *   (_insert, select, _update, delete)</li>
    
    SNA's avatar
    SNA committed
    *</ul>
    * @ingroup core
    */
    
    SNA's avatar
    SNA committed
    class SecurityControler
    {
    
        /**
        * Returns an Security Object based on a security identifier
        *
    
    SNA's avatar
    SNA committed
        * @param  $securityId string  Security identifier
    
        * @return Security object with properties from the database or null
        */
    
    SNA's avatar
    SNA committed
        public function get($securityId)
    
    SNA's avatar
    SNA committed
            if (empty($securityId)) {
    
    SNA's avatar
    SNA committed
            }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $query = "select * from " . SECURITY_TABLE . " where security_id = ?";
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $stmt = $db->query($query, array($securityId));
    
            if ($stmt->rowCount() > 0) {
    
    SNA's avatar
    SNA committed
                $access = new SecurityObj();
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
                $queryResult = $stmt->fetchObject();
    
    SNA's avatar
    SNA committed
                foreach ($queryResult as $key => $value) {
    
                    $access->{$key} = $value;
    
    SNA's avatar
    SNA committed
            } else {
    
                return null;
            }
        }
    
        /**
        * Returns all security object for a given usergroup
        *
    
    SNA's avatar
    SNA committed
        * @param  $groupId string  Usergroup identifier
    
        * @return Array of security objects or null
        */
    
    SNA's avatar
    SNA committed
        public function getAccessForGroup($groupId)
    
    SNA's avatar
    SNA committed
            if (empty($groupId)) {
    
    SNA's avatar
    SNA committed
            }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
            
            $query = "select * from " . SECURITY_TABLE . " where group_id = ?";
    
            $stmt = $db->query($query, array($groupId));
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if ($stmt->rowCount() > 0) {
                while ($queryResult = $stmt->fetchObject()) {
    
    SNA's avatar
    SNA committed
                    $access = new SecurityObj();
                    foreach ($queryResult as $key => $value) {
    
                        $access->{$key} = $value;
    
                    }
                    array_push($security, $access);
                }
            }
            return $security;
        }
    
        /**
        * Saves in the database a security object
        *
        * @param  $security Security object to be saved
        * @param  $mode string  Saving mode : add or up (add by default)
        * @return bool true if the save is complete, false otherwise
    
        public function save($security, $mode="add")
        {
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if (!isset($security)) {
    
    SNA's avatar
    SNA committed
            }
    
    SNA's avatar
    SNA committed
            if ($mode == "up") {
                return $this->_update($security);
            } else if ($mode == "add") {
                return $this->_insert($security);
            }
    
    
            return false;
        }
    
        /**
        * Inserts in the database (security table) a Security object
        *
        * @param  $security Security object
    
    SNA's avatar
    SNA committed
        * @return bool true if the _insertion is complete, false otherwise
    
    SNA's avatar
    SNA committed
        private function _insert($security)
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if (!isset($security)) {
    
    SNA's avatar
    SNA committed
            }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
            
    
    SNA's avatar
    SNA committed
            $prepQuery = $this->_insertPrepare($security);
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            
    
    SNA's avatar
    SNA committed
            $query = "insert into " . SECURITY_TABLE . " (" . $prepQuery['COLUMNS']
                   . ") values (" . $prepQuery['VALUES'] . ")";
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            
            $stmt = $db->query($query, $prepQuery['ARRAY_VALUES']);
            $ok = true;
            
    
            return $ok;
        }
    
        /**
        * Updates a security in the database (security table) with a Security object
        *
        * @param  $security Security object
    
    SNA's avatar
    SNA committed
        * @return bool true if the _update is complete, false otherwise
    
    SNA's avatar
    SNA committed
        private function _update($security)
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if (!isset($security)) {
    
    SNA's avatar
    SNA committed
            }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
    
            $prep_query = $this->_updatePrepare($security);
    
    
    SNA's avatar
    SNA committed
            $query = "update " . SECURITY_TABLE . " set "
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
                   . $prep_query['QUERY'] . " where security_id=?";
    
            $prep_query['VALUES'][] = $security->security_id;
        
            $stmt = self::$db->query($query, $prep_query['VALUES']);
            $ok = true;
    
    
            return $ok;
        }
    
        /**
        * Deletes in the database (security table) a given security
        *
    
    SNA's avatar
    SNA committed
        * @param  $securityId string  Security identifier
    
        * @return bool true if the deletion is complete, false otherwise
        */
    
    SNA's avatar
    SNA committed
        public function delete($securityId)
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if (!isset($securityId) || empty($securityId)) {
    
    SNA's avatar
    SNA committed
            }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
    
            $query = "delete from " . SECURITY_TABLE . " where security_id=?";
    
            $db->query($query, array($securityId));
            $ok = true;
    
    
            return $ok;
        }
    
        /**
        * Deletes in the database (security table) all security of a given usergroup
        *
    
    SNA's avatar
    SNA committed
        * @param  $groupId string  Usergroup identifier
    
        * @return bool true if the deletion is complete, false otherwise
        */
    
    SNA's avatar
    SNA committed
        public function deleteForGroup($groupId)
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if (!isset($groupId) || empty($groupId)) {
    
    SNA's avatar
    SNA committed
            }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
    
            $query = "delete from " . SECURITY_TABLE . " where group_id=?";
    
            $db->query($query, array($groupId));
            $ok = true;
    
    
    SNA's avatar
    SNA committed
        * Prepares the _update query for a given Security object
    
        *
        * @param  $security Security object
        * @return String containing the fields and the values
        */
    
    SNA's avatar
    SNA committed
        private function _updatePrepare($security)
    
    SNA's avatar
    SNA committed
            $result = array();
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $arrayValues=array();
    
    SNA's avatar
    SNA committed
            foreach ($security->getArray() as $key => $value) {
                // For now all fields in the usergroups table are strings or date
                // excepts the security_id
                if (! empty($value)) {
                    if ($key <> 'security_id') {
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
                        $result[]=$key."=?";
                        $arrayValues[]=$value;
    
    SNA's avatar
    SNA committed
                    }
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            return array(
                'QUERY' => implode(",",$result), 
                'VALUES' => $arrayValues,
            );
    
    SNA's avatar
    SNA committed
        * Prepares the _insert query for a given Security object
    
        *
        * @param  $security Security object
        * @return Array containing the fields and the values
        */
    
    SNA's avatar
    SNA committed
        private function _insertPrepare($security)
    
    SNA's avatar
    SNA committed
            $columns = array();
            $values = array();
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $arrayValues = array();
    
    SNA's avatar
    SNA committed
            foreach ($security->getArray() as $key => $value) {
                // For now all fields in the security table are strings
                // or date excepts the security_id
                if (! empty($value)) {
                    if ($key <> 'security_id') {
                        $columns[] = $key;
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
                        $values[] = "?";
                        $arrayValues[]=$value;
    
    SNA's avatar
    SNA committed
            return array(
    
                'COLUMNS' => implode(",", $columns),
                'VALUES'  => implode(",", $values),
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
                'ARRAY_VALUES' => $arrayValues
    
    SNA's avatar
    SNA committed
            );
    
        public function check_where_clause($collId, $whereClause,
    
    SNA's avatar
    SNA committed
           $view, $userId)
    
            $res = array(
                'RESULT' => false,
    
    SNA's avatar
    SNA committed
                'TXT' => '',
    
            if (empty($collId) || empty($whereClause)) {
    
                $res['TXT'] = _ERROR_PARAMETERS_FUNCTION;
                return $res;
            }
    
    SNA's avatar
    SNA committed
            $where = ' ' . $whereClause;
    
            $where = str_replace('\\', '', $where);
    
    SNA's avatar
    SNA committed
            $where = $this->process_security_where_clause($where, $userId);
            if (str_replace(' ', '', $where) == '') {
    
            $where = str_replace('where', ' ', $where);
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
    
            $query = 'select res_id from ' . $view . ' where ' . $where;
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $ok = $db->query($query, array(), true);
    
                $res['TXT'] = _SYNTAX_ERROR_WHERE_CLAUSE;
                return $res;
    
                $res['TXT'] = _SYNTAX_OK;
                $res['RESULT'] = true;
            }
            return $res;
        }
    
        /**
    
    SNA's avatar
    SNA committed
        * Process a where clause, using the process_where_clause methods of the
        * modules, the core and the apps
    
    SNA's avatar
    SNA committed
        * @param  $whereClause string Where clause to process
        * @param  $userId string User identifier
    
        * @return string Proper where clause
        */
    
        public function process_security_where_clause($whereClause, $userId, $addWhere = true)
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            if (!empty($whereClause)) {
    
                $whereClause = str_replace("&#039;", "'", $whereClause);
    
                if ($addWhere) {
                    $where = ' where ' . $whereClause;
                } else {
                    $where = $whereClause;
                }
    
    SNA's avatar
    SNA committed
                $where = $this->process_where_clause($where, $userId);
    
    SNA's avatar
    SNA committed
                foreach (array_keys($_SESSION['modules_loaded']) as $key) {
    
                    if (file_exists(
                        $_SESSION['config']['corepath'] . 'custom'
                            . DIRECTORY_SEPARATOR . $_SESSION['custom_override_id']
                            . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR
                            . $_SESSION['modules_loaded'][$key]['name'] . DIRECTORY_SEPARATOR . "class"
                            . DIRECTORY_SEPARATOR . "class_modules_tools.php"
                    )
                    ) {
                        $pathModuleTools = $_SESSION['config']['corepath'] . 'custom'
                            . DIRECTORY_SEPARATOR . $_SESSION['custom_override_id']
                            . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR
                            . $_SESSION['modules_loaded'][$key]['name'] . DIRECTORY_SEPARATOR . "class"
                            . DIRECTORY_SEPARATOR . "class_modules_tools.php";
                    } else {
                        $pathModuleTools = 'modules' . DIRECTORY_SEPARATOR
                            . $_SESSION['modules_loaded'][$key]['name'] . DIRECTORY_SEPARATOR . "class"
                            . DIRECTORY_SEPARATOR . "class_modules_tools.php";
                    }
    
    
    SNA's avatar
    SNA committed
                    if (file_exists($pathModuleTools)) {
                        require_once($pathModuleTools);
                        if (class_exists($key)) {
                            $object = new $key;
                            if (method_exists(
                                $object, 'process_where_clause'
                            ) == true
                            ) {
                                $where = $object->process_where_clause(
                                    $where, $userId
                                );
                            }
                        }
    
    SNA's avatar
    SNA committed
    
    
                $where = preg_replace('/, ,/', ',', $where);
                $where = preg_replace('/\( ?,/', '(', $where);
                $where = preg_replace('/, ?\)/', ')', $where);
    
                // Process with the apps vars
    
    SNA's avatar
    SNA committed
                require_once 'apps' . DIRECTORY_SEPARATOR
                    . $_SESSION['config']['app_id'] . DIRECTORY_SEPARATOR . 'class'
                    . DIRECTORY_SEPARATOR . 'class_business_app_tools.php';
    
                $object = new business_app_tools();
    
    SNA's avatar
    SNA committed
                if (method_exists($object, 'process_where_clause')) {
                    $where = $object->process_where_clause($where, $userId);
    
    SNA's avatar
    SNA committed
            } else {
    
                return '';
            }
        }
    
        /**
        * Process a where clause with the core specific vars
        *
    
    SNA's avatar
    SNA committed
        * @param  $whereClause string Where clause to process
        * @param  $userId string User identifier
    
        * @return string Proper where clause
        */
    
    SNA's avatar
    SNA committed
        public function process_where_clause($whereClause, $userId)
    
    SNA's avatar
    SNA committed
            if (preg_match('/@user/', $whereClause)) {
    
                $whereClause = str_replace(
    
                    "@user", "'" . trim($userId) . "'", $whereClause
    
    SNA's avatar
    SNA committed
                );
    
    Giovannoni Laurent's avatar
    Giovannoni Laurent committed
            $db = new Database();
            
            $query = "select mail from " . USERS_TABLE . " where user_id = ?";
            $stmt = $db->query($query, array($userId));
            $userObj = $stmt->fetchObject();
    
            if (preg_match('/@email/', $whereClause)) {
                $whereClause = str_replace(
                    "@email", "'" . trim($userObj->mail) . "'", $whereClause
                );
            }
            return $whereClause;
    
    SNA's avatar
    SNA committed
        * Loads into session, the security parameters corresponding to the user
        * groups.
    
    SNA's avatar
    SNA committed
        * @param  $userId string User Identifier
    
    SNA's avatar
    SNA committed
        public function load_security($userId)
    
        {
            $tab['collections'] = array();
            $tab['security'] = array();
    
            $func = new functions();
    
    SNA's avatar
    SNA committed
            if ($userId == "superadmin") {
                for ($i = 0; $i < count($_SESSION['collections']); $i ++) {
    
                    $tab['security'][$_SESSION['collections'][$i]['id']] = array();
                    $tab['security'][$_SESSION['collections'][$i]['id']]['DOC'] = array(
                        'table'  => $_SESSION['collections'][$i]['table'],
                        'label_coll' => $_SESSION['collections'][$i]['label'],
                        'view'  => $_SESSION['collections'][$i]['view'],
                        'where' => " (1=1) ",
                    );
    
    SNA's avatar
    SNA committed
                    array_push(
                        $tab['collections'], $_SESSION['collections'][$i]['id']
                    );
    
    SNA's avatar
    SNA committed
            } else {
    
                $uc = new users_controler();
    
    SNA's avatar
    SNA committed
                $groups = $uc->getGroups($userId);
    
    SNA's avatar
    SNA committed
                for ($i = 0; $i < count($groups); $i ++) {
                    $tmp = $this->getAccessForGroup($groups[$i]['GROUP_ID']);
                    for ($j = 0; $j < count($tmp);$j ++) {
    
    SNA's avatar
    SNA committed
                for ($i = 0; $i < count($access); $i ++) {
    
    SNA's avatar
    SNA committed
                    $collId = $access[$i]->__get('coll_id');
                    $whereClause = $access[$i]->__get('where_clause');
                    $whereClause = $this->process_security_where_clause(
                        $whereClause, $userId
                    );
                    $whereClause = str_replace('where', '', $whereClause);
    
    SNA's avatar
    SNA committed
                    $ind = $this->get_ind_collection($collId);
    
    SNA's avatar
    SNA committed
                    if (trim($whereClause) == "") {
    
    SNA's avatar
    SNA committed
                    } else {
                        $where = "( " . $func->show_string($whereClause) . " )";
    
    SNA's avatar
    SNA committed
                    if (! in_array($collId, $tab['collections'])) {
                        $tab['security'][$collId] = array();
    
    
                        $tab['security'][$collId]['DOC'] = array(
                            'table'  => $_SESSION['collections'][$ind]['table'],
                            'label_coll'  => $_SESSION['collections'][$ind]['label'],
                            'view'  => $_SESSION['collections'][$ind]['view'],
                            'where'  => $where,
                        );
    
    SNA's avatar
    SNA committed
                        array_push($tab['collections'], $collId);
                    } else {
    
                        if (isset($tab['security'][$collId]['DOC'])
                            && count($tab['security'][$collId]['DOC']) > 0
    
    SNA's avatar
    SNA committed
                        ) {
    
                            $tab['security'][ $collId]['DOC']['where'] .= " or "
    
    SNA's avatar
    SNA committed
                                . $where;
                        } else {
    
                            $tab['security'][$collId]['DOC'] = array(
    
                                'table'  => $_SESSION['collections'][$ind]['table'],
                                'label_coll'  => $_SESSION['collections'][$ind]['label'],
                                'view'  => $_SESSION['collections'][$ind]['view'],
                                'where'  => $where,
    
    SNA's avatar
    SNA committed
                            );
    
                        }
                    }
                }
            }
            return $tab;
        }
    
        /**
        * Gets the indice of the collection in the  $_SESSION['collections'] array
        *
    
    SNA's avatar
    SNA committed
        * @param  $collId string  Collection identifier
        * @return integer Indice of the collection in the $_SESSION['collections']
    
        *           or -1 if not found
    
    SNA's avatar
    SNA committed
        public function get_ind_collection($collId)
    
    SNA's avatar
    SNA committed
            for ($i = 0; $i < count($_SESSION['collections']); $i ++) {
                if (trim($_SESSION['collections'][$i]['id']) == trim($collId)) {
    
    SNA's avatar
    SNA committed
    
    
        /**
        * Check the where clause syntax
        *
        * @param  $whereClause string The where clause to check
        * @return bool true if the request is not secure, false otherwise
        */
        public function isUnsecureRequest($whereClause)
        {
    
            $whereClause = str_replace("&#039;", "'", $whereClause);
    
            $search1 = '#\b(?:abort|alter|copy|create|delete|disgard|drop|'
                    . 'execute|grant|insert|load|lock|move|reset|truncate|update)\b#i';
            preg_match($search1, $whereClause, $out);
            if (isset($out[0])) {
                $count = count($out[0]);
                if ($count == 1) {
                    $find1 = true;
                } else {
                    $find1 = false;
                }
            } else {
                $find1 = false;
            }
            return $find1;
        }