Skip to content

Commit c5f10e8

Browse files
authored
feat: silence webhook token errors (#177)
fixes #5296
1 parent 96b7db9 commit c5f10e8

File tree

3 files changed

+69
-37
lines changed

3 files changed

+69
-37
lines changed

Diff for: src/Resources/config/packages/shopware.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ shopware:
88
SWAG_PAYPAL__API_CANNOT_BE_ZERO_OR_NEGATIVE: notice
99
SWAG_PAYPAL__API_PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED: notice
1010
SWAG_PAYPAL__API_PAYMENT_SOURCE_DECLINED_BY_PROCESSOR: notice
11+
SWAG_PAYPAL_POS__WEBHOOK_ID_INVALID: warning

Diff for: src/Webhook/WebhookController.php

+22-19
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,26 @@ public function deregisterWebhook(string $salesChannelId): JsonResponse
138138
#[Route(path: '/api/_action/paypal/webhook/execute', name: 'api.action.paypal.webhook.execute', methods: ['POST'], defaults: ['auth_required' => false])]
139139
public function executeWebhook(Request $request, Context $context): Response
140140
{
141-
$token = $this->getShopwareToken($request);
142-
$this->validateShopwareToken($token, $context);
141+
$token = $request->query->getAlnum(WebhookService::PAYPAL_WEBHOOK_TOKEN_NAME);
142+
if (!$this->validateShopwareToken($token, $context)) {
143+
if ($id = $request->request->get('id')) {
144+
$this->logger->warning(
145+
'[PayPal Webhook] Shopware token of webhook "{webhookId}" is invalid. Please check for stale webhooks.',
146+
['webhookId' => $id],
147+
);
148+
}
149+
150+
return new Response('Shopware token is invalid', Response::HTTP_BAD_REQUEST);
151+
}
143152

144153
$webhook = $this->createWebhookFromPostData($request);
145-
$this->tryToExecuteWebhook($context, $webhook);
154+
155+
try {
156+
$this->tryToExecuteWebhook($context, $webhook);
157+
} catch (BadRequestHttpException $e) {
158+
// errors are already logged, no need to throw this exception
159+
return new Response($e->getMessage(), $e->getStatusCode());
160+
}
146161

147162
return new Response();
148163
}
@@ -198,34 +213,22 @@ protected function tryToExecuteWebhook(Context $context, Webhook $webhook): void
198213
}
199214
}
200215

201-
/**
202-
* @throws BadRequestHttpException
203-
*/
204-
private function getShopwareToken(Request $request): string
216+
private function validateShopwareToken(string $token, Context $context): bool
205217
{
206-
$token = $request->query->getAlnum(WebhookService::PAYPAL_WEBHOOK_TOKEN_NAME);
207218
if ($token === '') {
208-
throw new BadRequestHttpException('Shopware token is invalid');
219+
return false;
209220
}
210221

211-
return $token;
212-
}
213-
214-
/**
215-
* @throws BadRequestHttpException
216-
*/
217-
private function validateShopwareToken(string $token, Context $context): void
218-
{
219222
$criteria = (new Criteria())->addFilter(new EqualsFilter('configurationValue', $token));
220223
/** @var SystemConfigCollection $systemConfigCollection */
221224
$systemConfigCollection = $this->systemConfigRepository->search($criteria, $context)->getEntities();
222225

223226
foreach ($systemConfigCollection as $systemConfigEntity) {
224227
if ($systemConfigEntity->getConfigurationKey() === Settings::WEBHOOK_EXECUTE_TOKEN) {
225-
return;
228+
return true;
226229
}
227230
}
228231

229-
throw new BadRequestHttpException('Shopware token is invalid');
232+
return false;
230233
}
231234
}

Diff for: tests/Webhook/WebhookControllerTest.php

+46-18
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,10 @@ public function testExecuteWebhookThrowsPayPalApiException(): void
116116
$context->addExtension(self::THROW_PAYPAL_API_EXCEPTION, new ArrayStruct());
117117
$request = $this->createRequestWithWebhookData();
118118

119-
$this->expectException(BadRequestHttpException::class);
120-
$this->expectExceptionMessage('An error occurred during execution of webhook');
121-
$this->controller->executeWebhook($request, $context);
119+
$response = $this->controller->executeWebhook($request, $context);
120+
121+
static::assertSame('An error occurred during execution of webhook', $response->getContent());
122+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
122123

