From 2a2a56089116337d90d0af1db80f7727d4754daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mu=C3=B1oz?= Date: Wed, 10 Apr 2024 18:03:12 +0200 Subject: [PATCH 1/4] Fixes use restricted data token on unrestricted report documents --- src/Middleware/RestrictedReport.php | 2 +- .../ReportsV20210630/Requests/GetReportDocument.php | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Middleware/RestrictedReport.php b/src/Middleware/RestrictedReport.php index 116d21a65..c58f45165 100644 --- a/src/Middleware/RestrictedReport.php +++ b/src/Middleware/RestrictedReport.php @@ -23,7 +23,7 @@ public function __invoke(PendingRequest $pendingRequest) $connector = $pendingRequest->getConnector(); if ( ! $reports[$reportType]['restricted'] - || Endpoint::isSandbox(Endpoint::tryFrom($connector->endpoint)) + || Endpoint::isSandbox($connector->endpoint) ) { $pendingRequest->authenticate($connector->lwaAuth()); } diff --git a/src/Seller/ReportsV20210630/Requests/GetReportDocument.php b/src/Seller/ReportsV20210630/Requests/GetReportDocument.php index fa5d98ccf..4b7103082 100644 --- a/src/Seller/ReportsV20210630/Requests/GetReportDocument.php +++ b/src/Seller/ReportsV20210630/Requests/GetReportDocument.php @@ -19,15 +19,18 @@ class GetReportDocument extends Request protected Method $method = Method::GET; /** - * @param string $reportDocumentId The identifier for the report document. - * @param string $reportType The report type of the report document. + * @param string $reportDocumentId The identifier for the report document. + * @param string $reportType The report type of the report document. */ public function __construct( protected string $reportDocumentId, protected string $reportType, ) { - $rdtMiddleware = new RestrictedDataToken($this->resolveEndpoint(), 'GET', []); - $this->middleware()->onRequest($rdtMiddleware); + $reports = json_decode(file_get_contents(RESOURCE_DIR . '/reports.json'), true); + if (true === ($reports[$reportType]['restricted'] ?? true)) { + $rdtMiddleware = new RestrictedDataToken($this->resolveEndpoint(), 'GET', []); + $this->middleware()->onRequest($rdtMiddleware); + } $this->middleware()->onRequest(new RestrictedReport); } From 4c8797f1d7d6a04cf26ce64ba2b483621732a883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mu=C3=B1oz?= Date: Wed, 10 Apr 2024 18:09:37 +0200 Subject: [PATCH 2/4] fix formatting --- src/Seller/ReportsV20210630/Requests/GetReportDocument.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Seller/ReportsV20210630/Requests/GetReportDocument.php b/src/Seller/ReportsV20210630/Requests/GetReportDocument.php index 4b7103082..5450d3189 100644 --- a/src/Seller/ReportsV20210630/Requests/GetReportDocument.php +++ b/src/Seller/ReportsV20210630/Requests/GetReportDocument.php @@ -19,8 +19,8 @@ class GetReportDocument extends Request protected Method $method = Method::GET; /** - * @param string $reportDocumentId The identifier for the report document. - * @param string $reportType The report type of the report document. + * @param string $reportDocumentId The identifier for the report document. + * @param string $reportType The report type of the report document. */ public function __construct( protected string $reportDocumentId, From d4609562b9390b49ab3fc0bfd5ce63e4762c7ceb Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Wed, 17 Apr 2024 23:06:26 -0400 Subject: [PATCH 3/4] Generate request w/o RDT/Grantless middleware if other middleware exists * Any middleware applied to an endpoint that is specified in the restricted.json or grantless.json resource files must invoke the relevant RDT/Grantless middleware itself, since those middlewares will no longer be automatically applied * Invoke RestrictedDataToken middleware from RestrictedReport middleware, instead of applying both middlewares to the GetReportDocument request class * Remove restricted report check from GetReportDocument class since it is autogenerated * Safety checks in DownloadsDocument when looking for the document type in JSON files --- src/Generator/Generators/RequestGenerator.php | 64 ++++++++++--------- src/Middleware/RestrictedReport.php | 11 +++- .../Requests/GetReportDocument.php | 6 -- src/Traits/DownloadsDocument.php | 5 +- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/Generator/Generators/RequestGenerator.php b/src/Generator/Generators/RequestGenerator.php index 2f65ef77f..45a6d36b7 100644 --- a/src/Generator/Generators/RequestGenerator.php +++ b/src/Generator/Generators/RequestGenerator.php @@ -64,39 +64,41 @@ protected function generateRequestClass(Endpoint $endpoint): PhpFile $isRestricted = isset($restrictedOperations->{$path}->operations->{$httpMethod}); $isGrantless = isset($grantlessOperations->{$path}->{$httpMethod}); - if ($isRestricted || $isGrantless) { - if ($isRestricted) { - $namespace->addUse(RestrictedDataToken::class); - $useGenericPath = $restrictedOperations->{$path}->genericPath; - $knownDataElements = $restrictedOperations->{$path}->operations->{$httpMethod}; - $constructor->addBody( - new Literal(sprintf( - '$rdtMiddleware = new RestrictedDataToken(%s, \'%s\', %s);', - $useGenericPath ? "'$path'" : '$this->resolveEndpoint()', - strtoupper($httpMethod), - '['.implode(', ', array_map(fn ($el) => "'$el'", $knownDataElements)).']' - )) - ); - $constructor->addBody('$this->middleware()->onRequest($rdtMiddleware);'); - } elseif ($isGrantless) { - $namespace - ->addUse(Grantless::class) - ->addUse(GrantlessScope::class); - $scope = GrantlessScope::from($grantlessOperations->{$path}->{$httpMethod}); - - $constructor->addBody( - new Literal(sprintf( - '$this->middleware()->onRequest(new Grantless(GrantlessScope::%s));', - $scope->name - )) - ); - } - } $requestMiddleware = $middleware->{$path}->{$httpMethod}->request ?? []; - foreach ($requestMiddleware as $cls) { - $namespace->addUse(PACKAGE_NAMESPACE."\\Middleware\\$cls"); - $constructor->addBody(new Literal(sprintf('$this->middleware()->onRequest(new %s);', $cls))); + if ($requestMiddleware) { + // If there is request middleware besides the RDT or Grantless middlewares applied to a request + // that also is grantless or uses an RDT, the other middleware needs to invoke the RDT and/or + // Grantless middleware, otherwise it will not be applied + foreach ($requestMiddleware as $cls) { + $namespace->addUse(PACKAGE_NAMESPACE."\\Middleware\\$cls"); + $constructor->addBody(new Literal(sprintf('$this->middleware()->onRequest(new %s);', $cls))); + } + } elseif ($isRestricted) { + $namespace->addUse(RestrictedDataToken::class); + $useGenericPath = $restrictedOperations->{$path}->genericPath; + $knownDataElements = $restrictedOperations->{$path}->operations->{$httpMethod}; + $constructor->addBody( + new Literal(sprintf( + '$rdtMiddleware = new RestrictedDataToken(%s, \'%s\', %s);', + $useGenericPath ? "'$path'" : '$this->resolveEndpoint()', + strtoupper($httpMethod), + '['.implode(', ', array_map(fn ($el) => "'$el'", $knownDataElements)).']' + )) + ); + $constructor->addBody('$this->middleware()->onRequest($rdtMiddleware);'); + } elseif ($isGrantless) { + $namespace + ->addUse(Grantless::class) + ->addUse(GrantlessScope::class); + $scope = GrantlessScope::from($grantlessOperations->{$path}->{$httpMethod}); + + $constructor->addBody( + new Literal(sprintf( + '$this->middleware()->onRequest(new Grantless(GrantlessScope::%s));', + $scope->name + )) + ); } // Remove the constructor if it's not being used diff --git a/src/Middleware/RestrictedReport.php b/src/Middleware/RestrictedReport.php index c58f45165..528161ab3 100644 --- a/src/Middleware/RestrictedReport.php +++ b/src/Middleware/RestrictedReport.php @@ -22,10 +22,15 @@ public function __invoke(PendingRequest $pendingRequest) $connector = $pendingRequest->getConnector(); if ( - ! $reports[$reportType]['restricted'] - || Endpoint::isSandbox($connector->endpoint) + $reports[$reportType]['restricted'] + && ! Endpoint::isSandbox($connector->endpoint) ) { - $pendingRequest->authenticate($connector->lwaAuth()); + $rdtMiddleware = new RestrictedDataToken( + $pendingRequest->getRequest()->resolveEndpoint(), + $pendingRequest->getMethod()->value, + [] + ); + $rdtMiddleware($pendingRequest); } // The reportType key is not part of the actual API request. We added it to make it diff --git a/src/Seller/ReportsV20210630/Requests/GetReportDocument.php b/src/Seller/ReportsV20210630/Requests/GetReportDocument.php index 5450d3189..0c96695fc 100644 --- a/src/Seller/ReportsV20210630/Requests/GetReportDocument.php +++ b/src/Seller/ReportsV20210630/Requests/GetReportDocument.php @@ -6,7 +6,6 @@ use Saloon\Enums\Method; use Saloon\Http\Request; use Saloon\Http\Response; -use SellingPartnerApi\Middleware\RestrictedDataToken; use SellingPartnerApi\Middleware\RestrictedReport; use SellingPartnerApi\Seller\ReportsV20210630\Responses\ErrorList; use SellingPartnerApi\Seller\ReportsV20210630\Responses\ReportDocument; @@ -26,11 +25,6 @@ public function __construct( protected string $reportDocumentId, protected string $reportType, ) { - $reports = json_decode(file_get_contents(RESOURCE_DIR . '/reports.json'), true); - if (true === ($reports[$reportType]['restricted'] ?? true)) { - $rdtMiddleware = new RestrictedDataToken($this->resolveEndpoint(), 'GET', []); - $this->middleware()->onRequest($rdtMiddleware); - } $this->middleware()->onRequest(new RestrictedReport); } diff --git a/src/Traits/DownloadsDocument.php b/src/Traits/DownloadsDocument.php index dc8818561..8e9a5936c 100644 --- a/src/Traits/DownloadsDocument.php +++ b/src/Traits/DownloadsDocument.php @@ -8,6 +8,7 @@ use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Psr7\Header; use GuzzleHttp\Psr7\InflateStream; +use Illuminate\Support\Arr; use InvalidArgumentException; use OpenSpout\Reader\CSV\Options; use OpenSpout\Reader\CSV\Reader as CSVReader; @@ -190,7 +191,7 @@ protected static function documentTypeInfo(string $documentTypeName): array // Check feeds first because the file is smaller $feedTypes = json_decode(file_get_contents(RESOURCE_DIR.'/feeds.json'), true); - if ($feedTypes[$documentTypeName]) { + if (Arr::get($feedTypes, $documentTypeName)) { $documentTypeInfo = [ 'name' => $documentTypeName, 'contentType' => ContentType::from($feedTypes[$documentTypeName]), @@ -200,7 +201,7 @@ protected static function documentTypeInfo(string $documentTypeName): array if (! $documentTypeInfo) { $reportTypes = json_decode(file_get_contents(RESOURCE_DIR.'/reports.json'), true); - if ($reportTypes[$documentTypeName]) { + if (Arr::get($reportTypes, $documentTypeName)) { $documentTypeInfo = $reportTypes[$documentTypeName]; $documentTypeInfo['name'] = $documentTypeName; $documentTypeInfo['contentType'] = ContentType::from($documentTypeInfo['contentType']); From 9572ff09a5113ea66c639f8d6bf4f1508a7b02e5 Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Fri, 19 Apr 2024 20:24:24 -0400 Subject: [PATCH 4/4] Replace Arr::get() with isset() in DownloadsDocument --- src/Traits/DownloadsDocument.php | 5 ++--- src/Traits/UploadsDocument.php | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Traits/DownloadsDocument.php b/src/Traits/DownloadsDocument.php index 8e9a5936c..644f25cc7 100644 --- a/src/Traits/DownloadsDocument.php +++ b/src/Traits/DownloadsDocument.php @@ -8,7 +8,6 @@ use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Psr7\Header; use GuzzleHttp\Psr7\InflateStream; -use Illuminate\Support\Arr; use InvalidArgumentException; use OpenSpout\Reader\CSV\Options; use OpenSpout\Reader\CSV\Reader as CSVReader; @@ -191,7 +190,7 @@ protected static function documentTypeInfo(string $documentTypeName): array // Check feeds first because the file is smaller $feedTypes = json_decode(file_get_contents(RESOURCE_DIR.'/feeds.json'), true); - if (Arr::get($feedTypes, $documentTypeName)) { + if (isset($feedTypes[$documentTypeName])) { $documentTypeInfo = [ 'name' => $documentTypeName, 'contentType' => ContentType::from($feedTypes[$documentTypeName]), @@ -201,7 +200,7 @@ protected static function documentTypeInfo(string $documentTypeName): array if (! $documentTypeInfo) { $reportTypes = json_decode(file_get_contents(RESOURCE_DIR.'/reports.json'), true); - if (Arr::get($reportTypes, $documentTypeName)) { + if (isset($reportTypes[$documentTypeName])) { $documentTypeInfo = $reportTypes[$documentTypeName]; $documentTypeInfo['name'] = $documentTypeName; $documentTypeInfo['contentType'] = ContentType::from($documentTypeInfo['contentType']); diff --git a/src/Traits/UploadsDocument.php b/src/Traits/UploadsDocument.php index e46ed7c74..c2413a252 100644 --- a/src/Traits/UploadsDocument.php +++ b/src/Traits/UploadsDocument.php @@ -40,7 +40,7 @@ public function upload( public static function getContentType(string $feedType, ?string $charset = null): string { $feedTypes = json_decode(file_get_contents(RESOURCE_DIR.'/feeds.json'), true); - $contentType = $feedTypes[$feedType]; + $contentType = $feedTypes[$feedType] ?? null; if (! $contentType) { throw new RuntimeException("Unknown feed type '{$feedType}'");