Merge remote-tracking branch 'security/QA_4_9-security' into QA_4_9
This commit is contained in:
commit
f271cadd59
@ -65,7 +65,7 @@
|
||||
"samyoul/u2f-php-server": "<1.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Cookie encryption",
|
||||
"ext-openssl": "For encryption performance",
|
||||
"ext-curl": "Updates checking",
|
||||
"ext-opcache": "Better performance",
|
||||
"ext-zlib": "For gz import and export",
|
||||
@ -76,7 +76,8 @@
|
||||
"tecnickcom/tcpdf": "For PDF support",
|
||||
"pragmarx/google2fa": "For 2FA authentication",
|
||||
"bacon/bacon-qr-code": "For 2FA authentication",
|
||||
"samyoul/u2f-php-server": "For FIDO U2F authentication"
|
||||
"samyoul/u2f-php-server": "For FIDO U2F authentication",
|
||||
"paragonie/sodium_compat": "For modern encryption support"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7",
|
||||
@ -87,7 +88,9 @@
|
||||
"pragmarx/google2fa": "^3.0",
|
||||
"bacon/bacon-qr-code": "^1.0",
|
||||
"samyoul/u2f-php-server": "^1.1",
|
||||
"phpmyadmin/coding-standard": "^0.3"
|
||||
"phpmyadmin/coding-standard": "^0.3",
|
||||
"paragonie/random_compat": ">=2",
|
||||
"paragonie/sodium_compat": "^1.17"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
||||
@ -148,6 +148,13 @@ $cfg['SaveDir'] = '';
|
||||
*/
|
||||
//$cfg['SendErrorReports'] = 'always';
|
||||
|
||||
/**
|
||||
* 'URLQueryEncryption' defines whether phpMyAdmin will encrypt sensitive data from the URL query string.
|
||||
* 'URLQueryEncryptionSecretKey' is a 32 bytes long secret key used to encrypt/decrypt the URL query string.
|
||||
*/
|
||||
//$cfg['URLQueryEncryption'] = true;
|
||||
//$cfg['URLQueryEncryptionSecretKey'] = '';
|
||||
|
||||
/**
|
||||
* You can find more configuration options in the documentation
|
||||
* in the doc/ folder or at <https://docs.phpmyadmin.net/>.
|
||||
|
||||
@ -1477,6 +1477,20 @@ Server connection settings
|
||||
after logout (doesn't affect config authentication method). Should be
|
||||
absolute including protocol.
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['hide_connection_errors']
|
||||
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
.. versionadded:: 4.9.8
|
||||
|
||||
Whether to show or hide detailed MySQL/MariaDB connection errors on the login page.
|
||||
|
||||
.. note::
|
||||
|
||||
This error message can contain the target database server hostname or IP address,
|
||||
which may reveal information about your network to an attacker.
|
||||
|
||||
Generic settings
|
||||
----------------
|
||||
|
||||
@ -1736,6 +1750,27 @@ Generic settings
|
||||
Define whether phpMyAdmin will continue executing a multi-query
|
||||
statement if one of the queries fails. Default is to abort execution.
|
||||
|
||||
.. config:option:: $cfg['URLQueryEncryption']
|
||||
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
.. versionadded:: 4.9.8
|
||||
|
||||
Define whether phpMyAdmin will encrypt sensitive data (like database name
|
||||
and table name) from the URL query string. Default is to not encrypt the URL
|
||||
query string.
|
||||
|
||||
.. config:option:: $cfg['URLQueryEncryptionSecretKey']
|
||||
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
.. versionadded:: 4.9.8
|
||||
|
||||
A secret key used to encrypt/decrypt the URL query string.
|
||||
Should be 32 bytes long.
|
||||
|
||||
Cookie authentication options
|
||||
-----------------------------
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ function loadChildNodes (isNode, $expandElem, callback) {
|
||||
}
|
||||
|
||||
var url = $('#pma_navigation').find('a.navigation_url').attr('href');
|
||||
$.get(url, params, function (data) {
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
$destination.find('div.list_container').remove(); // FIXME: Hack, there shouldn't be a list container there
|
||||
if (isNode) {
|
||||
|
||||
@ -193,7 +193,7 @@ class ServerBinlogController extends Controller
|
||||
}
|
||||
|
||||
$html .= '<a href="server_binlog.php" data-post="'
|
||||
. Url::getCommon($this_url_params, '') . '"';
|
||||
. Url::getCommon($this_url_params, '', false) . '"';
|
||||
if (Util::showIcons('TableNavigationLinksMode')) {
|
||||
$html .= ' title="' . _pgettext('Previous page', 'Previous') . '">';
|
||||
} else {
|
||||
@ -215,7 +215,7 @@ class ServerBinlogController extends Controller
|
||||
$tempTitle = __('Show Full Queries');
|
||||
$tempImgMode = 'full';
|
||||
}
|
||||
$html .= '<a href="server_binlog.php" data-post="' . Url::getCommon($this_url_params, '')
|
||||
$html .= '<a href="server_binlog.php" data-post="' . Url::getCommon($this_url_params, '', false)
|
||||
. '" title="' . $tempTitle . '">'
|
||||
. '<img src="' . $GLOBALS['pmaThemeImage'] . 's_' . $tempImgMode
|
||||
. 'text.png" alt="' . $tempTitle . '" /></a>';
|
||||
@ -226,7 +226,7 @@ class ServerBinlogController extends Controller
|
||||
$this_url_params = $url_params;
|
||||
$this_url_params['pos'] = $pos + $GLOBALS['cfg']['MaxRows'];
|
||||
$html .= ' - <a href="server_binlog.php" data-post="'
|
||||
. Url::getCommon($this_url_params, '')
|
||||
. Url::getCommon($this_url_params, '', false)
|
||||
. '"';
|
||||
if (Util::showIcons('TableNavigationLinksMode')) {
|
||||
$html .= ' title="' . _pgettext('Next page', 'Next') . '">';
|
||||
|
||||
@ -1241,13 +1241,6 @@ class TableStructureController extends TableController
|
||||
'DistinctValues' => Util::getIcon('b_browse', __('Distinct values')),
|
||||
);
|
||||
|
||||
$edit_view_url = '';
|
||||
if ($this->_tbl_is_view && ! $this->_db_is_system_schema) {
|
||||
$edit_view_url = Url::getCommon(
|
||||
array('db' => $this->db, 'table' => $this->table)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays Space usage and row statistics
|
||||
*/
|
||||
@ -1275,11 +1268,11 @@ class TableStructureController extends TableController
|
||||
'tbl_is_view' => $this->_tbl_is_view,
|
||||
'mime_map' => $mime_map,
|
||||
'url_query' => $this->_url_query,
|
||||
'url_params' => $url_params,
|
||||
'titles' => $titles,
|
||||
'tbl_storage_engine' => $this->_tbl_storage_engine,
|
||||
'primary' => $primary_index,
|
||||
'columns_with_unique_index' => $columns_with_unique_index,
|
||||
'edit_view_url' => $edit_view_url,
|
||||
'columns_list' => $columns_list,
|
||||
'table_stats' => isset($tablestats) ? $tablestats : null,
|
||||
'fields' => $fields,
|
||||
|
||||
@ -1317,4 +1317,36 @@ class Core
|
||||
$hmac = hash_hmac('sha256', $sqlQuery, $_SESSION[' HMAC_secret '] . $cfg['blowfish_secret']);
|
||||
return hash_equals($hmac, $signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function populateRequestWithEncryptedQueryParams()
|
||||
{
|
||||
if (
|
||||
(! isset($_GET['eq']) || ! is_string($_GET['eq']))
|
||||
&& (! isset($_POST['eq']) || ! is_string($_POST['eq']))
|
||||
) {
|
||||
unset($_GET['eq'], $_POST['eq'], $_REQUEST['eq']);
|
||||
return;
|
||||
}
|
||||
|
||||
$isFromPost = isset($_POST['eq']);
|
||||
$decryptedQuery = Url::decryptQuery($isFromPost ? $_POST['eq'] : $_GET['eq']);
|
||||
unset($_GET['eq'], $_POST['eq'], $_REQUEST['eq']);
|
||||
if ($decryptedQuery === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$urlQueryParams = (array) json_decode($decryptedQuery);
|
||||
foreach ($urlQueryParams as $urlQueryParamKey => $urlQueryParamValue) {
|
||||
if ($isFromPost) {
|
||||
$_POST[$urlQueryParamKey] = $urlQueryParamValue;
|
||||
} else {
|
||||
$_GET[$urlQueryParamKey] = $urlQueryParamValue;
|
||||
}
|
||||
|
||||
$_REQUEST[$urlQueryParamKey] = $urlQueryParamValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
155
libraries/classes/Crypto/Crypto.php
Normal file
155
libraries/classes/Crypto/Crypto.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace PhpMyAdmin\Crypto;
|
||||
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Random;
|
||||
|
||||
final class Crypto
|
||||
{
|
||||
/** @var bool */
|
||||
private $hasRandomBytesSupport;
|
||||
|
||||
/** @var bool */
|
||||
private $hasSodiumSupport;
|
||||
|
||||
/**
|
||||
* @param bool $forceFallback Force the usage of the fallback functions.
|
||||
*/
|
||||
public function __construct($forceFallback = false)
|
||||
{
|
||||
$this->hasRandomBytesSupport = ! $forceFallback && is_callable('random_bytes');
|
||||
$this->hasSodiumSupport = ! $forceFallback
|
||||
&& $this->hasRandomBytesSupport
|
||||
&& is_callable('sodium_crypto_secretbox')
|
||||
&& is_callable('sodium_crypto_secretbox_open')
|
||||
&& defined('SODIUM_CRYPTO_SECRETBOX_NONCEBYTES')
|
||||
&& defined('SODIUM_CRYPTO_SECRETBOX_KEYBYTES');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plaintext
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encrypt($plaintext)
|
||||
{
|
||||
if ($this->hasSodiumSupport) {
|
||||
return $this->encryptWithSodium($plaintext);
|
||||
}
|
||||
|
||||
return $this->encryptWithPhpseclib($plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ciphertext
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->hasSodiumSupport) {
|
||||
return $this->decryptWithSodium($ciphertext);
|
||||
}
|
||||
|
||||
return $this->decryptWithPhpseclib($ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getEncryptionKey()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$keyLength = $this->hasSodiumSupport ? SODIUM_CRYPTO_SECRETBOX_KEYBYTES : 32;
|
||||
|
||||
$key = $PMA_Config->get('URLQueryEncryptionSecretKey');
|
||||
if (is_string($key) && mb_strlen($key, '8bit') === $keyLength) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
$key = isset($_SESSION['URLQueryEncryptionSecretKey']) ? $_SESSION['URLQueryEncryptionSecretKey'] : null;
|
||||
if (is_string($key) && mb_strlen($key, '8bit') === $keyLength) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
$key = $this->hasRandomBytesSupport ? random_bytes($keyLength) : Random::string($keyLength);
|
||||
$_SESSION['URLQueryEncryptionSecretKey'] = $key;
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plaintext
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encryptWithPhpseclib($plaintext)
|
||||
{
|
||||
$key = $this->getEncryptionKey();
|
||||
$cipher = new AES(AES::MODE_CBC);
|
||||
$iv = $this->hasRandomBytesSupport ? random_bytes(16) : Random::string(16);
|
||||
$cipher->setIV($iv);
|
||||
$cipher->setKey($key);
|
||||
$ciphertext = $cipher->encrypt($plaintext);
|
||||
$hmac = hash_hmac('sha256', $iv . $ciphertext, $key, true);
|
||||
|
||||
return $hmac . $iv . $ciphertext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encrypted
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function decryptWithPhpseclib($encrypted)
|
||||
{
|
||||
$key = $this->getEncryptionKey();
|
||||
$hmac = mb_substr($encrypted, 0, 32, '8bit');
|
||||
$iv = mb_substr($encrypted, 32, 16, '8bit');
|
||||
$ciphertext = mb_substr($encrypted, 48, null, '8bit');
|
||||
$calculatedHmac = hash_hmac('sha256', $iv . $ciphertext, $key, true);
|
||||
if (! hash_equals($hmac, $calculatedHmac)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cipher = new AES(AES::MODE_CBC);
|
||||
$cipher->setIV($iv);
|
||||
$cipher->setKey($key);
|
||||
|
||||
return $cipher->decrypt($ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plaintext
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encryptWithSodium($plaintext)
|
||||
{
|
||||
$key = $this->getEncryptionKey();
|
||||
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
||||
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
|
||||
|
||||
return $nonce . $ciphertext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encrypted
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function decryptWithSodium($encrypted)
|
||||
{
|
||||
$key = $this->getEncryptionKey();
|
||||
$nonce = mb_substr($encrypted, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
||||
$ciphertext = mb_substr($encrypted, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
||||
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
|
||||
if ($decrypted === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $decrypted;
|
||||
}
|
||||
}
|
||||
@ -1563,17 +1563,22 @@ class DatabaseInterface
|
||||
*/
|
||||
public function initRelationParamsCache()
|
||||
{
|
||||
if (strlen($GLOBALS['db'])) {
|
||||
$cfgRelation = $this->relation->getRelationsParam();
|
||||
if (empty($cfgRelation['db'])) {
|
||||
$this->relation->fixPmaTables($GLOBALS['db'], false);
|
||||
}
|
||||
}
|
||||
$cfgRelation = $this->relation->getRelationsParam();
|
||||
if (empty($cfgRelation['db']) && isset($GLOBALS['dblist'])) {
|
||||
if ($GLOBALS['dblist']->databases->exists('phpmyadmin')) {
|
||||
$this->relation->fixPmaTables('phpmyadmin', false);
|
||||
}
|
||||
$storageDbName = $GLOBALS['cfg']['Server']['pmadb'] ?? '';
|
||||
// Use "phpmyadmin" as a default database name to check to keep the behavior consistent
|
||||
$storageDbName = $storageDbName !== null
|
||||
&& is_string($storageDbName)
|
||||
&& $storageDbName !== '' ? $storageDbName : 'phpmyadmin';
|
||||
|
||||
// This will make users not having explicitly listed databases
|
||||
// have config values filled by the default phpMyAdmin storage table name values
|
||||
$this->relation->fixPmaTables($storageDbName, false);
|
||||
|
||||
// This global will be changed if fixPmaTables did find one valid table
|
||||
$storageDbName = $GLOBALS['cfg']['Server']['pmadb'] ?? '';
|
||||
|
||||
// Empty means that until now no pmadb was found eligible
|
||||
if (empty($storageDbName)) {
|
||||
$this->relation->fixPmaTables($GLOBALS['db'], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -149,16 +149,29 @@ class DbiMysqli implements DbiExtension
|
||||
$host = $server['host'];
|
||||
}
|
||||
|
||||
$return_value = mysqli_real_connect(
|
||||
$link,
|
||||
$host,
|
||||
$user,
|
||||
$password,
|
||||
'',
|
||||
$server['port'],
|
||||
$server['socket'],
|
||||
$client_flags
|
||||
);
|
||||
if ($server['hide_connection_errors']) {
|
||||
$return_value = @mysqli_real_connect(
|
||||
$link,
|
||||
$host,
|
||||
$user,
|
||||
$password,
|
||||
'',
|
||||
$server['port'],
|
||||
$server['socket'],
|
||||
$client_flags
|
||||
);
|
||||
} else {
|
||||
$return_value = mysqli_real_connect(
|
||||
$link,
|
||||
$host,
|
||||
$user,
|
||||
$password,
|
||||
'',
|
||||
$server['port'],
|
||||
$server['socket'],
|
||||
$client_flags
|
||||
);
|
||||
}
|
||||
|
||||
if ($return_value === false || is_null($return_value)) {
|
||||
/*
|
||||
@ -180,7 +193,20 @@ class DbiMysqli implements DbiExtension
|
||||
);
|
||||
$server['ssl'] = true;
|
||||
return self::connect($user, $password, $server);
|
||||
} elseif ($error_number === 1045 && $server['hide_connection_errors']) {
|
||||
trigger_error(
|
||||
sprintf(
|
||||
__(
|
||||
'Error 1045: Access denied for user. Additional error information'
|
||||
. ' may be available, but is being hidden by the %s configuration directive.'
|
||||
),
|
||||
'[code][doc@cfg_Servers_hide_connection_errors]'
|
||||
. '$cfg[\'Servers\'][$i][\'hide_connection_errors\'][/doc][/code]'
|
||||
),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1736,9 +1736,8 @@ class Results
|
||||
|
||||
$tmp_image = '<img class="fulltext" src="' . $tmp_image_file . '" alt="'
|
||||
. $tmp_txt . '" title="' . $tmp_txt . '" />';
|
||||
$tmp_url = 'sql.php' . Url::getCommon($url_params_full_text);
|
||||
|
||||
return Util::linkOrButton($tmp_url, $tmp_image);
|
||||
return Util::linkOrButton('sql.php', $url_params_full_text, $tmp_image);
|
||||
|
||||
} // end of the '_getFullOrPartialTextButtonOrLink()' function
|
||||
|
||||
@ -1869,13 +1868,11 @@ class Results
|
||||
'session_max_rows' => $session_max_rows,
|
||||
'is_browse_distinct' => $this->__get('is_browse_distinct'),
|
||||
);
|
||||
$single_order_url = 'sql.php' . Url::getCommon($_single_url_params);
|
||||
$multi_order_url = 'sql.php' . Url::getCommon($_multi_url_params);
|
||||
|
||||
// Displays the sorting URL
|
||||
// enable sort order swapping for image
|
||||
$order_link = $this->_getSortOrderLink(
|
||||
$order_img, $fields_meta, $single_order_url, $multi_order_url
|
||||
$order_img, $fields_meta, $_single_url_params, $_multi_url_params
|
||||
);
|
||||
|
||||
$sorted_header_html .= $this->_getDraggableClassForSortableColumns(
|
||||
@ -2143,10 +2140,10 @@ class Results
|
||||
/**
|
||||
* Get sort order link
|
||||
*
|
||||
* @param string $order_img the sort order image
|
||||
* @param array $fields_meta set of field properties
|
||||
* @param string $order_url the url for sort
|
||||
* @param string $multi_order_url the url for sort
|
||||
* @param string $order_img the sort order image
|
||||
* @param array $fields_meta set of field properties
|
||||
* @param array $order_url_params the url params for sort
|
||||
* @param array $multi_order_url_params the url params for sort
|
||||
*
|
||||
* @return string the sort order link
|
||||
*
|
||||
@ -2155,7 +2152,7 @@ class Results
|
||||
* @see _getTableHeaders()
|
||||
*/
|
||||
private function _getSortOrderLink(
|
||||
$order_img, $fields_meta, $order_url, $multi_order_url
|
||||
$order_img, $fields_meta, $order_url_params, $multi_order_url_params
|
||||
) {
|
||||
$order_link_params = array(
|
||||
'class' => 'sortlink'
|
||||
@ -2163,10 +2160,12 @@ class Results
|
||||
|
||||
$order_link_content = htmlspecialchars($fields_meta->name);
|
||||
$inner_link_content = $order_link_content . $order_img
|
||||
. '<input type="hidden" value="' . $multi_order_url . '" />';
|
||||
. '<input type="hidden" value="sql.php'
|
||||
. Url::getCommon($multi_order_url_params, '?', false)
|
||||
. '" />';
|
||||
|
||||
return Util::linkOrButton(
|
||||
$order_url, $inner_link_content, $order_link_params
|
||||
'sql.php', $order_url_params, $inner_link_content, $order_link_params
|
||||
);
|
||||
|
||||
} // end of the '_getSortOrderLink()' function
|
||||
@ -2608,7 +2607,7 @@ class Results
|
||||
// 1. Prepares the row
|
||||
|
||||
// In print view these variable needs to be initialized
|
||||
$del_url = $del_str = $edit_anchor_class
|
||||
$del_url = $del_str = $edit_anchor_class = $editCopyUrlParams = $delUrlParams
|
||||
= $edit_str = $js_conf = $copy_url = $copy_str = $edit_url = null;
|
||||
|
||||
// 1.2 Defines the URLs for the modify/delete link(s)
|
||||
@ -2643,7 +2642,7 @@ class Results
|
||||
if ($displayParts['edit_lnk'] == self::UPDATE_ROW) {
|
||||
|
||||
list($edit_url, $copy_url, $edit_str, $copy_str,
|
||||
$edit_anchor_class)
|
||||
$edit_anchor_class, $editCopyUrlParams)
|
||||
= $this->_getModifiedLinks(
|
||||
$where_clause,
|
||||
$clause_is_unique, $url_sql_query
|
||||
@ -2652,7 +2651,7 @@ class Results
|
||||
} // end if (1.2.1)
|
||||
|
||||
// 1.2.2 Delete/Kill link(s)
|
||||
list($del_url, $del_str, $js_conf)
|
||||
list($del_url, $del_str, $js_conf, $delUrlParams)
|
||||
= $this->_getDeleteAndKillLinks(
|
||||
$where_clause, $clause_is_unique,
|
||||
$url_sql_query, $displayParts['del_lnk'],
|
||||
@ -2668,7 +2667,7 @@ class Results
|
||||
self::POSITION_LEFT, $del_url, $displayParts, $row_no,
|
||||
$where_clause, $where_clause_html, $condition_array,
|
||||
$edit_url, $copy_url, $edit_anchor_class,
|
||||
$edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
);
|
||||
|
||||
} elseif ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_NONE) {
|
||||
@ -2677,7 +2676,7 @@ class Results
|
||||
self::POSITION_NONE, $del_url, $displayParts, $row_no,
|
||||
$where_clause, $where_clause_html, $condition_array,
|
||||
$edit_url, $copy_url, $edit_anchor_class,
|
||||
$edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
);
|
||||
|
||||
} // end if (1.3)
|
||||
@ -2711,7 +2710,7 @@ class Results
|
||||
self::POSITION_RIGHT, $del_url, $displayParts, $row_no,
|
||||
$where_clause, $where_clause_html, $condition_array,
|
||||
$edit_url, $copy_url, $edit_anchor_class,
|
||||
$edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
);
|
||||
|
||||
}
|
||||
@ -3327,15 +3326,9 @@ class Results
|
||||
'goto' => 'sql.php',
|
||||
);
|
||||
|
||||
$edit_url = 'tbl_change.php'
|
||||
. Url::getCommon(
|
||||
$_url_params + array('default_action' => 'update')
|
||||
);
|
||||
$edit_url = 'tbl_change.php';
|
||||
|
||||
$copy_url = 'tbl_change.php'
|
||||
. Url::getCommon(
|
||||
$_url_params + array('default_action' => 'insert')
|
||||
);
|
||||
$copy_url = 'tbl_change.php';
|
||||
|
||||
$edit_str = $this->_getActionLinkContent(
|
||||
'b_edit', __('Edit')
|
||||
@ -3350,7 +3343,7 @@ class Results
|
||||
$edit_anchor_class .= ' nonunique';
|
||||
}
|
||||
|
||||
return array($edit_url, $copy_url, $edit_str, $copy_str, $edit_anchor_class);
|
||||
return array($edit_url, $copy_url, $edit_str, $copy_str, $edit_anchor_class, $_url_params);
|
||||
|
||||
} // end of the '_getModifiedLinks()' function
|
||||
|
||||
@ -3401,7 +3394,7 @@ class Results
|
||||
'message_to_show' => __('The row has been deleted.'),
|
||||
'goto' => $lnk_goto,
|
||||
);
|
||||
$del_url = 'sql.php' . Url::getCommon($_url_params);
|
||||
$del_url = 'sql.php';
|
||||
|
||||
$js_conf = 'DELETE FROM ' . Sanitize::jsFormat($this->__get('table'))
|
||||
. ' WHERE ' . Sanitize::jsFormat($where_clause, false)
|
||||
@ -3428,16 +3421,16 @@ class Results
|
||||
'goto' => $lnk_goto,
|
||||
);
|
||||
|
||||
$del_url = 'sql.php' . Url::getCommon($_url_params);
|
||||
$del_url = 'sql.php';
|
||||
$js_conf = $kill;
|
||||
$del_str = Util::getIcon(
|
||||
'b_drop', __('Kill')
|
||||
);
|
||||
} else {
|
||||
$del_url = $del_str = $js_conf = null;
|
||||
$del_url = $del_str = $js_conf = $_url_params = null;
|
||||
}
|
||||
|
||||
return array($del_url, $del_str, $js_conf);
|
||||
return array($del_url, $del_str, $js_conf, $_url_params);
|
||||
|
||||
} // end of the '_getDeleteAndKillLinks()' function
|
||||
|
||||
@ -3505,6 +3498,8 @@ class Results
|
||||
* @param string $copy_str the label for copy row
|
||||
* @param string $del_str the label for delete row
|
||||
* @param string $js_conf text for the JS confirmation
|
||||
* @param array $editCopyUrlParams URL parameters
|
||||
* @param array $delUrlParams URL parameters
|
||||
*
|
||||
* @return string html content
|
||||
*
|
||||
@ -3515,7 +3510,7 @@ class Results
|
||||
private function _getPlacedLinks(
|
||||
$dir, $del_url, array $displayParts, $row_no, $where_clause, $where_clause_html,
|
||||
array $condition_array, $edit_url, $copy_url,
|
||||
$edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
) {
|
||||
|
||||
if (! isset($js_conf)) {
|
||||
@ -3526,7 +3521,7 @@ class Results
|
||||
$dir, $del_url, $displayParts,
|
||||
$row_no, $where_clause, $where_clause_html, $condition_array,
|
||||
$edit_url, $copy_url, $edit_anchor_class,
|
||||
$edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
);
|
||||
|
||||
} // end of the '_getPlacedLinks()' function
|
||||
@ -4804,8 +4799,8 @@ class Results
|
||||
/**
|
||||
* Generates HTML to display the Create view in span tag
|
||||
*
|
||||
* @param array $analyzed_sql_results analyzed sql results
|
||||
* @param string $url_query String with URL Parameters
|
||||
* @param array $analyzed_sql_results analyzed sql results
|
||||
* @param array $url_query URL Parameters
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
@ -4813,14 +4808,15 @@ class Results
|
||||
*
|
||||
* @see _getResultsOperations()
|
||||
*/
|
||||
private function _getLinkForCreateView(array $analyzed_sql_results, $url_query)
|
||||
private function _getLinkForCreateView(array $analyzed_sql_results, $urlParams)
|
||||
{
|
||||
$results_operations_html = '';
|
||||
if (empty($analyzed_sql_results['procedure'])) {
|
||||
|
||||
$results_operations_html .= '<span>'
|
||||
. Util::linkOrButton(
|
||||
'view_create.php' . $url_query,
|
||||
'view_create.php',
|
||||
$urlParams,
|
||||
Util::getIcon(
|
||||
'b_view_add', __('Create view'), true
|
||||
),
|
||||
@ -4867,6 +4863,7 @@ class Results
|
||||
{
|
||||
$html = Util::linkOrButton(
|
||||
'#',
|
||||
null,
|
||||
Util::getIcon(
|
||||
'b_insrow', __('Copy to clipboard'), true
|
||||
),
|
||||
@ -4887,6 +4884,7 @@ class Results
|
||||
{
|
||||
$html = Util::linkOrButton(
|
||||
'#',
|
||||
null,
|
||||
Util::getIcon(
|
||||
'b_print', __('Print'), true
|
||||
),
|
||||
@ -4927,7 +4925,6 @@ class Results
|
||||
'printview' => '1',
|
||||
'sql_query' => $this->__get('sql_query'),
|
||||
);
|
||||
$url_query = Url::getCommon($_url_params);
|
||||
|
||||
if (!$header_shown) {
|
||||
$results_operations_html .= $header;
|
||||
@ -4937,7 +4934,7 @@ class Results
|
||||
// show only view and not other options
|
||||
if ($only_view) {
|
||||
$results_operations_html .= $this->_getLinkForCreateView(
|
||||
$analyzed_sql_results, $url_query
|
||||
$analyzed_sql_results, $_url_params
|
||||
);
|
||||
|
||||
if ($header_shown) {
|
||||
@ -4992,7 +4989,8 @@ class Results
|
||||
}
|
||||
|
||||
$results_operations_html .= Util::linkOrButton(
|
||||
'tbl_export.php' . Url::getCommon($_url_params),
|
||||
'tbl_export.php',
|
||||
$_url_params,
|
||||
Util::getIcon(
|
||||
'b_tblexport', __('Export'), true
|
||||
)
|
||||
@ -5001,7 +4999,8 @@ class Results
|
||||
|
||||
// prepare chart
|
||||
$results_operations_html .= Util::linkOrButton(
|
||||
'tbl_chart.php' . Url::getCommon($_url_params),
|
||||
'tbl_chart.php',
|
||||
$_url_params,
|
||||
Util::getIcon(
|
||||
'b_chart', __('Display chart'), true
|
||||
)
|
||||
@ -5021,8 +5020,8 @@ class Results
|
||||
if ($geometry_found) {
|
||||
$results_operations_html
|
||||
.= Util::linkOrButton(
|
||||
'tbl_gis_visualization.php'
|
||||
. Url::getCommon($_url_params),
|
||||
'tbl_gis_visualization.php',
|
||||
$_url_params,
|
||||
Util::getIcon(
|
||||
'b_globe',
|
||||
__('Visualize GIS data'),
|
||||
@ -5047,7 +5046,7 @@ class Results
|
||||
}
|
||||
|
||||
$results_operations_html .= $this->_getLinkForCreateView(
|
||||
$analyzed_sql_results, $url_query
|
||||
$analyzed_sql_results, $_url_params
|
||||
);
|
||||
|
||||
if ($header_shown) {
|
||||
@ -5367,7 +5366,7 @@ class Results
|
||||
$tag_params['class'] = 'ajax';
|
||||
}
|
||||
$result .= Util::linkOrButton(
|
||||
'sql.php' . Url::getCommon($_url_params),
|
||||
'sql.php', $_url_params,
|
||||
$displayedData, $tag_params
|
||||
);
|
||||
}
|
||||
@ -5443,6 +5442,7 @@ class Results
|
||||
* Prepares an Edit link
|
||||
*
|
||||
* @param string $edit_url edit url
|
||||
* @param array $urlParams URL parameters
|
||||
* @param string $class css classes for td element
|
||||
* @param string $edit_str text for the edit link
|
||||
* @param string $where_clause where clause
|
||||
@ -5455,7 +5455,7 @@ class Results
|
||||
* @see _getTableBody(), _getCheckboxAndLinks()
|
||||
*/
|
||||
private function _getEditLink(
|
||||
$edit_url, $class, $edit_str, $where_clause, $where_clause_html
|
||||
$edit_url, $urlParams, $class, $edit_str, $where_clause, $where_clause_html
|
||||
) {
|
||||
|
||||
$ret = '';
|
||||
@ -5463,7 +5463,7 @@ class Results
|
||||
|
||||
$ret .= '<td class="' . $class . ' center print_ignore" '
|
||||
. ' ><span class="nowrap">'
|
||||
. Util::linkOrButton($edit_url, $edit_str);
|
||||
. Util::linkOrButton($edit_url, $urlParams, $edit_str);
|
||||
/*
|
||||
* Where clause for selecting this row uniquely is provided as
|
||||
* a hidden input. Used by jQuery scripts for handling grid editing
|
||||
@ -5484,6 +5484,7 @@ class Results
|
||||
* Prepares an Copy link
|
||||
*
|
||||
* @param string $copy_url copy url
|
||||
* @param array $urlParams URL parameters
|
||||
* @param string $copy_str text for the copy link
|
||||
* @param string $where_clause where clause
|
||||
* @param string $where_clause_html url encoded where clause
|
||||
@ -5496,7 +5497,7 @@ class Results
|
||||
* @see _getTableBody(), _getCheckboxAndLinks()
|
||||
*/
|
||||
private function _getCopyLink(
|
||||
$copy_url, $copy_str, $where_clause, $where_clause_html, $class
|
||||
$copy_url, $urlParams, $copy_str, $where_clause, $where_clause_html, $class
|
||||
) {
|
||||
|
||||
$ret = '';
|
||||
@ -5508,7 +5509,7 @@ class Results
|
||||
}
|
||||
|
||||
$ret .= 'center print_ignore" ' . ' ><span class="nowrap">'
|
||||
. Util::linkOrButton($copy_url, $copy_str);
|
||||
. Util::linkOrButton($copy_url, $urlParams, $copy_str);
|
||||
|
||||
/*
|
||||
* Where clause for selecting this row uniquely is provided as
|
||||
@ -5529,10 +5530,11 @@ class Results
|
||||
/**
|
||||
* Prepares a Delete link
|
||||
*
|
||||
* @param string $del_url delete url
|
||||
* @param string $del_str text for the delete link
|
||||
* @param string $js_conf text for the JS confirmation
|
||||
* @param string $class css classes for the td element
|
||||
* @param string $del_url delete url
|
||||
* @param array $delUrlParams URL parameters
|
||||
* @param string $del_str text for the delete link
|
||||
* @param string $js_conf text for the JS confirmation
|
||||
* @param string $class css classes for the td element
|
||||
*
|
||||
* @return string the generated HTML
|
||||
*
|
||||
@ -5540,7 +5542,7 @@ class Results
|
||||
*
|
||||
* @see _getTableBody(), _getCheckboxAndLinks()
|
||||
*/
|
||||
private function _getDeleteLink($del_url, $del_str, $js_conf, $class)
|
||||
private function _getDeleteLink($del_url, $delUrlParams, $del_str, $js_conf, $class)
|
||||
{
|
||||
|
||||
$ret = '';
|
||||
@ -5556,6 +5558,7 @@ class Results
|
||||
$ret .= 'center print_ignore" ' . ' >'
|
||||
. Util::linkOrButton(
|
||||
$del_url,
|
||||
$delUrlParams,
|
||||
$del_str,
|
||||
array('class' => 'delete_row requireConfirm' . $ajax)
|
||||
)
|
||||
@ -5586,6 +5589,8 @@ class Results
|
||||
* @param string $copy_str text for the copy link
|
||||
* @param string $del_str text for the delete link
|
||||
* @param string $js_conf text for the JS confirmation
|
||||
* @param array $editCopyUrlParams URL parameters
|
||||
* @param array $delUrlParams URL parameters
|
||||
*
|
||||
* @return string the generated HTML
|
||||
*
|
||||
@ -5596,49 +5601,51 @@ class Results
|
||||
private function _getCheckboxAndLinks(
|
||||
$position, $del_url, array $displayParts, $row_no, $where_clause,
|
||||
$where_clause_html, array $condition_array,
|
||||
$edit_url, $copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_url, $copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
) {
|
||||
|
||||
$ret = '';
|
||||
$editUrlParams = $editCopyUrlParams + array('default_action' => 'update');
|
||||
$copyUrlParams = $editCopyUrlParams + array('default_action' => 'insert');
|
||||
|
||||
if ($position == self::POSITION_LEFT) {
|
||||
|
||||
$ret .= $this->_getCheckboxForMultiRowSubmissions(
|
||||
$del_url, $displayParts, $row_no, $where_clause_html,
|
||||
$del_url . Url::getCommon($delUrlParams), $displayParts, $row_no, $where_clause_html,
|
||||
$condition_array, '_left', ''
|
||||
);
|
||||
|
||||
$ret .= $this->_getEditLink(
|
||||
$edit_url, $class, $edit_str, $where_clause, $where_clause_html
|
||||
$edit_url, $editUrlParams, $class, $edit_str, $where_clause, $where_clause_html
|
||||
);
|
||||
|
||||
$ret .= $this->_getCopyLink(
|
||||
$copy_url, $copy_str, $where_clause, $where_clause_html, ''
|
||||
$copy_url, $copyUrlParams, $copy_str, $where_clause, $where_clause_html, ''
|
||||
);
|
||||
|
||||
$ret .= $this->_getDeleteLink($del_url, $del_str, $js_conf, '');
|
||||
$ret .= $this->_getDeleteLink($del_url, $delUrlParams, $del_str, $js_conf, '');
|
||||
|
||||
} elseif ($position == self::POSITION_RIGHT) {
|
||||
|
||||
$ret .= $this->_getDeleteLink($del_url, $del_str, $js_conf, '');
|
||||
$ret .= $this->_getDeleteLink($del_url, $delUrlParams, $del_str, $js_conf, '');
|
||||
|
||||
$ret .= $this->_getCopyLink(
|
||||
$copy_url, $copy_str, $where_clause, $where_clause_html, ''
|
||||
$copy_url, $copyUrlParams, $copy_str, $where_clause, $where_clause_html, ''
|
||||
);
|
||||
|
||||
$ret .= $this->_getEditLink(
|
||||
$edit_url, $class, $edit_str, $where_clause, $where_clause_html
|
||||
$edit_url, $editUrlParams, $class, $edit_str, $where_clause, $where_clause_html
|
||||
);
|
||||
|
||||
$ret .= $this->_getCheckboxForMultiRowSubmissions(
|
||||
$del_url, $displayParts, $row_no, $where_clause_html,
|
||||
$del_url . Url::getCommon($delUrlParams), $displayParts, $row_no, $where_clause_html,
|
||||
$condition_array, '_right', ''
|
||||
);
|
||||
|
||||
} else { // $position == self::POSITION_NONE
|
||||
|
||||
$ret .= $this->_getCheckboxForMultiRowSubmissions(
|
||||
$del_url, $displayParts, $row_no, $where_clause_html,
|
||||
$del_url . Url::getCommon($delUrlParams), $displayParts, $row_no, $where_clause_html,
|
||||
$condition_array, '_left', ''
|
||||
);
|
||||
}
|
||||
|
||||
@ -197,6 +197,7 @@ class ErrorReport
|
||||
unset($queryArray["table"]);
|
||||
unset($queryArray["token"]);
|
||||
unset($queryArray["server"]);
|
||||
unset($queryArray["eq"]);
|
||||
$query = http_build_query($queryArray);
|
||||
} else {
|
||||
$query = '';
|
||||
|
||||
@ -479,14 +479,14 @@ class Export
|
||||
*/
|
||||
$back_button = '<p id="export_back_button">[ <a href="';
|
||||
if ($export_type == 'server') {
|
||||
$back_button .= 'server_export.php" data-post="' . Url::getCommon([], '');
|
||||
$back_button .= 'server_export.php" data-post="' . Url::getCommon([], '', false);
|
||||
} elseif ($export_type == 'database') {
|
||||
$back_button .= 'db_export.php" data-post="' . Url::getCommon(array('db' => $db), '');
|
||||
$back_button .= 'db_export.php" data-post="' . Url::getCommon(array('db' => $db), '', false);
|
||||
} else {
|
||||
$back_button .= 'tbl_export.php" data-post="' . Url::getCommon(
|
||||
array(
|
||||
'db' => $db, 'table' => $table
|
||||
), ''
|
||||
), '', false
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -741,7 +741,7 @@ class Index
|
||||
$r .= '" ' . $row_span . '>'
|
||||
. ' <a class="';
|
||||
$r .= 'ajax';
|
||||
$r .= '" href="tbl_indexes.php" data-post="' . Url::getCommon($this_params, '')
|
||||
$r .= '" href="tbl_indexes.php" data-post="' . Url::getCommon($this_params, '', false)
|
||||
. '">' . Util::getIcon('b_edit', __('Edit')) . '</a>'
|
||||
. '</td>' . "\n";
|
||||
$this_params = $GLOBALS['url_params'];
|
||||
@ -766,7 +766,8 @@ class Index
|
||||
$r .= '<input type="hidden" class="drop_primary_key_index_msg"'
|
||||
. ' value="' . $js_msg . '" />';
|
||||
$r .= Util::linkOrButton(
|
||||
'sql.php' . Url::getCommon($this_params),
|
||||
'sql.php',
|
||||
$this_params,
|
||||
Util::getIcon('b_drop', __('Drop')),
|
||||
array('class' => 'drop_primary_key_index_anchor ajax')
|
||||
);
|
||||
|
||||
@ -280,12 +280,12 @@ class InsertEdit
|
||||
|
||||
if (! $is_show) {
|
||||
return ' : <a href="tbl_change.php" data-post="'
|
||||
. Url::getCommon($this_url_params, '') . '">'
|
||||
. Url::getCommon($this_url_params, '', false) . '">'
|
||||
. $this->showTypeOrFunctionLabel($which)
|
||||
. '</a>';
|
||||
}
|
||||
return '<th><a href="tbl_change.php" data-post="'
|
||||
. Url::getCommon($this_url_params, '')
|
||||
. Url::getCommon($this_url_params, '', false)
|
||||
. '" title="' . __('Hide') . '">'
|
||||
. $this->showTypeOrFunctionLabel($which)
|
||||
. '</a></th>';
|
||||
@ -857,7 +857,7 @@ class InsertEdit
|
||||
'rownumber' => $rownumber,
|
||||
'data' => $data
|
||||
),
|
||||
''
|
||||
'', false
|
||||
) . '">'
|
||||
. str_replace("'", "\'", $titles['Browse']) . '</a>';
|
||||
return $html_output;
|
||||
@ -1704,6 +1704,7 @@ class InsertEdit
|
||||
return '<span class="open_gis_editor">'
|
||||
. Util::linkOrButton(
|
||||
'#',
|
||||
null,
|
||||
$edit_str,
|
||||
array(),
|
||||
'_blank'
|
||||
|
||||
@ -231,7 +231,7 @@ class Navigation
|
||||
$html .= '<tr>';
|
||||
$html .= '<td>' . htmlspecialchars($hiddenItem) . '</td>';
|
||||
$html .= '<td style="width:80px"><a href="navigation.php" data-post="'
|
||||
. Url::getCommon($params, '') . '"'
|
||||
. Url::getCommon($params, '', false) . '"'
|
||||
. ' class="unhideNavItem ajax">'
|
||||
. Util::getIcon('show', __('Show'))
|
||||
. '</a></td>';
|
||||
|
||||
@ -102,13 +102,13 @@ class NavigationTree
|
||||
$this->_pos = $this->_getNavigationDbPos();
|
||||
}
|
||||
// Get the active node
|
||||
if (isset($_REQUEST['aPath'])) {
|
||||
$this->_aPath[0] = $this->_parsePath($_REQUEST['aPath']);
|
||||
$this->_pos2_name[0] = $_REQUEST['pos2_name'];
|
||||
$this->_pos2_value[0] = $_REQUEST['pos2_value'];
|
||||
if (isset($_REQUEST['pos3_name'])) {
|
||||
$this->_pos3_name[0] = $_REQUEST['pos3_name'];
|
||||
$this->_pos3_value[0] = $_REQUEST['pos3_value'];
|
||||
if (isset($_POST['aPath'])) {
|
||||
$this->_aPath[0] = $this->_parsePath($_POST['aPath']);
|
||||
$this->_pos2_name[0] = $_POST['pos2_name'];
|
||||
$this->_pos2_value[0] = $_POST['pos2_value'];
|
||||
if (isset($_POST['pos3_name'])) {
|
||||
$this->_pos3_name[0] = $_POST['pos3_name'];
|
||||
$this->_pos3_value[0] = $_POST['pos3_value'];
|
||||
}
|
||||
} else {
|
||||
if (isset($_POST['n0_aPath'])) {
|
||||
@ -129,8 +129,8 @@ class NavigationTree
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($_REQUEST['vPath'])) {
|
||||
$this->_vPath[0] = $this->_parsePath($_REQUEST['vPath']);
|
||||
if (isset($_POST['vPath'])) {
|
||||
$this->_vPath[0] = $this->_parsePath($_POST['vPath']);
|
||||
} else {
|
||||
if (isset($_POST['n0_vPath'])) {
|
||||
$count = 0;
|
||||
@ -142,11 +142,11 @@ class NavigationTree
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($_REQUEST['searchClause'])) {
|
||||
$this->_searchClause = $_REQUEST['searchClause'];
|
||||
if (isset($_POST['searchClause'])) {
|
||||
$this->_searchClause = $_POST['searchClause'];
|
||||
}
|
||||
if (isset($_REQUEST['searchClause2'])) {
|
||||
$this->_searchClause2 = $_REQUEST['searchClause2'];
|
||||
if (isset($_POST['searchClause2'])) {
|
||||
$this->_searchClause2 = $_POST['searchClause2'];
|
||||
}
|
||||
// Initialise the tree by creating a root node
|
||||
$node = NodeFactory::getInstance('NodeDatabaseContainer', 'root');
|
||||
@ -1156,7 +1156,7 @@ class NavigationTree
|
||||
}
|
||||
|
||||
foreach ($icons as $key => $icon) {
|
||||
$link = vsprintf($iconLinks[$key], $args);
|
||||
$link = $this->encryptQueryParams(vsprintf($iconLinks[$key], $args));
|
||||
if ($linkClass != '') {
|
||||
$retval .= "<a class='$linkClass' href='$link'>";
|
||||
$retval .= "{$icon}</a>";
|
||||
@ -1174,7 +1174,7 @@ class NavigationTree
|
||||
foreach ($node->parents(true) as $parent) {;
|
||||
$args[] = urlencode($parent->real_name);
|
||||
}
|
||||
$link = vsprintf($node->links['text'], $args);
|
||||
$link = $this->encryptQueryParams(vsprintf($node->links['text'], $args));
|
||||
$title = isset($node->links['title']) ? $node->links['title'] : '';
|
||||
if ($node->type == Node::CONTAINER) {
|
||||
$retval .= " <a class='hover_show_full' href='$link'>";
|
||||
@ -1557,4 +1557,23 @@ class NavigationTree
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $link
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encryptQueryParams($link)
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
if (! $PMA_Config->get('URLQueryEncryption')) {
|
||||
return $link;
|
||||
}
|
||||
|
||||
$url = parse_url($link);
|
||||
parse_str(htmlspecialchars_decode($url['query']), $query);
|
||||
|
||||
return $url['path'] . '?' . htmlspecialchars(Url::buildHttpQuery($query));
|
||||
}
|
||||
}
|
||||
|
||||
@ -678,7 +678,7 @@ class NodeDatabase extends Node
|
||||
);
|
||||
$ret = '<span class="dbItemControls">'
|
||||
. '<a href="navigation.php" data-post="'
|
||||
. Url::getCommon($params, '') . '"'
|
||||
. Url::getCommon($params, '', false) . '"'
|
||||
. ' class="showUnhide ajax">'
|
||||
. Util::getImage(
|
||||
'show',
|
||||
|
||||
@ -49,7 +49,7 @@ abstract class NodeDatabaseChild extends Node
|
||||
|
||||
$ret = '<span class="navItemControls">'
|
||||
. '<a href="navigation.php" data-post="'
|
||||
. Url::getCommon($params, '') . '"'
|
||||
. Url::getCommon($params, '', false) . '"'
|
||||
. ' class="hideNavItem ajax">'
|
||||
. Util::getImage('hide', __('Hide'))
|
||||
. '</a></span>';
|
||||
|
||||
@ -1507,7 +1507,8 @@ class Operations
|
||||
{
|
||||
return '<li>'
|
||||
. Util::linkOrButton(
|
||||
'sql.php' . Url::getCommon(array_merge($url_params, $params)),
|
||||
'sql.php',
|
||||
array_merge($url_params, $params),
|
||||
$action_message,
|
||||
['class' => 'maintain_action ajax']
|
||||
)
|
||||
@ -1567,7 +1568,8 @@ class Operations
|
||||
public function getDeleteDataOrTablelink(array $url_params, $syntax, $link, $htmlId)
|
||||
{
|
||||
return '<li>' . Util::linkOrButton(
|
||||
'sql.php' . Url::getCommon($url_params),
|
||||
'sql.php',
|
||||
$url_params,
|
||||
$link,
|
||||
array('id' => $htmlId, 'class' => 'ajax')
|
||||
)
|
||||
|
||||
@ -73,7 +73,7 @@ class ReplicationGui
|
||||
$_url_params['repl_clear_scr'] = true;
|
||||
|
||||
$html .= ' <li><a href="server_replication.php" data-post="';
|
||||
$html .= Url::getCommon($_url_params, '')
|
||||
$html .= Url::getCommon($_url_params, '', false)
|
||||
. '" id="master_addslaveuser_href">';
|
||||
$html .= __('Add slave replication user') . '</a></li>';
|
||||
}
|
||||
@ -188,7 +188,7 @@ class ReplicationGui
|
||||
}
|
||||
|
||||
$_url_params['sr_slave_control_parm'] = 'IO_THREAD';
|
||||
$slave_control_io_link = Url::getCommon($_url_params, '');
|
||||
$slave_control_io_link = Url::getCommon($_url_params, '', false);
|
||||
|
||||
if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
|
||||
$_url_params['sr_slave_action'] = 'start';
|
||||
@ -197,7 +197,7 @@ class ReplicationGui
|
||||
}
|
||||
|
||||
$_url_params['sr_slave_control_parm'] = 'SQL_THREAD';
|
||||
$slave_control_sql_link = Url::getCommon($_url_params, '');
|
||||
$slave_control_sql_link = Url::getCommon($_url_params, '', false);
|
||||
|
||||
if ($server_slave_replication[0]['Slave_IO_Running'] == 'No'
|
||||
|| $server_slave_replication[0]['Slave_SQL_Running'] == 'No'
|
||||
@ -208,15 +208,15 @@ class ReplicationGui
|
||||
}
|
||||
|
||||
$_url_params['sr_slave_control_parm'] = null;
|
||||
$slave_control_full_link = Url::getCommon($_url_params, '');
|
||||
$slave_control_full_link = Url::getCommon($_url_params, '', false);
|
||||
|
||||
$_url_params['sr_slave_action'] = 'reset';
|
||||
$slave_control_reset_link = Url::getCommon($_url_params, '');
|
||||
$slave_control_reset_link = Url::getCommon($_url_params, '', false);
|
||||
|
||||
$_url_params = $GLOBALS['url_params'];
|
||||
$_url_params['sr_take_action'] = true;
|
||||
$_url_params['sr_slave_skip_error'] = true;
|
||||
$slave_skip_error_link = Url::getCommon($_url_params, '');
|
||||
$slave_skip_error_link = Url::getCommon($_url_params, '', false);
|
||||
|
||||
if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
|
||||
$html .= Message::error(
|
||||
@ -233,7 +233,7 @@ class ReplicationGui
|
||||
$_url_params['sl_configure'] = true;
|
||||
$_url_params['repl_clear_scr'] = true;
|
||||
|
||||
$reconfiguremaster_link = Url::getCommon($_url_params, '');
|
||||
$reconfiguremaster_link = Url::getCommon($_url_params, '', false);
|
||||
|
||||
$html .= __(
|
||||
'Server is configured as slave in a replication process. Would you ' .
|
||||
@ -293,7 +293,7 @@ class ReplicationGui
|
||||
'This server is not configured as slave in a replication process. '
|
||||
. 'Would you like to %sconfigure%s it?'
|
||||
),
|
||||
'<a href="server_replication.php" data-post="' . Url::getCommon($_url_params, '') . '">',
|
||||
'<a href="server_replication.php" data-post="' . Url::getCommon($_url_params, '', false) . '">',
|
||||
'</a>'
|
||||
);
|
||||
}
|
||||
@ -355,7 +355,7 @@ class ReplicationGui
|
||||
'This server is not configured as master in a replication process. '
|
||||
. 'Would you like to %sconfigure%s it?'
|
||||
),
|
||||
'<a href="server_replication.php" data-post="' . Url::getCommon($_url_params, '') . '">',
|
||||
'<a href="server_replication.php" data-post="' . Url::getCommon($_url_params, '', false) . '">',
|
||||
'</a>'
|
||||
);
|
||||
$html .= '</fieldset>';
|
||||
|
||||
@ -191,7 +191,7 @@ class RteList
|
||||
*/
|
||||
public static function getRoutineRow(array $routine, $rowclass = '')
|
||||
{
|
||||
global $url_query, $db, $titles;
|
||||
global $url_query, $url_params, $db, $titles;
|
||||
|
||||
$sql_drop = sprintf(
|
||||
'DROP %s IF EXISTS %s',
|
||||
@ -316,7 +316,11 @@ class RteList
|
||||
$retval .= " </td>\n";
|
||||
$retval .= " <td>\n";
|
||||
$retval .= Util::linkOrButton(
|
||||
'sql.php' . $url_query . '&sql_query=' . urlencode($sql_drop) . '&goto=db_routines.php' . urlencode("?db={$db}"),
|
||||
'sql.php',
|
||||
array_merge(
|
||||
$url_params,
|
||||
['sql_query' => $sql_drop, 'goto' => 'db_routines.php' . Url::getCommon(['db' => $db])]
|
||||
),
|
||||
$titles['Drop'],
|
||||
['class' => 'ajax drop_anchor']
|
||||
);
|
||||
@ -343,7 +347,7 @@ class RteList
|
||||
*/
|
||||
public static function getTriggerRow(array $trigger, $rowclass = '')
|
||||
{
|
||||
global $url_query, $db, $table, $titles;
|
||||
global $url_query, $url_params, $db, $table, $titles;
|
||||
|
||||
$retval = " <tr class='$rowclass'>\n";
|
||||
$retval .= " <td>\n";
|
||||
@ -360,8 +364,8 @@ class RteList
|
||||
$retval .= " </td>\n";
|
||||
if (empty($table)) {
|
||||
$retval .= " <td>\n";
|
||||
$retval .= "<a href='db_triggers.php{$url_query}"
|
||||
. "&table=" . urlencode($trigger['table']) . "'>"
|
||||
$retval .= "<a href='db_triggers.php"
|
||||
. Url::getCommon(array_merge($url_params, ['table' => $trigger['table']])) . "'>"
|
||||
. htmlspecialchars($trigger['table']) . "</a>";
|
||||
$retval .= " </td>\n";
|
||||
}
|
||||
@ -390,7 +394,11 @@ class RteList
|
||||
$retval .= " <td>\n";
|
||||
if (Util::currentUserHasPrivilege('TRIGGER', $db)) {
|
||||
$retval .= Util::linkOrButton(
|
||||
'sql.php' . $url_query . '&sql_query=' . urlencode($trigger['drop']) . '&goto=db_triggers.php' . urlencode("?db={$db}"),
|
||||
'sql.php',
|
||||
array_merge(
|
||||
$url_params,
|
||||
['sql_query' => $trigger['drop'], 'goto' => 'db_triggers.php' . Url::getCommon(['db' => $db])]
|
||||
),
|
||||
$titles['Drop'],
|
||||
['class' => 'ajax drop_anchor']
|
||||
);
|
||||
@ -419,7 +427,7 @@ class RteList
|
||||
*/
|
||||
public static function getEventRow(array $event, $rowclass = '')
|
||||
{
|
||||
global $url_query, $db, $titles;
|
||||
global $url_query, $url_params, $db, $titles;
|
||||
|
||||
$sql_drop = sprintf(
|
||||
'DROP EVENT IF EXISTS %s',
|
||||
@ -468,7 +476,11 @@ class RteList
|
||||
$retval .= " <td>\n";
|
||||
if (Util::currentUserHasPrivilege('EVENT', $db)) {
|
||||
$retval .= Util::linkOrButton(
|
||||
'sql.php' . $url_query . '&sql_query=' . urlencode($sql_drop) . '&goto=db_events.php' . urlencode("?db={$db}"),
|
||||
'sql.php',
|
||||
array_merge(
|
||||
$url_params,
|
||||
['sql_query' => $sql_drop, 'goto' => 'db_events.php' . Url::getCommon(['db' => $db])]
|
||||
),
|
||||
$titles['Drop'],
|
||||
['class' => 'ajax drop_anchor']
|
||||
);
|
||||
|
||||
@ -2844,7 +2844,7 @@ class Privileges
|
||||
|
||||
$html .= ' href="server_privileges.php';
|
||||
if ($linktype == 'revoke') {
|
||||
$html .= '" data-post="' . Url::getCommon($params, '');
|
||||
$html .= '" data-post="' . Url::getCommon($params, '', false);
|
||||
} else {
|
||||
$html .= Url::getCommon($params);
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ class Processes
|
||||
}
|
||||
|
||||
$retval .= '<th>';
|
||||
$columnUrl = Url::getCommon($column);
|
||||
$columnUrl = Url::getCommon($column, '', false);
|
||||
$retval .= '<a href="server_status_processes.php" data-post="' . $columnUrl . '" class="sortlink">';
|
||||
|
||||
$retval .= $column['column_name'];
|
||||
@ -179,7 +179,7 @@ class Processes
|
||||
if (isset($_POST['sort_order'])) {
|
||||
$url_params['sort_order'] = $_POST['sort_order'];
|
||||
}
|
||||
$retval .= '<a href="server_status_processes.php" data-post="' . Url::getCommon($url_params, '') . '" >';
|
||||
$retval .= '<a href="server_status_processes.php" data-post="' . Url::getCommon($url_params, '', false) . '" >';
|
||||
if ($show_full_sql) {
|
||||
$retval .= Util::getImage('s_partialtext',
|
||||
__('Truncate Shown Queries'), ['class' => 'icon_fulltext']);
|
||||
@ -275,7 +275,7 @@ class Processes
|
||||
|
||||
$retval = '<tr>';
|
||||
$retval .= '<td><a class="ajax kill_process" href="server_status_processes.php"'
|
||||
. ' data-post="' . Url::getCommon(['kill' => $process['Id']], '') . '">'
|
||||
. ' data-post="' . Url::getCommon(['kill' => $process['Id']], '', false) . '">'
|
||||
. __('Kill') . '</a></td>';
|
||||
$retval .= '<td class="value">' . $process['Id'] . '</td>';
|
||||
$retval .= '<td>' . htmlspecialchars($process['User']) . '</td>';
|
||||
|
||||
@ -115,7 +115,7 @@ class UserGroups
|
||||
array(
|
||||
'viewUsers' => 1, 'userGroup' => $groupName
|
||||
),
|
||||
''
|
||||
'', false
|
||||
)
|
||||
. '">'
|
||||
. Util::getIcon('b_usrlist', __('View users'))
|
||||
@ -126,7 +126,7 @@ class UserGroups
|
||||
array(
|
||||
'editUserGroup' => 1, 'userGroup' => $groupName
|
||||
),
|
||||
''
|
||||
'', false
|
||||
)
|
||||
. '">'
|
||||
. Util::getIcon('b_edit', __('Edit')) . '</a>';
|
||||
@ -137,7 +137,7 @@ class UserGroups
|
||||
array(
|
||||
'deleteUserGroup' => 1, 'userGroup' => $groupName
|
||||
),
|
||||
''
|
||||
'', false
|
||||
)
|
||||
. '">'
|
||||
. Util::getIcon('b_drop', __('Delete')) . '</a>';
|
||||
|
||||
@ -227,7 +227,7 @@ class Sql
|
||||
. htmlspecialchars($_POST['curr_value'])
|
||||
. '</span>'
|
||||
. '<a href="browse_foreigners.php" data-post="'
|
||||
. Url::getCommon($_url_params, '') . '"'
|
||||
. Url::getCommon($_url_params, '', false) . '"'
|
||||
. 'class="ajax browse_foreign" ' . '>'
|
||||
. __('Browse foreign values')
|
||||
. '</a>';
|
||||
|
||||
@ -199,20 +199,20 @@ class Tracking
|
||||
$html .= Url::getCommon($url_params + [
|
||||
'version' => $version['version'],
|
||||
'submit_delete_version' => true,
|
||||
], '');
|
||||
], '', false);
|
||||
$html .= '">' . $delete . '</a></td>';
|
||||
$html .= '<td><a href="tbl_tracking.php" data-post="';
|
||||
$html .= Url::getCommon($url_params + [
|
||||
'report' => 'true',
|
||||
'version' => $version['version'],
|
||||
], '');
|
||||
], '', false);
|
||||
$html .= '">' . $report . '</a>';
|
||||
$html .= ' ';
|
||||
$html .= '<a href="tbl_tracking.php" data-post="';
|
||||
$html .= Url::getCommon($url_params + [
|
||||
'snapshot' => 'true',
|
||||
'version' => $version['version'],
|
||||
], '');
|
||||
], '', false);
|
||||
$html .= '">' . $structure . '</a>';
|
||||
$html .= '</td>';
|
||||
$html .= '</tr>';
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
*/
|
||||
namespace PhpMyAdmin;
|
||||
|
||||
use PhpMyAdmin\Crypto\Crypto;
|
||||
|
||||
/**
|
||||
* Static methods for URL/hidden inputs generating
|
||||
*
|
||||
@ -159,14 +161,15 @@ class Url
|
||||
*
|
||||
* @param mixed $params optional, Contains an associative array with url params
|
||||
* @param string $divider optional character to use instead of '?'
|
||||
* @param bool $encrypt whether to encrypt URL params
|
||||
*
|
||||
* @return string string with URL parameters
|
||||
* @access public
|
||||
*/
|
||||
public static function getCommon($params = array(), $divider = '?')
|
||||
public static function getCommon($params = array(), $divider = '?', $encrypt = true)
|
||||
{
|
||||
return htmlspecialchars(
|
||||
Url::getCommonRaw($params, $divider)
|
||||
Url::getCommonRaw($params, $divider, $encrypt)
|
||||
);
|
||||
}
|
||||
|
||||
@ -195,15 +198,15 @@ class Url
|
||||
*
|
||||
* @param mixed $params optional, Contains an associative array with url params
|
||||
* @param string $divider optional character to use instead of '?'
|
||||
* @param bool $encrypt whether to encrypt URL params
|
||||
*
|
||||
* @return string string with URL parameters
|
||||
* @access public
|
||||
*/
|
||||
public static function getCommonRaw($params = array(), $divider = '?')
|
||||
public static function getCommonRaw($params = array(), $divider = '?', $encrypt = true)
|
||||
{
|
||||
/** @var Config $PMA_Config */
|
||||
global $PMA_Config;
|
||||
$separator = Url::getArgSeparator();
|
||||
|
||||
// avoid overwriting when creating navi panel links to servers
|
||||
if (isset($GLOBALS['server'])
|
||||
@ -218,7 +221,7 @@ class Url
|
||||
$params['lang'] = $GLOBALS['lang'];
|
||||
}
|
||||
|
||||
$query = http_build_query($params, null, $separator);
|
||||
$query = self::buildHttpQuery($params, $encrypt);
|
||||
|
||||
if ($divider != '?' || strlen($query) > 0) {
|
||||
return $divider . $query;
|
||||
@ -227,6 +230,81 @@ class Url
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $params
|
||||
* @param bool $encrypt whether to encrypt URL params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildHttpQuery($params, $encrypt = true)
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$separator = self::getArgSeparator();
|
||||
|
||||
if (! $encrypt || ! $PMA_Config->get('URLQueryEncryption')) {
|
||||
return http_build_query($params, null, $separator);
|
||||
}
|
||||
|
||||
$data = $params;
|
||||
$keys = [
|
||||
'db',
|
||||
'table',
|
||||
'field',
|
||||
'sql_query',
|
||||
'sql_signature',
|
||||
'where_clause',
|
||||
'goto',
|
||||
'back',
|
||||
'message_to_show',
|
||||
'username',
|
||||
'hostname',
|
||||
'dbname',
|
||||
'tablename',
|
||||
'checkprivsdb',
|
||||
'checkprivstable',
|
||||
];
|
||||
$paramsToEncrypt = [];
|
||||
foreach ($params as $paramKey => $paramValue) {
|
||||
if (! in_array($paramKey, $keys)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$paramsToEncrypt[$paramKey] = $paramValue;
|
||||
unset($data[$paramKey]);
|
||||
}
|
||||
|
||||
if ($paramsToEncrypt !== []) {
|
||||
$data['eq'] = self::encryptQuery(json_encode($paramsToEncrypt));
|
||||
}
|
||||
|
||||
return http_build_query($data, null, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function encryptQuery($query)
|
||||
{
|
||||
$crypto = new Crypto();
|
||||
|
||||
return strtr(base64_encode($crypto->encrypt($query)), '+/', '-_');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function decryptQuery($query)
|
||||
{
|
||||
$crypto = new Crypto();
|
||||
|
||||
return $crypto->decrypt(base64_decode(strtr($query, '-_', '+/')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns url separator
|
||||
*
|
||||
|
||||
@ -1039,7 +1039,8 @@ class Util
|
||||
$explain_params['sql_query'] = 'EXPLAIN ' . $sql_query;
|
||||
$explain_link = ' [ '
|
||||
. self::linkOrButton(
|
||||
'import.php' . Url::getCommon($explain_params),
|
||||
'import.php',
|
||||
$explain_params,
|
||||
__('Explain SQL')
|
||||
) . ' ]';
|
||||
} elseif (preg_match(
|
||||
@ -1050,7 +1051,8 @@ class Util
|
||||
= mb_substr($sql_query, 8);
|
||||
$explain_link = ' [ '
|
||||
. self::linkOrButton(
|
||||
'import.php' . Url::getCommon($explain_params),
|
||||
'import.php',
|
||||
$explain_params,
|
||||
__('Skip Explain SQL')
|
||||
) . ']';
|
||||
$url = 'https://mariadb.org/explain_analyzer/analyze/'
|
||||
@ -1059,6 +1061,7 @@ class Util
|
||||
$explain_link .= ' ['
|
||||
. self::linkOrButton(
|
||||
htmlspecialchars('url.php?url=' . urlencode($url)),
|
||||
null,
|
||||
sprintf(__('Analyze Explain at %s'), 'mariadb.org'),
|
||||
array(),
|
||||
'_blank'
|
||||
@ -1074,9 +1077,8 @@ class Util
|
||||
if (! empty($cfg['SQLQuery']['Edit'])
|
||||
&& empty($GLOBALS['show_as_php'])
|
||||
) {
|
||||
$edit_link .= Url::getCommon($url_params);
|
||||
$edit_link = ' [ '
|
||||
. self::linkOrButton($edit_link, __('Edit'))
|
||||
. self::linkOrButton($edit_link, $url_params, __('Edit'))
|
||||
. ' ]';
|
||||
} else {
|
||||
$edit_link = '';
|
||||
@ -1089,14 +1091,16 @@ class Util
|
||||
if (! empty($GLOBALS['show_as_php'])) {
|
||||
$php_link = ' [ '
|
||||
. self::linkOrButton(
|
||||
'import.php' . Url::getCommon($url_params),
|
||||
'import.php',
|
||||
$url_params,
|
||||
__('Without PHP code')
|
||||
)
|
||||
. ' ]';
|
||||
|
||||
$php_link .= ' [ '
|
||||
. self::linkOrButton(
|
||||
'import.php' . Url::getCommon($url_params),
|
||||
'import.php',
|
||||
$url_params,
|
||||
__('Submit query')
|
||||
)
|
||||
. ' ]';
|
||||
@ -1105,7 +1109,8 @@ class Util
|
||||
$php_params['show_as_php'] = 1;
|
||||
$php_link = ' [ '
|
||||
. self::linkOrButton(
|
||||
'import.php' . Url::getCommon($php_params),
|
||||
'import.php',
|
||||
$php_params,
|
||||
__('Create PHP code')
|
||||
)
|
||||
. ' ]';
|
||||
@ -1121,7 +1126,7 @@ class Util
|
||||
) {
|
||||
$refresh_link = 'import.php' . Url::getCommon($url_params);
|
||||
$refresh_link = ' [ '
|
||||
. self::linkOrButton($refresh_link, __('Refresh')) . ']';
|
||||
. self::linkOrButton('import.php', $url_params, __('Refresh')) . ']';
|
||||
} else {
|
||||
$refresh_link = '';
|
||||
} //refresh
|
||||
@ -1163,6 +1168,7 @@ class Util
|
||||
$inline_edit_link = ' ['
|
||||
. self::linkOrButton(
|
||||
'#',
|
||||
null,
|
||||
_pgettext('Inline edit query', 'Edit inline'),
|
||||
array('class' => 'inline_edit_sql')
|
||||
)
|
||||
@ -1707,17 +1713,22 @@ class Util
|
||||
* - URL components are over Suhosin limits
|
||||
* - There is SQL query in the parameters
|
||||
*
|
||||
* @param string $url the URL
|
||||
* @param string $message the link message
|
||||
* @param mixed $tag_params string: js confirmation; array: additional tag
|
||||
* params (f.e. style="")
|
||||
* @param string $target target
|
||||
* @param string $urlPath the URL
|
||||
* @param array|null $urlParams URL parameters
|
||||
* @param string $message the link message
|
||||
* @param mixed $tag_params string: js confirmation; array: additional tag params (f.e. style="")
|
||||
* @param string $target target
|
||||
*
|
||||
* @return string the results to be echoed or saved in an array
|
||||
*/
|
||||
public static function linkOrButton(
|
||||
$url, $message, $tag_params = array(), $target = ''
|
||||
$urlPath, $urlParams, $message, $tag_params = array(), $target = ''
|
||||
) {
|
||||
$url = $urlPath;
|
||||
if (is_array($urlParams)) {
|
||||
$url = $urlPath . Url::getCommon($urlParams, '?', false);
|
||||
}
|
||||
|
||||
$url_length = strlen($url);
|
||||
|
||||
if (! is_array($tag_params)) {
|
||||
@ -1776,7 +1787,11 @@ class Util
|
||||
) {
|
||||
$url .= '?' . explode('&', $parts[1], 2)[0];
|
||||
}
|
||||
|
||||
} else {
|
||||
$url = $urlPath;
|
||||
if (is_array($urlParams)) {
|
||||
$url = $urlPath . Url::getCommon($urlParams);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($tag_params as $par_name => $par_value) {
|
||||
@ -4737,9 +4752,7 @@ class Util
|
||||
$urlParams['tbl_group'] = $_REQUEST['tbl_group'];
|
||||
}
|
||||
|
||||
$url = 'db_structure.php' . Url::getCommon($urlParams);
|
||||
|
||||
return self::linkOrButton($url, $title . $orderImg, $orderLinkParams);
|
||||
return self::linkOrButton('db_structure.php', $urlParams, $title . $orderImg, $orderLinkParams);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -132,6 +132,8 @@ if (! defined('PMA_NO_SESSION')) {
|
||||
Session::setUp($GLOBALS['PMA_Config'], $GLOBALS['error_handler']);
|
||||
}
|
||||
|
||||
Core::populateRequestWithEncryptedQueryParams();
|
||||
|
||||
/**
|
||||
* init some variables LABEL_variables_init
|
||||
*/
|
||||
|
||||
@ -603,6 +603,13 @@ $cfg['Servers'][$i]['tracking_add_drop_table'] = true;
|
||||
*/
|
||||
$cfg['Servers'][$i]['tracking_add_drop_database'] = true;
|
||||
|
||||
/**
|
||||
* Whether to show or hide detailed MySQL/MariaDB connection errors on the login page.
|
||||
*
|
||||
* @global bool $cfg['Servers'][$i]['hide_connection_errors']
|
||||
*/
|
||||
$cfg['Servers'][$i]['hide_connection_errors'] = false;
|
||||
|
||||
/**
|
||||
* Default server (0 = no default server)
|
||||
*
|
||||
@ -817,6 +824,20 @@ $cfg['UseDbSearch'] = true;
|
||||
*/
|
||||
$cfg['IgnoreMultiSubmitErrors'] = false;
|
||||
|
||||
/**
|
||||
* Define whether phpMyAdmin will encrypt sensitive data from the URL query string.
|
||||
*
|
||||
* @global bool $cfg['URLQueryEncryption']
|
||||
*/
|
||||
$cfg['URLQueryEncryption'] = false;
|
||||
|
||||
/**
|
||||
* A secret key used to encrypt/decrypt the URL query string. Should be 32 bytes long.
|
||||
*
|
||||
* @global string $cfg['URLQueryEncryptionSecretKey']
|
||||
*/
|
||||
$cfg['URLQueryEncryptionSecretKey'] = '';
|
||||
|
||||
/**
|
||||
* allow login to any user entered server in cookie based authentication
|
||||
*
|
||||
|
||||
@ -157,7 +157,7 @@ if ($cf->getServerCount() > 0) {
|
||||
, __('Edit') , '</a>';
|
||||
echo ' | ';
|
||||
echo '<a class="delete-server" href="' . Url::getCommon(array('page' => 'servers', 'mode' => 'remove', 'id' => $id));
|
||||
echo '" data-post="' . Url::getCommon(array('token' => $_SESSION[' PMA_token ']), '') . '">';
|
||||
echo '" data-post="' . Url::getCommon(array('token' => $_SESSION[' PMA_token ']), '', false) . '">';
|
||||
echo __('Delete') . '</a>';
|
||||
echo '</small>';
|
||||
echo '</td>';
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
'back': 'db_tracking.php',
|
||||
'table': version.table_name,
|
||||
'delete_tracking': true
|
||||
}, '') }}">
|
||||
}, '', false) }}">
|
||||
{{ Util_getIcon('b_drop', 'Delete tracking'|trans) }}
|
||||
</a>
|
||||
</td>
|
||||
@ -61,7 +61,7 @@
|
||||
'goto': 'tbl_tracking.php',
|
||||
'back': 'db_tracking.php',
|
||||
'table': version.table_name
|
||||
}, '') }}">
|
||||
}, '', false) }}">
|
||||
{{ Util_getIcon('b_versions', 'Versions'|trans) }}
|
||||
</a>
|
||||
<a href="tbl_tracking.php" data-post="
|
||||
@ -72,7 +72,7 @@
|
||||
'table': version.table_name,
|
||||
'report': true,
|
||||
'version': version.version
|
||||
}, '') }}">
|
||||
}, '', false) }}">
|
||||
{{ Util_getIcon('b_report', 'Tracking report'|trans) }}
|
||||
</a>
|
||||
<a href="tbl_tracking.php" data-post="
|
||||
@ -83,7 +83,7 @@
|
||||
'table': version.table_name,
|
||||
'snapshot': true,
|
||||
'version': version.version
|
||||
}, '') }}">
|
||||
}, '', false) }}">
|
||||
{{ Util_getIcon('b_props', 'Structure snapshot'|trans) }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@ -67,7 +67,7 @@
|
||||
{{ Message_notice('Note: Enabling the database statistics here might cause heavy traffic between the web server and the MySQL server.'|trans) }}
|
||||
<ul>
|
||||
<li class="li_switch_dbstats">
|
||||
<a href="server_databases.php" data-post="{{ Url_getCommon({'dbstats': '1'}, '') }}" title="{% trans 'Enable statistics' %}">
|
||||
<a href="server_databases.php" data-post="{{ Url_getCommon({'dbstats': '1'}, '', false) }}" title="{% trans 'Enable statistics' %}">
|
||||
<strong>{% trans 'Enable statistics' %}</strong>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@ -26,9 +26,8 @@
|
||||
{% if one_key['constraint'] is defined %}
|
||||
<input type="hidden" class="drop_foreign_key_msg" value="
|
||||
{{- js_msg }}" />
|
||||
{% set drop_url = 'sql.php' ~ Url_getCommon(this_params) %}
|
||||
{% set drop_str = Util_getIcon('b_drop', 'Drop'|trans) %}
|
||||
{{ Util_linkOrButton(drop_url, drop_str, {'class': 'drop_foreign_key_anchor ajax'}) }}
|
||||
{{ Util_linkOrButton('sql.php', this_params, drop_str, {'class': 'drop_foreign_key_anchor ajax'}) }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
value="{{ criteria_values[column_index] }}"
|
||||
{% endif %} />
|
||||
<a class="ajax browse_foreign" href="browse_foreigners.php" data-post="
|
||||
{{- Url_getCommon({'db': db, 'table': table}, '') -}}
|
||||
{{- Url_getCommon({'db': db, 'table': table}, '', false) -}}
|
||||
&field={{ column_name|url_encode }}&fieldkey=
|
||||
{{- column_index }}&fromsearch=1">
|
||||
{{ titles['Browse']|replace({"'": "\\'"})|raw }}
|
||||
@ -34,10 +34,9 @@
|
||||
class="textfield"
|
||||
id="field_{{ column_index }}" />
|
||||
{% if in_fbs %}
|
||||
{% set edit_url = 'gis_data_editor.php' ~ Url_getCommon() %}
|
||||
{% set edit_str = Util_getIcon('b_edit', 'Edit/Insert'|trans) %}
|
||||
<span class="open_search_gis_editor">
|
||||
{{ Util_linkOrButton(edit_url, edit_str, [], '_blank') }}
|
||||
{{ Util_linkOrButton('gis_data_editor.php', [], edit_str, [], '_blank') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% elseif column_type starts with 'enum'
|
||||
|
||||
@ -134,7 +134,7 @@
|
||||
{% if partitions is empty %}
|
||||
<input type="submit" name="edit_partitioning" value="{% trans 'Partition table' %}" />
|
||||
{% else %}
|
||||
{{ Util_linkOrButton(remove_url, 'Remove partitioning'|trans, {
|
||||
{{ Util_linkOrButton('sql.php', remove_url_params, 'Remove partitioning'|trans, {
|
||||
'class': 'button ajax',
|
||||
'id': 'remove_partitioning'
|
||||
}) }}
|
||||
|
||||
@ -133,9 +133,9 @@
|
||||
{# Work on the table #}
|
||||
<div id="structure-action-links">
|
||||
{% if tbl_is_view and not db_is_system_schema %}
|
||||
{% set edit_view_url = 'view_create.php' ~ edit_view_url %}
|
||||
{{ Util_linkOrButton(
|
||||
edit_view_url,
|
||||
'view_create.php',
|
||||
{'db': db, 'table': table},
|
||||
Util_getIcon('b_edit', 'Edit view'|trans, true)
|
||||
) }}
|
||||
{% endif %}
|
||||
@ -194,7 +194,6 @@
|
||||
{{ Util_getDivForSliderEffect('partitions', 'Partitions'|trans) }}
|
||||
|
||||
{% set remove_sql = 'ALTER TABLE ' ~ Util_backquote(table) ~ ' REMOVE PARTITIONING' %}
|
||||
{% set remove_url = 'sql.php' ~ url_query ~ '&sql_query=' ~ remove_sql|url_encode %}
|
||||
|
||||
{% include 'table/structure/display_partitions.twig' with {
|
||||
'db': db,
|
||||
@ -209,7 +208,7 @@
|
||||
'sub_partition_expression': has_sub_partitions ? first_sub_partition.getExpression(),
|
||||
'action_icons': action_icons,
|
||||
'range_or_list': range_or_list,
|
||||
'remove_url': remove_url
|
||||
'remove_url_params': url_params|merge({'sql_query': remove_sql})
|
||||
} only %}
|
||||
{% else %}
|
||||
{% include 'table/structure/display_partitions.twig' with {
|
||||
|
||||
@ -26,6 +26,7 @@ class PageSettingsTest extends PmaTestCase
|
||||
public function setUp()
|
||||
{
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
$GLOBALS['server'] = 1;
|
||||
$GLOBALS['db'] = 'db';
|
||||
$GLOBALS['table'] = '';
|
||||
|
||||
@ -34,6 +34,7 @@ class ServerDatabasesControllerTest extends PmaTestCase
|
||||
|
||||
//$GLOBALS
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
|
||||
$GLOBALS['db'] = 'db';
|
||||
|
||||
@ -11,6 +11,7 @@ use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Core;
|
||||
use PhpMyAdmin\Sanitize;
|
||||
use PhpMyAdmin\Tests\PmaTestCase;
|
||||
use PhpMyAdmin\Url;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
@ -50,6 +51,7 @@ class CoreTest extends PmaTestCase
|
||||
$GLOBALS['db'] = '';
|
||||
$GLOBALS['table'] = '';
|
||||
$GLOBALS['PMA_PHP_SELF'] = 'http://example.net/';
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1226,4 +1228,61 @@ class CoreTest extends PmaTestCase
|
||||
// Must work now, (good secret and blowfish_secret)
|
||||
$this->assertTrue(Core::checkSqlQuerySignature($sqlQuery, $hmac));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testPopulateRequestWithEncryptedQueryParams()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryption', true);
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$_GET = ['pos' => '0', 'eq' => Url::encryptQuery('{"db":"test_db","table":"test_table"}')];
|
||||
$_REQUEST = $_GET;
|
||||
|
||||
Core::populateRequestWithEncryptedQueryParams();
|
||||
|
||||
$expected = ['pos' => '0', 'db' => 'test_db', 'table' => 'test_table'];
|
||||
|
||||
$this->assertEquals($expected, $_GET);
|
||||
$this->assertEquals($expected, $_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*
|
||||
* @dataProvider providerForTestPopulateRequestWithEncryptedQueryParamsWithInvalidParam
|
||||
*/
|
||||
public function testPopulateRequestWithEncryptedQueryParamsWithInvalidParam($encrypted, $decrypted)
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryption', true);
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$_GET = $encrypted;
|
||||
$_REQUEST = $encrypted;
|
||||
|
||||
Core::populateRequestWithEncryptedQueryParams();
|
||||
|
||||
$this->assertEquals($decrypted, $_GET);
|
||||
$this->assertEquals($decrypted, $_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][][]
|
||||
*/
|
||||
public function providerForTestPopulateRequestWithEncryptedQueryParamsWithInvalidParam()
|
||||
{
|
||||
return [
|
||||
[[], []],
|
||||
[['eq' => []], []],
|
||||
[['eq' => ''], []],
|
||||
[['eq' => 'invalid'], []],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
114
test/classes/Crypto/CryptoTest.php
Normal file
114
test/classes/Crypto/CryptoTest.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace PhpMyAdmin\Tests\Crypto;
|
||||
|
||||
use PhpMyAdmin\Crypto\Crypto;
|
||||
use PhpMyAdmin\Tests\PmaTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Crypto\Crypto
|
||||
*/
|
||||
class CryptoTest extends PmaTestCase
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testWithValidKeyFromConfig()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$cryptoWithSodium = new Crypto();
|
||||
$encrypted = $cryptoWithSodium->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithSodium->decrypt($encrypted));
|
||||
$this->assertArrayNotHasKey('URLQueryEncryptionSecretKey', $_SESSION);
|
||||
|
||||
$cryptoWithPhpseclib = new Crypto(true);
|
||||
$encrypted = $cryptoWithPhpseclib->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithPhpseclib->decrypt($encrypted));
|
||||
$this->assertArrayNotHasKey('URLQueryEncryptionSecretKey', $_SESSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testWithValidKeyFromSession()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = ['URLQueryEncryptionSecretKey' => str_repeat('a', 32)];
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', '');
|
||||
|
||||
$cryptoWithSodium = new Crypto();
|
||||
$encrypted = $cryptoWithSodium->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithSodium->decrypt($encrypted));
|
||||
$this->assertArrayHasKey('URLQueryEncryptionSecretKey', $_SESSION);
|
||||
|
||||
$cryptoWithPhpseclib = new Crypto(true);
|
||||
$encrypted = $cryptoWithPhpseclib->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithPhpseclib->decrypt($encrypted));
|
||||
$this->assertArrayHasKey('URLQueryEncryptionSecretKey', $_SESSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testWithNewSessionKey()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', '');
|
||||
|
||||
$cryptoWithSodium = new Crypto();
|
||||
$encrypted = $cryptoWithSodium->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithSodium->decrypt($encrypted));
|
||||
$this->assertArrayHasKey('URLQueryEncryptionSecretKey', $_SESSION);
|
||||
$this->assertEquals(32, mb_strlen($_SESSION['URLQueryEncryptionSecretKey'], '8bit'));
|
||||
|
||||
$cryptoWithPhpseclib = new Crypto(true);
|
||||
$encrypted = $cryptoWithPhpseclib->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithPhpseclib->decrypt($encrypted));
|
||||
$this->assertArrayHasKey('URLQueryEncryptionSecretKey', $_SESSION);
|
||||
$this->assertEquals(32, mb_strlen($_SESSION['URLQueryEncryptionSecretKey'], '8bit'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testDecryptWithInvalidKey()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$cryptoWithSodium = new Crypto();
|
||||
$encrypted = $cryptoWithSodium->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithSodium->decrypt($encrypted));
|
||||
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('b', 32));
|
||||
|
||||
$cryptoWithSodium = new Crypto();
|
||||
$this->assertNull($cryptoWithSodium->decrypt($encrypted));
|
||||
|
||||
$cryptoWithPhpseclib = new Crypto(true);
|
||||
$encrypted = $cryptoWithPhpseclib->encrypt('test');
|
||||
$this->assertNotSame('test', $encrypted);
|
||||
$this->assertSame('test', $cryptoWithPhpseclib->decrypt($encrypted));
|
||||
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$cryptoWithPhpseclib = new Crypto(true);
|
||||
$this->assertNull($cryptoWithPhpseclib->decrypt($encrypted));
|
||||
}
|
||||
}
|
||||
@ -44,6 +44,7 @@ class ResultsTest extends PmaTestCase
|
||||
$GLOBALS['PMA_PHP_SELF'] = 'index.php';
|
||||
$this->object = new DisplayResults('as', '', '', '');
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
$GLOBALS['text_dir'] = 'ltr';
|
||||
$_SESSION[' HMAC_secret '] = 'test';
|
||||
@ -430,10 +431,16 @@ class ResultsTest extends PmaTestCase
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'tbl_change.php?db=Data&table=customer&where_clause=%60'
|
||||
. 'customer%60.%60id%60+%3D+1&clause_is_unique=1&sql_query='
|
||||
. 'SELECT+%2A+FROM+%60customer%60&goto=sql.php&default_'
|
||||
. 'action=update',
|
||||
'tbl_change.php',
|
||||
[
|
||||
'db' => 'Data',
|
||||
'table' => 'customer',
|
||||
'where_clause' => '`customer`.`id` = 1',
|
||||
'clause_is_unique' => true,
|
||||
'sql_query' => 'SELECT * FROM `customer`',
|
||||
'goto' => 'sql.php',
|
||||
'default_action' => 'update',
|
||||
],
|
||||
'klass edit_row_anchor',
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Edit" alt='
|
||||
. '"Edit" class="icon ic_b_edit" /> Edit</span>',
|
||||
@ -444,7 +451,7 @@ class ResultsTest extends PmaTestCase
|
||||
. '<a href="tbl_change.php" data-post="db=Data&table=customer&where_'
|
||||
. 'clause=%60customer%60.%60id%60+%3D+1&clause_is_unique=1&'
|
||||
. 'sql_query=SELECT+%2A+FROM+%60customer%60&goto=sql.php&'
|
||||
. 'default_action=update"'
|
||||
. 'default_action=update&server=0&lang=en"'
|
||||
. '><span class="nowrap"><img src="themes/dot.gif" title="Edit" '
|
||||
. 'alt="Edit" class="icon ic_b_edit" /> Edit</span></a>'
|
||||
. '<input type="hidden" class="where_clause" value ="%60customer'
|
||||
@ -468,7 +475,7 @@ class ResultsTest extends PmaTestCase
|
||||
* @dataProvider dataProviderForGetEditLink
|
||||
*/
|
||||
public function testGetEditLink(
|
||||
$edit_url, $class, $edit_str, $where_clause, $where_clause_html, $output
|
||||
$edit_url, $urlParams, $class, $edit_str, $where_clause, $where_clause_html, $output
|
||||
) {
|
||||
$GLOBALS['cfg']['ActionLinksMode'] = 'both';
|
||||
$GLOBALS['cfg']['LinkLengthLimit'] = 1000;
|
||||
@ -478,7 +485,7 @@ class ResultsTest extends PmaTestCase
|
||||
$this->_callPrivateFunction(
|
||||
'_getEditLink',
|
||||
array(
|
||||
$edit_url, $class, $edit_str, $where_clause, $where_clause_html
|
||||
$edit_url, $urlParams, $class, $edit_str, $where_clause, $where_clause_html
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -493,10 +500,16 @@ class ResultsTest extends PmaTestCase
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'tbl_change.php?db=Data&table=customer&where_clause=%60cust'
|
||||
. 'omer%60.%60id%60+%3D+1&clause_is_unique=1&sql_query='
|
||||
. 'SELECT+%2A+FROM+%60customer%60&goto=sql.php&default_'
|
||||
. 'action=insert',
|
||||
'tbl_change.php',
|
||||
[
|
||||
'db' => 'Data',
|
||||
'table' => 'customer',
|
||||
'where_clause' => '`customer`.`id` = 1',
|
||||
'clause_is_unique' => true,
|
||||
'sql_query' => 'SELECT * FROM `customer`',
|
||||
'goto' => 'sql.php',
|
||||
'default_action' => 'insert',
|
||||
],
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Copy" alt'
|
||||
. '="Copy" class="icon ic_b_insrow" /> Copy</span>',
|
||||
'`customer`.`id` = 1',
|
||||
@ -507,7 +520,7 @@ class ResultsTest extends PmaTestCase
|
||||
. '<a href="tbl_change.php" data-post="db=Data&table=customer&where_'
|
||||
. 'clause=%60customer%60.%60id%60+%3D+1&clause_is_unique=1&'
|
||||
. 'sql_query=SELECT+%2A+FROM+%60customer%60&goto=sql.php&'
|
||||
. 'default_action=insert"'
|
||||
. 'default_action=insert&server=0&lang=en"'
|
||||
. '><span class="nowrap"><img src="themes/dot.gif" title="Copy" '
|
||||
. 'alt="Copy" class="icon ic_b_insrow" /> Copy</span></a>'
|
||||
. '<input type="hidden" class="where_clause" value="%60customer%60'
|
||||
@ -531,7 +544,7 @@ class ResultsTest extends PmaTestCase
|
||||
* @dataProvider dataProviderForGetCopyLink
|
||||
*/
|
||||
public function testGetCopyLink(
|
||||
$copy_url, $copy_str, $where_clause, $where_clause_html, $class, $output
|
||||
$copy_url, $urlParams, $copy_str, $where_clause, $where_clause_html, $class, $output
|
||||
) {
|
||||
$GLOBALS['cfg']['ActionLinksMode'] = 'both';
|
||||
$GLOBALS['cfg']['LinkLengthLimit'] = 1000;
|
||||
@ -541,7 +554,7 @@ class ResultsTest extends PmaTestCase
|
||||
$this->_callPrivateFunction(
|
||||
'_getCopyLink',
|
||||
array(
|
||||
$copy_url, $copy_str, $where_clause, $where_clause_html, $class
|
||||
$copy_url, $urlParams, $copy_str, $where_clause, $where_clause_html, $class
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -556,12 +569,14 @@ class ResultsTest extends PmaTestCase
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'sql.php?db=Data&table=customer&sql_query=DELETE+FROM+%60'
|
||||
. 'Data%60.%60customer%60+WHERE+%60customer%60.%60id%60+%3D+1&'
|
||||
. 'message_to_show=The+row+has+been+deleted&goto=sql.php%3Fdb'
|
||||
. '%3DData%26table%3Dcustomer%26sql_query%3DSELECT%2B%252A%2BFROM'
|
||||
. '%2B%2560customer%2560%26message_to_show%3DThe%2Brow%2Bhas%2Bbeen'
|
||||
. '%2Bdeleted%26goto%3Dtbl_structure.php',
|
||||
'sql.php',
|
||||
[
|
||||
'db' => 'Data',
|
||||
'table' => 'customer',
|
||||
'sql_query' => 'DELETE FROM `Data`.`customer` WHERE `customer`.`id` = 1',
|
||||
'message_to_show' => 'The row has been deleted.',
|
||||
'goto' => 'tbl_sql.php',
|
||||
],
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
|
||||
. 'alt="Delete" class="icon ic_b_drop" /> Delete</span>',
|
||||
'DELETE FROM `Data`.`customer` WHERE `customer`.`id` = 1',
|
||||
@ -569,10 +584,8 @@ class ResultsTest extends PmaTestCase
|
||||
'<td class="klass center print_ignore" >'
|
||||
. '<a href="sql.php" data-post="db=Data&table=customer&sql_query=DELETE'
|
||||
. '+FROM+%60Data%60.%60customer%60+WHERE+%60customer%60.%60id%60+%3D'
|
||||
. '+1&message_to_show=The+row+has+been+deleted&goto=sql.php'
|
||||
. '%3Fdb%3DData%26table%3Dcustomer%26sql_query%3DSELECT%2B%252A%2B'
|
||||
. 'FROM%2B%2560customer%2560%26message_to_show%3DThe%2Brow%2Bhas%2B'
|
||||
. 'been%2Bdeleted%26goto%3Dtbl_structure.php" '
|
||||
. '+1&message_to_show=The+row+has+been+deleted.'
|
||||
. '&goto=tbl_sql.php&server=0&lang=en" '
|
||||
. 'class="delete_row requireConfirm"><span class="nowrap"><img src="themes/dot.'
|
||||
. 'gif" title="Delete" alt="Delete" class="icon ic_b_drop" /> '
|
||||
. 'Delete</span></a>'
|
||||
@ -596,7 +609,7 @@ class ResultsTest extends PmaTestCase
|
||||
* @dataProvider dataProviderForGetDeleteLink
|
||||
*/
|
||||
public function testGetDeleteLink(
|
||||
$del_url, $del_str, $js_conf, $class, $output
|
||||
$del_url, $delUrlParams, $del_str, $js_conf, $class, $output
|
||||
) {
|
||||
$GLOBALS['cfg']['ActionLinksMode'] = 'both';
|
||||
$GLOBALS['cfg']['LinkLengthLimit'] = 1000;
|
||||
@ -606,7 +619,7 @@ class ResultsTest extends PmaTestCase
|
||||
$this->_callPrivateFunction(
|
||||
'_getDeleteLink',
|
||||
array(
|
||||
$del_url, $del_str, $js_conf, $class
|
||||
$del_url, $delUrlParams, $del_str, $js_conf, $class
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -622,12 +635,7 @@ class ResultsTest extends PmaTestCase
|
||||
return array(
|
||||
array(
|
||||
DisplayResults::POSITION_LEFT,
|
||||
'sql.php?db=data&table=new&sql_query=DELETE+FROM+%60data'
|
||||
. '%60.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&message_to_show='
|
||||
. 'The+row+has+been+deleted&goto=sql.php%3Fdb%3Ddata%26table%3D'
|
||||
. 'new%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26'
|
||||
. 'message_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3D'
|
||||
. 'tbl_structure.php',
|
||||
'sql.php',
|
||||
array(
|
||||
'edit_lnk' => 'ur',
|
||||
'del_lnk' => 'dr',
|
||||
@ -643,12 +651,8 @@ class ResultsTest extends PmaTestCase
|
||||
array(
|
||||
'`new`.`id`' => '= 1',
|
||||
),
|
||||
'tbl_change.php?db=data&table=new&where_clause=%60new%60.'
|
||||
. '%60id%60+%3D+1&clause_is_unique=1&sql_query=SELECT+%2A+'
|
||||
. 'FROM+%60new%60&goto=sql.php&default_action=update',
|
||||
'tbl_change.php?db=data&table=new&where_clause=%60new%60.'
|
||||
. '%60id%60+%3D+1&clause_is_unique=1&sql_query=SELECT+%2A+'
|
||||
. 'FROM+%60new%60&goto=sql.php&default_action=insert',
|
||||
'tbl_change.php',
|
||||
'tbl_change.php',
|
||||
'edit_row_anchor',
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
|
||||
. 'alt="Edit" class="icon ic_b_edit" /> Edit</span>',
|
||||
@ -657,6 +661,21 @@ class ResultsTest extends PmaTestCase
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
|
||||
. 'alt="Delete" class="icon ic_b_drop" /> Delete</span>',
|
||||
'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
|
||||
[
|
||||
'db' => 'data',
|
||||
'table' => 'new',
|
||||
'where_clause' => '`new`.`id` = 1',
|
||||
'clause_is_unique' => true,
|
||||
'sql_query' => 'SELECT * FROM `new`',
|
||||
'goto' => 'sql.php',
|
||||
],
|
||||
[
|
||||
'db' => 'data',
|
||||
'table' => 'new',
|
||||
'sql_query' => 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
|
||||
'message_to_show' => 'The row has been deleted.',
|
||||
'goto' => 'tbl_sql.php',
|
||||
],
|
||||
'<td class="center print_ignore"><input type="checkbox" id="id_rows_to_delete0_'
|
||||
. 'left" name="rows_to_delete[0]" class="multi_checkbox checkall" '
|
||||
. 'value="%60new%60.%60id%60+%3D+1" /><input type="hidden" class='
|
||||
@ -666,7 +685,7 @@ class ResultsTest extends PmaTestCase
|
||||
. '<a href="tbl_change.php" data-post="db=data&table=new&where_'
|
||||
. 'clause=%60new%60.%60id%60+%3D+1&clause_is_unique=1&'
|
||||
. 'sql_query=SELECT+%2A+FROM+%60new%60&goto=sql.php&default'
|
||||
. '_action=update">'
|
||||
. '_action=update&server=0&lang=en">'
|
||||
. '<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
|
||||
. 'alt="Edit" class="icon ic_b_edit" /> Edit</span></a>'
|
||||
. '<input type="hidden" class="where_clause" value ="%60new%60.%60'
|
||||
@ -675,17 +694,15 @@ class ResultsTest extends PmaTestCase
|
||||
. '<a href="tbl_change.php" data-post="db=data&table=new&where_clause'
|
||||
. '=%60new%60.%60id%60+%3D+1&clause_is_unique=1&sql_query='
|
||||
. 'SELECT+%2A+FROM+%60new%60&goto=sql.php&default_action='
|
||||
. 'insert"><span class'
|
||||
. 'insert&server=0&lang=en"><span class'
|
||||
. '="nowrap"><img src="themes/dot.gif" title="Copy" alt="Copy" '
|
||||
. 'class="icon ic_b_insrow" /> Copy</span></a>'
|
||||
. '<input type="hidden" class="where_clause" value="%60new%60.%60id'
|
||||
. '%60+%3D+1" /></span></td><td class="center print_ignore" >'
|
||||
. '<a href="sql.php" data-post="db=data&table=new&sql_query=DELETE+'
|
||||
. 'FROM+%60data%60.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&'
|
||||
. 'message_to_show=The+row+has+been+deleted&goto=sql.php%3F'
|
||||
. 'db%3Ddata%26table%3Dnew%26sql_query%3DSELECT%2B%252A%2BFROM%2B'
|
||||
. '%2560new%2560%26message_to_show%3DThe%2Brow%2Bhas%2Bbeen%2B'
|
||||
. 'deleted%26goto%3Dtbl_structure.php" '
|
||||
. 'message_to_show=The+row+has+been+deleted.'
|
||||
. '&goto=tbl_sql.php&server=0&lang=en" '
|
||||
. 'class="delete_row requireConfirm"><span class="nowrap"><img src="themes/dot.'
|
||||
. 'gif" title="Delete" alt="Delete" class="icon ic_b_drop" /> '
|
||||
. 'Delete</span></a>'
|
||||
@ -694,12 +711,7 @@ class ResultsTest extends PmaTestCase
|
||||
),
|
||||
array(
|
||||
DisplayResults::POSITION_RIGHT,
|
||||
'sql.php?db=data&table=new&sql_query=DELETE+FROM+%60data%60'
|
||||
. '.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&message_to_show='
|
||||
. 'The+row+has+been+deleted&goto=sql.php%3Fdb%3Ddata%26table%3D'
|
||||
. 'new%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26message'
|
||||
. '_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3Dtbl_'
|
||||
. 'structure.php',
|
||||
'sql.php',
|
||||
array(
|
||||
'edit_lnk' => 'ur',
|
||||
'del_lnk' => 'dr',
|
||||
@ -715,12 +727,8 @@ class ResultsTest extends PmaTestCase
|
||||
array(
|
||||
'`new`.`id`' => '= 1',
|
||||
),
|
||||
'tbl_change.php?db=data&table=new&where_clause=%60new%60.'
|
||||
. '%60id%60+%3D+1&clause_is_unique=1&sql_query=SELECT+%2A+'
|
||||
. 'FROM+%60new%60&goto=sql.php&default_action=update',
|
||||
'tbl_change.php?db=data&table=new&where_clause=%60new%60.'
|
||||
. '%60id%60+%3D+1&clause_is_unique=1&sql_query=SELECT+%2A+'
|
||||
. 'FROM+%60new%60&goto=sql.php&default_action=insert',
|
||||
'tbl_change.php',
|
||||
'tbl_change.php',
|
||||
'edit_row_anchor',
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
|
||||
. 'alt="Edit" class="icon ic_b_edit" /> Edit</span>',
|
||||
@ -729,13 +737,26 @@ class ResultsTest extends PmaTestCase
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
|
||||
. 'alt="Delete" class="icon ic_b_drop" /> Delete</span>',
|
||||
'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
|
||||
[
|
||||
'db' => 'data',
|
||||
'table' => 'new',
|
||||
'where_clause' => '`new`.`id` = 1',
|
||||
'clause_is_unique' => true,
|
||||
'sql_query' => 'SELECT * FROM `new`',
|
||||
'goto' => 'sql.php',
|
||||
],
|
||||
[
|
||||
'db' => 'data',
|
||||
'table' => 'new',
|
||||
'sql_query' => 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
|
||||
'message_to_show' => 'The row has been deleted.',
|
||||
'goto' => 'tbl_sql.php',
|
||||
],
|
||||
'<td class="center print_ignore" >'
|
||||
. '<a href="sql.php" data-post="db=data&table=new&sql_query=DELETE+'
|
||||
. 'FROM+%60data%60.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&'
|
||||
. 'message_to_show=The+row+has+been+deleted&goto=sql.php%3Fdb'
|
||||
. '%3Ddata%26table%3Dnew%26sql_query%3DSELECT%2B%252A%2BFROM%2B%25'
|
||||
. '60new%2560%26message_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted'
|
||||
. '%26goto%3Dtbl_structure.php" class="delete'
|
||||
. 'message_to_show=The+row+has+been+deleted.&goto=tbl_sql.php'
|
||||
. '&server=0&lang=en" class="delete'
|
||||
. '_row requireConfirm"><span class="nowrap"><img src="themes/dot.gif" title='
|
||||
. '"Delete" alt="Delete" class="icon ic_b_drop" /> Delete</span></a>'
|
||||
. '<div class="hide">DELETE FROM `data`.`new` WHERE `new`.'
|
||||
@ -743,7 +764,7 @@ class ResultsTest extends PmaTestCase
|
||||
. '<a href="tbl_change.php" data-post="db=data&table=new&where_'
|
||||
. 'clause=%60new%60.%60id%60+%3D+1&clause_is_unique=1&sql_'
|
||||
. 'query=SELECT+%2A+FROM+%60new%60&goto=sql.php&default_'
|
||||
. 'action=insert"><span '
|
||||
. 'action=insert&server=0&lang=en"><span '
|
||||
. 'class="nowrap"><img src="themes/dot.gif" title="Copy" alt="Copy" '
|
||||
. 'class="icon ic_b_insrow" /> Copy</span></a>'
|
||||
. '<input type="hidden" class="where_clause" value="%60new%60.%60id'
|
||||
@ -752,7 +773,7 @@ class ResultsTest extends PmaTestCase
|
||||
. '<a href="tbl_change.php" data-post="db=data&table=new&where_clause'
|
||||
. '=%60new%60.%60id%60+%3D+1&clause_is_unique=1&sql_query='
|
||||
. 'SELECT+%2A+FROM+%60new%60&goto=sql.php&default_action='
|
||||
. 'update"><span class='
|
||||
. 'update&server=0&lang=en"><span class='
|
||||
. '"nowrap"><img src="themes/dot.gif" title="Edit" alt="Edit" class'
|
||||
. '="icon ic_b_edit" /> Edit</span></a>'
|
||||
. '<input type="hidden" class="where_clause" value ="%60new%60.%60'
|
||||
@ -764,12 +785,7 @@ class ResultsTest extends PmaTestCase
|
||||
),
|
||||
array(
|
||||
DisplayResults::POSITION_NONE,
|
||||
'sql.php?db=data&table=new&sql_query=DELETE+FROM+%60data%60.'
|
||||
. '%60new%60+WHERE+%60new%60.%60id%60+%3D+1&message_to_show=The+'
|
||||
. 'row+has+been+deleted&goto=sql.php%3Fdb%3Ddata%26table%3Dnew'
|
||||
. '%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26message_'
|
||||
. 'to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3Dtbl_structure'
|
||||
. '.php',
|
||||
'sql.php',
|
||||
array(
|
||||
'edit_lnk' => 'ur',
|
||||
'del_lnk' => 'dr',
|
||||
@ -785,12 +801,8 @@ class ResultsTest extends PmaTestCase
|
||||
array(
|
||||
'`new`.`id`' => '= 1',
|
||||
),
|
||||
'tbl_change.php?db=data&table=new&where_clause=%60new%60.%60'
|
||||
. 'id%60+%3D+1&clause_is_unique=1&sql_query=SELECT+%2A+FROM+'
|
||||
. '%60new%60&goto=sql.php&default_action=update',
|
||||
'tbl_change.php?db=data&table=new&where_clause=%60new%60.%60'
|
||||
. 'id%60+%3D+1&clause_is_unique=1&sql_query=SELECT+%2A+FROM+'
|
||||
. '%60new%60&goto=sql.php&default_action=insert',
|
||||
'tbl_change.php',
|
||||
'tbl_change.php',
|
||||
'edit_row_anchor',
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
|
||||
. 'alt="Edit" class="icon ic_b_edit" /> Edit</span>',
|
||||
@ -799,6 +811,21 @@ class ResultsTest extends PmaTestCase
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
|
||||
. 'alt="Delete" class="icon ic_b_drop" /> Delete</span>',
|
||||
'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
|
||||
[
|
||||
'db' => 'data',
|
||||
'table' => 'new',
|
||||
'where_clause' => '`new`.`id` = 1',
|
||||
'clause_is_unique' => true,
|
||||
'sql_query' => 'SELECT * FROM `new`',
|
||||
'goto' => 'sql.php',
|
||||
],
|
||||
[
|
||||
'db' => 'data',
|
||||
'table' => 'new',
|
||||
'sql_query' => 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
|
||||
'message_to_show' => 'The row has been deleted.',
|
||||
'goto' => 'tbl_sql.php',
|
||||
],
|
||||
'<td class="center print_ignore"><input type="checkbox" id="id_rows_to_'
|
||||
. 'delete0_left" name="rows_to_delete[0]" class="multi_checkbox '
|
||||
. 'checkall" value="%60new%60.%60id%60+%3D+1" /><input type='
|
||||
@ -835,7 +862,7 @@ class ResultsTest extends PmaTestCase
|
||||
public function testGetCheckboxAndLinks(
|
||||
$position, $del_url, $displayParts, $row_no, $where_clause,
|
||||
$where_clause_html, $condition_array, $edit_url,
|
||||
$copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf, $output
|
||||
$copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams, $output
|
||||
) {
|
||||
$this->assertEquals(
|
||||
$output,
|
||||
@ -845,7 +872,7 @@ class ResultsTest extends PmaTestCase
|
||||
$position, $del_url, $displayParts, $row_no, $where_clause,
|
||||
$where_clause_html, $condition_array,
|
||||
$edit_url, $copy_url, $class, $edit_str,
|
||||
$copy_str, $del_str, $js_conf
|
||||
$copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -896,6 +923,8 @@ class ResultsTest extends PmaTestCase
|
||||
'<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
|
||||
. 'alt="Delete" class="icon ic_b_drop" /> Delete</span>',
|
||||
null,
|
||||
[],
|
||||
[],
|
||||
'<td class="center print_ignore"><input type="checkbox" id="id_rows_to_'
|
||||
. 'delete0_left" name="rows_to_delete[0]" class="multi_checkbox '
|
||||
. 'checkall" value="%60new%60.%60id%60+%3D+1" /><input type='
|
||||
@ -931,7 +960,7 @@ class ResultsTest extends PmaTestCase
|
||||
public function testGetPlacedLinks(
|
||||
$dir, $del_url, $displayParts, $row_no, $where_clause, $where_clause_html,
|
||||
$condition_array, $edit_url, $copy_url,
|
||||
$edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf, $output
|
||||
$edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams, $output
|
||||
) {
|
||||
$this->assertEquals(
|
||||
$output,
|
||||
@ -941,7 +970,7 @@ class ResultsTest extends PmaTestCase
|
||||
$dir, $del_url, $displayParts, $row_no, $where_clause,
|
||||
$where_clause_html, $condition_array,
|
||||
$edit_url, $copy_url, $edit_anchor_class,
|
||||
$edit_str, $copy_str, $del_str, $js_conf
|
||||
$edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@ -46,6 +46,7 @@ class FooterTest extends PmaTestCase
|
||||
$GLOBALS['table'] = '';
|
||||
$GLOBALS['text_dir'] = 'ltr';
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
$GLOBALS['cfg']['Server']['DisableIS'] = false;
|
||||
$GLOBALS['cfg']['Server']['verbose'] = 'verbose host';
|
||||
|
||||
@ -62,6 +62,7 @@ class InsertEditTest extends TestCase
|
||||
$GLOBALS['cfg']['LoginCookieValidity'] = 1440;
|
||||
$GLOBALS['cfg']['enable_drag_drop_import'] = true;
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
|
||||
$this->insertEdit = new InsertEdit($GLOBALS['dbi']);
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Navigation\NavigationTree;
|
||||
use PhpMyAdmin\Tests\PmaTestCase;
|
||||
use PhpMyAdmin\Theme;
|
||||
use PhpMyAdmin\Url;
|
||||
use ReflectionMethod;
|
||||
|
||||
/*
|
||||
* we must set $GLOBALS['server'] here
|
||||
@ -43,6 +45,7 @@ class NavigationTreeTest extends PmaTestCase
|
||||
{
|
||||
$GLOBALS['server'] = 1;
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
$GLOBALS['cfg']['Server']['host'] = 'localhost';
|
||||
$GLOBALS['cfg']['Server']['user'] = 'root';
|
||||
@ -100,4 +103,37 @@ class NavigationTreeTest extends PmaTestCase
|
||||
$result = $this->object->renderDbSelect();
|
||||
$this->assertContains('pma_navigation_select_database', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testEncryptQueryParams()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryption', false);
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$method = new ReflectionMethod($this->object, 'encryptQueryParams');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$link = 'tbl_structure.php?server=1&db=test_db&table=test_table&pos=0';
|
||||
|
||||
$actual = $method->invoke($this->object, $link);
|
||||
$this->assertEquals($link, $actual);
|
||||
|
||||
$PMA_Config->set('URLQueryEncryption', true);
|
||||
|
||||
$actual = $method->invoke($this->object, $link);
|
||||
$this->assertStringStartsWith('tbl_structure.php?server=1&pos=0&eq=', $actual);
|
||||
|
||||
$url = parse_url($actual);
|
||||
parse_str(htmlspecialchars_decode($url['query']), $query);
|
||||
|
||||
$this->assertRegExp('/^[a-zA-Z0-9-_=]+$/', $query['eq']);
|
||||
$decrypted = Url::decryptQuery($query['eq']);
|
||||
$this->assertJson($decrypted);
|
||||
$this->assertSame('{"db":"test_db","table":"test_table"}', $decrypted);
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ class AuthenticationCookieTest extends PmaTestCase
|
||||
function setUp()
|
||||
{
|
||||
$GLOBALS['PMA_Config'] = new Config();
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
$GLOBALS['server'] = 0;
|
||||
$GLOBALS['text_dir'] = 'ltr';
|
||||
|
||||
@ -28,6 +28,7 @@ class PmaTestCase extends TestCase
|
||||
{
|
||||
require 'libraries/config.default.php';
|
||||
$GLOBALS['cfg'] = $cfg;
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -196,7 +196,7 @@ class ProcessesTest extends TestCase
|
||||
|
||||
//validate 1: $kill_process
|
||||
$kill_process = 'href="server_status_processes.php" data-post="'
|
||||
. Url::getCommon(['kill' => $process['id']], '') . '"';
|
||||
. Url::getCommon(['kill' => $process['id']], '', false) . '"';
|
||||
$this->assertContains(
|
||||
$kill_process,
|
||||
$html
|
||||
|
||||
@ -129,7 +129,7 @@ class UserGroupsTest extends TestCase
|
||||
array(
|
||||
'viewUsers'=>1, 'userGroup'=>htmlspecialchars('usergroup')
|
||||
),
|
||||
''
|
||||
'', false
|
||||
);
|
||||
$this->assertContains(
|
||||
$url_tag,
|
||||
@ -141,7 +141,7 @@ class UserGroupsTest extends TestCase
|
||||
'editUserGroup'=>1,
|
||||
'userGroup'=>htmlspecialchars('usergroup')
|
||||
),
|
||||
''
|
||||
'', false
|
||||
);
|
||||
$this->assertContains(
|
||||
$url_tag,
|
||||
@ -153,7 +153,7 @@ class UserGroupsTest extends TestCase
|
||||
'deleteUserGroup'=> 1,
|
||||
'userGroup'=>htmlspecialchars('usergroup')
|
||||
),
|
||||
""
|
||||
"", false
|
||||
);
|
||||
$this->assertContains(
|
||||
$url_tag,
|
||||
|
||||
@ -27,6 +27,7 @@ class UrlTest extends TestCase
|
||||
public function setUp()
|
||||
{
|
||||
unset($_COOKIE['pma_lang']);
|
||||
$GLOBALS['PMA_Config']->set('URLQueryEncryption', false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,4 +106,61 @@ class UrlTest extends TestCase
|
||||
$expected = '?server=x' . htmlentities($separator) . 'lang=en' ;
|
||||
$this->assertEquals($expected, Url::getCommon());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testBuildHttpQueryWithUrlQueryEncryptionDisabled()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$PMA_Config->set('URLQueryEncryption', false);
|
||||
$params = ['db' => 'test_db', 'table' => 'test_table', 'pos' => 0];
|
||||
$this->assertEquals('db=test_db&table=test_table&pos=0', Url::buildHttpQuery($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testBuildHttpQueryWithUrlQueryEncryptionEnabled()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryption', true);
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$params = ['db' => 'test_db', 'table' => 'test_table', 'pos' => 0];
|
||||
$query = Url::buildHttpQuery($params);
|
||||
$this->assertStringStartsWith('pos=0&eq=', $query);
|
||||
parse_str($query, $queryParams);
|
||||
$this->assertCount(2, $queryParams);
|
||||
$this->assertSame('0', $queryParams['pos']);
|
||||
$this->assertTrue(is_string($queryParams['eq']));
|
||||
$this->assertNotSame('', $queryParams['eq']);
|
||||
$this->assertRegExp('/^[a-zA-Z0-9-_=]+$/', $queryParams['eq']);
|
||||
$decrypted = Url::decryptQuery($queryParams['eq']);
|
||||
$this->assertJson($decrypted);
|
||||
$this->assertSame('{"db":"test_db","table":"test_table"}', $decrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testQueryEncryption()
|
||||
{
|
||||
global $PMA_Config;
|
||||
|
||||
$_SESSION = [];
|
||||
$PMA_Config->set('URLQueryEncryption', true);
|
||||
$PMA_Config->set('URLQueryEncryptionSecretKey', str_repeat('a', 32));
|
||||
|
||||
$query = '{"db":"test_db","table":"test_table"}';
|
||||
$encrypted = Url::encryptQuery($query);
|
||||
$this->assertNotSame($query, $encrypted);
|
||||
$this->assertNotSame('', $encrypted);
|
||||
$this->assertRegExp('/^[a-zA-Z0-9-_=]+$/', $encrypted);
|
||||
$decrypted = Url::decryptQuery($encrypted);
|
||||
$this->assertSame($query, $decrypted);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2107,22 +2107,22 @@ class UtilTest extends PmaTestCase
|
||||
{
|
||||
return [
|
||||
[
|
||||
['index.php', 'text'],
|
||||
['index.php', null, 'text'],
|
||||
1000,
|
||||
'<a href="index.php" >text</a>'
|
||||
],
|
||||
[
|
||||
['index.php?some=parameter', 'text'],
|
||||
['index.php', ['some' => 'parameter'], 'text'],
|
||||
20,
|
||||
'<a href="index.php" data-post="some=parameter">text</a>',
|
||||
'<a href="index.php" data-post="some=parameter&lang=en">text</a>',
|
||||
],
|
||||
[
|
||||
['index.php', 'text', [], 'target'],
|
||||
['index.php', null, 'text', [], 'target'],
|
||||
1000,
|
||||
'<a href="index.php" target="target">text</a>',
|
||||
],
|
||||
[
|
||||
['url.php?url=http://phpmyadmin.net/', 'text', [], '_blank'],
|
||||
['url.php?url=http://phpmyadmin.net/', null, 'text', [], '_blank'],
|
||||
1000,
|
||||
'<a href="url.php?url=http://phpmyadmin.net/" target="_blank" rel="noopener noreferrer">text</a>',
|
||||
],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user