mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-16 22:42:16 +00:00
- FilterWidget: now it is possible to provide the encryptedColumns parameter to specify which columns of a database table are encrypted, how to cast them and which password to use to decrypt them
- Added new constants PGSQL_BYTEA_TYPE, CRYPT_CONF_PASSWORDS, CRYPT_CAST, CRYPT_PASSWORD_NAME, CRYPT_SELECT_TEMPLATE, CRYPT_WHERE_TEMPLATE and CRYPT_WRITE_TEMPLATE to application/core/DB_Model.php - Added new optional parameter encryptedColumns to application/core/DB_Model insert, update, load, loadWhere, execQuery, execReadOnlyQuery and _toPhp - Added new private methods _addEncrypt, _addDecryptQuery and _addDecryptLoad to application/core/DB_Model.php - core/DB_Model: now it is possible to provide the encryptedColumns parameter to specify which columns of a database table are encrypted, how to cast them and which password to use to decrypt them - Adapted application/models/system/PersonLog_model.php
This commit is contained in:
+225
-97
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Copyright (C) 2023 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* This program 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.
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use phpseclib\Crypt\Twofish;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -46,16 +44,20 @@ class DB_Model extends CI_Model
|
||||
const PGSQL_INT8_TYPE = 'int8';
|
||||
const PGSQL_FLOAT4_TYPE = 'float4';
|
||||
const PGSQL_FLOAT8_TYPE = 'float8';
|
||||
const PGSQL_BYTEA_TYPE = 'bytea';
|
||||
|
||||
// Name of the config entry containing an array of password that can be used to encrypt/decrypt
|
||||
const ENCRYPTION_PASSWORDS = 'encryption_passwords';
|
||||
const CRYPT_CONF_PASSWORDS = 'encryption_passwords';
|
||||
const CRYPT_CAST = 'cast';
|
||||
const CRYPT_PASSWORD_NAME = 'passwordName';
|
||||
const CRYPT_SELECT_TEMPLATE = 'PGP_SYM_DECRYPT(%s, \'%s\')::%s AS %s';
|
||||
const CRYPT_WHERE_TEMPLATE = 'PGP_SYM_DECRYPT(%s, \'%s\')::%s';
|
||||
const CRYPT_WRITE_TEMPLATE = 'PGP_SYM_ENCRYPT(\'%s\', \'%s\')';
|
||||
|
||||
protected $dbTable; // Name of the DB-Table for CI-Insert, -Update, ...
|
||||
protected $pk; // Name of the PrimaryKey for DB-Update, Load, ...
|
||||
protected $hasSequence; // False if this table has a composite primary key that is not using a sequence
|
||||
// True if this table has a primary key that uses a sequence
|
||||
protected $passwordName; // Eventually the name of the password that is used to encrypt/decrypt
|
||||
protected $encryptedColumns; // Eventually an array of columns to be encrypted/decrypted
|
||||
|
||||
private $executedQueryMetaData;
|
||||
private $executedQueryListFields;
|
||||
@@ -78,8 +80,6 @@ class DB_Model extends CI_Model
|
||||
|
||||
// Set properties
|
||||
$this->hasSequence = true;
|
||||
$this->passwordName = null;
|
||||
$this->encryptedColumns = null;
|
||||
$this->debugMode = isset($this->db->db_debug) && $this->db->db_debug === true;
|
||||
|
||||
// Loads UDF model
|
||||
@@ -114,7 +114,7 @@ class DB_Model extends CI_Model
|
||||
* @param array $data DataArray for Insert
|
||||
* @return array
|
||||
*/
|
||||
public function insert($data)
|
||||
public function insert($data, $encryptedColumns = null)
|
||||
{
|
||||
// Check class properties
|
||||
if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL);
|
||||
@@ -122,8 +122,8 @@ class DB_Model extends CI_Model
|
||||
// If this table has UDF and the validation of them is ok
|
||||
if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable))) return $validate;
|
||||
|
||||
//
|
||||
$this->_encrypt($data);
|
||||
// Add the pgp_sym_eccrypt postgresql function to the set clause if needed
|
||||
$this->_addEncrypt($encryptedColumns, $data);
|
||||
|
||||
// DB-INSERT
|
||||
$insert = $this->db->insert($this->dbTable, $data);
|
||||
@@ -167,7 +167,7 @@ class DB_Model extends CI_Model
|
||||
* @param array $data DataArray for Insert
|
||||
* @return array
|
||||
*/
|
||||
public function update($id, $data)
|
||||
public function update($id, $data, $encryptedColumns = null)
|
||||
{
|
||||
// Check class properties
|
||||
if (is_null($this->pk)) return error('The given primary key is not valid', EXIT_MODEL);
|
||||
@@ -193,8 +193,8 @@ class DB_Model extends CI_Model
|
||||
|
||||
$this->db->where($tmpId);
|
||||
|
||||
//
|
||||
$this->_encrypt($data);
|
||||
// Add the pgp_sym_eccrypt postgresql function to the set clause if needed
|
||||
$this->_addEncrypt($encryptedColumns, $data);
|
||||
|
||||
// DB-UPDATE
|
||||
$update = $this->db->update($this->dbTable, $data);
|
||||
@@ -259,7 +259,7 @@ class DB_Model extends CI_Model
|
||||
* @param string $id ID (Primary Key) for SELECT ... WHERE
|
||||
* @return array
|
||||
*/
|
||||
public function load($id = null)
|
||||
public function load($id = null, $encryptedColumns = null)
|
||||
{
|
||||
// Check class properties
|
||||
if (is_null($this->pk)) return error('The given primary key is not valid', EXIT_MODEL);
|
||||
@@ -280,7 +280,7 @@ class DB_Model extends CI_Model
|
||||
$tmpId = array($this->pk => $id);
|
||||
}
|
||||
|
||||
return $this->loadWhere($tmpId);
|
||||
return $this->loadWhere($tmpId, $encryptedColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,11 +288,14 @@ class DB_Model extends CI_Model
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadWhere($where = null)
|
||||
public function loadWhere($where = null, $encryptedColumns = null)
|
||||
{
|
||||
// Check class properties
|
||||
if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL);
|
||||
|
||||
// Add the pgp_sym_decrypt postgresql function to the select and where clause if needed
|
||||
$this->_addDecryptLoad($encryptedColumns, $where);
|
||||
|
||||
// Execute query
|
||||
$result = $this->db->get_where($this->dbTable, $where);
|
||||
|
||||
@@ -300,10 +303,7 @@ class DB_Model extends CI_Model
|
||||
|
||||
if ($result)
|
||||
{
|
||||
// Decrypt data if needed
|
||||
$this->_decrypt($result);
|
||||
|
||||
return success($this->_toPhp($result));
|
||||
return success($this->_toPhp($result, $encryptedColumns));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -366,9 +366,6 @@ class DB_Model extends CI_Model
|
||||
// Execute the query
|
||||
$resultDB = $this->db->get_where($this->dbTable, $where);
|
||||
|
||||
// Decrypt data if needed
|
||||
$this->_decrypt($resultDB);
|
||||
|
||||
$this->_logLastQuery();
|
||||
|
||||
// If everything went ok...
|
||||
@@ -799,7 +796,7 @@ class DB_Model extends CI_Model
|
||||
/**
|
||||
* Like execQuery, but it allows only to perform queries to read data
|
||||
*/
|
||||
public function execReadOnlyQuery($query, $parametersArray = null)
|
||||
public function execReadOnlyQuery($query, $parametersArray = null, $encryptedColumns = null)
|
||||
{
|
||||
$result = error('You are allowed to run only query for reading data'); //
|
||||
$cleanedQuery = trim(preg_replace('/\t|\n|\r|;/', '', $query)); //
|
||||
@@ -816,7 +813,7 @@ class DB_Model extends CI_Model
|
||||
{
|
||||
$queryToExec = str_replace(';', '', $query); //
|
||||
|
||||
$result = $this->execQuery($queryToExec, $parametersArray);
|
||||
$result = $this->execQuery($queryToExec, $parametersArray, $encryptedColumns);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -831,13 +828,16 @@ class DB_Model extends CI_Model
|
||||
* boolean if the query is of the write type (INSERT, UPDATE, DELETE...)
|
||||
* array that represents DB data
|
||||
*/
|
||||
protected function execQuery($query, $parametersArray = null)
|
||||
protected function execQuery($query, $parametersArray = null, $encryptedColumns = null)
|
||||
{
|
||||
$result = null;
|
||||
|
||||
// If the query is empty don't lose time
|
||||
if (!isEmptyString($query))
|
||||
{
|
||||
// Add the pgp_sym_decrypt postgresql function to the given query
|
||||
$this->_addDecryptQuery($encryptedColumns, $query);
|
||||
|
||||
// If there are parameters to bind to the query
|
||||
if (is_array($parametersArray) && count($parametersArray) > 0)
|
||||
{
|
||||
@@ -853,7 +853,7 @@ class DB_Model extends CI_Model
|
||||
// If no errors occurred
|
||||
if ($resultDB)
|
||||
{
|
||||
$result = success($this->_toPhp($resultDB));
|
||||
$result = success($this->_toPhp($resultDB, $encryptedColumns));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -895,92 +895,202 @@ class DB_Model extends CI_Model
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* If the cryptography is enabled and correctly configured
|
||||
* To add the pgp_sym_encrypt function to the set clause where needed
|
||||
*/
|
||||
private function _isCryptoEnabledAndValid()
|
||||
private function _addEncrypt($encryptedColumns, &$data)
|
||||
{
|
||||
// Get the password list to decrypt/encrypt from the configuration
|
||||
$encryptionPasswords = $this->config->item(self::ENCRYPTION_PASSWORDS);
|
||||
|
||||
// If not configured or wrongly configured
|
||||
if (isEmptyArray($encryptionPasswords)) return false;
|
||||
|
||||
// If array of encrypted columns is defined or wrongly defined for this model
|
||||
if (isEmptyArray($this->encryptedColumns)) return false;
|
||||
|
||||
// If no decryption/encryption password name is defined for this model
|
||||
if (isEmptyString($this->passwordName)) return false;
|
||||
|
||||
// If the configured password name does not exists in the password list to decrypt/encrypt
|
||||
if (!array_key_exists($this->passwordName, $encryptionPasswords)) return false;
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cipher to decrypt/encrypt data
|
||||
*/
|
||||
private function _getCipher()
|
||||
{
|
||||
// Set the cipher type
|
||||
$cipher = new Twofish();
|
||||
// Set the password to encrypt using the chosen one
|
||||
$cipher->setPassword($this->config->item(self::ENCRYPTION_PASSWORDS)[$this->passwordName]);
|
||||
|
||||
return $cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
* To encrypt data
|
||||
* Data is an associative array that contains column names as keys and the colum value as array value
|
||||
*/
|
||||
private function _encrypt(&$data)
|
||||
{
|
||||
// If no encryption is configured or not correctly configured then exit this method
|
||||
if (!$this->_isCryptoEnabledAndValid()) return;
|
||||
|
||||
// Gets the cipher
|
||||
$cipher = $this->_getCipher();
|
||||
$tmpData = array(); // Temporary array used to copy not encrypted columns
|
||||
|
||||
// For each column that is going to be inserted/updated
|
||||
foreach ($data as $column => $value)
|
||||
{
|
||||
// If the current column is in the list of the columns to be encrypted
|
||||
if (in_array($column, $this->encryptedColumns))
|
||||
// and contains the password name element
|
||||
if (array_key_exists($column, $encryptedColumns)
|
||||
&& array_key_exists(self::CRYPT_PASSWORD_NAME, $encryptedColumns[$column]))
|
||||
{
|
||||
// Encrypt it!
|
||||
$data[$column] = base64_encode($cipher->encrypt($value));
|
||||
// Password to encrypt data
|
||||
$encryptionPassword = $this->config->item(self::CRYPT_CONF_PASSWORDS)[
|
||||
$encryptedColumns[$column][self::CRYPT_PASSWORD_NAME]
|
||||
];
|
||||
|
||||
// Add the encrypted column to the set clause without escaping
|
||||
$this->db->set(
|
||||
$column,
|
||||
sprintf(
|
||||
self::CRYPT_WRITE_TEMPLATE,
|
||||
$value,
|
||||
$encryptionPassword
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
else // otherwise copy this element as it is
|
||||
{
|
||||
$tmpData[$column] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$data = $tmpData; // this array does not contain encrypted columns
|
||||
}
|
||||
|
||||
/**
|
||||
* To add the pgp_sym_decrypt function to the given query
|
||||
*/
|
||||
private function _addDecryptQuery($encryptedColumns, &$query)
|
||||
{
|
||||
// If it is request to get encrypted columns
|
||||
if (!isEmptyArray($encryptedColumns))
|
||||
{
|
||||
// For each requested encrypted column
|
||||
foreach ($encryptedColumns as $encryptedColumn => $definition)
|
||||
{
|
||||
// If the requested encrypted column is well defined
|
||||
if (!isEmptyArray($definition)
|
||||
&& array_key_exists(self::CRYPT_CAST, $definition)
|
||||
&& array_key_exists(self::CRYPT_PASSWORD_NAME, $definition))
|
||||
{
|
||||
// And if exists the wanted password to decrypt in the configs
|
||||
if (array_key_exists(
|
||||
$definition[self::CRYPT_PASSWORD_NAME],
|
||||
$this->config->item(self::CRYPT_CONF_PASSWORDS))
|
||||
)
|
||||
{
|
||||
// Password to decrypt data
|
||||
$decryptionPassword = $this->config->item(self::CRYPT_CONF_PASSWORDS)[
|
||||
$definition[self::CRYPT_PASSWORD_NAME]
|
||||
];
|
||||
|
||||
// Find and replace all the occurrences of the provided encrypted columns
|
||||
// with the postgresql decryption function
|
||||
$query = str_replace(
|
||||
$encryptedColumn,
|
||||
sprintf(
|
||||
self::CRYPT_WHERE_TEMPLATE,
|
||||
$encryptedColumn,
|
||||
$decryptionPassword,
|
||||
$definition[self::CRYPT_CAST]
|
||||
),
|
||||
$query
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To decrypt data
|
||||
* dbResult is an array of objects, each object is a representation of a database record,
|
||||
* each property of the object is the column name and the property value is the database value
|
||||
* To add the pgp_sym_decrypt function to the select and where clause where needed
|
||||
*/
|
||||
private function _decrypt(&$dbResult)
|
||||
private function _addDecryptLoad($encryptedColumns, &$where)
|
||||
{
|
||||
// If no encryption is configured or not correctly configured then exit this method
|
||||
if (!$this->_isCryptoEnabledAndValid()) return;
|
||||
|
||||
// Gets the cipher
|
||||
$cipher = $this->_getCipher();
|
||||
|
||||
// For each record from database
|
||||
foreach ($dbResult->result() as $record)
|
||||
// If it is request to get encrypted columns
|
||||
if (!isEmptyArray($encryptedColumns))
|
||||
{
|
||||
// For each column to be encrypted
|
||||
foreach ($this->encryptedColumns as $column)
|
||||
// For each requested encrypted column
|
||||
foreach ($encryptedColumns as $encryptedColumn => $definition)
|
||||
{
|
||||
// If the current record contains such a column
|
||||
if (property_exists($record, $column))
|
||||
// If the requested encrypted column is well defined
|
||||
if (!isEmptyArray($definition)
|
||||
&& array_key_exists(self::CRYPT_CAST, $definition)
|
||||
&& array_key_exists(self::CRYPT_PASSWORD_NAME, $definition))
|
||||
{
|
||||
// Decrypt it!
|
||||
$record->{$column} = $cipher->decrypt(base64_decode($record->{$column}));
|
||||
// And if exists the wanted password to decrypt in the configs
|
||||
if (array_key_exists(
|
||||
$definition[self::CRYPT_PASSWORD_NAME],
|
||||
$this->config->item(self::CRYPT_CONF_PASSWORDS))
|
||||
)
|
||||
{
|
||||
// Password to decrypt data
|
||||
$decryptionPassword = $this->config->item(self::CRYPT_CONF_PASSWORDS)[
|
||||
$definition[self::CRYPT_PASSWORD_NAME]
|
||||
];
|
||||
|
||||
// -----------------------------------------
|
||||
// SELECT
|
||||
|
||||
// Add to the select clause the column to be decrypted
|
||||
// NOTE: this is going to override any previously added column with the same name
|
||||
$this->addSelect(
|
||||
sprintf(
|
||||
self::CRYPT_SELECT_TEMPLATE,
|
||||
$encryptedColumn,
|
||||
$decryptionPassword,
|
||||
$definition[self::CRYPT_CAST],
|
||||
$encryptedColumn
|
||||
)
|
||||
);
|
||||
|
||||
// -----------------------------------------
|
||||
// WHERE
|
||||
|
||||
// If the where parameter is a valid array
|
||||
if (!isEmptyArray($where))
|
||||
{
|
||||
$tmpWhere = array();
|
||||
|
||||
// For each condition of the where clause
|
||||
foreach ($where as $column => $condition)
|
||||
{
|
||||
$operator = null; // operator not found in the column name
|
||||
|
||||
// Custom operators
|
||||
if (strpos($column, '>') != false
|
||||
|| strpos($column, '<') != false
|
||||
|| strpos($column, '>=') != false
|
||||
|| strpos($column, '<=') != false
|
||||
|| strpos($column, '!=') != false
|
||||
|| strpos($column, '=') != false
|
||||
)
|
||||
{
|
||||
$operator = ' '.substr(trim($column), -1).' ';
|
||||
}
|
||||
else // default operator
|
||||
{
|
||||
$operator = ' = ';
|
||||
}
|
||||
|
||||
// If the column from the where clause is the same from the encrypted columns definition
|
||||
if (trim($column) == $encryptedColumn
|
||||
|| ($operator != null && substr(trim($column), 0, strlen(trim($column)) - 2) == $encryptedColumn)
|
||||
)
|
||||
{
|
||||
// Then rename the column using the postgresql decryption function
|
||||
$tmpWhere[
|
||||
sprintf(
|
||||
self::CRYPT_WHERE_TEMPLATE,
|
||||
$encryptedColumn,
|
||||
$decryptionPassword,
|
||||
$definition[self::CRYPT_CAST]
|
||||
).$operator
|
||||
] = $condition;
|
||||
}
|
||||
else // otherwise copy the column as it is
|
||||
{
|
||||
$tmpWhere[$column] = $condition;
|
||||
}
|
||||
}
|
||||
|
||||
$where = $tmpWhere; // replace with the new where
|
||||
}
|
||||
// Otherwise if the where parameter is a valid string
|
||||
elseif (!isEmptyString($where))
|
||||
{
|
||||
// Find and replace all the occurrences of the provided encrypted columns
|
||||
// with the postgresql decryption function
|
||||
$where = str_replace(
|
||||
$encryptedColumn,
|
||||
sprintf(
|
||||
self::CRYPT_WHERE_TEMPLATE,
|
||||
$encryptedColumn,
|
||||
$decryptionPassword,
|
||||
$definition[self::CRYPT_CAST]
|
||||
),
|
||||
$where
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,7 +1139,7 @@ class DB_Model extends CI_Model
|
||||
* - A FALSE value on failure
|
||||
* - Otherwise an object filled with data on success
|
||||
*/
|
||||
private function _toPhp($result)
|
||||
private function _toPhp($result, $encryptedColumns = null)
|
||||
{
|
||||
$udfs = false; // if UDFs are inside the given result set
|
||||
$toPhp = $result; // if there is nothing to convert then return the result from DB
|
||||
@@ -1045,7 +1155,9 @@ class DB_Model extends CI_Model
|
||||
// Looking for booleans, arrays and UDFs
|
||||
foreach ($this->executedQueryMetaData as $eqmd)
|
||||
{
|
||||
// If array type, boolean type OR a UDF
|
||||
// If array type, boolean type, numeric type
|
||||
// Or bytea type
|
||||
// Or UDF type
|
||||
if (strpos($eqmd->type, DB_Model::PGSQL_ARRAY_TYPE) !== false
|
||||
|| $eqmd->type == DB_Model::PGSQL_BOOLEAN_TYPE
|
||||
|| $eqmd->type == DB_Model::PGSQL_INT2_TYPE
|
||||
@@ -1053,6 +1165,7 @@ class DB_Model extends CI_Model
|
||||
|| $eqmd->type == DB_Model::PGSQL_INT8_TYPE
|
||||
|| $eqmd->type == DB_Model::PGSQL_FLOAT4_TYPE
|
||||
|| $eqmd->type == DB_Model::PGSQL_FLOAT8_TYPE
|
||||
|| $eqmd->type == DB_Model::PGSQL_BYTEA_TYPE
|
||||
|| $this->udflib->isUDFColumn($eqmd->name, $eqmd->type))
|
||||
{
|
||||
// If UDFs are inside this result set
|
||||
@@ -1115,6 +1228,21 @@ class DB_Model extends CI_Model
|
||||
{
|
||||
$resultElement->{$toBeConverted->name} = $this->pgFloatPhp($resultElement->{$toBeConverted->name});
|
||||
}
|
||||
// Byte A type
|
||||
elseif ($toBeConverted->type == DB_Model::PGSQL_BYTEA_TYPE)
|
||||
{
|
||||
// If encrypted columns are defined
|
||||
// and if the byte a column is defined as encrypted column
|
||||
if (!isEmptyArray($encryptedColumns)
|
||||
&& array_key_exists($toBeConverted->name, $encryptedColumns))
|
||||
{
|
||||
// keep the column
|
||||
}
|
||||
else // otherwise remove the column from the result
|
||||
{
|
||||
unset($resultElement->{$toBeConverted->name});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 fhcomplete.org
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
@@ -16,6 +33,7 @@ class FilterWidgetLib
|
||||
const SESSION_SELECTED_FIELDS = 'selectedFields';
|
||||
const SESSION_COLUMNS_ALIASES = 'columnsAliases';
|
||||
const SESSION_ADDITIONAL_COLUMNS = 'additionalColumns';
|
||||
const SESSION_ENCRYPTED_COLUMNS = 'encryptedColumns';
|
||||
const SESSION_CHECKBOXES = 'checkboxes';
|
||||
const SESSION_FILTERS = 'filters';
|
||||
const SESSION_METADATA = 'datasetMetadata';
|
||||
@@ -56,6 +74,7 @@ class FilterWidgetLib
|
||||
const ADDITIONAL_COLUMNS = 'additionalColumns';
|
||||
const CHECKBOXES = 'checkboxes';
|
||||
const COLUMNS_ALIASES = 'columnsAliases';
|
||||
const ENCRYPTED_COLUMNS = 'encryptedColumns';
|
||||
|
||||
// ...to format/mark records of a dataset
|
||||
const FORMAT_ROW = 'formatRow';
|
||||
@@ -367,7 +386,7 @@ class FilterWidgetLib
|
||||
/**
|
||||
* Retrieves the dataset from the DB
|
||||
*/
|
||||
public function getDataset($datasetQuery)
|
||||
public function getDataset($datasetQuery, $encryptedColumns)
|
||||
{
|
||||
$dataset = null;
|
||||
|
||||
@@ -376,7 +395,7 @@ class FilterWidgetLib
|
||||
$this->_ci->load->model('system/Filters_model', 'FiltersModel');
|
||||
|
||||
// Execute the given SQL statement suppressing error messages
|
||||
$dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery);
|
||||
$dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $encryptedColumns);
|
||||
}
|
||||
|
||||
return $dataset;
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 fhcomplete.org
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class Person_model extends DB_Model
|
||||
{
|
||||
/**
|
||||
@@ -8,6 +25,7 @@ class Person_model extends DB_Model
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->dbTable = 'public.tbl_person';
|
||||
$this->pk = 'person_id';
|
||||
|
||||
@@ -336,3 +354,4 @@ class Person_model extends DB_Model
|
||||
return $this->execQuery($qry, array($person_id, $person_id, $person_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 fhcomplete.org
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class PersonLog_model extends DB_Model
|
||||
{
|
||||
/**
|
||||
@@ -17,7 +34,7 @@ class PersonLog_model extends DB_Model
|
||||
* @param array $data Data of Log Entry to save.
|
||||
* @return success object if true
|
||||
*/
|
||||
public function insert($data)
|
||||
public function insert($data, $encryptedColumns = null)
|
||||
{
|
||||
$result = $this->db->insert($this->dbTable, $data);
|
||||
if ($result)
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 fhcomplete.org
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* To filter data using a SQL statement
|
||||
*/
|
||||
@@ -59,6 +76,8 @@ class FilterWidget extends Widget
|
||||
|
||||
private $_sessionTimeout; // session expiring time
|
||||
|
||||
private $_encryptedColumns; // contains info about encrypted columns
|
||||
|
||||
private static $_FilterWidgetInstance; // static property that contains the instance of itself
|
||||
|
||||
/**
|
||||
@@ -195,6 +214,7 @@ class FilterWidget extends Widget
|
||||
$this->_formatRow = null;
|
||||
$this->_markRow = null;
|
||||
$this->_checkboxes = null;
|
||||
$this->_encryptedColumns = null;
|
||||
$this->_hideOptions = null;
|
||||
$this->_hideSelectFields = null;
|
||||
$this->_hideSelectFilters = null;
|
||||
@@ -252,6 +272,14 @@ class FilterWidget extends Widget
|
||||
$this->_additionalColumns = $args[FilterWidgetLib::ADDITIONAL_COLUMNS];
|
||||
}
|
||||
|
||||
// Parameter is used to define the ecrypted columns
|
||||
if (isset($args[FilterWidgetLib::ENCRYPTED_COLUMNS])
|
||||
&& is_array($args[FilterWidgetLib::ENCRYPTED_COLUMNS])
|
||||
&& count($args[FilterWidgetLib::ENCRYPTED_COLUMNS]) > 0)
|
||||
{
|
||||
$this->_encryptedColumns = $args[FilterWidgetLib::ENCRYPTED_COLUMNS];
|
||||
}
|
||||
|
||||
// Parameter is used to add use aliases for the columns fo the dataset
|
||||
if (isset($args[FilterWidgetLib::COLUMNS_ALIASES])
|
||||
&& is_array($args[FilterWidgetLib::COLUMNS_ALIASES])
|
||||
@@ -441,7 +469,7 @@ class FilterWidget extends Widget
|
||||
);
|
||||
|
||||
// Then retrieve dataset from DB
|
||||
$dataset = $this->filterwidgetlib->getDataset($datasetQuery);
|
||||
$dataset = $this->filterwidgetlib->getDataset($datasetQuery, $this->_encryptedColumns);
|
||||
|
||||
// Save changes into session if data are valid
|
||||
if (!isError($dataset))
|
||||
@@ -476,7 +504,7 @@ class FilterWidget extends Widget
|
||||
$datasetQuery = $this->filterwidgetlib->generateDatasetQuery($this->_query, $parsedFilterJson->filters);
|
||||
|
||||
// Then retrieve dataset from DB
|
||||
$dataset = $this->filterwidgetlib->getDataset($datasetQuery);
|
||||
$dataset = $this->filterwidgetlib->getDataset($datasetQuery, $this->_encryptedColumns);
|
||||
|
||||
// Try to load the name of the filter using the PhrasesLib
|
||||
$filterName = $this->filterwidgetlib->getFilterName($parsedFilterJson);
|
||||
@@ -497,6 +525,7 @@ class FilterWidget extends Widget
|
||||
FilterWidgetLib::SESSION_SELECTED_FIELDS => $this->_getColumnsNames($parsedFilterJson->columns), // all the selected fields
|
||||
FilterWidgetLib::SESSION_COLUMNS_ALIASES => $this->_columnsAliases, // all the fields aliases
|
||||
FilterWidgetLib::SESSION_ADDITIONAL_COLUMNS => $this->_additionalColumns, // additional columns
|
||||
FilterWidgetLib::SESSION_ENCRYPTED_COLUMNS => $this->_encryptedColumns, // encrypted columns
|
||||
FilterWidgetLib::SESSION_CHECKBOXES => $this->_checkboxes, // the name of the field used to build the checkboxes column
|
||||
FilterWidgetLib::SESSION_FILTERS => $parsedFilterJson->filters, // all the filters used to filter the dataset
|
||||
FilterWidgetLib::SESSION_METADATA => $this->FiltersModel->getExecutedQueryMetaData(), // the metadata of the dataset
|
||||
|
||||
Reference in New Issue
Block a user