123124
static::assertTrue(
124125
$this->logger->hasRecordThatContains('testPayPalApiExceptionMessage', Level::Error),
@@ -132,9 +133,10 @@ public function testExecuteWebhookThrowsWebhookException(): void
132133
$context->addExtension(self::THROW_WEBHOOK_EXCEPTION, new ArrayStruct());
133134
$request = $this->createRequestWithWebhookData();
134135

135-
$this->expectException(BadRequestHttpException::class);
136-
$this->expectExceptionMessage('An error occurred during execution of webhook');
137-
$this->controller->executeWebhook($request, $context);
136+
$response = $this->controller->executeWebhook($request, $context);
137+
138+
static::assertSame('An error occurred during execution of webhook', $response->getContent());
139+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
138140

139141
static::assertTrue(
140142
$this->logger->hasRecordThatContains('testWebhookExceptionMessage', Level::Error),
@@ -148,9 +150,10 @@ public function testExecuteWebhookThrowsGeneralException(): void
148150
$context->addExtension(self::THROW_GENERAL_EXCEPTION, new ArrayStruct());
149151
$request = $this->createRequestWithWebhookData();
150152

151-
$this->expectException(BadRequestHttpException::class);
152-
$this->expectExceptionMessage('An error occurred during execution of webhook');
153-
$this->controller->executeWebhook($request, $context);
153+
$response = $this->controller->executeWebhook($request, $context);
154+
155+
static::assertSame('An error occurred during execution of webhook', $response->getContent());
156+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
154157

155158
static::assertTrue(
156159
$this->logger->hasRecordThatContains('testGeneralExceptionMessage', Level::Error),
@@ -164,19 +167,26 @@ public function testExecuteWebhookEmptyToken(): void
164167
$context->addExtension(self::EMPTY_TOKEN, new ArrayStruct());
165168
$request = $this->createRequestWithWebhookData();
166169

167-
$this->expectException(BadRequestHttpException::class);
168-
$this->expectExceptionMessage('Shopware token is invalid');
169-
$this->controller->executeWebhook($request, $context);
170+
$response = $this->controller->executeWebhook($request, $context);
171+
172+
static::assertSame('Shopware token is invalid', $response->getContent());
173+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
174+
static::assertTrue(
175+
$this->logger->hasRecordThatContains('Shopware token of webhook "{webhookId}" is invalid', Level::Warning),
176+
'Expected invalid-shopware-token log entry not found',
177+
);
170178
}
171179

172180
public function testExecuteWebhookEmptyTokenSent(): void
173181
{
174182
$context = Context::createDefaultContext();
175183
$request = new Request();
176184

177-
$this->expectException(BadRequestHttpException::class);
178-
$this->expectExceptionMessage('Shopware token is invalid');
179-
$this->controller->executeWebhook($request, $context);
185+
$response = $this->controller->executeWebhook($request, $context);
186+
187+
static::assertSame('Shopware token is invalid', $response->getContent());
188+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
189+
static::assertEquals([], $this->logger->getRecords());
180190
}
181191

182192
public function testExecuteWebhookInvalidToken(): void
@@ -186,9 +196,27 @@ public function testExecuteWebhookInvalidToken(): void
186196
[WebhookService::PAYPAL_WEBHOOK_TOKEN_NAME => 'invalid-token']
187197
);
188198

189-
$this->expectException(BadRequestHttpException::class);
190-
$this->expectExceptionMessage('Shopware token is invalid');
191-
$this->controller->executeWebhook($request, $context);
199+
$response = $this->controller->executeWebhook($request, $context);
200+
201+
static::assertSame('Shopware token is invalid', $response->getContent());
202+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
203+
static::assertEquals([], $this->logger->getRecords());
204+
}
205+
206+
public function testExecuteWebhookInvalidTokenWithId(): void
207+
{
208+
$context = Context::createDefaultContext();
209+
$request = $this->createRequestWithWebhookData();
210+
$request->query->set(WebhookService::PAYPAL_WEBHOOK_TOKEN_NAME, 'invalid-token');
211+
212+
$response = $this->controller->executeWebhook($request, $context);
213+
214+
static::assertSame('Shopware token is invalid', $response->getContent());
215+
static::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
216+
static::assertTrue(
217+
$this->logger->hasRecordThatContains('Shopware token of webhook "{webhookId}" is invalid', Level::Warning),
218+
'Expected invalid-shopware-token log entry not found',
219+
);
192220
}
193221

194222
public function testExecuteWebhookNoData(): void

0 commit comments

Comments
 (0)