Skip to content

Commit

Permalink
ENGCOM-6014: [WIP] Short-term admin accounts #22833 #22837
Browse files Browse the repository at this point in the history
  • Loading branch information
VladimirZaets authored Mar 26, 2020
2 parents f3df323 + 07048f6 commit d812b02
Show file tree
Hide file tree
Showing 42 changed files with 2,312 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
<waitForPageLoad time="30" stepKey="wait2"/>
<seeInField selector="{{AdminEditUserSection.usernameTextField}}" userInput="$$noReportUser.username$$" stepKey="seeUsernameInField"/>
<fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="fillCurrentPassword"/>
<click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRoleTab"/>
<scrollToTopOfPage stepKey="scrollToTopOfPage"/>

<click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRoleTab"/>
<fillField selector="{{AdminEditUserSection.roleNameFilterTextField}}" userInput="$$noReportUserRole.rolename$$" stepKey="fillRoleNameSearch"/>
<click selector="{{AdminEditUserSection.searchButton}}" stepKey="clickSearchButtonUserRole"/>
<waitForPageLoad time="10" stepKey="wait3"/>
Expand Down
67 changes: 67 additions & 0 deletions app/code/Magento/Security/Api/Data/UserExpirationInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\Security\Api\Data;

use \Magento\Security\Api\Data\UserExpirationExtensionInterface;

/**
* Interface UserExpirationInterface to be used as a DTO for expires_at property on User model.
*/
interface UserExpirationInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{

public const EXPIRES_AT = 'expires_at';

public const USER_ID = 'user_id';

/**
* `expires_at` getter.
*
* @return string
*/
public function getExpiresAt();

/**
* `expires_at` setter.
*
* @param string $expiresAt
* @return $this
*/
public function setExpiresAt($expiresAt);

/**
* `user_id` getter.
*
* @return string
*/
public function getUserId();

/**
* `user_id` setter.
*
* @param string $userId
* @return $this
*/
public function setUserId($userId);

/**
* Retrieve existing extension attributes object or create a new one.
*
* @return \Magento\Security\Api\Data\UserExpirationExtensionInterface|null
*/
public function getExtensionAttributes();

/**
* Set an extension attributes object.
*
* @param \Magento\Security\Api\Data\UserExpirationExtensionInterface $extensionAttributes
* @return $this
*/
public function setExtensionAttributes(UserExpirationExtensionInterface $extensionAttributes);
}
112 changes: 112 additions & 0 deletions app/code/Magento/Security/Model/Plugin/AdminUserForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Security\Model\Plugin;

use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
use Magento\Security\Model\ResourceModel\UserExpiration;
use Magento\Security\Model\UserExpirationFactory;

/**
* Add the `expires_at` form field to the User main form.
*/
class AdminUserForm
{

/**
* @var TimezoneInterface
*/
private $localeDate;

/**
* @var UserExpiration
*/
private $userExpirationResource;

/**
* @var UserExpirationFactory
*/
private $userExpirationFactory;

/**
* UserForm constructor.
*
* @param TimezoneInterface $localeDate
* @param UserExpirationFactory $userExpirationFactory
* @param UserExpiration $userExpirationResource
*/
public function __construct(
TimezoneInterface $localeDate,
UserExpirationFactory $userExpirationFactory,
UserExpiration $userExpirationResource
) {
$this->localeDate = $localeDate;
$this->userExpirationResource = $userExpirationResource;
$this->userExpirationFactory = $userExpirationFactory;
}

/**
* Add the `expires_at` field to the admin user edit form.
*
* @param \Magento\User\Block\User\Edit\Tab\Main $subject
* @param \Closure $proceed
* @return mixed
*/
public function aroundGetFormHtml(
\Magento\User\Block\User\Edit\Tab\Main $subject,
\Closure $proceed
) {
/** @var \Magento\Framework\Data\Form $form */
$form = $subject->getForm();
if (is_object($form)) {
$dateFormat = $this->localeDate->getDateFormat(
\IntlDateFormatter::MEDIUM
);
$timeFormat = $this->localeDate->getTimeFormat(
\IntlDateFormatter::MEDIUM
);
$fieldset = $form->getElement('base_fieldset');
$userIdField = $fieldset->getElements()->searchById('user_id');
$userExpirationValue = null;
if ($userIdField) {
$userId = $userIdField->getValue();
$userExpirationValue = $this->loadUserExpirationByUserId($userId);
}
$fieldset->addField(
'expires_at',
'date',
[
'name' => 'expires_at',
'label' => __('Expiration Date'),
'title' => __('Expiration Date'),
'date_format' => $dateFormat,
'time_format' => $timeFormat,
'class' => 'validate-date',
'value' => $userExpirationValue,
]
);

$subject->setForm($form);
}

return $proceed();
}

/**
* Loads a user expiration record by user ID.
*
* @param string $userId
* @return string
*/
private function loadUserExpirationByUserId($userId)
{
/** @var \Magento\Security\Model\UserExpiration $userExpiration */
$userExpiration = $this->userExpirationFactory->create();
$this->userExpirationResource->load($userExpiration, $userId);
return $userExpiration->getExpiresAt();
}
}
18 changes: 17 additions & 1 deletion app/code/Magento/Security/Model/Plugin/AuthSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use Magento\Backend\Model\Auth\Session;
use Magento\Security\Model\AdminSessionsManager;
use Magento\Security\Model\UserExpirationManager;

