Skip to content

Commit

Permalink
Abstract out tokens from being tied tightly to access
Browse files Browse the repository at this point in the history
  • Loading branch information
bradjones1 committed Nov 12, 2022
1 parent a1d3f8a commit 993d279
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 77 deletions.
93 changes: 93 additions & 0 deletions src/Token/AbstractToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php
/**
* This file is part of the league/oauth2-client library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Alex Bilbie <[email protected]>
* @license http://opensource.org/licenses/MIT MIT
* @link http://thephpleague.com/oauth2-client/ Documentation
* @link https://packagist.org/packages/league/oauth2-client Packagist
* @link https://github.com/thephpleague/oauth2-client GitHub
*/

namespace League\OAuth2\Client\Token;

abstract class AbstractToken {

/**
* @var int
*/
protected $expires;

/**
* @var array
*/
protected $values = [];

/**
* @var int
*/
private static $timeNow;

/**
* Constructs an access token.
*
* @param array $options An array of options returned by the service provider
* in the access token request. The `access_token` option is required.
* @throws InvalidArgumentException if `access_token` is not provided in `$options`.
*/
public function __construct(array $options = []) {
// We need to know when the token expires. Show preference to
// 'expires_in' since it is defined in RFC6749 Section 5.1.
// Defer to 'expires' if it is provided instead.
if (isset($options['expires_in'])) {
if (!is_numeric($options['expires_in'])) {
throw new \InvalidArgumentException('expires_in value must be an integer');
}

$this->expires = $options['expires_in'] != 0 ? $this->getTimeNow() + $options['expires_in'] : 0;
} elseif (!empty($options['expires'])) {
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];

if (!$this->isExpirationTimestamp($expires)) {
$expires += $this->getTimeNow();
}

$this->expires = $expires;
}
}

/**
* Set the time now. This should only be used for testing purposes.
*
* @param int $timeNow the time in seconds since epoch
* @return void
*/
public static function setTimeNow($timeNow)
{
self::$timeNow = $timeNow;
}

/**
* Reset the time now if it was set for test purposes.
*
* @return void
*/
public static function resetTimeNow()
{
self::$timeNow = null;
}

/**
* @return int
*/
public function getTimeNow()
{
return self::$timeNow ? self::$timeNow : time();
}

}
73 changes: 5 additions & 68 deletions src/Token/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @link http://tools.ietf.org/html/rfc6749#section-1.4 Access Token (RFC 6749, §1.4)
*/
class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInterface
class AccessToken extends AbstractToken implements AccessTokenInterface, ResourceOwnerAccessTokenInterface
{
/**
* @var string
Expand All @@ -44,54 +44,12 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
*/
protected $resourceOwnerId;

/**
* @var array
*/
protected $values = [];

/**
* @var int
*/
private static $timeNow;

/**
* Set the time now. This should only be used for testing purposes.
*
* @param int $timeNow the time in seconds since epoch
* @return void
*/
public static function setTimeNow($timeNow)
{
self::$timeNow = $timeNow;
}

/**
* Reset the time now if it was set for test purposes.
*
* @return void
*/
public static function resetTimeNow()
{
self::$timeNow = null;
}

/**
* @return int
*/
public function getTimeNow()
{
return self::$timeNow ? self::$timeNow : time();
}

/**
* Constructs an access token.
*
* @param array $options An array of options returned by the service provider
* in the access token request. The `access_token` option is required.
* @throws InvalidArgumentException if `access_token` is not provided in `$options`.
*/
/**
* @inheritDoc
*/
public function __construct(array $options = [])
{
parent::__construct($options);
if (empty($options['access_token'])) {
throw new InvalidArgumentException('Required option not passed: "access_token"');
}
Expand All @@ -106,27 +64,6 @@ public function __construct(array $options = [])
$this->refreshToken = $options['refresh_token'];
}

// We need to know when the token expires. Show preference to
// 'expires_in' since it is defined in RFC6749 Section 5.1.
// Defer to 'expires' if it is provided instead.
if (isset($options['expires_in'])) {
if (!is_numeric($options['expires_in'])) {
throw new \InvalidArgumentException('expires_in value must be an integer');
}

$this->expires = $options['expires_in'] != 0 ? $this->getTimeNow() + $options['expires_in'] : 0;
} elseif (!empty($options['expires'])) {
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];

if (!$this->isExpirationTimestamp($expires)) {
$expires += $this->getTimeNow();
}

$this->expires = $expires;
}

// Capture any additional values that might exist in the token but are
// not part of the standard response. Vendors will sometimes pass
// additional user data this way.
Expand Down
29 changes: 29 additions & 0 deletions src/Token/IdToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* This file is part of the league/oauth2-client library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Alex Bilbie <[email protected]>
* @license http://opensource.org/licenses/MIT MIT
* @link http://thephpleague.com/oauth2-client/ Documentation
* @link https://packagist.org/packages/league/oauth2-client Packagist
* @link https://github.com/thephpleague/oauth2-client GitHub
*/

namespace League\OAuth2\Client\Token;

class IdToken extends AbstractToken implements ResourceOwnerTokenInterface {

/**
* @inheritDoc
*/
public function __construct(array $options = []) {
parent::__construct($options);
if (!empty($options['resource_owner_id'])) {
$this->resourceOwnerId = $options['resource_owner_id'];
}
}

}
11 changes: 2 additions & 9 deletions src/Token/ResourceOwnerAccessTokenInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,5 @@

namespace League\OAuth2\Client\Token;

interface ResourceOwnerAccessTokenInterface extends AccessTokenInterface
{
/**
* Returns the resource owner identifier, if defined.
*
* @return string|null
*/
public function getResourceOwnerId();
}
interface ResourceOwnerAccessTokenInterface extends AccessTokenInterface, ResourceOwnerTokenInterface
{}
25 changes: 25 additions & 0 deletions src/Token/ResourceOwnerTokenInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
/**
* This file is part of the league/oauth2-client library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Alex Bilbie <[email protected]>
* @license http://opensource.org/licenses/MIT MIT
* @link http://thephpleague.com/oauth2-client/ Documentation
* @link https://packagist.org/packages/league/oauth2-client Packagist
* @link https://github.com/thephpleague/oauth2-client GitHub
*/

namespace League\OAuth2\Client\Token;

interface ResourceOwnerTokenInterface
{
/**
* Returns the resource owner identifier, if defined.
*
* @return string|null
*/
public function getResourceOwnerId();
}

0 comments on commit 993d279

Please sign in to comment.