123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- declare(strict_types=1);
- namespace Magento\Backend\App\Request;
- use Magento\Backend\App\AbstractAction;
- use Magento\Backend\App\Action\Context;
- use Magento\Backend\Model\Auth;
- use Magento\Framework\App\ActionInterface;
- use Magento\Framework\App\CsrfAwareActionInterface;
- use Magento\Framework\App\Request\InvalidRequestException;
- use Magento\Framework\App\RequestInterface;
- use Magento\Framework\App\ResponseInterface;
- use Magento\Framework\Controller\ResultInterface;
- use Magento\Framework\Data\Form\FormKey;
- use Magento\Framework\Exception\NotFoundException;
- use Magento\Framework\Phrase;
- use Magento\TestFramework\Request;
- use Magento\TestFramework\Response;
- use PHPUnit\Framework\TestCase;
- use Magento\TestFramework\Helper\Bootstrap;
- use Magento\TestFramework\Bootstrap as TestBootstrap;
- use Magento\Framework\App\Request\Http as HttpRequest;
- use Magento\Framework\App\Response\Http as HttpResponse;
- use Zend\Stdlib\Parameters;
- use Magento\Backend\Model\UrlInterface as BackendUrl;
- use Magento\Framework\App\Response\HttpFactory as HttpResponseFactory;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class BackendValidatorTest extends TestCase
- {
- private const AWARE_VALIDATION_PARAM = 'test_param';
- private const AWARE_LOCATION_VALUE = 'test1';
- private const CSRF_AWARE_MESSAGE = 'csrf_aware';
- /**
- * @var ActionInterface
- */
- private $mockUnawareAction;
- /**
- * @var AbstractAction
- */
- private $mockAwareAction;
- /**
- * @var BackendValidator
- */
- private $validator;
- /**
- * @var Request
- */
- private $request;
- /**
- * @var FormKey
- */
- private $formKey;
- /**
- * @var BackendUrl
- */
- private $url;
- /**
- * @var Auth
- */
- private $auth;
- /**
- * @var CsrfAwareActionInterface
- */
- private $mockCsrfAwareAction;
- /**
- * @var HttpResponseFactory
- */
- private $httpResponseFactory;
- /**
- * @return ActionInterface
- */
- private function createUnawareAction(): ActionInterface
- {
- return new class implements ActionInterface {
- /**
- * @inheritDoc
- */
- public function execute()
- {
- throw new NotFoundException(new Phrase('Not implemented'));
- }
- };
- }
- /**
- * @return AbstractAction
- */
- private function createAwareAction(): AbstractAction
- {
- $l = self::AWARE_LOCATION_VALUE;
- $p = self::AWARE_VALIDATION_PARAM;
- return new class($l, $p) extends AbstractAction{
- /**
- * @var string
- */
- private $locationValue;
- /**
- * @var string
- */
- private $param;
- /**
- * @param string $locationValue
- * @param string $param
- */
- public function __construct(
- string $locationValue,
- string $param
- ) {
- parent::__construct(
- Bootstrap::getObjectManager()->get(Context::class)
- );
- $this->locationValue= $locationValue;
- $this->param = $param;
- }
- /**
- * @inheritDoc
- */
- public function execute()
- {
- throw new NotFoundException(new Phrase('Not implemented'));
- }
- /**
- * @inheritDoc
- */
- public function _processUrlKeys()
- {
- if ($this->_request->getParam($this->param)) {
- return true;
- } else {
- /** @var Response $response */
- $response = $this->_response;
- $response->setHeader('Location', $this->locationValue);
- return false;
- }
- }
- };
- }
- /**
- * @return CsrfAwareActionInterface
- */
- private function createCsrfAwareAction(): CsrfAwareActionInterface
- {
- $r = Bootstrap::getObjectManager()
- ->get(ResponseInterface::class);
- $m = self::CSRF_AWARE_MESSAGE;
- return new class ($r, $m) implements CsrfAwareActionInterface {
- /**
- * @var ResponseInterface
- */
- private $response;
- /**
- * @var string
- */
- private $message;
- /**
- * @param ResponseInterface $response
- * @param string $message
- */
- public function __construct(
- ResponseInterface $response,
- string $message
- ) {
- $this->response = $response;
- $this->message = $message;
- }
- /**
- * @inheritDoc
- */
- public function execute()
- {
- return $this->response;
- }
- /**
- * @inheritDoc
- */
- public function createCsrfValidationException(
- RequestInterface $request
- ): ?InvalidRequestException {
- return new InvalidRequestException(
- $this->response,
- [new Phrase($this->message)]
- );
- }
- /**
- * @inheritDoc
- */
- public function validateForCsrf(RequestInterface $request): ?bool
- {
- return false;
- }
- };
- }
- /**
- * @inheritDoc
- */
- protected function setUp()
- {
- $objectManager = Bootstrap::getObjectManager();
- $this->request = $objectManager->get(RequestInterface::class);
- $this->validator = $objectManager->get(BackendValidator::class);
- $this->mockUnawareAction = $this->createUnawareAction();
- $this->mockAwareAction = $this->createAwareAction();
- $this->formKey = $objectManager->get(FormKey::class);
- $this->url = $objectManager->get(BackendUrl::class);
- $this->auth = $objectManager->get(Auth::class);
- $this->mockCsrfAwareAction = $this->createCsrfAwareAction();
- $this->httpResponseFactory = $objectManager->get(
- HttpResponseFactory::class
- );
- }
- /**
- * @magentoConfigFixture admin/security/use_form_key 1
- * @magentoAppArea adminhtml
- */
- public function testValidateWithValidKey()
- {
- $this->request->setMethod(HttpRequest::METHOD_GET);
- $this->auth->login(
- TestBootstrap::ADMIN_NAME,
- TestBootstrap::ADMIN_PASSWORD
- );
- $this->request->setParams([
- BackendUrl::SECRET_KEY_PARAM_NAME => $this->url->getSecretKey(),
- ]);
- $this->validator->validate(
- $this->request,
- $this->mockUnawareAction
- );
- }
- /**
- * @expectedException \Magento\Framework\App\Request\InvalidRequestException
- *
- * @magentoConfigFixture admin/security/use_form_key 1
- * @magentoAppArea adminhtml
- */
- public function testValidateWithInvalidKey()
- {
- $invalidKey = $this->url->getSecretKey() .'Invalid';
- $this->request->setParams([
- BackendUrl::SECRET_KEY_PARAM_NAME => $invalidKey,
- ]);
- $this->request->setMethod(HttpRequest::METHOD_GET);
- $this->auth->login(
- TestBootstrap::ADMIN_NAME,
- TestBootstrap::ADMIN_PASSWORD
- );
- $this->validator->validate(
- $this->request,
- $this->mockUnawareAction
- );
- }
- /**
- * @expectedException \Magento\Framework\App\Request\InvalidRequestException
- *
- * @magentoConfigFixture admin/security/use_form_key 0
- * @magentoAppArea adminhtml
- */
- public function testValidateWithInvalidFormKey()
- {
- $this->request->setPost(
- new Parameters(['form_key' => $this->formKey->getFormKey() .'1'])
- );
- $this->request->setMethod(HttpRequest::METHOD_POST);
- $this->validator->validate(
- $this->request,
- $this->mockUnawareAction
- );
- }
- /**
- * @magentoConfigFixture admin/security/use_form_key 0
- * @magentoAppArea adminhtml
- */
- public function testValidateInvalidWithAwareAction()
- {
- $this->request->setParams([self::AWARE_VALIDATION_PARAM => '']);
- /** @var InvalidRequestException|null $caught */
- $caught = null;
- try {
- $this->validator->validate(
- $this->request,
- $this->mockAwareAction
- );
- } catch (InvalidRequestException $exception) {
- $caught = $exception;
- }
- $this->assertNotNull($caught);
- /** @var Response $response */
- $response = $caught->getReplaceResult();
- $this->assertInstanceOf(Response::class, $response);
- $this->assertEquals(
- self::AWARE_LOCATION_VALUE,
- $response->getHeader('Location')->getFieldValue()
- );
- $this->assertNull($caught->getMessages());
- }
- /**
- * @magentoAppArea adminhtml
- */
- public function testValidateValidWithAwareAction()
- {
- $this->request->setParams(
- [self::AWARE_VALIDATION_PARAM => '1']
- );
- $this->validator->validate(
- $this->request,
- $this->mockAwareAction
- );
- }
- /**
- * @magentoConfigFixture admin/security/use_form_key 1
- * @magentoAppArea adminhtml
- */
- public function testValidateWithCsrfAwareAction()
- {
- //Setting up request that would be valid for default validation.
- $this->request->setMethod(HttpRequest::METHOD_GET);
- $this->auth->login(
- TestBootstrap::ADMIN_NAME,
- TestBootstrap::ADMIN_PASSWORD
- );
- $this->request->setParams([
- BackendUrl::SECRET_KEY_PARAM_NAME => $this->url->getSecretKey(),
- ]);
- /** @var InvalidRequestException|null $caught */
- $caught = null;
- try {
- $this->validator->validate(
- $this->request,
- $this->mockCsrfAwareAction
- );
- } catch (InvalidRequestException $exception) {
- $caught = $exception;
- }
- //Checking that custom validation was called and invalidated
- //valid request.
- $this->assertNotNull($caught);
- $this->assertCount(1, $caught->getMessages());
- $this->assertEquals(
- self::CSRF_AWARE_MESSAGE,
- $caught->getMessages()[0]->getText()
- );
- }
- public function testInvalidAjaxRequest()
- {
- //Setting up AJAX request with invalid secret key.
- $this->request->setMethod(HttpRequest::METHOD_GET);
- $this->auth->login(
- TestBootstrap::ADMIN_NAME,
- TestBootstrap::ADMIN_PASSWORD
- );
- $this->request->setParams([
- BackendUrl::SECRET_KEY_PARAM_NAME => 'invalid',
- 'isAjax' => '1'
- ]);
- /** @var InvalidRequestException|null $caught */
- $caught = null;
- try {
- $this->validator->validate(
- $this->request,
- $this->mockUnawareAction
- );
- } catch (InvalidRequestException $exception) {
- $caught = $exception;
- }
- $this->assertNotNull($caught);
- $this->assertInstanceOf(
- ResultInterface::class,
- $caught->getReplaceResult()
- );
- /** @var ResultInterface $result */
- $result = $caught->getReplaceResult();
- /** @var HttpResponse $response */
- $response = $this->httpResponseFactory->create();
- $result->renderResult($response);
- $this->assertEmpty($response->getBody());
- $this->assertEquals(401, $response->getHttpResponseCode());
- }
- }
|