/**
* Magento\Backend\Model\Auth\Session decorator
Expand All @@ -33,22 +34,32 @@ class AuthSession
*/
protected $securityCookie;

/**
* @var UserExpirationManager
*/
private $userExpirationManager;

/**
* @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Framework\Message\ManagerInterface $messageManager
* @param AdminSessionsManager $sessionsManager
* @param \Magento\Security\Model\SecurityCookie $securityCookie
* @param UserExpirationManager|null $userExpirationManager
*/
public function __construct(
\Magento\Framework\App\RequestInterface $request,
\Magento\Framework\Message\ManagerInterface $messageManager,
AdminSessionsManager $sessionsManager,
\Magento\Security\Model\SecurityCookie $securityCookie
\Magento\Security\Model\SecurityCookie $securityCookie,
\Magento\Security\Model\UserExpirationManager $userExpirationManager = null
) {
$this->request = $request;
$this->messageManager = $messageManager;
$this->sessionsManager = $sessionsManager;
$this->securityCookie = $securityCookie;
$this->userExpirationManager = $userExpirationManager ?:
\Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Security\Model\UserExpirationManager::class);
}

/**
Expand All @@ -64,6 +75,11 @@ public function aroundProlong(Session $session, \Closure $proceed)
$session->destroy();
$this->addUserLogoutNotification();
return null;
} elseif ($this->userExpirationManager->isUserExpired($session->getUser()->getId())) {
$this->userExpirationManager->deactivateExpiredUsersById([$session->getUser()->getId()]);
$session->destroy();
$this->addUserLogoutNotification();
return null;
}
$result = $proceed();
$this->sessionsManager->processProlong();
Expand Down
42 changes: 42 additions & 0 deletions app/code/Magento/Security/Model/Plugin/UserValidationRules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Security\Model\Plugin;

use Magento\Security\Model\UserExpiration\Validator;

/**
* \Magento\User\Model\UserValidationRules decorator
*/
class UserValidationRules
{
/**@var Validator */
private $validator;

/**
* UserValidationRules constructor.
*
* @param Validator $validator
*/
public function __construct(Validator $validator)
{
$this->validator = $validator;
}

/**
* Add the Expires At validator to user validation rules.
*
* @param \Magento\User\Model\UserValidationRules $userValidationRules
* @param \Magento\Framework\Validator\DataObject $result
* @return \Magento\Framework\Validator\DataObject
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterAddUserInfoRules(\Magento\User\Model\UserValidationRules $userValidationRules, $result)
{
return $result->addRule($this->validator, 'expires_at');
}
}
88 changes: 88 additions & 0 deletions app/code/Magento/Security/Model/ResourceModel/UserExpiration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Security\Model\ResourceModel;

/**
* Admin User Expiration resource model
*/
class UserExpiration extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{

/**
* Flag that notifies whether Primary key of table is auto-incremented
*
* @var bool
*/
protected $_isPkAutoIncrement = false;

/**
* @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
*/
private $timezone;

/**
* UserExpiration constructor.
*
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone
* @param string $connectionName
*/
public function __construct(
\Magento\Framework\Model\ResourceModel\Db\Context $context,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone,
?string $connectionName = null
) {
parent::__construct($context, $connectionName);
$this->timezone = $timezone;
}

/**
* Define main table
*
* @return void
*/
protected function _construct()
{
$this->_init('admin_user_expiration', 'user_id');
}

/**
* Convert to UTC time.
*
* @param \Magento\Framework\Model\AbstractModel $userExpiration
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _beforeSave(\Magento\Framework\Model\AbstractModel $userExpiration)
{
/** @var $userExpiration \Magento\Security\Model\UserExpiration */
$expiresAt = $userExpiration->getExpiresAt();
$utcValue = $this->timezone->convertConfigTimeToUtc($expiresAt);
$userExpiration->setExpiresAt($utcValue);

return $this;
}

/**
* Convert to store time.
*
* @param \Magento\Framework\Model\AbstractModel $userExpiration
* @return $this|\Magento\Framework\Model\ResourceModel\Db\AbstractDb
* @throws \Exception
*/
protected function _afterLoad(\Magento\Framework\Model\AbstractModel $userExpiration)
{
/** @var $userExpiration \Magento\Security\Model\UserExpiration */
if ($userExpiration->getExpiresAt()) {
$storeValue = $this->timezone->date($userExpiration->getExpiresAt());
$userExpiration->setExpiresAt($storeValue->format('Y-m-d H:i:s'));
}

return $this;
}
}
Loading

0 comments on commit d812b02

Please sign in to comment.