creads/partners-sdk-php

View on GitHub
src/OAuthAccessToken.php

Summary

Maintainability
A
3 hrs
Test Coverage
<?php

namespace Creads\Partners;

use GuzzleHttp\Client as GuzzleClient;

class OAuthAccessToken implements AuthenticationInterface
{
    protected $baseUri = 'https://connect.creads-partners.com/';
    protected $params = [];
    protected $clientId;
    protected $clientSecret;

    public function __construct($clientId, $clientSecret, $params = [])
    {
        if (isset($params['base_uri'])) {
            $this->baseUri = rtrim($params['base_uri'], '/').'/';
        }

        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
        $this->params = array_merge($this->getDefaultParameters(), $params);

        if (isset($params['grant_type'])) {
            if (in_array($params['grant_type'], ['client_credentials', 'password'])) {
                throw new \Exception(sprintf('Unrecognized grant_type: %s', $params['grant_type']));
            }
            if ('password' === $params['grant_type'] && (!isset($params['username']) || !isset($params['password']))) {
                throw new \Exception("'password' grant_type required a username and a password");
            }
        }
    }

    public function getConfig()
    {
        return [
            'headers' => [
                'Authorization' => 'Bearer '.$this->getAccessToken(),
            ],
        ];
    }

    protected function getDefaultParameters()
    {
        return [
            'tokens_dir' => sys_get_temp_dir(),
        ];
    }

    public function getAccessToken($scope = 'base', $noStoring = false)
    {
        if ($noStoring || $this->isTokenExpired()) {
            $multipartBody = [
                [
                    'name'     => 'client_id',
                    'contents' => $this->clientId,
                ],
                [
                    'name'     => 'client_secret',
                    'contents' => $this->clientSecret,
                ],
                [
                    'name'     => 'grant_type',
                    'contents' => isset($this->params['grant_type']) ? $this->params['grant_type'] : 'client_credentials',
                ],
                [
                    'name'     => 'scope',
                    'contents' => $scope,
                ],
            ];
            if (isset($this->params['grant_type']) && $this->params['grant_type'] === 'password') {
                $multipartBody[] = [
                    'name'     => 'username',
                    'contents' => $this->params['username'],
                ];
                $multipartBody[] = [
                    'name'     => 'password',
                    'contents' => $this->params['password'],
                ];
            }
            $client = new GuzzleClient(['base_uri' => $this->baseUri, 'http_errors' => false]);
            $res = $client->request(
                'POST',
                '/oauth2/token',
                [
                    'multipart' => $multipartBody,
                ]
            );
            if ($res->getStatusCode() > 399) {
                throw new \Exception(sprintf("Couldnt get a token: (%s):\n %s", $res->getStatusCode(), $res->getBody()));
            }
            $body = json_decode($res->getBody(), true);
            if (!isset($body['access_token'])) {
                throw new \Exception('Could not retrieve authorization from Partners.');
            }

            $this->storeToken($body);

            return $body['access_token'];
        } else {
            $storedToken = json_decode(file_get_contents($this->getTokenFilePath()), true);

            return $storedToken['access_token'];
        }
    }

    protected function isTokenExpired()
    {
        if (!@file_exists($this->getTokenFilePath())) {
            return true;
        }

        $expiresAt = json_decode(file_get_contents($this->getTokenFilePath()), true)['expires_at'];

        if (is_int($expiresAt)) {
            return true;
        }

        $now = new \DateTime();

        return $expiresAt <= $now->getTimestamp();
    }

    protected function getTokenFilePath()
    {
        return rtrim($this->params['tokens_dir'], '/').'/partners_api_token';
    }

    protected function storeToken($body)
    {
        $now = new \DateTime();
        $expiresAt = $now->getTimestamp() + intval($body['expires_in']);
        $body['expires_at'] = $expiresAt;
        file_put_contents($this->getTokenFilePath(), json_encode($body));
    }
}