Skip to content

Commit 0cbb3af

Browse files
committed
Merge branch 'ACP2E-4044' of https://github.com/adobe-commerce-tier-4/magento2ce into Tier4-08-13-2025
2 parents 2a997fd + 42e3866 commit 0cbb3af

27 files changed

+837
-67
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Backend\Model\Config\Password;
9+
10+
use Magento\Framework\App\Config\Value;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\User\Model\UserValidationRules;
13+
14+
/**
15+
* Backend model for admin minimum password length configuration
16+
*/
17+
class MinimumLength extends Value
18+
{
19+
/**
20+
* Validate the minimum password length value
21+
*
22+
* @return $this
23+
* @throws LocalizedException
24+
*/
25+
public function beforeSave()
26+
{
27+
$value = (int) $this->getValue();
28+
29+
if ($value < UserValidationRules::MIN_PASSWORD_LENGTH) {
30+
throw new LocalizedException(
31+
__(
32+
'The minimum admin password length must be at least %1 characters.',
33+
UserValidationRules::MIN_PASSWORD_LENGTH
34+
)
35+
);
36+
}
37+
38+
return parent::beforeSave();
39+
}
40+
}

app/code/Magento/Backend/etc/adminhtml/system.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,12 @@
461461
<validate>required-entry integer validate-greater-than-zero</validate>
462462
<backend_model>Magento\Config\Model\Config\Backend\Admin\Password\Link\Expirationperiod</backend_model>
463463
</field>
464+
<field id="minimum_password_length" translate="label comment" type="text" sortOrder="8" showInDefault="1" canRestore="1">
465+
<label>Minimum Admin Password Length</label>
466+
<comment>Minimum number of characters required for admin user passwords. Values below 7 are not allowed.</comment>
467+
<validate>required-entry validate-digits validate-digits-range digits-range-7-65535</validate>
468+
<backend_model>Magento\Backend\Model\Config\Password\MinimumLength</backend_model>
469+
</field>
464470
<field id="use_form_key" translate="label" type="select" sortOrder="10" showInDefault="1" canRestore="1">
465471
<label>Add Secret Key to URLs</label>
466472
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>

app/code/Magento/Backend/etc/config.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<dashboard>
1212
<enable_charts>0</enable_charts>
1313
</dashboard>
14+
<security>
15+
<minimum_password_length>7</minimum_password_length>
16+
</security>
1417
</admin>
1518
<dev>
1619
<template>

app/code/Magento/Backend/i18n/en_US.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,5 @@ Pagination,Pagination
467467
"Use URL parameter to enable template path hints for Storefront","Use URL parameter to enable template path hints for Storefront"
468468
"Add the following parameter to the URL to show template hints ?templatehints=[parameter_value]","Add the following parameter to the URL to show template hints ?templatehints=[parameter_value]"
469469
"URL key "%1" matches a reserved endpoint name (%2). Use another URL key.","URL key "%1" matches a reserved endpoint name (%2). Use another URL key."
470+
"Minimum Admin Password Length","Minimum Admin Password Length"
471+
"Minimum number of characters required for admin user passwords. Values below 7 are not allowed.","Minimum number of characters required for admin user passwords. Values below 7 are not allowed."

app/code/Magento/Ui/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ Keyword,Keyword
8585
"Please enter a valid email address (Ex: [email protected]).","Please enter a valid email address (Ex: [email protected])."
8686
"Please enter 6 or more characters. Leading and trailing spaces will be ignored.","Please enter 6 or more characters. Leading and trailing spaces will be ignored."
8787
"Please enter 7 or more characters, using both numeric and alphabetic.","Please enter 7 or more characters, using both numeric and alphabetic."
88+
"Please enter %1 or more characters, using both numeric and alphabetic.","Please enter %1 or more characters, using both numeric and alphabetic."
8889
"Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.","Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored."
8990
"Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.","Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters."
9091
"Please enter a valid URL. Protocol is required (http://, https:// or ftp://).","Please enter a valid URL. Protocol is required (http://, https:// or ftp://)."

