Skip to content

Commit cf71a09

Browse files
committed
Merge branch 'AC-1450' of github.com:magento-cia/magento2ce into cia-2.4.4-develop-bugfixes-04112021
2 parents 2a43df0 + a6e72dc commit cf71a09

File tree

7 files changed

+244
-11
lines changed

7 files changed

+244
-11
lines changed

app/code/Magento/Swagger/Controller/Index/Index.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
use Magento\Framework\App\Action\Action;
1111
use Magento\Framework\App\Action\Context;
1212
use Magento\Framework\App\Action\HttpGetActionInterface;
13+
use Magento\Framework\App\ObjectManager;
14+
use Magento\Framework\App\RequestInterface;
15+
use Magento\Framework\Exception\NotFoundException;
1316
use Magento\Framework\View\Page\Config as PageConfig;
1417
use Magento\Framework\View\Result\PageFactory as PageFactory;
18+
use Magento\Swagger\Model\Config;
1519

1620
class Index extends Action implements HttpGetActionInterface
1721
{
@@ -25,16 +29,28 @@ class Index extends Action implements HttpGetActionInterface
2529
*/
2630
private $pageFactory;
2731

32+
/**
33+
* @var Config
34+
*/
35+
private $config;
36+
2837
/**
2938
* @param Context $context
3039
* @param PageConfig $pageConfig
3140
* @param PageFactory $pageFactory
41+
* @param Config|null $config
3242
*/
33-
public function __construct(Context $context, PageConfig $pageConfig, PageFactory $pageFactory)
34-
{
43+
public function __construct(
44+
Context $context,
45+
PageConfig $pageConfig,
46+
PageFactory $pageFactory,
47+
?Config $config = null
48+
) {
3549
parent::__construct($context);
3650
$this->pageConfig = $pageConfig;
3751
$this->pageFactory = $pageFactory;
52+
$this->config = $config ?? ObjectManager::getInstance()
53+
->get(Config::class);
3854
}
3955

4056
/**
@@ -45,4 +61,16 @@ public function execute()
4561
$this->pageConfig->addBodyClass('swagger-section');
4662
return $this->pageFactory->create();
4763
}
64+
65+
/**
66+
* @inheritDoc
67+
*/
68+
public function dispatch(RequestInterface $request)
69+
{
70+
if (!$this->config->isEnabled()) {
71+
throw new NotFoundException(__('Page not found.'));
72+
}
73+
74+
return parent::dispatch($request);
75+
}
4876
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\Swagger\Model;
10+
11+
use Magento\Framework\App\State;
12+
13+
/**
14+
* Configuration for Swagger
15+
*/
16+
class Config
17+
{
18+
/**
19+
* @var State
20+
*/
21+
private $state;
22+
23+
/**
24+
* @var bool
25+
*/
26+
private $enabledInProduction;
27+
28+
/**
29+
* @param State $state
30+
* @param bool $enabledInProduction
31+
*/
32+
public function __construct(State $state, bool $enabledInProduction = false)
33+
{
34+
$this->state = $state;
35+
$this->enabledInProduction = $enabledInProduction;
36+
}
37+
38+
/**
39+
* Is Swagger enabled
40+
*
41+
* @return bool
42+
*/
43+
public function isEnabled(): bool
44+
{
45+
return $this->state->getMode() === State::MODE_DEVELOPER || $this->enabledInProduction;
46+
}
47+
}

app/code/Magento/Swagger/Test/Mftf/Test/StorefrontMagentoApiSwaggerActionsExistTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<title value="Authorize and logout on Swagger page"/>
1414
<description value="Authorize and logout on Swagger page use API Key"/>
1515
<severity value="CRITICAL"/>
16+
<group value="developer_mode_only"/>
1617
</annotations>
1718
<before>
1819
<getOTP stepKey="getOtpCode"/>

app/code/Magento/Swagger/Test/Unit/Controller/Index/IndexTest.php

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,105 @@
99
namespace Magento\Swagger\Test\Unit\Controller\Index;
1010

1111
use Magento\Framework\App\Action\Context;
12+
use Magento\Framework\App\Request\Http;
13+
use Magento\Framework\Exception\NotFoundException;
1214
use Magento\Framework\View\Page\Config as PageConfig;
1315
use Magento\Framework\View\Result\PageFactory;
1416
use Magento\Swagger\Controller\Index\Index;
17+
use Magento\Swagger\Model\Config;
1518
use PHPUnit\Framework\MockObject\MockObject;
1619
use PHPUnit\Framework\TestCase;
1720

1821
class IndexTest extends TestCase
1922
{
20-
public function testExecute()
23+
/**
24+
* @var PageConfig|MockObject
25+
*/
26+
private $pageConfigMock;
27+
28+
/**
29+
* @var PageFactory|MockObject
30+
*/
31+
private $resultPageFactory;
32+
33+
/**
34+
* @var Config|MockObject
35+
*/
36+
private $config;
37+
38+
/**
39+
* @var Index
40+
*/
41+
private $indexAction;
42+
43+
protected function setUp(): void
2144
{
2245
/** @var MockObject|Context $pageConfigMock */
2346
$contextMock = $this->createMock(Context::class);
2447

2548
/** @var MockObject|PageConfig $pageConfigMock */
26-
$pageConfigMock = $this->getMockBuilder(PageConfig::class)
49+
$this->pageConfigMock = $this->getMockBuilder(PageConfig::class)
2750
->disableOriginalConstructor()
2851
->getMock();
2952
/** @var MockObject|PageFactory $resultPageFactory */
30-
$resultPageFactory = $this->getMockBuilder(PageFactory::class)
53+
$this->resultPageFactory = $this->getMockBuilder(PageFactory::class)
3154
->disableOriginalConstructor()
3255
->getMock();
3356

34-
$pageConfigMock->expects($this->once())->method('addBodyClass')->with('swagger-section');
35-
$resultPageFactory->expects($this->once())->method('create');
57+
$this->config = self::getMockBuilder(Config::class)
58+
->disableOriginalConstructor()
59+
->getMock();
60+
61+
$this->indexAction = new Index(
62+
$contextMock,
63+
$this->pageConfigMock,
64+
$this->resultPageFactory,
65+
$this->config
66+
);
67+
}
68+
69+
/**
70+
* @doesNotPerformAssertions
71+
*/
72+
public function testExecute()
73+
{
74+
$this->pageConfigMock->expects($this->once())
75+
->method('addBodyClass')
76+
->with('swagger-section');
77+
$this->resultPageFactory->expects($this->once())
78+
->method('create');
79+
80+
$this->indexAction->execute();
81+
}
82+
83+
public function testDispatchRejectsWhenDisabled()
84+
{
85+
$this->expectException(NotFoundException::class);
86+
$this->expectExceptionMessage('Page not found.');
87+
88+
$request = self::getMockBuilder(Http::class)
89+
->disableOriginalConstructor()
90+
->getMock();
91+
92+
$this->config->method('isEnabled')
93+
->willReturn(false);
94+
$this->indexAction->dispatch($request);
95+
}
96+
97+
/**
98+
* @doesNotPerformAssertions
99+
*/
100+
public function testDispatchIsSuccessfulWhenEnabled()
101+
{
102+
$request = self::getMockBuilder(Http::class)
103+
->disableOriginalConstructor()
104+
->getMock();
105+
// Assert that execute is called
106+
$request->expects($this->once())
107+
->method('getFullActionName');
108+
$this->config->method('isEnabled')
109+
->willReturn(true);
36110

37-
$indexAction = new Index($contextMock, $pageConfigMock, $resultPageFactory);
38-
$indexAction->execute();
111+
$this->indexAction->dispatch($request);
39112
}
40113
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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\Swagger\Test\Unit\Model;
10+
11+
use Magento\Framework\App\State;
12+
use Magento\Swagger\Model\Config;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class ConfigTest extends TestCase
17+
{
18+
/**
19+
* @var State|MockObject
20+
*/
21+
private $state;
22+
23+
protected function setUp(): void
24+
{
25+
$this->state = self::getMockBuilder(State::class)
26+
->disableOriginalConstructor()
27+
->getMock();
28+
}
29+
30+
public function testDisabledInProductionByDefault()
31+
{
32+
$this->state->method('getMode')
33+
->willReturn(State::MODE_PRODUCTION);
34+
$config = new Config($this->state);
35+
36+
self::assertFalse($config->isEnabled());
37+
}
38+
39+
/**
40+
* @param string $mode
41+
* @param bool $configuredValue
42+
* @param bool $expectedResult
43+
* @dataProvider useCaseProvider
44+
*/
45+
public function testUseCases(string $mode, bool $configuredValue, bool $expectedResult)
46+
{
47+
$this->state->method('getMode')
48+
->willReturn($mode);
49+
$config = new Config($this->state, $configuredValue);
50+
51+
self::assertSame($expectedResult, $config->isEnabled());
52+
}
53+
54+
/**
55+
* Use cases for modes
56+
*
57+
* @return array[]
58+
*/
59+
public function useCaseProvider(): array
60+
{
61+
return [
62+
[State::MODE_PRODUCTION, false, false],
63+
[State::MODE_PRODUCTION, true, true],
64+
[State::MODE_DEVELOPER, true, true],
65+
[State::MODE_DEVELOPER, false, true],
66+
];
67+
}
68+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp:etc/csp_whitelist.xsd">
10+
<policies>
11+
<policy id="img-src">
12+
<values>
13+
<value id="swagger" type="host">validator.swagger.io</value>
14+
</values>
15+
</policy>
16+
</policies>
17+
</csp_whitelist>

lib/internal/Magento/Framework/Filesystem/Driver/File/Mime.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
class Mime
1616
{
1717
/**
18-
* Mime types
19-
*
2018
* @var array
2119
*/
2220
private $mimeTypes = [
@@ -91,6 +89,7 @@ class Mime
9189
private $genericMimeTypes = [
9290
'application/x-empty',
9391
'inode/x-empty',
92+
'application/octet-stream'
9493
];
9594

9695
/**

0 commit comments

Comments
 (0)