From 60dc240d68ea7d4004185a7c4c2738c6776fbdfb Mon Sep 17 00:00:00 2001 From: Marc Kreidler Date: Thu, 18 Dec 2025 17:43:20 +0100 Subject: [PATCH] Revert the following commits that tried to implement getToken using OAuthTokenManager Revert "add use OAuthTokenManager and create instance in constructor"This reverts commit 2a1e7c9b0974ebd7e082d5a2fa62753d6254a767.Revert "Add missing ) to retrieveROPCToken"This reverts commit 8df5cfc49e774127d906b99802211eb63ad7de04. Revert "Implement retrieveROPCToken as proposed in https://github.com/Part-DB/Part-DB-server/pull/1151#discussion_r2622976206" This reverts commit 66cc732082da07bcc689d278abc7c0bc128140b7. --- .../Providers/BuerklinProvider.php | 52 +++++++++++++++---- src/Services/OAuth/OAuthTokenManager.php | 17 ------ 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php b/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php index a205ab8a..610e2ac5 100644 --- a/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php +++ b/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php @@ -30,7 +30,6 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Services\InfoProviderSystem\DTOs\PriceDTO; use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; -use App\Services\OAuth\OAuthTokenManager; use App\Settings\InfoProviderSystem\BuerklinSettings; use Psr\Cache\CacheItemPoolInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -51,10 +50,9 @@ class BuerklinProvider implements BatchInfoProviderInterface public function __construct( private readonly HttpClientInterface $client, - private readonly OAuthTokenManager $authTokenManager, private readonly CacheItemPoolInterface $partInfoCache, private readonly BuerklinSettings $settings, - ) { + ) { } @@ -64,16 +62,52 @@ class BuerklinProvider implements BatchInfoProviderInterface */ private function getToken(): string { - //Check if we already have a token saved for this app, otherwise we have to retrieve one via OAuth - if (!$this->authTokenManager->hasToken(self::OAUTH_APP_NAME)) { - $this->authTokenManager->retrieveROPCToken(self::OAUTH_APP_NAME, $this->settings->username, $this->settings->password); + // Cache token to avoid hammering the auth server on every request + $cacheKey = 'buerklin.oauth.token'; + $item = $this->partInfoCache->getItem($cacheKey); + + if ($item->isHit()) { + $token = $item->get(); + if (is_string($token) && $token !== '') { + return $token; + } } - $token = $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME); - if ($token === null) { - throw new \RuntimeException('Could not retrieve OAuth token for Buerklin API.'); + // Buerklin OAuth2 password grant (ROPC) + $resp = $this->client->request('POST', 'https://www.buerklin.com/authorizationserver/oauth/token/', [ + 'headers' => [ + 'Accept' => 'application/json', + 'Content-Type' => 'application/x-www-form-urlencoded', + ], + 'body' => [ + 'grant_type' => 'password', + 'client_id' => $this->settings->clientId, + 'client_secret' => $this->settings->secret, + 'username' => $this->settings->username, + 'password' => $this->settings->password, + ], + ]); + + $data = $resp->toArray(false); + + if (!isset($data['access_token'])) { + throw new \RuntimeException( + 'Invalid token response from Buerklin: HTTP ' . $resp->getStatusCode() . ' body=' . $resp->getContent(false) + ); } + $token = (string) $data['access_token']; + + // Cache for (expires_in - 30s) if available + $ttl = 300; + if (isset($data['expires_in']) && is_numeric($data['expires_in'])) { + $ttl = max(60, (int) $data['expires_in'] - 30); + } + + $item->set($token); + $item->expiresAfter($ttl); + $this->partInfoCache->save($item); + return $token; } diff --git a/src/Services/OAuth/OAuthTokenManager.php b/src/Services/OAuth/OAuthTokenManager.php index 83a605e5..9c22503b 100644 --- a/src/Services/OAuth/OAuthTokenManager.php +++ b/src/Services/OAuth/OAuthTokenManager.php @@ -159,21 +159,4 @@ final class OAuthTokenManager return $this->saveToken($app_name, $access_token); } - - /** - * Retrieves an access token for the given app name using the client ROPC grant (so no user flow is needed) - * The app_name must be registered in the knpu_oauth2_client.yaml - * The token is saved to the database, and afterwards can be used as usual - * @param string $app_name - * @return OAuthToken - */ - public function retrieveROPCToken(string $app_name, string $user, string $password): OAuthToken - { - $client = $this->clientRegistry->getClient($app_name); - $access_token = $client->getOAuth2Provider()->getAccessToken('password', [ - 'username' => $user, - 'password' => $password - ]); - return $this->saveToken($app_name, $access_token); - } } \ No newline at end of file