Skip to content

Commit d147d80

Browse files
author
Joan He
committed
Merge remote-tracking branch 'arcticfoxes/MC-5895' into 2.3-qwerty-pr
2 parents 1bcf22b + 8fa06d2 commit d147d80

File tree

2 files changed

+513
-12
lines changed

2 files changed

+513
-12
lines changed

app/code/Magento/Ui/Controller/Index/Render.php

Lines changed: 112 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
77

88
use Magento\Backend\App\Action\Context;
99
use Magento\Framework\App\ObjectManager;
10-
use Magento\Framework\App\Response\Http as HttpResponse;
1110
use Magento\Framework\View\Element\UiComponentFactory;
1211
use Magento\Framework\View\Element\UiComponentInterface;
1312
use Magento\Ui\Model\UiComponentTypeResolver;
13+
use Magento\Framework\Escaper;
14+
use Magento\Framework\Controller\Result\JsonFactory;
15+
use Psr\Log\LoggerInterface;
16+
use Magento\Framework\AuthorizationInterface;
1417

1518
/**
1619
* Is responsible for providing ui components information on store front.
1720
*
1821
* @SuppressWarnings(PHPMD.AllPurposeAction)
22+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1923
*/
2024
class Render extends \Magento\Framework\App\Action\Action
2125
{
@@ -34,42 +38,117 @@ class Render extends \Magento\Framework\App\Action\Action
3438
*/
3539
private $contentTypeResolver;
3640

41+
/**
42+
* @var JsonFactory
43+
*/
44+
private $resultJsonFactory;
45+
46+
/**
47+
* @var Escaper
48+
*/
49+
private $escaper;
50+
51+
/**
52+
* @var LoggerInterface
53+
*/
54+
private $logger;
55+
56+
/**
57+
* @var AuthorizationInterface
58+
*/
59+
private $authorization;
60+
3761
/**
3862
* Render constructor.
3963
* @param Context $context
4064
* @param UiComponentFactory $uiComponentFactory
4165
* @param UiComponentTypeResolver|null $contentTypeResolver
66+
* @param JsonFactory|null $resultJsonFactory
67+
* @param Escaper|null $escaper
68+
* @param LoggerInterface|null $logger
4269
*/
4370
public function __construct(
4471
Context $context,
4572
UiComponentFactory $uiComponentFactory,
46-
?UiComponentTypeResolver $contentTypeResolver = null
73+
?UiComponentTypeResolver $contentTypeResolver = null,
74+
JsonFactory $resultJsonFactory = null,
75+
Escaper $escaper = null,
76+
LoggerInterface $logger = null
4777
) {
4878
parent::__construct($context);
4979
$this->context = $context;
5080
$this->uiComponentFactory = $uiComponentFactory;
81+
$this->authorization = $context->getAuthorization();
5182
$this->contentTypeResolver = $contentTypeResolver
5283
?? ObjectManager::getInstance()->get(UiComponentTypeResolver::class);
84+
$this->resultJsonFactory = $resultJsonFactory ?? ObjectManager::getInstance()->get(JsonFactory::class);
85+
$this->escaper = $escaper ?? ObjectManager::getInstance()->get(Escaper::class);
86+
$this->logger = $logger ?? ObjectManager::getInstance()->get(LoggerInterface::class);
5387
}
5488

5589
/**
56-
* Action for AJAX request
57-
*
58-
* @return void
90+
* @inheritdoc
5991
*/
6092
public function execute()
6193
{
6294
if ($this->_request->getParam('namespace') === null) {
63-
$this->_redirect('noroute');
95+
$this->_redirect('admin/noroute');
96+
6497
return;
6598
}
6699

67-
$component = $this->uiComponentFactory->create($this->_request->getParam('namespace'));
68-
$this->prepareComponent($component);
69-
/** @var HttpResponse $response */
70-
$response = $this->getResponse();
71-
$response->appendBody((string) $component->render());
72-
$response->setHeader('Content-Type', $this->contentTypeResolver->resolve($component->getContext()), true);
100+
try {
101+
$component = $this->uiComponentFactory->create($this->getRequest()->getParam('namespace'));
102+
if ($this->validateAclResource($component->getContext()->getDataProvider()->getConfigData())) {
103+
$this->prepareComponent($component);
104+
$this->getResponse()->appendBody((string)$component->render());
105+
106+
$contentType = $this->contentTypeResolver->resolve($component->getContext());
107+
$this->getResponse()->setHeader('Content-Type', $contentType, true);
108+
} else {
109+
/** @var \Magento\Framework\Controller\Result\Json $resultJson */
110+
$resultJson = $this->resultJsonFactory->create();
111+
$resultJson->setStatusHeader(
112+
\Zend\Http\Response::STATUS_CODE_403,
113+
\Zend\Http\AbstractMessage::VERSION_11,
114+
'Forbidden'
115+
);
116+
return $resultJson->setData([
117+
'error' => $this->escaper->escapeHtml('Forbidden'),
118+
'errorcode' => 403
119+
]);
120+
}
121+
} catch (\Magento\Framework\Exception\LocalizedException $e) {
122+
$this->logger->critical($e);
123+
$result = [
124+
'error' => $this->escaper->escapeHtml($e->getMessage()),
125+
'errorcode' => $this->escaper->escapeHtml($e->getCode())
126+
];
127+
/** @var \Magento\Framework\Controller\Result\Json $resultJson */
128+
$resultJson = $this->resultJsonFactory->create();
129+
$resultJson->setStatusHeader(
130+
\Zend\Http\Response::STATUS_CODE_400,
131+
\Zend\Http\AbstractMessage::VERSION_11,
132+
'Bad Request'
133+
);
134+
135+
return $resultJson->setData($result);
136+
} catch (\Exception $e) {
137+
$this->logger->critical($e);
138+
$result = [
139+
'error' => __('UI component could not be rendered because of system exception'),
140+
'errorcode' => $this->escaper->escapeHtml($e->getCode())
141+
];
142+
/** @var \Magento\Framework\Controller\Result\Json $resultJson */
143+
$resultJson = $this->resultJsonFactory->create();
144+
$resultJson->setStatusHeader(
145+
\Zend\Http\Response::STATUS_CODE_400,
146+
\Zend\Http\AbstractMessage::VERSION_11,
147+
'Bad Request'
148+
);
149+
150+
return $resultJson->setData($result);
151+
}
73152
}
74153

75154
/**
@@ -85,4 +164,25 @@ private function prepareComponent(UiComponentInterface $component)
85164
}
86165
$component->prepare();
87166
}
167+
168+
/**
169+
* Optionally validate ACL resource of components with a DataSource/DataProvider
170+
*
171+
* @param mixed $dataProviderConfigData
172+
* @return bool
173+
*/
174+
private function validateAclResource($dataProviderConfigData)
175+
{
176+
if (isset($dataProviderConfigData['aclResource'])) {
177+
if (!$this->authorization->isAllowed($dataProviderConfigData['aclResource'])) {
178+
if (!$this->_request->isAjax()) {
179+
$this->_redirect('noroute');
180+
}
181+
182+
return false;
183+
}
184+
}
185+
186+
return true;
187+
}
88188
}

0 commit comments

Comments
 (0)