<?php
namespace XF\ConnectedAccount\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\OAuth2\Token\StdOAuth2Token;
use XF\Entity\ConnectedAccountProvider;
use XF\Entity\User;
class StorageState
{
/**
* @var ConnectedAccountProvider
*/
protected $provider;
/**
* @var User
*/
protected $user;
protected $storageName;
protected $storageType = 'local';
protected $tokenData = [];
public function __construct(ConnectedAccountProvider $provider, User $user)
{
$this->provider = $provider;
$this->user = $user;
$handler = $provider->handler;
$storageName = $handler->getOAuthServiceName();
if (strpos($storageName, '\\') !== false)
{
$parts = explode('\\', $storageName);
$storageName = end($parts);
}
$this->storageName = $storageName;
$this->storageType = ($this->user->user_id == \XF::visitor()->user_id ? 'session' : 'local');
}
public function getProvider()
{
return $this->provider;
}
public function getStorageName()
{
return $this->storageName;
}
public function getProviderToken()
{
// If a token is already stored in session, retrieve it.
$token = $this->retrieveToken();
if ($token)
{
return $token;
}
// If a user is already associated, create and store the token based on that association.
$token = $this->getTokenObjectForUser();
if ($token)
{
return $token;
}
return false;
}
public function hasToken()
{
return $this->getStorage()->hasAccessToken($this->storageName);
}
public function retrieveToken()
{
if ($this->hasToken())
{
return $this->getStorage()->retrieveAccessToken($this->storageName);
}
return false;
}
public function getUserToken()
{
$user = $this->user;
$provider = $this->provider;
if (!isset($user->ConnectedAccounts[$provider->provider_id]))
{
return false;
}
$connectedAccount = $user->ConnectedAccounts[$provider->provider_id];
if (empty($connectedAccount->extra_data['token']))
{
return false;
}
$this->tokenData = [
'token' => $connectedAccount->extra_data['token'],
'secret' => $connectedAccount->extra_data['secret'] ?? null
];
return $this->tokenData;
}
public function getTokenObjectForUser()
{
$provider = $this->provider;
$handler = $provider->handler;
$tokenData = $this->getUserToken();
if (!$tokenData)
{
return false;
}
switch ($version = $handler->getOAuthVersion())
{
case 1:
case 2:
/** @var StdOAuth2Token|StdOAuth1Token $tokenObj */
$class = "\\OAuth\\OAuth{$version}\\Token\\StdOAuth{$version}Token";
$tokenObj = new $class();
if ($version === 1)
{
$tokenObj->setAccessTokenSecret($tokenData['secret']);
}
break;
default:
throw new \InvalidArgumentException("Unknown OAuth version '$version'");
break;
}
$tokenObj->setAccessToken($tokenData['token']);
$this->storeToken($tokenObj);
return $tokenObj;
}
public function storeToken(TokenInterface $token)
{
$this->getStorage()->storeAccessToken($this->storageName, $token);
}
public function clearToken()
{
$this->getStorage()->clearToken($this->storageName);
}
public function hasProviderData()
{
return $this->getStorage()->hasData($this->storageName);
}
public function retrieveProviderData()
{
if ($this->hasProviderData())
{
return $this->getStorage()->retrieveData($this->storageName);
}
return false;
}
public function storeProviderData($data)
{
$this->getStorage()->storeData($this->storageName, $data);
}
public function clearProviderData()
{
$this->getStorage()->clearData($this->storageName);
}
public function getStorage()
{
return \XF::app()->oAuth()->storage($this->storageType);
}
public function getStorageType()
{
return $this->storageType;
}
}