7
7
8
8
use Magento \Backend \App \Action \Context ;
9
9
use Magento \Framework \App \ObjectManager ;
10
- use Magento \Framework \App \Response \Http as HttpResponse ;
11
10
use Magento \Framework \View \Element \UiComponentFactory ;
12
11
use Magento \Framework \View \Element \UiComponentInterface ;
13
12
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 ;
14
17
15
18
/**
16
19
* Is responsible for providing ui components information on store front.
17
20
*
18
21
* @SuppressWarnings(PHPMD.AllPurposeAction)
22
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
19
23
*/
20
24
class Render extends \Magento \Framework \App \Action \Action
21
25
{
@@ -34,42 +38,117 @@ class Render extends \Magento\Framework\App\Action\Action
34
38
*/
35
39
private $ contentTypeResolver ;
36
40
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
+
37
61
/**
38
62
* Render constructor.
39
63
* @param Context $context
40
64
* @param UiComponentFactory $uiComponentFactory
41
65
* @param UiComponentTypeResolver|null $contentTypeResolver
66
+ * @param JsonFactory|null $resultJsonFactory
67
+ * @param Escaper|null $escaper
68
+ * @param LoggerInterface|null $logger
42
69
*/
43
70
public function __construct (
44
71
Context $ context ,
45
72
UiComponentFactory $ uiComponentFactory ,
46
- ?UiComponentTypeResolver $ contentTypeResolver = null
73
+ ?UiComponentTypeResolver $ contentTypeResolver = null ,
74
+ JsonFactory $ resultJsonFactory = null ,
75
+ Escaper $ escaper = null ,
76
+ LoggerInterface $ logger = null
47
77
) {
48
78
parent ::__construct ($ context );
49
79
$ this ->context = $ context ;
50
80
$ this ->uiComponentFactory = $ uiComponentFactory ;
81
+ $ this ->authorization = $ context ->getAuthorization ();
51
82
$ this ->contentTypeResolver = $ contentTypeResolver
52
83
?? 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);
53
87
}
54
88
55
89
/**
56
- * Action for AJAX request
57
- *
58
- * @return void
90
+ * @inheritdoc
59
91
*/
60
92
public function execute ()
61
93
{
62
94
if ($ this ->_request ->getParam ('namespace ' ) === null ) {
63
- $ this ->_redirect ('noroute ' );
95
+ $ this ->_redirect ('admin/noroute ' );
96
+
64
97
return ;
65
98
}
66
99
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
+ }
73
152
}
74
153
75
154
/**
@@ -85,4 +164,25 @@ private function prepareComponent(UiComponentInterface $component)
85
164
}
86
165
$ component ->prepare ();
87
166
}
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
+ }
88
188
}
0 commit comments