Merge #18223 - Add a configuration option to allow shared bookmarks: $cfg['AllowSharedBookmarks']

Pull-request: #18223

Signed-off-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
William Desportes 2023-05-06 12:02:50 +02:00
commit 25bd2ac711
No known key found for this signature in database
GPG Key ID: 90A0EF1B8251A889
13 changed files with 79 additions and 13 deletions

View File

@ -3540,6 +3540,15 @@ Various display setting
specify the amount of saved history items using specify the amount of saved history items using
:config:option:`$cfg['QueryHistoryMax']`. :config:option:`$cfg['QueryHistoryMax']`.
.. config:option:: $cfg['AllowSharedBookmarks']
:type: boolean
:default: true
.. versionadded:: 6.0.0
Allow users to create bookmarks that are available for all other users
.. config:option:: $cfg['BrowseMIME'] .. config:option:: $cfg['BrowseMIME']
:type: boolean :type: boolean

View File

@ -175,7 +175,7 @@ class Bookmark
/** /**
* Creates a Bookmark object from the parameters * Creates a Bookmark object from the parameters
* *
* @param mixed[] $bkmFields the properties of the bookmark to add; here, $bkm_fields['bkm_sql_query'] is urlencoded * @param mixed[] $bkmFields the properties of the bookmark to add; here, $bkmFields['bkm_sql_query'] is urlencoded
* @param bool $allUsers whether to make the bookmark available for all users * @param bool $allUsers whether to make the bookmark available for all users
*/ */
public static function createBookmark( public static function createBookmark(
@ -191,6 +191,14 @@ class Bookmark
return false; return false;
} }
if (! $GLOBALS['cfg']['AllowSharedBookmarks']) {
$allUsers = false;
}
if (! $allUsers && ! strlen((string) $bkmFields['bkm_user'])) {
return false;
}
$bookmark = new Bookmark($dbi, new Relation($dbi)); $bookmark = new Bookmark($dbi, new Relation($dbi));
$bookmark->database = $bkmFields['bkm_database']; $bookmark->database = $bkmFields['bkm_database'];
$bookmark->label = $bkmFields['bkm_label']; $bookmark->label = $bkmFields['bkm_label'];
@ -227,10 +235,17 @@ class Bookmark
string $user, string $user,
string|false $db = false, string|false $db = false,
): array { ): array {
$exactUserMatch = ! $GLOBALS['cfg']['AllowSharedBookmarks'];
$query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database) $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database)
. '.' . Util::backquote($bookmarkFeature->bookmark) . '.' . Util::backquote($bookmarkFeature->bookmark)
. " WHERE ( `user` = ''" . ' WHERE (`user` = ' . $dbi->quoteString($user);
. ' OR `user` = ' . $dbi->quoteString($user) . ' )'; if (! $exactUserMatch) {
$query .= " OR `user` = ''";
}
$query .= ')';
if ($db !== false) { if ($db !== false) {
$query .= ' AND dbase = ' . $dbi->quoteString($db); $query .= ' AND dbase = ' . $dbi->quoteString($db);
} }
@ -275,6 +290,10 @@ class Bookmark
return null; return null;
} }
if (! $GLOBALS['cfg']['AllowSharedBookmarks']) {
$exactUserMatch = true;
}
$query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database) $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database)
. '.' . Util::backquote($bookmarkFeature->bookmark) . '.' . Util::backquote($bookmarkFeature->bookmark)
. ' WHERE dbase = ' . $dbi->quoteString($db->getName()); . ' WHERE dbase = ' . $dbi->quoteString($db->getName());

View File

