Fix #17262 - Add warning when setting a password to a blank value if AllowNoPassword is false (#19315)
* Fix #17262 - Add warning when setting a password to a blank value if AllowNoPassword is false Closes #17262 Signed-off-by: Jacek Barecki <jacek.barecki@gmail.com> Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
parent
720de704f8
commit
003f092277
@ -158,7 +158,7 @@ return [
|
||||
'server_plugins' => ['class' => Plugins::class, 'arguments' => ['@dbi']],
|
||||
'server_privileges' => [
|
||||
'class' => Privileges::class,
|
||||
'arguments' => ['@template', '@dbi', '@relation', '@relation_cleanup', '@server_plugins'],
|
||||
'arguments' => ['@template', '@dbi', '@relation', '@relation_cleanup', '@server_plugins', '@config'],
|
||||
],
|
||||
'server_privileges_account_locking' => [
|
||||
'class' => AccountLocking::class,
|
||||
|
||||
@ -700,6 +700,7 @@ return [
|
||||
'$relation' => '@relation',
|
||||
'$dbi' => '@dbi',
|
||||
'$userPrivilegesFactory' => '@' . UserPrivilegesFactory::class,
|
||||
'$config' => '@config',
|
||||
],
|
||||
],
|
||||
Server\ReplicationController::class => [
|
||||
|
||||
@ -1974,6 +1974,10 @@ export function checkPassword ($theForm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function shouldShowEmptyPasswordWarning (form): boolean {
|
||||
return (form.find('#nopass_1').is(':checked') && form.data('allowNoPassword') === 0);
|
||||
}
|
||||
|
||||
export function onloadChangePasswordEvents (): void {
|
||||
/* Handler for hostname type */
|
||||
$(document).on('change', '#select_pred_hostname', function () {
|
||||
@ -2067,25 +2071,35 @@ export function onloadChangePasswordEvents (): void {
|
||||
*/
|
||||
var thisValue = $(this).val();
|
||||
|
||||
var $msgbox = ajaxShowMessage(window.Messages.strProcessingRequest);
|
||||
$theForm.append('<input type="hidden" name="ajax_request" value="true">');
|
||||
var submitForm = function () {
|
||||
var $msgbox = ajaxShowMessage(window.Messages.strProcessingRequest);
|
||||
$theForm.append('<input type="hidden" name="ajax_request" value="true">');
|
||||
|
||||
$.post($theForm.attr('action'), $theForm.serialize() + CommonParams.get('arg_separator') + 'change_pw=' + thisValue, function (data) {
|
||||
if (typeof data === 'undefined' || data.success !== true) {
|
||||
ajaxShowMessage(data.error, false);
|
||||
$.post($theForm.attr('action'), $theForm.serialize() + CommonParams.get('arg_separator') + 'change_pw=' + thisValue, function (data) {
|
||||
if (typeof data === 'undefined' || data.success !== true) {
|
||||
ajaxShowMessage(data.error, false);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var $pageContent = $('#page_content');
|
||||
$pageContent.prepend(data.message);
|
||||
highlightSql($pageContent);
|
||||
$('#change_password_dialog').hide().remove();
|
||||
$('#edit_user_dialog').dialog('close').remove();
|
||||
ajaxRemoveMessage($msgbox);
|
||||
}); // end $.post()
|
||||
var $pageContent = $('#page_content');
|
||||
$pageContent.prepend(data.message);
|
||||
highlightSql($pageContent);
|
||||
$('#change_password_dialog').hide().remove();
|
||||
$('#edit_user_dialog').dialog('close').remove();
|
||||
ajaxRemoveMessage($msgbox);
|
||||
}); // end $.post()
|
||||
|
||||
$('#changePasswordModal').modal('hide');
|
||||
$('#changePasswordModal').modal('hide');
|
||||
};
|
||||
|
||||
if (shouldShowEmptyPasswordWarning($theForm)) {
|
||||
$(this).confirm(window.Messages.strPasswordEmptyWhenAllowNoPasswordIsEnabled, '', function () {
|
||||
submitForm();
|
||||
});
|
||||
} else {
|
||||
submitForm();
|
||||
}
|
||||
});
|
||||
|
||||
$.get($(this).attr('href'), { 'ajax_request': true }, function (data) {
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
import $ from 'jquery';
|
||||
import { AJAX } from '../modules/ajax.ts';
|
||||
import { checkPassword, checkPasswordStrength, checkboxesSel, displayPasswordGenerateButton, getSqlEditor } from '../modules/functions.ts';
|
||||
import {
|
||||
checkPassword,
|
||||
checkPasswordStrength,
|
||||
checkboxesSel,
|
||||
displayPasswordGenerateButton,
|
||||
getSqlEditor,
|
||||
shouldShowEmptyPasswordWarning
|
||||
} from '../modules/functions.ts';
|
||||
import { CommonParams } from '../modules/common.ts';
|
||||
import { Navigation } from '../modules/navigation.ts';
|
||||
import { ajaxRemoveMessage, ajaxShowMessage } from '../modules/ajax-message.ts';
|
||||
@ -475,6 +482,26 @@ const CheckAddUser = {
|
||||
}
|
||||
};
|
||||
|
||||
const CheckEmptyPasswordWhenAllowNoPasswordIsEnabled = {
|
||||
handleEvent: function () {
|
||||
const theForm = this;
|
||||
|
||||
if (shouldShowEmptyPasswordWarning($(theForm))) {
|
||||
$(this).confirm(window.Messages.strPasswordEmptyWhenAllowNoPasswordIsEnabled, '', function () {
|
||||
theForm.submit();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return false;
|
||||
} else {
|
||||
theForm.submit();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const selectPasswordRadioWhenChangingPassword = () => {
|
||||
$('#nopass_0').prop('checked', true);
|
||||
};
|
||||
@ -561,4 +588,5 @@ AJAX.registerOnload('server/privileges.js', function () {
|
||||
|
||||
$('#addUsersForm').on('submit', CheckAddUser.handleEvent);
|
||||
$('#copyUserForm').on('submit', CheckAddUser.handleEvent);
|
||||
$('#change_password_form').on('submit', CheckEmptyPasswordWhenAllowNoPasswordIsEnabled.handleEvent);
|
||||
});
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<form method="post" id="change_password_form" action="
|
||||
{{- is_privileges ? url('/server/privileges') : url('/user-password') }}" name="chgPassword" class="{{ is_privileges ? 'submenu-item' }}" autocomplete="off">
|
||||
{{- is_privileges ? url('/server/privileges') : url('/user-password') }}" name="chgPassword" class="{{ is_privileges ? 'submenu-item' }}" autocomplete="off" data-allow-no-password="{{ allow_no_password ? 1 : 0 }}">
|
||||
{{ get_hidden_inputs() }}
|
||||
{% if is_privileges %}
|
||||
<input type="hidden" name="username" value="{{ username }}">
|
||||
|
||||
@ -143,6 +143,11 @@ final class JavaScriptMessagesController implements InvocableController
|
||||
'strUserEmpty' => __('The user name is empty!'),
|
||||
'strPasswordEmpty' => __('The password is empty!'),
|
||||
'strPasswordNotSame' => __('The passwords aren\'t the same!'),
|
||||
'strPasswordEmptyWhenAllowNoPasswordIsEnabled' => __(
|
||||
'You are trying to set this account to log in with no password, but the configuration directive ' .
|
||||
'<code>AllowNoPassword</code> is false. If you proceed, the account will not be able to log in ' .
|
||||
'through phpMyAdmin.',
|
||||
),
|
||||
'strRemovingSelectedUsers' => __('Removing Selected Users'),
|
||||
'strClose' => __('Close'),
|
||||
'strLock' => _pgettext('Lock the account.', 'Lock'),
|
||||
|
||||
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers\Server;
|
||||
|
||||
use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\ConfigStorage\RelationCleanup;
|
||||
use PhpMyAdmin\Controllers\InvocableController;
|
||||
@ -38,6 +39,7 @@ final class PrivilegesController implements InvocableController
|
||||
private readonly Relation $relation,
|
||||
private readonly DatabaseInterface $dbi,
|
||||
private readonly UserPrivilegesFactory $userPrivilegesFactory,
|
||||
private readonly Config $config,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -62,6 +64,7 @@ final class PrivilegesController implements InvocableController
|
||||
$this->relation,
|
||||
$relationCleanup,
|
||||
new Plugins($this->dbi),
|
||||
$this->config,
|
||||
);
|
||||
|
||||
$this->response->addHTML('<div class="container-fluid">');
|
||||
|
||||
@ -76,6 +76,7 @@ class Privileges
|
||||
public Relation $relation,
|
||||
private RelationCleanup $relationCleanup,
|
||||
private Plugins $plugins,
|
||||
private readonly Config $config,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -3270,6 +3271,7 @@ class Privileges
|
||||
'has_more_auth_plugins' => $hasMoreAuthPlugins,
|
||||
'active_auth_plugins' => $activeAuthPlugins,
|
||||
'orig_auth_plugin' => $origAuthPlugin,
|
||||
'allow_no_password' => $this->config->selectedServer['AllowNoPassword'],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ class PrivilegesControllerTest extends AbstractTestCase
|
||||
new Relation($this->dbi),
|
||||
$this->dbi,
|
||||
new UserPrivilegesFactory($this->dbi),
|
||||
new Config(),
|
||||
))($request);
|
||||
|
||||
$actual = $response->getHTMLResult();
|
||||
|
||||
@ -1889,6 +1889,7 @@ class PrivilegesTest extends AbstractTestCase
|
||||
$relation,
|
||||
new RelationCleanup($this->dbi, $relation),
|
||||
new Plugins($this->dbi),
|
||||
new Config(),
|
||||
);
|
||||
$method = new ReflectionMethod(Privileges::class, 'getUserPrivileges');
|
||||
|
||||
@ -1902,7 +1903,14 @@ class PrivilegesTest extends AbstractTestCase
|
||||
{
|
||||
$relation = new Relation($dbi);
|
||||
|
||||
return new Privileges(new Template(), $dbi, $relation, new RelationCleanup($dbi, $relation), new Plugins($dbi));
|
||||
return new Privileges(
|
||||
new Template(),
|
||||
$dbi,
|
||||
$relation,
|
||||
new RelationCleanup($dbi, $relation),
|
||||
new Plugins($dbi),
|
||||
new Config(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests;
|
||||
|
||||
use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\ConfigStorage\RelationCleanup;
|
||||
use PhpMyAdmin\Message;
|
||||
@ -35,6 +36,7 @@ class UserPasswordTest extends AbstractTestCase
|
||||
$relation,
|
||||
new RelationCleanup($dbi, $relation),
|
||||
new Plugins($dbi),
|
||||
new Config(),
|
||||
);
|
||||
$this->object = new UserPassword(
|
||||
$serverPrivileges,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user