This commit is contained in:
Marc Kreidler 2025-12-18 16:41:32 +01:00
parent 0b162e2a31
commit 66cc732082
2 changed files with 23 additions and 42 deletions

View file

@ -62,52 +62,16 @@ class BuerklinProvider implements BatchInfoProviderInterface
*/
private function getToken(): string
{
// 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;
}
//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);
}
// 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 = $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME);
if ($token === null) {
throw new \RuntimeException('Could not retrieve OAuth token for Buerklin API.');
}
$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;
}

View file

@ -159,4 +159,21 @@ 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);
}
}