@ -329,6 +329,7 @@ class Descriptions
. 'storage). If disabled, this utilizes JS-routines to display query history ' . 'storage). If disabled, this utilizes JS-routines to display query history '
. '(lost by window close).', . '(lost by window close).',
), ),
'AllowSharedBookmarks_desc' => __('Allow users to create bookmarks that are available for all other users'),
'Servers_SessionTimeZone_desc' => __( 'Servers_SessionTimeZone_desc' => __(
'Sets the effective timezone; possibly different than the one from your database server', 'Sets the effective timezone; possibly different than the one from your database server',
), ),
@ -854,6 +855,7 @@ class Descriptions
'ProtectBinary_name' => __('Protect binary columns'), 'ProtectBinary_name' => __('Protect binary columns'),
'QueryHistoryDB_name' => __('Permanent query history'), 'QueryHistoryDB_name' => __('Permanent query history'),
'QueryHistoryMax_name' => __('Query history length'), 'QueryHistoryMax_name' => __('Query history length'),
'AllowSharedBookmarks_name' => __('Allow shared bookmarks between users'),
'RecodingEngine_name' => __('Recoding engine'), 'RecodingEngine_name' => __('Recoding engine'),
'RememberSorting_name' => __('Remember table\'s sorting'), 'RememberSorting_name' => __('Remember table\'s sorting'),
'TablePrimaryKeyOrder_name' => __('Primary key default sort order'), 'TablePrimaryKeyOrder_name' => __('Primary key default sort order'),

View File

@ -15,6 +15,7 @@ class SqlForm extends \PhpMyAdmin\Config\Forms\User\SqlForm
$result = parent::getForms(); $result = parent::getForms();
/* Following are not available to user */ /* Following are not available to user */
$result['Sql_queries'][] = 'QueryHistoryDB'; $result['Sql_queries'][] = 'QueryHistoryDB';
$result['Sql_queries'][] = 'AllowSharedBookmarks';
return $result; return $result;
} }

View File

@ -1925,6 +1925,17 @@ final class Settings
*/ */
public int $QueryHistoryMax; public int $QueryHistoryMax;
/**
* Allow shared bookmarks between users
*
* ```php
* $cfg['AllowSharedBookmarks'] = true;
* ```
*
* @link https://docs.phpmyadmin.net/en/latest/config.html#cfg_AllowSharedBookmarks
*/
public bool $AllowSharedBookmarks;
/** /**
* Use MIME-Types (stored in column comments table) for * Use MIME-Types (stored in column comments table) for
* *
@ -2565,6 +2576,7 @@ final class Settings
$this->repeatCells = $this->setRepeatCells($settings); $this->repeatCells = $this->setRepeatCells($settings);
$this->QueryHistoryDB = $this->setQueryHistoryDB($settings); $this->QueryHistoryDB = $this->setQueryHistoryDB($settings);
$this->QueryHistoryMax = $this->setQueryHistoryMax($settings); $this->QueryHistoryMax = $this->setQueryHistoryMax($settings);
$this->AllowSharedBookmarks = $this->setAllowSharedBookmarks($settings);
$this->BrowseMIME = $this->setBrowseMIME($settings); $this->BrowseMIME = $this->setBrowseMIME($settings);
$this->MaxExactCount = $this->setMaxExactCount($settings); $this->MaxExactCount = $this->setMaxExactCount($settings);
$this->MaxExactCountViews = $this->setMaxExactCountViews($settings); $this->MaxExactCountViews = $this->setMaxExactCountViews($settings);
@ -2762,6 +2774,7 @@ final class Settings
'RepeatCells' => $this->repeatCells, 'RepeatCells' => $this->repeatCells,
'QueryHistoryDB' => $this->QueryHistoryDB, 'QueryHistoryDB' => $this->QueryHistoryDB,
'QueryHistoryMax' => $this->QueryHistoryMax, 'QueryHistoryMax' => $this->QueryHistoryMax,
'AllowSharedBookmarks' => $this->AllowSharedBookmarks,
'BrowseMIME' => $this->BrowseMIME, 'BrowseMIME' => $this->BrowseMIME,
'MaxExactCount' => $this->MaxExactCount, 'MaxExactCount' => $this->MaxExactCount,
'MaxExactCountViews' => $this->MaxExactCountViews, 'MaxExactCountViews' => $this->MaxExactCountViews,
@ -4796,6 +4809,16 @@ final class Settings
return $queryHistoryMax >= 1 ? $queryHistoryMax : 25; return $queryHistoryMax >= 1 ? $queryHistoryMax : 25;
} }
/** @param array<int|string, mixed> $settings */
private function setAllowSharedBookmarks(array $settings): bool
{
if (! isset($settings['AllowSharedBookmarks'])) {
return true;
}
return (bool) $settings['AllowSharedBookmarks'];
}
/** @param array<int|string, mixed> $settings */ /** @param array<int|string, mixed> $settings */
private function setBrowseMIME(array $settings): bool private function setBrowseMIME(array $settings): bool
{ {

View File

@ -1035,6 +1035,7 @@ class Sql
]), ]),
'user' => $GLOBALS['cfg']['Server']['user'], 'user' => $GLOBALS['cfg']['Server']['user'],
'sql_query' => $completeQuery ?? $sqlQuery, 'sql_query' => $completeQuery ?? $sqlQuery,
'allow_shared_bookmarks' => $GLOBALS['cfg']['AllowSharedBookmarks'],
]); ]);
} }

