AzuraCast/src/Service/Dropbox/OAuthAdapter.php

100 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service\Dropbox;
use App\Entity\StorageLocation;
use App\Utilities\Types;
use GuzzleHttp\Exception\ClientException;
use Psr\Cache\CacheItemPoolInterface;
use Spatie\Dropbox\RefreshableTokenProvider;
final class OAuthAdapter implements RefreshableTokenProvider
{
private StorageLocation $storageLocation;
public function __construct(
private readonly CacheItemPoolInterface $psr6Cache
) {
}
public function withStorageLocation(StorageLocation $storageLocation): self
{
$clone = clone $this;
$clone->setStorageLocation($storageLocation);
return $clone;
}
private function setStorageLocation(StorageLocation $storageLocation): void
{
$this->storageLocation = $storageLocation;
}
public function setup(): void
{
$this->psr6Cache->deleteItem($this->getTokenCacheKey());
if (!empty($this->storageLocation->getDropboxAuthToken())) {
// Convert the short-lived auth code into an oauth refresh token.
$token = $this->getOauthProvider()->getAccessToken(
'authorization_code',
[
'code' => $this->storageLocation->getDropboxAuthToken(),
]
);
$this->storageLocation->setDropboxAuthToken(null);
$this->storageLocation->setDropboxRefreshToken($token->getRefreshToken());
}
}
public function refresh(ClientException $exception): bool
{
$this->psr6Cache->deleteItem($this->getTokenCacheKey());
$this->getToken();
return true;
}
public function getToken(): string
{
$cacheKey = $this->getTokenCacheKey();
$cacheItem = $this->psr6Cache->getItem($cacheKey);
if (!$cacheItem->isHit()) {
if (empty($this->storageLocation->getDropboxRefreshToken())) {
$cacheItem->set($this->storageLocation->getDropboxAuthToken());
} else {
// Try to get a new auth token from the refresh token.
$token = $this->getOauthProvider()->getAccessToken(
'refresh_token',
[
'refresh_token' => $this->storageLocation->getDropboxRefreshToken(),
]
);
$cacheItem->set($token->getToken());
}
$cacheItem->expiresAfter(600);
$this->psr6Cache->save($cacheItem);
}
return Types::string($cacheItem->get());
}
private function getOauthProvider(): OAuthProvider
{
return new OAuthProvider([
'clientId' => $this->storageLocation->getDropboxAppKey(),
'clientSecret' => $this->storageLocation->getDropboxAppSecret(),
]);
}
private function getTokenCacheKey(): string
{
return 'storage_location_' . ($this->storageLocation->getId() ?? 'new') . '_auth_token';
}
}