From 7a67ac94dd9a925256f2c94b4ebc597f5e949206 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko Date: Mon, 3 Oct 2016 17:29:25 +0300 Subject: [PATCH] MAGETWO-59090: [Github] Admin can't reset password for more than one customer #5260 --- .../Adminhtml/Index/ResetPassword.php | 3 + .../Adminhtml/Index/ResetPasswordTest.php | 52 ++++++++++- .../Model/Plugin/AccountManagement.php | 12 ++- .../Magento/Security/etc/adminhtml/di.xml | 5 ++ .../Adminhtml/Index/ResetPasswordTest.php | 88 +++++++++++++++++++ 5 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 45d31dc0e2764..3c3fa73087e4a 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -6,6 +6,7 @@ namespace Magento\Customer\Controller\Adminhtml\Index; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Exception\SecurityViolationException; class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index { @@ -40,6 +41,8 @@ public function execute() $messages = $exception->getMessage(); } $this->_addSessionErrorMessages($messages); + } catch (SecurityViolationException $exception) { + $this->messageManager->addErrorMessage($exception->getMessage()); } catch (\Exception $exception) { $this->messageManager->addException( $exception, diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php index b7295fb9ceb4f..44444935973d4 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -143,7 +143,7 @@ protected function setUp() $this->messageManager = $this->getMockBuilder( \Magento\Framework\Message\Manager::class )->disableOriginalConstructor()->setMethods( - ['addSuccess', 'addMessage', 'addException'] + ['addSuccess', 'addMessage', 'addException', 'addErrorMessage'] )->getMock(); $this->resultRedirectFactoryMock = $this->getMockBuilder( @@ -332,6 +332,56 @@ public function testResetPasswordActionCoreException() $this->_testedObject->execute(); } + public function testResetPasswordActionSecurityException() + { + $securityText = 'Security violation.'; + $exception = new \Magento\Framework\Exception\SecurityViolationException(__($securityText)); + $customerId = 1; + $email = 'some@example.com'; + $websiteId = 1; + + $this->_request->expects( + $this->once() + )->method( + 'getParam' + )->with( + $this->equalTo('customer_id'), + $this->equalTo(0) + )->will( + $this->returnValue($customerId) + ); + $customer = $this->getMockForAbstractClass( + \Magento\Customer\Api\Data\CustomerInterface::class, + ['getId', 'getEmail', 'getWebsiteId'] + ); + $customer->expects($this->once())->method('getEmail')->will($this->returnValue($email)); + $customer->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId)); + $this->_customerRepositoryMock->expects( + $this->once() + )->method( + 'getById' + )->with( + $customerId + )->will( + $this->returnValue($customer) + ); + $this->_customerAccountManagementMock->expects( + $this->once() + )->method( + 'initiatePasswordReset' + )->willThrowException($exception); + + $this->messageManager->expects( + $this->once() + )->method( + 'addErrorMessage' + )->with( + $this->equalTo($exception->getMessage()) + ); + + $this->_testedObject->execute(); + } + public function testResetPasswordActionCoreExceptionWarn() { $warningText = 'Warning'; diff --git a/app/code/Magento/Security/Model/Plugin/AccountManagement.php b/app/code/Magento/Security/Model/Plugin/AccountManagement.php index ba1d4af5618b7..c65442ec40020 100644 --- a/app/code/Magento/Security/Model/Plugin/AccountManagement.php +++ b/app/code/Magento/Security/Model/Plugin/AccountManagement.php @@ -25,18 +25,26 @@ class AccountManagement */ protected $securityManager; + /** + * @var int + */ + protected $passwordRequestEvent; + /** * AccountManagement constructor. * * @param \Magento\Framework\App\RequestInterface $request * @param SecurityManager $securityManager + * @param int $passwordRequestEvent */ public function __construct( \Magento\Framework\App\RequestInterface $request, - \Magento\Security\Model\SecurityManager $securityManager + \Magento\Security\Model\SecurityManager $securityManager, + $passwordRequestEvent = PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ) { $this->request = $request; $this->securityManager = $securityManager; + $this->passwordRequestEvent = $passwordRequestEvent; } /** @@ -56,7 +64,7 @@ public function beforeInitiatePasswordReset( $websiteId = null ) { $this->securityManager->performSecurityCheck( - PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST, + $this->passwordRequestEvent, $email ); return [$email, $template, $websiteId]; diff --git a/app/code/Magento/Security/etc/adminhtml/di.xml b/app/code/Magento/Security/etc/adminhtml/di.xml index 4cbd3c3adc567..c134638d1266e 100644 --- a/app/code/Magento/Security/etc/adminhtml/di.xml +++ b/app/code/Magento/Security/etc/adminhtml/di.xml @@ -15,6 +15,11 @@ + + + Magento\Security\Model\PasswordResetRequestEvent::ADMIN_PASSWORD_RESET_REQUEST + + diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php new file mode 100644 index 0000000000000..f3571c17ddffe --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -0,0 +1,88 @@ +passwordResetRequestEventCreate( + \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST + ); + $this->getRequest()->setPostValue(['customer_id' => '1']); + $this->dispatch('backend/customer/index/resetPassword'); + $this->assertSessionMessages( + $this->equalTo(['The customer will receive an email with a link to reset password.']), + \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + ); + $this->assertRedirect($this->stringStartsWith($this->baseControllerUrl . 'edit')); + } + + /** + * Checks reset password functionality with default settings, customer and admin reset request events. + * + * @magentoConfigFixture current_store admin/security/limit_password_reset_requests_method 1 + * @magentoConfigFixture current_store admin/security/min_time_between_password_reset_requests 10 + * @magentoConfigFixture current_store contact/email/recipient_email hello@example.com + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testResetPasswordWithSecurityViolationException() + { + $this->passwordResetRequestEventCreate( + \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST + ); + $this->passwordResetRequestEventCreate( + \Magento\Security\Model\PasswordResetRequestEvent::ADMIN_PASSWORD_RESET_REQUEST + ); + $this->getRequest()->setPostValue(['customer_id' => '1']); + $this->dispatch('backend/customer/index/resetPassword'); + $this->assertSessionMessages( + $this->equalTo( + ['Too many password reset requests. Please wait and try again or contact hello@example.com.'] + ), + \Magento\Framework\Message\MessageInterface::TYPE_ERROR + ); + $this->assertRedirect($this->stringStartsWith($this->baseControllerUrl . 'edit')); + } + + /** + * Create and save reset request event with provided request type. + * + * @param int $requestType + */ + private function passwordResetRequestEventCreate($requestType) + { + $passwordResetRequestEventFactory = $this->_objectManager->get( + \Magento\Security\Model\PasswordResetRequestEventFactory::class + ); + $passwordResetRequestEvent = $passwordResetRequestEventFactory->create(); + $passwordResetRequestEvent + ->setRequestType($requestType) + ->setAccountReference('customer@example.com') + ->setCreatedAt(strtotime('now')) + ->setIp('3232249856') + ->save(); + } +}