View File

@ -116,6 +116,7 @@ class SqlQueryForm
'bookmarks' => $bookmarks, 'bookmarks' => $bookmarks,
'can_convert_kanji' => Encoding::canConvertKanji(), 'can_convert_kanji' => Encoding::canConvertKanji(),
'is_foreign_key_check' => ForeignKey::isCheckEnabled(), 'is_foreign_key_check' => ForeignKey::isCheckEnabled(),
'allow_shared_bookmarks' => $GLOBALS['cfg']['AllowSharedBookmarks'],
]); ]);
} }

View File

@ -610,6 +610,7 @@
<file src="libraries/classes/Config/Forms/Setup/SqlForm.php"> <file src="libraries/classes/Config/Forms/Setup/SqlForm.php">
<MixedArrayAssignment> <MixedArrayAssignment>
<code><![CDATA[$result['Sql_queries'][]]]></code> <code><![CDATA[$result['Sql_queries'][]]]></code>
<code><![CDATA[$result['Sql_queries'][]]]></code>
</MixedArrayAssignment> </MixedArrayAssignment>
</file> </file>
<file src="libraries/classes/Config/ServerConfigChecks.php"> <file src="libraries/classes/Config/ServerConfigChecks.php">

View File

@ -44,6 +44,7 @@
cached_affected_rows: int|numeric-string, cached_affected_rows: int|numeric-string,
cfg: array{ cfg: array{
AllowArbitraryServer: bool, AllowArbitraryServer: bool,
AllowSharedBookmarks: bool,
AllowThirdPartyFraming: bool|'sameorigin', AllowThirdPartyFraming: bool|'sameorigin',
ArbitraryServerRegexp: string, ArbitraryServerRegexp: string,
AvailableCharsets: string[], AvailableCharsets: string[],

View File

@ -15,10 +15,12 @@
<input class="form-control" id="bookmarkLabelField" type="text" name="bkm_fields[bkm_label]" value=""> <input class="form-control" id="bookmarkLabelField" type="text" name="bkm_fields[bkm_label]" value="">
</div> </div>
<div class="form-check form-switch"> {% if allow_shared_bookmarks %}
<input class="form-check-input" type="checkbox" role="switch" id="bookmarkAllUsersCheckbox" name="bkm_all_users" value="true"> <div class="form-check form-switch">
<label class="form-check-label" for="bookmarkAllUsersCheckbox">{% trans 'Let every user access this bookmark' %}</label> <input class="form-check-input" type="checkbox" role="switch" id="bookmarkAllUsersCheckbox" name="bkm_all_users" value="true">
</div> <label class="form-check-label" for="bookmarkAllUsersCheckbox">{% trans 'Let every user access this bookmark' %}</label>
</div>
{% endif %}
</div> </div>
<div class="card-footer"> <div class="card-footer">
<input class="btn btn-secondary" type="submit" value="{% trans 'Create new bookmark' %}"> <input class="btn btn-secondary" type="submit" value="{% trans 'Create new bookmark' %}">

View File

@ -87,12 +87,14 @@
<input class="form-control" type="text" name="bkm_label" id="bkm_label" tabindex="110" value=""> <input class="form-control" type="text" name="bkm_label" id="bkm_label" tabindex="110" value="">
</div> </div>
<div class="col-12"> {% if allow_shared_bookmarks %}
<div class="form-check form-check-inline"> <div class="col-12">
<input class="form-check-input" type="checkbox" name="bkm_all_users" tabindex="111" id="id_bkm_all_users" value="true"> <div class="form-check form-check-inline">
<label class="form-check-label" for="id_bkm_all_users">{% trans 'Let every user access this bookmark' %}</label> <input class="form-check-input" type="checkbox" name="bkm_all_users" tabindex="111" id="id_bkm_all_users" value="true">
<label class="form-check-label" for="id_bkm_all_users">{% trans 'Let every user access this bookmark' %}</label>
</div>
</div> </div>
</div> {% endif %}
<div class="col-12"> <div class="col-12">
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">

View File

@ -43,7 +43,7 @@ class BookmarkTest extends AbstractTestCase
public function testGetList(): void public function testGetList(): void
{ {
$this->dummyDbi->addResult( $this->dummyDbi->addResult(
'SELECT * FROM `phpmyadmin`.`pma_bookmark` WHERE ( `user` = \'\' OR `user` = \'root\' )' 'SELECT * FROM `phpmyadmin`.`pma_bookmark` WHERE (`user` = \'root\' OR `user` = \'\')'
. ' AND dbase = \'sakila\' ORDER BY label ASC', . ' AND dbase = \'sakila\' ORDER BY label ASC',
[['1', 'sakila', 'root', 'label', 'SELECT * FROM `actor` WHERE `actor_id` < 10;']], [['1', 'sakila', 'root', 'label', 'SELECT * FROM `actor` WHERE `actor_id` < 10;']],
['id', 'dbase', 'user', 'label', 'query'], ['id', 'dbase', 'user', 'label', 'query'],

View File

@ -197,6 +197,7 @@ class SettingsTest extends TestCase
'ShowPropertyComments' => true, 'ShowPropertyComments' => true,
'QueryHistoryDB' => false, 'QueryHistoryDB' => false,
'QueryHistoryMax' => 25, 'QueryHistoryMax' => 25,
'AllowSharedBookmarks' => true,
'BrowseMIME' => true, 'BrowseMIME' => true,
'MaxExactCount' => 50000, 'MaxExactCount' => 50000,
'MaxExactCountViews' => 0, 'MaxExactCountViews' => 0,
@ -454,6 +455,7 @@ class SettingsTest extends TestCase
['ShowPropertyComments', null, true], ['ShowPropertyComments', null, true],
['QueryHistoryDB', null, false], ['QueryHistoryDB', null, false],
['QueryHistoryMax', null, 25], ['QueryHistoryMax', null, 25],
['AllowSharedBookmarks', null, true],
['BrowseMIME', null, true], ['BrowseMIME', null, true],
['MaxExactCount', null, 50000], ['MaxExactCount', null, 50000],
['MaxExactCountViews', null, 0], ['MaxExactCountViews', null, 0],
@ -619,6 +621,7 @@ class SettingsTest extends TestCase
['ShowPropertyComments', false, false], ['ShowPropertyComments', false, false],
['QueryHistoryDB', true, true], ['QueryHistoryDB', true, true],
['QueryHistoryMax', 1, 1], ['QueryHistoryMax', 1, 1],
['AllowSharedBookmarks', false, false],
['BrowseMIME', false, false], ['BrowseMIME', false, false],
['MaxExactCount', 1, 1], ['MaxExactCount', 1, 1],
['MaxExactCountViews', 0, 0], ['MaxExactCountViews', 0, 0],
@ -887,6 +890,7 @@ class SettingsTest extends TestCase
['ShowPropertyComments', 0, false], ['ShowPropertyComments', 0, false],
['QueryHistoryDB', 1, true], ['QueryHistoryDB', 1, true],
['QueryHistoryMax', '1', 1], ['QueryHistoryMax', '1', 1],
['AllowSharedBookmarks', 0, false],
['BrowseMIME', 0, false], ['BrowseMIME', 0, false],
['MaxExactCount', '1', 1], ['MaxExactCount', '1', 1],
['MaxExactCountViews', '1', 1], ['MaxExactCountViews', '1', 1],