Skip to content

Commit b2a2476

Browse files
[Magento Community Engineering] Community Contributions - 2.4-develop
- merged latest code from mainline branch
2 parents 5d86c5d + 45a3970 commit b2a2476

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2312
-5
lines changed

app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@
3535
<waitForPageLoad time="30" stepKey="wait2"/>
3636
<seeInField selector="{{AdminEditUserSection.usernameTextField}}" userInput="$$noReportUser.username$$" stepKey="seeUsernameInField"/>
3737
<fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="fillCurrentPassword"/>
38-
<click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRoleTab"/>
38+
<scrollToTopOfPage stepKey="scrollToTopOfPage"/>
3939

40+
<click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRoleTab"/>
4041
<fillField selector="{{AdminEditUserSection.roleNameFilterTextField}}" userInput="$$noReportUserRole.rolename$$" stepKey="fillRoleNameSearch"/>
4142
<click selector="{{AdminEditUserSection.searchButton}}" stepKey="clickSearchButtonUserRole"/>
4243
<waitForPageLoad time="10" stepKey="wait3"/>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Security\Api\Data;
10+
11+
use \Magento\Security\Api\Data\UserExpirationExtensionInterface;
12+
13+
/**
14+
* Interface UserExpirationInterface to be used as a DTO for expires_at property on User model.
15+
*/
16+
interface UserExpirationInterface extends \Magento\Framework\Api\ExtensibleDataInterface
17+
{
18+
19+
public const EXPIRES_AT = 'expires_at';
20+
21+
public const USER_ID = 'user_id';
22+
23+
/**
24+
* `expires_at` getter.
25+
*
26+
* @return string
27+
*/
28+
public function getExpiresAt();
29+
30+
/**
31+
* `expires_at` setter.
32+
*
33+
* @param string $expiresAt
34+
* @return $this
35+
*/
36+
public function setExpiresAt($expiresAt);
37+
38+
/**
39+
* `user_id` getter.
40+
*
41+
* @return string
42+
*/
43+
public function getUserId();
44+
45+
/**
46+
* `user_id` setter.
47+
*
48+
* @param string $userId
49+
* @return $this
50+
*/
51+
public function setUserId($userId);
52+
53+
/**
54+
* Retrieve existing extension attributes object or create a new one.
55+
*
56+
* @return \Magento\Security\Api\Data\UserExpirationExtensionInterface|null
57+
*/
58+
public function getExtensionAttributes();
59+
60+
/**
61+
* Set an extension attributes object.
62+
*
63+
* @param \Magento\Security\Api\Data\UserExpirationExtensionInterface $extensionAttributes
64+
* @return $this
65+
*/
66+
public function setExtensionAttributes(UserExpirationExtensionInterface $extensionAttributes);
67+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Security\Model\Plugin;
9+
10+
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
11+
use Magento\Security\Model\ResourceModel\UserExpiration;
12+
use Magento\Security\Model\UserExpirationFactory;
13+
14+
/**
15+
* Add the `expires_at` form field to the User main form.
16+
*/
17+
class AdminUserForm
18+
{
19+
20+
/**
21+
* @var TimezoneInterface
22+
*/
23+
private $localeDate;
24+
25+
/**
26+
* @var UserExpiration
27+
*/
28+
private $userExpirationResource;
29+
30+
/**
31+
* @var UserExpirationFactory
32+
*/
33+
private $userExpirationFactory;
34+
35+
/**
36+
* UserForm constructor.
37+
*
38+
* @param TimezoneInterface $localeDate
39+
* @param UserExpirationFactory $userExpirationFactory
40+
* @param UserExpiration $userExpirationResource
41+
*/
42+
public function __construct(
43+
TimezoneInterface $localeDate,
44+
UserExpirationFactory $userExpirationFactory,
45+
UserExpiration $userExpirationResource
46+
) {
47+
$this->localeDate = $localeDate;
48+
$this->userExpirationResource = $userExpirationResource;
49+
$this->userExpirationFactory = $userExpirationFactory;
50+
}
51+
52+
/**
53+
* Add the `expires_at` field to the admin user edit form.
54+
*
55+
* @param \Magento\User\Block\User\Edit\Tab\Main $subject
56+
* @param \Closure $proceed
57+
* @return mixed
58+
*/
59+
public function aroundGetFormHtml(
60+
\Magento\User\Block\User\Edit\Tab\Main $subject,
61+
\Closure $proceed
62+
) {
63+
/** @var \Magento\Framework\Data\Form $form */
64+
$form = $subject->getForm();
65+
if (is_object($form)) {
66+
$dateFormat = $this->localeDate->getDateFormat(
67+
\IntlDateFormatter::MEDIUM
68+
);
69+
$timeFormat = $this->localeDate->getTimeFormat(
70+
\IntlDateFormatter::MEDIUM
71+
);
72+
$fieldset = $form->getElement('base_fieldset');
73+
$userIdField = $fieldset->getElements()->searchById('user_id');
74+
$userExpirationValue = null;
75+
if ($userIdField) {
76+
$userId = $userIdField->getValue();
77+
$userExpirationValue = $this->loadUserExpirationByUserId($userId);
78+
}
79+
$fieldset->addField(
80+
'expires_at',
81+
'date',
82+
[
83+
'name' => 'expires_at',
84+
'label' => __('Expiration Date'),
85+
'title' => __('Expiration Date'),
86+
'date_format' => $dateFormat,
87+
'time_format' => $timeFormat,
88+
'class' => 'validate-date',
89+
'value' => $userExpirationValue,
90+
]
91+
);
92+
93+
$subject->setForm($form);
94+
}
95+
96+
return $proceed();
97+
}
98+
99+
/**
100+
* Loads a user expiration record by user ID.
101+
*
102+
* @param string $userId
103+
* @return string
104+
*/
105+
private function loadUserExpirationByUserId($userId)
106+
{
107+
/** @var \Magento\Security\Model\UserExpiration $userExpiration */
108+
$userExpiration = $this->userExpirationFactory->create();
109+
$this->userExpirationResource->load($userExpiration, $userId);
110+
return $userExpiration->getExpiresAt();
111+
}
112+
}

app/code/Magento/Security/Model/Plugin/AuthSession.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Backend\Model\Auth\Session;
99
use Magento\Security\Model\AdminSessionsManager;
10+
use Magento\Security\Model\UserExpirationManager;
1011

1112
/**
1213
* Magento\Backend\Model\Auth\Session decorator
@@ -33,22 +34,32 @@ class AuthSession
3334
*/
3435
protected $securityCookie;
3536

37+
/**
38+
* @var UserExpirationManager
39+
*/
40+
private $userExpirationManager;
41+
3642
/**
3743
* @param \Magento\Framework\App\RequestInterface $request
3844
* @param \Magento\Framework\Message\ManagerInterface $messageManager
3945
* @param AdminSessionsManager $sessionsManager
4046
* @param \Magento\Security\Model\SecurityCookie $securityCookie
47+
* @param UserExpirationManager|null $userExpirationManager
4148
*/
4249
public function __construct(
4350
\Magento\Framework\App\RequestInterface $request,
4451
\Magento\Framework\Message\ManagerInterface $messageManager,
4552
AdminSessionsManager $sessionsManager,
46-
\Magento\Security\Model\SecurityCookie $securityCookie
53+
\Magento\Security\Model\SecurityCookie $securityCookie,
54+
\Magento\Security\Model\UserExpirationManager $userExpirationManager = null
4755
) {
4856
$this->request = $request;
4957
$this->messageManager = $messageManager;
5058
$this->sessionsManager = $sessionsManager;
5159
$this->securityCookie = $securityCookie;
60+
$this->userExpirationManager = $userExpirationManager ?:
61+
\Magento\Framework\App\ObjectManager::getInstance()
62+
->get(\Magento\Security\Model\UserExpirationManager::class);
5263
}
5364

5465
/**
@@ -64,6 +75,11 @@ public function aroundProlong(Session $session, \Closure $proceed)
6475
$session->destroy();
6576
$this->addUserLogoutNotification();
6677
return null;
78+
} elseif ($this->userExpirationManager->isUserExpired($session->getUser()->getId())) {
79+
$this->userExpirationManager->deactivateExpiredUsersById([$session->getUser()->getId()]);
80+
$session->destroy();
81+
$this->addUserLogoutNotification();
82+
return null;
6783
}
6884
$result = $proceed();
6985
$this->sessionsManager->processProlong();
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Security\Model\Plugin;
9+
10+
use Magento\Security\Model\UserExpiration\Validator;
11+
12+
/**
13+
* \Magento\User\Model\UserValidationRules decorator
14+
*/
15+
class UserValidationRules
16+
{
17+
/**@var Validator */
18+
private $validator;
19+
20+
/**
21+
* UserValidationRules constructor.
22+
*
23+
* @param Validator $validator
24+
*/
25+
public function __construct(Validator $validator)
26+
{
27+
$this->validator = $validator;
28+
}
29+
30+
/**
31+
* Add the Expires At validator to user validation rules.
32+
*
33+
* @param \Magento\User\Model\UserValidationRules $userValidationRules
34+
* @param \Magento\Framework\Validator\DataObject $result
35+
* @return \Magento\Framework\Validator\DataObject
36+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
37+
*/
38+
public function afterAddUserInfoRules(\Magento\User\Model\UserValidationRules $userValidationRules, $result)
39+
{
40+
return $result->addRule($this->validator, 'expires_at');
41+
}
42+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Security\Model\ResourceModel;
9+
10+
/**
11+
* Admin User Expiration resource model
12+
*/
13+
class UserExpiration extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
14+
{
15+
16+
/**
17+
* Flag that notifies whether Primary key of table is auto-incremented
18+
*
19+
* @var bool
20+
*/
21+
protected $_isPkAutoIncrement = false;
22+
23+
/**
24+
* @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
25+
*/
26+
private $timezone;
27+
28+
/**
29+
* UserExpiration constructor.
30+
*
31+
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
32+
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone
33+
* @param string $connectionName
34+
*/
35+
public function __construct(
36+
\Magento\Framework\Model\ResourceModel\Db\Context $context,
37+
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone,
38+
?string $connectionName = null
39+
) {
40+
parent::__construct($context, $connectionName);
41+
$this->timezone = $timezone;
42+
}
43+
44+
/**
45+
* Define main table
46+
*
47+
* @return void
48+
*/
49+
protected function _construct()
50+
{
51+
$this->_init('admin_user_expiration', 'user_id');
52+
}
53+
54+
/**
55+
* Convert to UTC time.
56+
*
57+
* @param \Magento\Framework\Model\AbstractModel $userExpiration
58+
* @return $this
59+
* @throws \Magento\Framework\Exception\LocalizedException
60+
*/
61+
protected function _beforeSave(\Magento\Framework\Model\AbstractModel $userExpiration)
62+
{
63+
/** @var $userExpiration \Magento\Security\Model\UserExpiration */
64+
$expiresAt = $userExpiration->getExpiresAt();
65+
$utcValue = $this->timezone->convertConfigTimeToUtc($expiresAt);
66+
$userExpiration->setExpiresAt($utcValue);
67+
68+
return $this;
69+
}
70+
71+
/**
72+
* Convert to store time.
73+
*
74+
* @param \Magento\Framework\Model\AbstractModel $userExpiration
75+
* @return $this|\Magento\Framework\Model\ResourceModel\Db\AbstractDb
76+
* @throws \Exception
77+
*/
78+
protected function _afterLoad(\Magento\Framework\Model\AbstractModel $userExpiration)
79+
{
80+
/** @var $userExpiration \Magento\Security\Model\UserExpiration */
81+
if ($userExpiration->getExpiresAt()) {
82+
$storeValue = $this->timezone->date($userExpiration->getExpiresAt());
83+
$userExpiration->setExpiresAt($storeValue->format('Y-m-d H:i:s'));
84+
}
85+
86+
return $this;
87+
}
88+
}

0 commit comments

Comments
 (0)