Skip to content

Commit eac4abd

Browse files
AC-12755 Improve web api async
1 parent f9458b2 commit eac4abd

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

app/code/Magento/Customer/Plugin/AsyncRequestCustomerGroupAuthorization.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
namespace Magento\Customer\Plugin;
1010

1111
use Magento\Customer\Api\Data\CustomerInterface;
12-
use Magento\Framework\App\ObjectManager;
1312
use Magento\Framework\AuthorizationInterface;
1413
use Magento\Framework\Exception\AuthorizationException;
1514
use Magento\AsynchronousOperations\Model\MassSchedule;
@@ -60,6 +59,11 @@ public function beforePublishMass(
6059
string $groupId = null,
6160
string $userId = null
6261
) {
62+
// only apply the plugin on account create.
63+
if ($topic !== 'async.magento.customer.api.accountmanagementinterface.createaccount.post') {
64+
return;
65+
}
66+
6367
foreach ($entitiesArray as $entityParams) {
6468
foreach ($entityParams as $entity) {
6569
if ($entity instanceof CustomerInterface) {

app/code/Magento/Quote/etc/webapi.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@
9898
<resources>
9999
<resource ref="self" />
100100
</resources>
101+
<data>
102+
<parameter name="customerId" force="true">%customer_id%</parameter>
103+
</data>
101104
</route>
102105
<route url="/V1/guest-carts/:cartId/order" method="PUT">
103106
<service class="Magento\Quote\Api\GuestCartManagementInterface" method="placeOrder"/>

app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88

99
namespace Magento\WebapiAsync\Controller\Rest\Asynchronous;
1010

11+
use Magento\Framework\Api\SimpleDataObjectConverter;
1112
use Magento\Framework\App\ObjectManager;
1213
use Magento\Framework\Exception\AuthorizationException;
1314
use Magento\Framework\Exception\InputException;
1415
use Magento\Framework\Exception\LocalizedException;
16+
use Magento\Framework\Reflection\MethodsMap;
1517
use Magento\Framework\Webapi\Exception;
1618
use Magento\Framework\Webapi\Rest\Request as RestRequest;
1719
use Magento\Framework\Webapi\ServiceInputProcessor;
@@ -61,6 +63,11 @@ class InputParamsResolver
6163
*/
6264
private $inputArraySizeLimitValue;
6365

66+
/**
67+
* @var MethodsMap
68+
*/
69+
private $methodsMap;
70+
6471
/**
6572
* Initialize dependencies.
6673
*
@@ -72,6 +79,7 @@ class InputParamsResolver
7279
* @param WebapiInputParamsResolver $inputParamsResolver
7380
* @param bool $isBulk
7481
* @param InputArraySizeLimitValue|null $inputArraySizeLimitValue
82+
* @param MethodsMap|null $methodsMap
7583
*/
7684
public function __construct(
7785
RestRequest $request,
@@ -81,7 +89,8 @@ public function __construct(
8189
RequestValidator $requestValidator,
8290
WebapiInputParamsResolver $inputParamsResolver,
8391
bool $isBulk = false,
84-
?InputArraySizeLimitValue $inputArraySizeLimitValue = null
92+
?InputArraySizeLimitValue $inputArraySizeLimitValue = null,
93+
?MethodsMap $methodsMap = null
8594
) {
8695
$this->request = $request;
8796
$this->paramsOverrider = $paramsOverrider;
@@ -92,6 +101,8 @@ public function __construct(
92101
$this->isBulk = $isBulk;
93102
$this->inputArraySizeLimitValue = $inputArraySizeLimitValue ?? ObjectManager::getInstance()
94103
->get(InputArraySizeLimitValue::class);
104+
$this->methodsMap = $methodsMap ?? ObjectManager::getInstance()
105+
->get(MethodsMap::class);
95106
}
96107

97108
/**
@@ -120,6 +131,12 @@ public function resolve()
120131
$this->inputArraySizeLimitValue->set($route->getInputArraySizeLimit());
121132

122133
foreach ($inputData as $key => $singleEntityParams) {
134+
if (!is_array($singleEntityParams)) {
135+
continue;
136+
}
137+
138+
$this->validateParameters($routeServiceClass, $routeServiceMethod, array_keys($route->getParameters()));
139+
123140
$webapiResolvedParams[$key] = $this->resolveBulkItemParams(
124141
$singleEntityParams,
125142
$routeServiceClass,
@@ -147,7 +164,18 @@ public function getInputData()
147164
$requestBodyParams = $this->request->getBodyParams();
148165
$inputData = array_merge($requestBodyParams, $inputData);
149166
}
150-
return $inputData;
167+
168+
return array_map(function ($singleEntityParams) {
169+
if (is_array($singleEntityParams)) {
170+
$singleEntityParams = $this->filterInputData($singleEntityParams);
171+
$singleEntityParams = $this->paramsOverrider->override(
172+
$singleEntityParams,
173+
$this->getRoute()->getParameters()
174+
);
175+
}
176+
177+
return $singleEntityParams;
178+
}, $inputData);
151179
}
152180

153181
/**
@@ -180,4 +208,63 @@ private function resolveBulkItemParams(array $inputData, string $serviceClass, s
180208
{
181209
return $this->serviceInputProcessor->process($serviceClass, $serviceMethod, $inputData);
182210
}
211+
212+
/**
213+
* Validates InputData
214+
*
215+
* @param array $inputData
216+
* @return array
217+
*/
218+
private function filterInputData(array $inputData): array
219+
{
220+
$result = [];
221+
222+
$data = array_filter($inputData, function ($k) use (&$result) {
223+
$key = is_string($k) ? strtolower(str_replace('_', "", $k)) : $k;
224+
return !isset($result[$key]) && ($result[$key] = true);
225+
}, ARRAY_FILTER_USE_KEY);
226+
227+
return array_map(function ($value) {
228+
return is_array($value) ? $this->filterInputData($value) : $value;
229+
}, $data);
230+
}
231+
232+
/**
233+
* Validate that parameters are really used in the current request.
234+
*
235+
* @param string $serviceClassName
236+
* @param string $serviceMethodName
237+
* @param array $paramOverriders
238+
*/
239+
private function validateParameters(
240+
string $serviceClassName,
241+
string $serviceMethodName,
242+
array $paramOverriders
243+
): void {
244+
$methodParams = $this->methodsMap->getMethodParams($serviceClassName, $serviceMethodName);
245+
foreach ($paramOverriders as $key => $param) {
246+
$arrayKeys = explode('.', $param ?? '');
247+
$value = array_shift($arrayKeys);
248+
249+
foreach ($methodParams as $serviceMethodParam) {
250+
$serviceMethodParamName = $serviceMethodParam[MethodsMap::METHOD_META_NAME];
251+
$serviceMethodType = $serviceMethodParam[MethodsMap::METHOD_META_TYPE];
252+
253+
$camelCaseValue = SimpleDataObjectConverter::snakeCaseToCamelCase($value);
254+
if ($serviceMethodParamName === $value || $serviceMethodParamName === $camelCaseValue) {
255+
if (count($arrayKeys) > 0) {
256+
$camelCaseKey = SimpleDataObjectConverter::snakeCaseToCamelCase('set_' . $arrayKeys[0]);
257+
$this->validateParameters($serviceMethodType, $camelCaseKey, [implode('.', $arrayKeys)]);
258+
}
259+
unset($paramOverriders[$key]);
260+
break;
261+
}
262+
}
263+
}
264+
if (!empty($paramOverriders)) {
265+
$message = 'The current request does not expect the next parameters: '
266+
. implode(', ', $paramOverriders);
267+
throw new \UnexpectedValueException(__($message)->__toString());
268+
}
269+
}
183270
}

0 commit comments

Comments
 (0)