app/code/Magento/User/Block/User/Edit/Tab/Main.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2012 Adobe
4+
* All Rights Reserved.
55
*/
66

77
namespace Magento\User\Block\User\Edit\Tab;
88

99
use Magento\Framework\App\ObjectManager;
1010
use Magento\Framework\Locale\OptionInterface;
11+
use Magento\User\Model\UserValidationRules;
1112

1213
/**
1314
* Cms page edit form main tab
@@ -16,7 +17,7 @@
1617
*/
1718
class Main extends \Magento\Backend\Block\Widget\Form\Generic
1819
{
19-
const CURRENT_USER_PASSWORD_FIELD = 'current_password';
20+
public const CURRENT_USER_PASSWORD_FIELD = 'current_password';
2021

2122
/**
2223
* @var \Magento\Backend\Model\Auth\Session
@@ -199,6 +200,17 @@ protected function _prepareForm()
199200
return parent::_prepareForm();
200201
}
201202

203+
/**
204+
* Get minimum password length from configuration
205+
*
206+
* @return int
207+
*/
208+
public function getMinimumPasswordLength(): int
209+
{
210+
return (int) $this->_scopeConfig->getValue('admin/security/minimum_password_length') ?:
211+
UserValidationRules::MIN_PASSWORD_LENGTH;
212+
}
213+
202214
/**
203215
* Add password input fields
204216
*
@@ -215,6 +227,8 @@ protected function _addPasswordFields(
215227
$isRequired = false
216228
) {
217229
$requiredFieldClass = $isRequired ? ' required-entry' : '';
230+
$minLength = $this->getMinimumPasswordLength();
231+
218232
$fieldset->addField(
219233
'password',
220234
'password',
@@ -223,7 +237,7 @@ protected function _addPasswordFields(
223237
'label' => $passwordLabel,
224238
'id' => 'customer_pass',
225239
'title' => $passwordLabel,
226-
'class' => 'input-text validate-admin-password' . $requiredFieldClass,
240+
'class' => 'input-text validate-admin-password admin-password-min-' . $minLength . $requiredFieldClass,
227241
'required' => $isRequired
228242
]
229243
);

app/code/Magento/User/Model/UserValidationRules.php

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2015 Adobe
4+
* All Rights Reserved.
55
*/
66

77
namespace Magento\User\Model;
88

99
use Laminas\Validator\Identical;
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\App\ObjectManager;
1012
use Magento\Framework\Validator\DataObject;
1113
use Magento\Framework\Validator\EmailAddress;
1214
use Magento\Framework\Validator\NotEmpty;
@@ -22,10 +24,41 @@
2224
class UserValidationRules
2325
{
2426
/**
25-
* Minimum length of admin password
27+
* Configuration path for minimum admin password length
28+
*/
29+
private const XML_PATH_MINIMUM_PASSWORD_LENGTH = 'admin/security/minimum_password_length';
30+
31+
/**
32+
* Minimum length of admin password (fallback)
2633
*/
2734
public const MIN_PASSWORD_LENGTH = 7;
2835

36+
/**
37+
* @var ScopeConfigInterface
38+
*/
39+
private $scopeConfig;
40+
41+
/**
42+
* @param ScopeConfigInterface|null $scopeConfig
43+
*/
44+
public function __construct(?ScopeConfigInterface $scopeConfig = null)
45+
{
46+
$this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
47+
}
48+
49+
/**
50+
* Get minimum password length from configuration
51+
*
52+
* @return int
53+
*/
54+
private function getMinimumPasswordLength(): int
55+
{
56+
$configValue = $this->scopeConfig ?
57+
$this->scopeConfig->getValue(self::XML_PATH_MINIMUM_PASSWORD_LENGTH) : null;
58+
59+
return $configValue ? (int) $configValue : self::MIN_PASSWORD_LENGTH;
60+
}
61+
2962
/**
3063
* Adds validation rule for user first name, last name, username and email
3164
*
@@ -83,7 +116,7 @@ public function addPasswordRules(DataObject $validator)
83116
{
84117
$passwordNotEmpty = new NotEmpty();
85118
$passwordNotEmpty->setMessage(__('Password is required field.'), NotEmpty::IS_EMPTY);
86-
$minPassLength = self::MIN_PASSWORD_LENGTH;
119+
$minPassLength = $this->getMinimumPasswordLength();
87120
$passwordLength = new StringLength(['min' => $minPassLength, 'encoding' => 'UTF-8']);
88121
$passwordLength->setMessage(
89122
__('Your password must be at least %1 characters.', $minPassLength),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="AdminCompleteUserCreationWithRoleActionGroup">
11+
<annotations>
12+
<description>Complete user creation by setting role and saving</description>
13+
</annotations>
14+
<arguments>
15+
<argument name="role" defaultValue="roleDefaultAdministrator"/>
16+
<argument name="user" defaultValue="activeAdmin"/>
17+
</arguments>
18+
<!-- Assign role -->
19+
<click stepKey="clickUserRole" selector="{{AdminEditUserSection.userRoleTab}}"/>
20+
<waitForPageLoad stepKey="waitForUserRoleTabOpened"/>
21+
<click stepKey="chooseRole" selector="{{AdminEditUserSection.administratorRoleRadio(role.name)}}"/>
22+
<!-- Save user -->
23+
<click selector="{{AdminEditUserSection.saveButton}}" stepKey="clickSaveUser"/>
24+
<waitForPageLoad stepKey="waitForSaveUser"/>
25+
<see stepKey="seeSuccessMessage" userInput="You saved the user."/>
26+
</actionGroup>
27+
</actionGroups>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="AdminFillNewUserFormActionGroup">
11+
<annotations>
12+
<description>Navigate to new user page and fill form with basic user information without saving</description>
13+
</annotations>
14+
<arguments>
15+
<argument name="user" defaultValue="activeAdmin"/>
16+
</arguments>
17+
<amOnPage url="{{AdminNewUserPage.url}}" stepKey="navigateToNewUser"/>
18+
<waitForPageLoad stepKey="waitForUsersPage"/>
19+
<fillField selector="{{AdminEditUserSection.usernameTextField}}" userInput="{{user.username}}" stepKey="enterUserName"/>
20+
<fillField selector="{{AdminEditUserSection.firstNameTextField}}" userInput="{{user.firstname}}" stepKey="enterFirstName"/>
21+
<fillField selector="{{AdminEditUserSection.lastNameTextField}}" userInput="{{user.lastname}}" stepKey="enterLastName"/>
22+
<fillField selector="{{AdminEditUserSection.emailTextField}}" userInput="{{user.username}}@magento.com" stepKey="enterEmail"/>
23+
<fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="enterCurrentPassword"/>
24+
</actionGroup>
25+
</actionGroups>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
11+
<actionGroup name="AdminNavigateToSecurityConfigActionGroup">
12+
<annotations>
13+
<description>Navigate to System > Configuration > Advanced > Admin > Security and expand Security tab</description>
14+
</annotations>
15+
<amOnPage url="{{AdminSecurityConfigPage.url}}" stepKey="navigateToAdminSecurityConfig"/>
16+
<waitForPageLoad stepKey="waitForConfigPageLoad"/>
17+
<conditionalClick selector="{{AdminSecurityConfigSection.securityTab}}" dependentSelector="{{AdminSecurityConfigSection.securityExpanded}}" visible="false" stepKey="expandSecurityTab"/>
18+
<waitForElementVisible selector="{{AdminSecurityConfigSection.minimumPasswordLengthField}}" stepKey="waitForPasswordLengthField"/>
19+
</actionGroup>
20+
21+
</actionGroups>

0 commit comments

Comments
 (0)