add composer's vendor directory
This commit is contained in:
parent
01a3860d73
commit
60b094d5fa
745 changed files with 56017 additions and 1 deletions
63
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AccessTokenInterface.php
vendored
Normal file
63
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AccessTokenInterface.php
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should get/save access tokens
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface AccessTokenInterface
|
||||
{
|
||||
/**
|
||||
* Look up the supplied oauth_token from storage.
|
||||
*
|
||||
* We need to retrieve access token data as we create and verify tokens.
|
||||
*
|
||||
* @param $oauth_token
|
||||
* oauth_token to be check with.
|
||||
*
|
||||
* @return
|
||||
* An associative array as below, and return NULL if the supplied oauth_token
|
||||
* is invalid:
|
||||
* - expires: Stored expiration in unix timestamp.
|
||||
* - client_id: (optional) Stored client identifier.
|
||||
* - user_id: (optional) Stored user identifier.
|
||||
* - scope: (optional) Stored scope values in space-separated string.
|
||||
* - id_token: (optional) Stored id_token (if "use_openid_connect" is true).
|
||||
*
|
||||
* @ingroup oauth2_section_7
|
||||
*/
|
||||
public function getAccessToken($oauth_token);
|
||||
|
||||
/**
|
||||
* Store the supplied access token values to storage.
|
||||
*
|
||||
* We need to store access token data as we create and verify tokens.
|
||||
*
|
||||
* @param $oauth_token oauth_token to be stored.
|
||||
* @param $client_id client identifier to be stored.
|
||||
* @param $user_id user identifier to be stored.
|
||||
* @param int $expires expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope OPTIONAL Scopes to be stored in space-separated string.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null);
|
||||
|
||||
/**
|
||||
* Expire an access token.
|
||||
*
|
||||
* This is not explicitly required in the spec, but if defined in a draft RFC for token
|
||||
* revoking (RFC 7009) https://tools.ietf.org/html/rfc7009
|
||||
*
|
||||
* @param $access_token
|
||||
* Access token to be expired.
|
||||
*
|
||||
* @ingroup oauth2_section_6
|
||||
*
|
||||
* @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
|
||||
*/
|
||||
//public function unsetAccessToken($access_token);
|
||||
}
|
86
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AuthorizationCodeInterface.php
vendored
Normal file
86
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AuthorizationCodeInterface.php
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should get/save authorization codes for the "Authorization Code"
|
||||
* grant type
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface AuthorizationCodeInterface
|
||||
{
|
||||
/**
|
||||
* The Authorization Code grant type supports a response type of "code".
|
||||
*
|
||||
* @var string
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-1.4.1
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4.2
|
||||
*/
|
||||
const RESPONSE_TYPE_CODE = "code";
|
||||
|
||||
/**
|
||||
* Fetch authorization code data (probably the most common grant type).
|
||||
*
|
||||
* Retrieve the stored data for the given authorization code.
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_AUTH_CODE.
|
||||
*
|
||||
* @param $code
|
||||
* Authorization code to be check with.
|
||||
*
|
||||
* @return
|
||||
* An associative array as below, and NULL if the code is invalid
|
||||
* @code
|
||||
* return array(
|
||||
* "client_id" => CLIENT_ID, // REQUIRED Stored client identifier
|
||||
* "user_id" => USER_ID, // REQUIRED Stored user identifier
|
||||
* "expires" => EXPIRES, // REQUIRED Stored expiration in unix timestamp
|
||||
* "redirect_uri" => REDIRECT_URI, // REQUIRED Stored redirect URI
|
||||
* "scope" => SCOPE, // OPTIONAL Stored scope values in space-separated string
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4.1
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
public function getAuthorizationCode($code);
|
||||
|
||||
/**
|
||||
* Take the provided authorization code values and store them somewhere.
|
||||
*
|
||||
* This function should be the storage counterpart to getAuthCode().
|
||||
*
|
||||
* If storage fails for some reason, we're not currently checking for
|
||||
* any sort of success/failure, so you should bail out of the script
|
||||
* and provide a descriptive fail message.
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_AUTH_CODE.
|
||||
*
|
||||
* @param string $code Authorization code to be stored.
|
||||
* @param mixed $client_id Client identifier to be stored.
|
||||
* @param mixed $user_id User identifier to be stored.
|
||||
* @param string $redirect_uri Redirect URI(s) to be stored in a space-separated string.
|
||||
* @param int $expires Expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope OPTIONAL Scopes to be stored in space-separated string.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null);
|
||||
|
||||
/**
|
||||
* once an Authorization Code is used, it must be exipired
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4.1.2
|
||||
*
|
||||
* The client MUST NOT use the authorization code
|
||||
* more than once. If an authorization code is used more than
|
||||
* once, the authorization server MUST deny the request and SHOULD
|
||||
* revoke (when possible) all tokens previously issued based on
|
||||
* that authorization code
|
||||
*
|
||||
*/
|
||||
public function expireAuthorizationCode($code);
|
||||
}
|
469
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Cassandra.php
vendored
Normal file
469
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Cassandra.php
vendored
Normal file
|
@ -0,0 +1,469 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use phpcassa\ColumnFamily;
|
||||
use phpcassa\ColumnSlice;
|
||||
use phpcassa\Connection\ConnectionPool;
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
* Cassandra storage for all storage types
|
||||
*
|
||||
* To use, install "thobbs/phpcassa" via composer
|
||||
* <code>
|
||||
* composer require thobbs/phpcassa:dev-master
|
||||
* </code>
|
||||
*
|
||||
* Once this is done, instantiate the
|
||||
* <code>
|
||||
* $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_server', array('127.0.0.1:9160'));
|
||||
* </code>
|
||||
*
|
||||
* Then, register the storage client:
|
||||
* <code>
|
||||
* $storage = new OAuth2\Storage\Cassandra($cassandra);
|
||||
* $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
|
||||
* </code>
|
||||
*
|
||||
* @see test/lib/OAuth2/Storage/Bootstrap::getCassandraStorage
|
||||
*/
|
||||
class Cassandra implements AuthorizationCodeInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
UserCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
ScopeInterface,
|
||||
PublicKeyInterface,
|
||||
UserClaimsInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
|
||||
private $cache;
|
||||
|
||||
/* The cassandra client */
|
||||
protected $cassandra;
|
||||
|
||||
/* Configuration array */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Cassandra Storage! uses phpCassa
|
||||
*
|
||||
* @param \phpcassa\ConnectionPool $cassandra
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($connection = array(), array $config = array())
|
||||
{
|
||||
if ($connection instanceof ConnectionPool) {
|
||||
$this->cassandra = $connection;
|
||||
} else {
|
||||
if (!is_array($connection)) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Cassandra must be an instance of phpcassa\Connection\ConnectionPool or a configuration array');
|
||||
}
|
||||
$connection = array_merge(array(
|
||||
'keyspace' => 'oauth2',
|
||||
'servers' => null,
|
||||
), $connection);
|
||||
|
||||
$this->cassandra = new ConnectionPool($connection['keyspace'], $connection['servers']);
|
||||
}
|
||||
|
||||
$this->config = array_merge(array(
|
||||
// cassandra config
|
||||
'column_family' => 'auth',
|
||||
|
||||
// key names
|
||||
'client_key' => 'oauth_clients:',
|
||||
'access_token_key' => 'oauth_access_tokens:',
|
||||
'refresh_token_key' => 'oauth_refresh_tokens:',
|
||||
'code_key' => 'oauth_authorization_codes:',
|
||||
'user_key' => 'oauth_users:',
|
||||
'jwt_key' => 'oauth_jwt:',
|
||||
'scope_key' => 'oauth_scopes:',
|
||||
'public_key_key' => 'oauth_public_keys:',
|
||||
), $config);
|
||||
}
|
||||
|
||||
protected function getValue($key)
|
||||
{
|
||||
if (isset($this->cache[$key])) {
|
||||
return $this->cache[$key];
|
||||
}
|
||||
$cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
|
||||
|
||||
try {
|
||||
$value = $cf->get($key, new ColumnSlice("", ""));
|
||||
$value = array_shift($value);
|
||||
} catch (\cassandra\NotFoundException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return json_decode($value, true);
|
||||
}
|
||||
|
||||
protected function setValue($key, $value, $expire = 0)
|
||||
{
|
||||
$this->cache[$key] = $value;
|
||||
|
||||
$cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
|
||||
|
||||
$str = json_encode($value);
|
||||
if ($expire > 0) {
|
||||
try {
|
||||
$seconds = $expire - time();
|
||||
// __data key set as C* requires a field, note: max TTL can only be 630720000 seconds
|
||||
$cf->insert($key, array('__data' => $str), null, $seconds);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// __data key set as C* requires a field
|
||||
$cf->insert($key, array('__data' => $str));
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function expireValue($key)
|
||||
{
|
||||
unset($this->cache[$key]);
|
||||
|
||||
$cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
|
||||
try {
|
||||
// __data key set as C* requires a field
|
||||
$cf->remove($key, array('__data'));
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
return $this->getValue($this->config['code_key'] . $code);
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['code_key'] . $authorization_code,
|
||||
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
|
||||
$expires
|
||||
);
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$key = $this->config['code_key'] . $code;
|
||||
unset($this->cache[$key]);
|
||||
|
||||
return $this->expireValue($key);
|
||||
}
|
||||
|
||||
/* UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
return $this->checkPassword($user, $password);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == sha1($password);
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// the default behavior is to use "username" as the user_id
|
||||
return array_merge(array(
|
||||
'user_id' => $username,
|
||||
), $userInfo);
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $first_name = null, $last_name = null)
|
||||
{
|
||||
$password = sha1($password);
|
||||
|
||||
return $this->setValue(
|
||||
$this->config['user_key'] . $username,
|
||||
compact('username', 'password', 'first_name', 'last_name')
|
||||
);
|
||||
}
|
||||
|
||||
/* ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
if (!$client = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset($client['client_secret'])
|
||||
&& $client['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
if (!$client = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($result['client_secret']);;
|
||||
}
|
||||
|
||||
/* ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
return $this->getValue($this->config['client_key'] . $client_id);
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['client_key'] . $client_id,
|
||||
compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
|
||||
);
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
if (isset($details['grant_types'])) {
|
||||
$grant_types = explode(' ', $details['grant_types']);
|
||||
|
||||
return in_array($grant_type, (array) $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
/* RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['refresh_token_key'] . $refresh_token,
|
||||
compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'),
|
||||
$expires
|
||||
);
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
return $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
|
||||
}
|
||||
|
||||
/* AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
return $this->getValue($this->config['access_token_key'].$access_token);
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['access_token_key'].$access_token,
|
||||
compact('access_token', 'client_id', 'user_id', 'expires', 'scope'),
|
||||
$expires
|
||||
);
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
return $this->expireValue($this->config['access_token_key'] . $access_token);
|
||||
}
|
||||
|
||||
/* ScopeInterface */
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', $scope);
|
||||
|
||||
$result = $this->getValue($this->config['scope_key'].'supported:global');
|
||||
|
||||
$supportedScope = explode(' ', (string) $result);
|
||||
|
||||
return (count(array_diff($scope, $supportedScope)) == 0);
|
||||
}
|
||||
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
|
||||
$result = $this->getValue($this->config['scope_key'].'default:global');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setScope($scope, $client_id = null, $type = 'supported')
|
||||
{
|
||||
if (!in_array($type, array('default', 'supported'))) {
|
||||
throw new \InvalidArgumentException('"$type" must be one of "default", "supported"');
|
||||
}
|
||||
|
||||
if (is_null($client_id)) {
|
||||
$key = $this->config['scope_key'].$type.':global';
|
||||
} else {
|
||||
$key = $this->config['scope_key'].$type.':'.$client_id;
|
||||
}
|
||||
|
||||
return $this->setValue($key, $scope);
|
||||
}
|
||||
|
||||
/*JWTBearerInterface */
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($jwt['subject']) && $jwt['subject'] == $subject ) {
|
||||
return $jwt['key'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setClientKey($client_id, $key, $subject = null)
|
||||
{
|
||||
return $this->setValue($this->config['jwt_key'] . $client_id, array(
|
||||
'key' => $key,
|
||||
'subject' => $subject
|
||||
));
|
||||
}
|
||||
|
||||
/*ScopeInterface */
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs cassandra implementation.
|
||||
throw new \Exception('getJti() for the Cassandra driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs cassandra implementation.
|
||||
throw new \Exception('setJti() for the Cassandra driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
/* PublicKeyInterface */
|
||||
public function getPublicKey($client_id = '')
|
||||
{
|
||||
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
|
||||
if (is_array($public_key)) {
|
||||
return $public_key['public_key'];
|
||||
}
|
||||
$public_key = $this->getValue($this->config['public_key_key']);
|
||||
if (is_array($public_key)) {
|
||||
return $public_key['public_key'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrivateKey($client_id = '')
|
||||
{
|
||||
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
|
||||
if (is_array($public_key)) {
|
||||
return $public_key['private_key'];
|
||||
}
|
||||
$public_key = $this->getValue($this->config['public_key_key']);
|
||||
if (is_array($public_key)) {
|
||||
return $public_key['private_key'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getEncryptionAlgorithm($client_id = null)
|
||||
{
|
||||
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
|
||||
if (is_array($public_key)) {
|
||||
return $public_key['encryption_algorithm'];
|
||||
}
|
||||
$public_key = $this->getValue($this->config['public_key_key']);
|
||||
if (is_array($public_key)) {
|
||||
return $public_key['encryption_algorithm'];
|
||||
}
|
||||
|
||||
return 'RS256';
|
||||
}
|
||||
|
||||
/* UserClaimsInterface */
|
||||
public function getUserClaims($user_id, $claims)
|
||||
{
|
||||
$userDetails = $this->getUserDetails($user_id);
|
||||
if (!is_array($userDetails)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$claims = explode(' ', trim($claims));
|
||||
$userClaims = array();
|
||||
|
||||
// for each requested claim, if the user has the claim, set it in the response
|
||||
$validClaims = explode(' ', self::VALID_CLAIMS);
|
||||
foreach ($validClaims as $validClaim) {
|
||||
if (in_array($validClaim, $claims)) {
|
||||
if ($validClaim == 'address') {
|
||||
// address is an object with subfields
|
||||
$userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
|
||||
} else {
|
||||
$userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
protected function getUserClaim($claim, $userDetails)
|
||||
{
|
||||
$userClaims = array();
|
||||
$claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
|
||||
$claimValues = explode(' ', $claimValuesString);
|
||||
|
||||
foreach ($claimValues as $value) {
|
||||
if ($value == 'email_verified') {
|
||||
$userClaims[$value] = $userDetails[$value]=='true' ? true : false;
|
||||
} else {
|
||||
$userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
}
|
49
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientCredentialsInterface.php
vendored
Normal file
49
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientCredentialsInterface.php
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify how the OAuth2 Server
|
||||
* should verify client credentials
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface ClientCredentialsInterface extends ClientInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Make sure that the client credentials is valid.
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier to be check with.
|
||||
* @param $client_secret
|
||||
* (optional) If a secret is required, check that they've given the right one.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the client credentials are valid, and MUST return FALSE if it isn't.
|
||||
* @endcode
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-3.1
|
||||
*
|
||||
* @ingroup oauth2_section_3
|
||||
*/
|
||||
public function checkClientCredentials($client_id, $client_secret = null);
|
||||
|
||||
/**
|
||||
* Determine if the client is a "public" client, and therefore
|
||||
* does not require passing credentials for certain grant types
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier to be check with.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the client is public, and FALSE if it isn't.
|
||||
* @endcode
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-2.3
|
||||
* @see https://github.com/bshaffer/oauth2-server-php/issues/257
|
||||
*
|
||||
* @ingroup oauth2_section_2
|
||||
*/
|
||||
public function isPublicClient($client_id);
|
||||
}
|
66
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientInterface.php
vendored
Normal file
66
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientInterface.php
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should retrieve client information
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface ClientInterface
|
||||
{
|
||||
/**
|
||||
* Get client details corresponding client_id.
|
||||
*
|
||||
* OAuth says we should store request URIs for each registered client.
|
||||
* Implement this function to grab the stored URI for a given client id.
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier to be check with.
|
||||
*
|
||||
* @return array
|
||||
* Client details. The only mandatory key in the array is "redirect_uri".
|
||||
* This function MUST return FALSE if the given client does not exist or is
|
||||
* invalid. "redirect_uri" can be space-delimited to allow for multiple valid uris.
|
||||
* <code>
|
||||
* return array(
|
||||
* "redirect_uri" => REDIRECT_URI, // REQUIRED redirect_uri registered for the client
|
||||
* "client_id" => CLIENT_ID, // OPTIONAL the client id
|
||||
* "grant_types" => GRANT_TYPES, // OPTIONAL an array of restricted grant types
|
||||
* "user_id" => USER_ID, // OPTIONAL the user identifier associated with this client
|
||||
* "scope" => SCOPE, // OPTIONAL the scopes allowed for this client
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
public function getClientDetails($client_id);
|
||||
|
||||
/**
|
||||
* Get the scope associated with this client
|
||||
*
|
||||
* @return
|
||||
* STRING the space-delineated scope list for the specified client_id
|
||||
*/
|
||||
public function getClientScope($client_id);
|
||||
|
||||
/**
|
||||
* Check restricted grant types of corresponding client identifier.
|
||||
*
|
||||
* If you want to restrict clients to certain grant types, override this
|
||||
* function.
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier to be check with.
|
||||
* @param $grant_type
|
||||
* Grant type to be check with
|
||||
*
|
||||
* @return
|
||||
* TRUE if the grant type is supported by this client identifier, and
|
||||
* FALSE if it isn't.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
public function checkRestrictedGrantType($client_id, $grant_type);
|
||||
}
|
331
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
vendored
Executable file
331
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
vendored
Executable file
|
@ -0,0 +1,331 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
* Simple Couchbase storage for all storage types
|
||||
*
|
||||
* This class should be extended or overridden as required
|
||||
*
|
||||
* NOTE: Passwords are stored in plaintext, which is never
|
||||
* a good idea. Be sure to override this for your application
|
||||
*
|
||||
* @author Tom Park <tom@raucter.com>
|
||||
*/
|
||||
class CouchbaseDB implements AuthorizationCodeInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
UserCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
protected $db;
|
||||
protected $config;
|
||||
|
||||
public function __construct($connection, $config = array())
|
||||
{
|
||||
if ($connection instanceof \Couchbase) {
|
||||
$this->db = $connection;
|
||||
} else {
|
||||
if (!is_array($connection) || !is_array($connection['servers'])) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\CouchbaseDB must be an instance of Couchbase or a configuration array containing a server array');
|
||||
}
|
||||
|
||||
$this->db = new \Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
|
||||
}
|
||||
|
||||
$this->config = array_merge(array(
|
||||
'client_table' => 'oauth_clients',
|
||||
'access_token_table' => 'oauth_access_tokens',
|
||||
'refresh_token_table' => 'oauth_refresh_tokens',
|
||||
'code_table' => 'oauth_authorization_codes',
|
||||
'user_table' => 'oauth_users',
|
||||
'jwt_table' => 'oauth_jwt',
|
||||
), $config);
|
||||
}
|
||||
|
||||
// Helper function to access couchbase item by type:
|
||||
protected function getObjectByType($name,$id)
|
||||
{
|
||||
return json_decode($this->db->get($this->config[$name].'-'.$id),true);
|
||||
}
|
||||
|
||||
// Helper function to set couchbase item by type:
|
||||
protected function setObjectByType($name,$id,$array)
|
||||
{
|
||||
$array['type'] = $name;
|
||||
|
||||
return $this->db->set($this->config[$name].'-'.$id,json_encode($array));
|
||||
}
|
||||
|
||||
// Helper function to delete couchbase item by type, wait for persist to at least 1 node
|
||||
protected function deleteObjectByType($name,$id)
|
||||
{
|
||||
$this->db->delete($this->config[$name].'-'.$id,"",1);
|
||||
}
|
||||
|
||||
/* ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
if ($result = $this->getObjectByType('client_table',$client_id)) {
|
||||
return $result['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
if (!$result = $this->getObjectByType('client_table',$client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($result['client_secret']);
|
||||
}
|
||||
|
||||
/* ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
$result = $this->getObjectByType('client_table',$client_id);
|
||||
|
||||
return is_null($result) ? false : $result;
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
if ($this->getClientDetails($client_id)) {
|
||||
|
||||
$this->setObjectByType('client_table',$client_id, array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $client_secret,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'grant_types' => $grant_types,
|
||||
'scope' => $scope,
|
||||
'user_id' => $user_id,
|
||||
));
|
||||
} else {
|
||||
$this->setObjectByType('client_table',$client_id, array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $client_secret,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'grant_types' => $grant_types,
|
||||
'scope' => $scope,
|
||||
'user_id' => $user_id,
|
||||
));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
if (isset($details['grant_types'])) {
|
||||
$grant_types = explode(' ', $details['grant_types']);
|
||||
|
||||
return in_array($grant_type, $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
/* AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
$token = $this->getObjectByType('access_token_table',$access_token);
|
||||
|
||||
return is_null($token) ? false : $token;
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// if it exists, update it.
|
||||
if ($this->getAccessToken($access_token)) {
|
||||
$this->setObjectByType('access_token_table',$access_token, array(
|
||||
'access_token' => $access_token,
|
||||
'client_id' => $client_id,
|
||||
'expires' => $expires,
|
||||
'user_id' => $user_id,
|
||||
'scope' => $scope
|
||||
));
|
||||
} else {
|
||||
$this->setObjectByType('access_token_table',$access_token, array(
|
||||
'access_token' => $access_token,
|
||||
'client_id' => $client_id,
|
||||
'expires' => $expires,
|
||||
'user_id' => $user_id,
|
||||
'scope' => $scope
|
||||
));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
$code = $this->getObjectByType('code_table',$code);
|
||||
|
||||
return is_null($code) ? false : $code;
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
// if it exists, update it.
|
||||
if ($this->getAuthorizationCode($code)) {
|
||||
$this->setObjectByType('code_table',$code, array(
|
||||
'authorization_code' => $code,
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
'id_token' => $id_token,
|
||||
));
|
||||
} else {
|
||||
$this->setObjectByType('code_table',$code,array(
|
||||
'authorization_code' => $code,
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
'id_token' => $id_token,
|
||||
));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$this->deleteObjectByType('code_table',$code);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
return $this->checkPassword($user, $password);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
$user['user_id'] = $user['username'];
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/* RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
$token = $this->getObjectByType('refresh_token_table',$refresh_token);
|
||||
|
||||
return is_null($token) ? false : $token;
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
$this->setObjectByType('refresh_token_table',$refresh_token, array(
|
||||
'refresh_token' => $refresh_token,
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
$this->deleteObjectByType('refresh_token_table',$refresh_token);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == $password;
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
$result = $this->getObjectByType('user_table',$username);
|
||||
|
||||
return is_null($result) ? false : $result;
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $firstName = null, $lastName = null)
|
||||
{
|
||||
if ($this->getUser($username)) {
|
||||
$this->setObjectByType('user_table',$username, array(
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName
|
||||
));
|
||||
|
||||
} else {
|
||||
$this->setObjectByType('user_table',$username, array(
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
if (!$jwt = $this->getObjectByType('jwt_table',$client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($jwt['subject']) && $jwt['subject'] == $subject) {
|
||||
return $jwt['key'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs couchbase implementation.
|
||||
throw new \Exception('getJti() for the Couchbase driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs couchbase implementation.
|
||||
throw new \Exception('setJti() for the Couchbase driver is currently unimplemented.');
|
||||
}
|
||||
}
|
528
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/DynamoDB.php
vendored
Normal file
528
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/DynamoDB.php
vendored
Normal file
|
@ -0,0 +1,528 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use Aws\DynamoDb\DynamoDbClient;
|
||||
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
/**
|
||||
* DynamoDB storage for all storage types
|
||||
*
|
||||
* To use, install "aws/aws-sdk-php" via composer
|
||||
* <code>
|
||||
* composer require aws/aws-sdk-php:dev-master
|
||||
* </code>
|
||||
*
|
||||
* Once this is done, instantiate the DynamoDB client
|
||||
* <code>
|
||||
* $storage = new OAuth2\Storage\Dynamodb(array("key" => "YOURKEY", "secret" => "YOURSECRET", "region" => "YOURREGION"));
|
||||
* </code>
|
||||
*
|
||||
* Table :
|
||||
* - oauth_access_tokens (primary hash key : access_token)
|
||||
* - oauth_authorization_codes (primary hash key : authorization_code)
|
||||
* - oauth_clients (primary hash key : client_id)
|
||||
* - oauth_jwt (primary hash key : client_id, primary range key : subject)
|
||||
* - oauth_public_keys (primary hash key : client_id)
|
||||
* - oauth_refresh_tokens (primary hash key : refresh_token)
|
||||
* - oauth_scopes (primary hash key : scope, secondary index : is_default-index hash key is_default)
|
||||
* - oauth_users (primary hash key : username)
|
||||
*
|
||||
* @author Frederic AUGUSTE <frederic.auguste at gmail dot com>
|
||||
*/
|
||||
class DynamoDB implements
|
||||
AuthorizationCodeInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
UserCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
ScopeInterface,
|
||||
PublicKeyInterface,
|
||||
UserClaimsInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
protected $client;
|
||||
protected $config;
|
||||
|
||||
public function __construct($connection, $config = array())
|
||||
{
|
||||
if (!($connection instanceof DynamoDbClient)) {
|
||||
if (!is_array($connection)) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Dynamodb must be an instance a configuration array containt key, secret, region');
|
||||
}
|
||||
if (!array_key_exists("key",$connection) || !array_key_exists("secret",$connection) || !array_key_exists("region",$connection) ) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Dynamodb must be an instance a configuration array containt key, secret, region');
|
||||
}
|
||||
$this->client = DynamoDbClient::factory(array(
|
||||
'key' => $connection["key"],
|
||||
'secret' => $connection["secret"],
|
||||
'region' =>$connection["region"]
|
||||
));
|
||||
} else {
|
||||
$this->client = $connection;
|
||||
}
|
||||
|
||||
$this->config = array_merge(array(
|
||||
'client_table' => 'oauth_clients',
|
||||
'access_token_table' => 'oauth_access_tokens',
|
||||
'refresh_token_table' => 'oauth_refresh_tokens',
|
||||
'code_table' => 'oauth_authorization_codes',
|
||||
'user_table' => 'oauth_users',
|
||||
'jwt_table' => 'oauth_jwt',
|
||||
'scope_table' => 'oauth_scopes',
|
||||
'public_key_table' => 'oauth_public_keys',
|
||||
), $config);
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['client_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id))
|
||||
));
|
||||
|
||||
return $result->count()==1 && $result["Item"]["client_secret"]["S"] == $client_secret;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['client_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id))
|
||||
));
|
||||
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
|
||||
return empty($result["Item"]["client_secret"]);
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['client_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$result = $this->dynamo2array($result);
|
||||
foreach (array('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id') as $key => $val) {
|
||||
if (!array_key_exists ($val, $result)) {
|
||||
$result[$val] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
$clientData = compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id');
|
||||
$clientData = array_filter($clientData, function ($value) { return !is_null($value); });
|
||||
|
||||
$result = $this->client->putItem(array(
|
||||
'TableName' => $this->config['client_table'],
|
||||
'Item' => $this->client->formatAttributes($clientData)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
if (isset($details['grant_types'])) {
|
||||
$grant_types = explode(' ', $details['grant_types']);
|
||||
|
||||
return in_array($grant_type, (array) $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['access_token_table'],
|
||||
"Key" => array('access_token' => array('S' => $access_token))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
if (array_key_exists ('expires', $token)) {
|
||||
$token['expires'] = strtotime($token['expires']);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
$clientData = compact('access_token', 'client_id', 'user_id', 'expires', 'scope');
|
||||
$clientData = array_filter($clientData, function ($value) { return !empty($value); });
|
||||
|
||||
$result = $this->client->putItem(array(
|
||||
'TableName' => $this->config['access_token_table'],
|
||||
'Item' => $this->client->formatAttributes($clientData)
|
||||
));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
$result = $this->client->deleteItem(array(
|
||||
'TableName' => $this->config['access_token_table'],
|
||||
'Key' => $this->client->formatAttributes(array("access_token" => $access_token))
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['code_table'],
|
||||
"Key" => array('authorization_code' => array('S' => $code))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
if (!array_key_exists("id_token", $token )) {
|
||||
$token['id_token'] = null;
|
||||
}
|
||||
$token['expires'] = strtotime($token['expires']);
|
||||
|
||||
return $token;
|
||||
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
$clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'id_token', 'scope');
|
||||
$clientData = array_filter($clientData, function ($value) { return !empty($value); });
|
||||
|
||||
$result = $this->client->putItem(array(
|
||||
'TableName' => $this->config['code_table'],
|
||||
'Item' => $this->client->formatAttributes($clientData)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
|
||||
$result = $this->client->deleteItem(array(
|
||||
'TableName' => $this->config['code_table'],
|
||||
'Key' => $this->client->formatAttributes(array("authorization_code" => $code))
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
return $this->checkPassword($user, $password);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
/* UserClaimsInterface */
|
||||
public function getUserClaims($user_id, $claims)
|
||||
{
|
||||
if (!$userDetails = $this->getUserDetails($user_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$claims = explode(' ', trim($claims));
|
||||
$userClaims = array();
|
||||
|
||||
// for each requested claim, if the user has the claim, set it in the response
|
||||
$validClaims = explode(' ', self::VALID_CLAIMS);
|
||||
foreach ($validClaims as $validClaim) {
|
||||
if (in_array($validClaim, $claims)) {
|
||||
if ($validClaim == 'address') {
|
||||
// address is an object with subfields
|
||||
$userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
|
||||
} else {
|
||||
$userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
protected function getUserClaim($claim, $userDetails)
|
||||
{
|
||||
$userClaims = array();
|
||||
$claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
|
||||
$claimValues = explode(' ', $claimValuesString);
|
||||
|
||||
foreach ($claimValues as $value) {
|
||||
if ($value == 'email_verified') {
|
||||
$userClaims[$value] = $userDetails[$value]=='true' ? true : false;
|
||||
} else {
|
||||
$userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['refresh_token_table'],
|
||||
"Key" => array('refresh_token' => array('S' => $refresh_token))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
$token['expires'] = strtotime($token['expires']);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
$clientData = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
|
||||
$clientData = array_filter($clientData, function ($value) { return !empty($value); });
|
||||
|
||||
$result = $this->client->putItem(array(
|
||||
'TableName' => $this->config['refresh_token_table'],
|
||||
'Item' => $this->client->formatAttributes($clientData)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
$result = $this->client->deleteItem(array(
|
||||
'TableName' => $this->config['refresh_token_table'],
|
||||
'Key' => $this->client->formatAttributes(array("refresh_token" => $refresh_token))
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == sha1($password);
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['user_table'],
|
||||
"Key" => array('username' => array('S' => $username))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
$token['user_id'] = $username;
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $first_name = null, $last_name = null)
|
||||
{
|
||||
// do not store in plaintext
|
||||
$password = sha1($password);
|
||||
|
||||
$clientData = compact('username', 'password', 'first_name', 'last_name');
|
||||
$clientData = array_filter($clientData, function ($value) { return !is_null($value); });
|
||||
|
||||
$result = $this->client->putItem(array(
|
||||
'TableName' => $this->config['user_table'],
|
||||
'Item' => $this->client->formatAttributes($clientData)
|
||||
));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/* ScopeInterface */
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', $scope);
|
||||
$scope_query = array();
|
||||
$count = 0;
|
||||
foreach ($scope as $key => $val) {
|
||||
$result = $this->client->query(array(
|
||||
'TableName' => $this->config['scope_table'],
|
||||
'Select' => 'COUNT',
|
||||
'KeyConditions' => array(
|
||||
'scope' => array(
|
||||
'AttributeValueList' => array(array('S' => $val)),
|
||||
'ComparisonOperator' => 'EQ'
|
||||
)
|
||||
)
|
||||
));
|
||||
$count += $result['Count'];
|
||||
}
|
||||
|
||||
return $count == count($scope);
|
||||
}
|
||||
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
|
||||
$result = $this->client->query(array(
|
||||
'TableName' => $this->config['scope_table'],
|
||||
'IndexName' => 'is_default-index',
|
||||
'Select' => 'ALL_ATTRIBUTES',
|
||||
'KeyConditions' => array(
|
||||
'is_default' => array(
|
||||
'AttributeValueList' => array(array('S' => 'true')),
|
||||
'ComparisonOperator' => 'EQ',
|
||||
),
|
||||
)
|
||||
));
|
||||
$defaultScope = array();
|
||||
if ($result->count() > 0) {
|
||||
$array = $result->toArray();
|
||||
foreach ($array["Items"] as $item) {
|
||||
$defaultScope[] = $item['scope']['S'];
|
||||
}
|
||||
|
||||
return empty($defaultScope) ? null : implode(' ', $defaultScope);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* JWTBearerInterface */
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['jwt_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id), 'subject' => array('S' => $subject))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
|
||||
return $token['public_key'];
|
||||
}
|
||||
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
//TODO not use.
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
//TODO not use.
|
||||
}
|
||||
|
||||
/* PublicKeyInterface */
|
||||
public function getPublicKey($client_id = '0')
|
||||
{
|
||||
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['public_key_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
|
||||
return $token['public_key'];
|
||||
|
||||
}
|
||||
|
||||
public function getPrivateKey($client_id = '0')
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['public_key_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return false ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
|
||||
return $token['private_key'];
|
||||
}
|
||||
|
||||
public function getEncryptionAlgorithm($client_id = null)
|
||||
{
|
||||
$result = $this->client->getItem(array(
|
||||
"TableName"=> $this->config['public_key_table'],
|
||||
"Key" => array('client_id' => array('S' => $client_id))
|
||||
));
|
||||
if ($result->count()==0) {
|
||||
return 'RS256' ;
|
||||
}
|
||||
$token = $this->dynamo2array($result);
|
||||
|
||||
return $token['encryption_algorithm'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform dynamodb resultset to an array.
|
||||
* @param $dynamodbResult
|
||||
* @return $array
|
||||
*/
|
||||
private function dynamo2array($dynamodbResult)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($dynamodbResult["Item"] as $key => $val) {
|
||||
$result[$key] = $val["S"];
|
||||
$result[] = $val["S"];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
88
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessToken.php
vendored
Normal file
88
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessToken.php
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\Encryption\EncryptionInterface;
|
||||
use OAuth2\Encryption\Jwt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class JwtAccessToken implements JwtAccessTokenInterface
|
||||
{
|
||||
protected $publicKeyStorage;
|
||||
protected $tokenStorage;
|
||||
protected $encryptionUtil;
|
||||
|
||||
/**
|
||||
* @param OAuth2\Encryption\PublicKeyInterface $publicKeyStorage the public key encryption to use
|
||||
* @param OAuth2\Storage\AccessTokenInterface $tokenStorage OPTIONAL persist the access token to another storage. This is useful if
|
||||
* you want to retain access token grant information somewhere, but
|
||||
* is not necessary when using this grant type.
|
||||
* @param OAuth2\Encryption\EncryptionInterface $encryptionUtil OPTIONAL class to use for "encode" and "decode" functions.
|
||||
*/
|
||||
public function __construct(PublicKeyInterface $publicKeyStorage, AccessTokenInterface $tokenStorage = null, EncryptionInterface $encryptionUtil = null)
|
||||
{
|
||||
$this->publicKeyStorage = $publicKeyStorage;
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
if (is_null($encryptionUtil)) {
|
||||
$encryptionUtil = new Jwt;
|
||||
}
|
||||
$this->encryptionUtil = $encryptionUtil;
|
||||
}
|
||||
|
||||
public function getAccessToken($oauth_token)
|
||||
{
|
||||
// just decode the token, don't verify
|
||||
if (!$tokenData = $this->encryptionUtil->decode($oauth_token, null, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client_id = isset($tokenData['aud']) ? $tokenData['aud'] : null;
|
||||
$public_key = $this->publicKeyStorage->getPublicKey($client_id);
|
||||
$algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
|
||||
|
||||
// now that we have the client_id, verify the token
|
||||
if (false === $this->encryptionUtil->decode($oauth_token, $public_key, array($algorithm))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// normalize the JWT claims to the format expected by other components in this library
|
||||
return $this->convertJwtToOAuth2($tokenData);
|
||||
}
|
||||
|
||||
public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
if ($this->tokenStorage) {
|
||||
return $this->tokenStorage->setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope);
|
||||
}
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
if ($this->tokenStorage) {
|
||||
return $this->tokenStorage->unsetAccessToken($access_token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// converts a JWT access token into an OAuth2-friendly format
|
||||
protected function convertJwtToOAuth2($tokenData)
|
||||
{
|
||||
$keyMapping = array(
|
||||
'aud' => 'client_id',
|
||||
'exp' => 'expires',
|
||||
'sub' => 'user_id'
|
||||
);
|
||||
|
||||
foreach ($keyMapping as $jwtKey => $oauth2Key) {
|
||||
if (isset($tokenData[$jwtKey])) {
|
||||
$tokenData[$oauth2Key] = $tokenData[$jwtKey];
|
||||
unset($tokenData[$jwtKey]);
|
||||
}
|
||||
}
|
||||
|
||||
return $tokenData;
|
||||
}
|
||||
}
|
14
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessTokenInterface.php
vendored
Normal file
14
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessTokenInterface.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* No specific methods, but allows the library to check "instanceof"
|
||||
* against interface rather than class
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface JwtAccessTokenInterface extends AccessTokenInterface
|
||||
{
|
||||
|
||||
}
|
74
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtBearerInterface.php
vendored
Normal file
74
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtBearerInterface.php
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should get the JWT key for clients
|
||||
*
|
||||
* @TODO consider extending ClientInterface, as this will almost always
|
||||
* be the same storage as retrieving clientData
|
||||
*
|
||||
* @author F21
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface JwtBearerInterface
|
||||
{
|
||||
/**
|
||||
* Get the public key associated with a client_id
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier to be checked with.
|
||||
*
|
||||
* @return
|
||||
* STRING Return the public key for the client_id if it exists, and MUST return FALSE if it doesn't.
|
||||
*/
|
||||
public function getClientKey($client_id, $subject);
|
||||
|
||||
/**
|
||||
* Get a jti (JSON token identifier) by matching against the client_id, subject, audience and expiration.
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier to match.
|
||||
*
|
||||
* @param $subject
|
||||
* The subject to match.
|
||||
*
|
||||
* @param $audience
|
||||
* The audience to match.
|
||||
*
|
||||
* @param $expiration
|
||||
* The expiration of the jti.
|
||||
*
|
||||
* @param $jti
|
||||
* The jti to match.
|
||||
*
|
||||
* @return
|
||||
* An associative array as below, and return NULL if the jti does not exist.
|
||||
* - issuer: Stored client identifier.
|
||||
* - subject: Stored subject.
|
||||
* - audience: Stored audience.
|
||||
* - expires: Stored expiration in unix timestamp.
|
||||
* - jti: The stored jti.
|
||||
*/
|
||||
public function getJti($client_id, $subject, $audience, $expiration, $jti);
|
||||
|
||||
/**
|
||||
* Store a used jti so that we can check against it to prevent replay attacks.
|
||||
* @param $client_id
|
||||
* Client identifier to insert.
|
||||
*
|
||||
* @param $subject
|
||||
* The subject to insert.
|
||||
*
|
||||
* @param $audience
|
||||
* The audience to insert.
|
||||
*
|
||||
* @param $expiration
|
||||
* The expiration of the jti.
|
||||
*
|
||||
* @param $jti
|
||||
* The jti to insert.
|
||||
*/
|
||||
public function setJti($client_id, $subject, $audience, $expiration, $jti);
|
||||
}
|
369
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Memory.php
vendored
Normal file
369
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Memory.php
vendored
Normal file
|
@ -0,0 +1,369 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
* Simple in-memory storage for all storage types
|
||||
*
|
||||
* NOTE: This class should never be used in production, and is
|
||||
* a stub class for example use only
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class Memory implements AuthorizationCodeInterface,
|
||||
UserCredentialsInterface,
|
||||
UserClaimsInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
ScopeInterface,
|
||||
PublicKeyInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
public $authorizationCodes;
|
||||
public $userCredentials;
|
||||
public $clientCredentials;
|
||||
public $refreshTokens;
|
||||
public $accessTokens;
|
||||
public $jwt;
|
||||
public $jti;
|
||||
public $supportedScopes;
|
||||
public $defaultScope;
|
||||
public $keys;
|
||||
|
||||
public function __construct($params = array())
|
||||
{
|
||||
$params = array_merge(array(
|
||||
'authorization_codes' => array(),
|
||||
'user_credentials' => array(),
|
||||
'client_credentials' => array(),
|
||||
'refresh_tokens' => array(),
|
||||
'access_tokens' => array(),
|
||||
'jwt' => array(),
|
||||
'jti' => array(),
|
||||
'default_scope' => null,
|
||||
'supported_scopes' => array(),
|
||||
'keys' => array(),
|
||||
), $params);
|
||||
|
||||
$this->authorizationCodes = $params['authorization_codes'];
|
||||
$this->userCredentials = $params['user_credentials'];
|
||||
$this->clientCredentials = $params['client_credentials'];
|
||||
$this->refreshTokens = $params['refresh_tokens'];
|
||||
$this->accessTokens = $params['access_tokens'];
|
||||
$this->jwt = $params['jwt'];
|
||||
$this->jti = $params['jti'];
|
||||
$this->supportedScopes = $params['supported_scopes'];
|
||||
$this->defaultScope = $params['default_scope'];
|
||||
$this->keys = $params['keys'];
|
||||
}
|
||||
|
||||
/* AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
if (!isset($this->authorizationCodes[$code])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_merge(array(
|
||||
'authorization_code' => $code,
|
||||
), $this->authorizationCodes[$code]);
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
$this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setAuthorizationCodes($authorization_codes)
|
||||
{
|
||||
$this->authorizationCodes = $authorization_codes;
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
unset($this->authorizationCodes[$code]);
|
||||
}
|
||||
|
||||
/* UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
$userDetails = $this->getUserDetails($username);
|
||||
|
||||
return $userDetails && $userDetails['password'] && $userDetails['password'] === $password;
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $firstName = null, $lastName = null)
|
||||
{
|
||||
$this->userCredentials[$username] = array(
|
||||
'password' => $password,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
if (!isset($this->userCredentials[$username])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_merge(array(
|
||||
'user_id' => $username,
|
||||
'password' => null,
|
||||
'first_name' => null,
|
||||
'last_name' => null,
|
||||
), $this->userCredentials[$username]);
|
||||
}
|
||||
|
||||
/* UserClaimsInterface */
|
||||
public function getUserClaims($user_id, $claims)
|
||||
{
|
||||
if (!$userDetails = $this->getUserDetails($user_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$claims = explode(' ', trim($claims));
|
||||
$userClaims = array();
|
||||
|
||||
// for each requested claim, if the user has the claim, set it in the response
|
||||
$validClaims = explode(' ', self::VALID_CLAIMS);
|
||||
foreach ($validClaims as $validClaim) {
|
||||
if (in_array($validClaim, $claims)) {
|
||||
if ($validClaim == 'address') {
|
||||
// address is an object with subfields
|
||||
$userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
|
||||
} else {
|
||||
$userClaims = array_merge($this->getUserClaim($validClaim, $userDetails));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
protected function getUserClaim($claim, $userDetails)
|
||||
{
|
||||
$userClaims = array();
|
||||
$claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
|
||||
$claimValues = explode(' ', $claimValuesString);
|
||||
|
||||
foreach ($claimValues as $value) {
|
||||
$userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/* ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
return isset($this->clientCredentials[$client_id]['client_secret']) && $this->clientCredentials[$client_id]['client_secret'] === $client_secret;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
if (!isset($this->clientCredentials[$client_id])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($this->clientCredentials[$client_id]['client_secret']);
|
||||
}
|
||||
|
||||
/* ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
if (!isset($this->clientCredentials[$client_id])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$clientDetails = array_merge(array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => null,
|
||||
'redirect_uri' => null,
|
||||
'scope' => null,
|
||||
), $this->clientCredentials[$client_id]);
|
||||
|
||||
return $clientDetails;
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
if (isset($this->clientCredentials[$client_id]['grant_types'])) {
|
||||
$grant_types = explode(' ', $this->clientCredentials[$client_id]['grant_types']);
|
||||
|
||||
return in_array($grant_type, $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
$this->clientCredentials[$client_id] = array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $client_secret,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'grant_types' => $grant_types,
|
||||
'scope' => $scope,
|
||||
'user_id' => $user_id,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
return isset($this->refreshTokens[$refresh_token]) ? $this->refreshTokens[$refresh_token] : false;
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
$this->refreshTokens[$refresh_token] = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
unset($this->refreshTokens[$refresh_token]);
|
||||
}
|
||||
|
||||
public function setRefreshTokens($refresh_tokens)
|
||||
{
|
||||
$this->refreshTokens = $refresh_tokens;
|
||||
}
|
||||
|
||||
/* AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
return isset($this->accessTokens[$access_token]) ? $this->accessTokens[$access_token] : false;
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
$this->accessTokens[$access_token] = compact('access_token', 'client_id', 'user_id', 'expires', 'scope', 'id_token');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
unset($this->accessTokens[$access_token]);
|
||||
}
|
||||
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', trim($scope));
|
||||
|
||||
return (count(array_diff($scope, $this->supportedScopes)) == 0);
|
||||
}
|
||||
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
return $this->defaultScope;
|
||||
}
|
||||
|
||||
/*JWTBearerInterface */
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
if (isset($this->jwt[$client_id])) {
|
||||
$jwt = $this->jwt[$client_id];
|
||||
if ($jwt) {
|
||||
if ($jwt["subject"] == $subject) {
|
||||
return $jwt["key"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
foreach ($this->jti as $storedJti) {
|
||||
if ($storedJti['issuer'] == $client_id && $storedJti['subject'] == $subject && $storedJti['audience'] == $audience && $storedJti['expires'] == $expires && $storedJti['jti'] == $jti) {
|
||||
return array(
|
||||
'issuer' => $storedJti['issuer'],
|
||||
'subject' => $storedJti['subject'],
|
||||
'audience' => $storedJti['audience'],
|
||||
'expires' => $storedJti['expires'],
|
||||
'jti' => $storedJti['jti']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
$this->jti[] = array('issuer' => $client_id, 'subject' => $subject, 'audience' => $audience, 'expires' => $expires, 'jti' => $jti);
|
||||
}
|
||||
|
||||
/*PublicKeyInterface */
|
||||
public function getPublicKey($client_id = null)
|
||||
{
|
||||
if (isset($this->keys[$client_id])) {
|
||||
return $this->keys[$client_id]['public_key'];
|
||||
}
|
||||
|
||||
// use a global encryption pair
|
||||
if (isset($this->keys['public_key'])) {
|
||||
return $this->keys['public_key'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getPrivateKey($client_id = null)
|
||||
{
|
||||
if (isset($this->keys[$client_id])) {
|
||||
return $this->keys[$client_id]['private_key'];
|
||||
}
|
||||
|
||||
// use a global encryption pair
|
||||
if (isset($this->keys['private_key'])) {
|
||||
return $this->keys['private_key'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEncryptionAlgorithm($client_id = null)
|
||||
{
|
||||
if (isset($this->keys[$client_id]['encryption_algorithm'])) {
|
||||
return $this->keys[$client_id]['encryption_algorithm'];
|
||||
}
|
||||
|
||||
// use a global encryption algorithm
|
||||
if (isset($this->keys['encryption_algorithm'])) {
|
||||
return $this->keys['encryption_algorithm'];
|
||||
}
|
||||
|
||||
return 'RS256';
|
||||
}
|
||||
}
|
333
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Mongo.php
vendored
Normal file
333
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Mongo.php
vendored
Normal file
|
@ -0,0 +1,333 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
* Simple MongoDB storage for all storage types
|
||||
*
|
||||
* NOTE: This class is meant to get users started
|
||||
* quickly. If your application requires further
|
||||
* customization, extend this class or create your own.
|
||||
*
|
||||
* NOTE: Passwords are stored in plaintext, which is never
|
||||
* a good idea. Be sure to override this for your application
|
||||
*
|
||||
* @author Julien Chaumond <chaumond@gmail.com>
|
||||
*/
|
||||
class Mongo implements AuthorizationCodeInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
UserCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
protected $db;
|
||||
protected $config;
|
||||
|
||||
public function __construct($connection, $config = array())
|
||||
{
|
||||
if ($connection instanceof \MongoDB) {
|
||||
$this->db = $connection;
|
||||
} else {
|
||||
if (!is_array($connection)) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Mongo must be an instance of MongoDB or a configuration array');
|
||||
}
|
||||
$server = sprintf('mongodb://%s:%d', $connection['host'], $connection['port']);
|
||||
$m = new \MongoClient($server);
|
||||
$this->db = $m->{$connection['database']};
|
||||
}
|
||||
|
||||
$this->config = array_merge(array(
|
||||
'client_table' => 'oauth_clients',
|
||||
'access_token_table' => 'oauth_access_tokens',
|
||||
'refresh_token_table' => 'oauth_refresh_tokens',
|
||||
'code_table' => 'oauth_authorization_codes',
|
||||
'user_table' => 'oauth_users',
|
||||
'jwt_table' => 'oauth_jwt',
|
||||
), $config);
|
||||
}
|
||||
|
||||
// Helper function to access a MongoDB collection by `type`:
|
||||
protected function collection($name)
|
||||
{
|
||||
return $this->db->{$this->config[$name]};
|
||||
}
|
||||
|
||||
/* ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
if ($result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
|
||||
return $result['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
if (!$result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($result['client_secret']);
|
||||
}
|
||||
|
||||
/* ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
$result = $this->collection('client_table')->findOne(array('client_id' => $client_id));
|
||||
|
||||
return is_null($result) ? false : $result;
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
if ($this->getClientDetails($client_id)) {
|
||||
$this->collection('client_table')->update(
|
||||
array('client_id' => $client_id),
|
||||
array('$set' => array(
|
||||
'client_secret' => $client_secret,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'grant_types' => $grant_types,
|
||||
'scope' => $scope,
|
||||
'user_id' => $user_id,
|
||||
))
|
||||
);
|
||||
} else {
|
||||
$client = array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $client_secret,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'grant_types' => $grant_types,
|
||||
'scope' => $scope,
|
||||
'user_id' => $user_id,
|
||||
);
|
||||
$this->collection('client_table')->insert($client);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
if (isset($details['grant_types'])) {
|
||||
$grant_types = explode(' ', $details['grant_types']);
|
||||
|
||||
return in_array($grant_type, $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
/* AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
$token = $this->collection('access_token_table')->findOne(array('access_token' => $access_token));
|
||||
|
||||
return is_null($token) ? false : $token;
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// if it exists, update it.
|
||||
if ($this->getAccessToken($access_token)) {
|
||||
$this->collection('access_token_table')->update(
|
||||
array('access_token' => $access_token),
|
||||
array('$set' => array(
|
||||
'client_id' => $client_id,
|
||||
'expires' => $expires,
|
||||
'user_id' => $user_id,
|
||||
'scope' => $scope
|
||||
))
|
||||
);
|
||||
} else {
|
||||
$token = array(
|
||||
'access_token' => $access_token,
|
||||
'client_id' => $client_id,
|
||||
'expires' => $expires,
|
||||
'user_id' => $user_id,
|
||||
'scope' => $scope
|
||||
);
|
||||
$this->collection('access_token_table')->insert($token);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
$this->collection('access_token_table')->remove(array('access_token' => $access_token));
|
||||
}
|
||||
|
||||
|
||||
/* AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
$code = $this->collection('code_table')->findOne(array('authorization_code' => $code));
|
||||
|
||||
return is_null($code) ? false : $code;
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
// if it exists, update it.
|
||||
if ($this->getAuthorizationCode($code)) {
|
||||
$this->collection('code_table')->update(
|
||||
array('authorization_code' => $code),
|
||||
array('$set' => array(
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
'id_token' => $id_token,
|
||||
))
|
||||
);
|
||||
} else {
|
||||
$token = array(
|
||||
'authorization_code' => $code,
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
'id_token' => $id_token,
|
||||
);
|
||||
$this->collection('code_table')->insert($token);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$this->collection('code_table')->remove(array('authorization_code' => $code));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
return $this->checkPassword($user, $password);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
$user['user_id'] = $user['username'];
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/* RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
$token = $this->collection('refresh_token_table')->findOne(array('refresh_token' => $refresh_token));
|
||||
|
||||
return is_null($token) ? false : $token;
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
$token = array(
|
||||
'refresh_token' => $refresh_token,
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope
|
||||
);
|
||||
$this->collection('refresh_token_table')->insert($token);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
$this->collection('refresh_token_table')->remove(array('refresh_token' => $refresh_token));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == $password;
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
$result = $this->collection('user_table')->findOne(array('username' => $username));
|
||||
|
||||
return is_null($result) ? false : $result;
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $firstName = null, $lastName = null)
|
||||
{
|
||||
if ($this->getUser($username)) {
|
||||
$this->collection('user_table')->update(
|
||||
array('username' => $username),
|
||||
array('$set' => array(
|
||||
'password' => $password,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName
|
||||
))
|
||||
);
|
||||
} else {
|
||||
$user = array(
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName
|
||||
);
|
||||
$this->collection('user_table')->insert($user);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
$result = $this->collection('jwt_table')->findOne(array(
|
||||
'client_id' => $client_id,
|
||||
'subject' => $subject
|
||||
));
|
||||
|
||||
return is_null($result) ? false : $result['key'];
|
||||
}
|
||||
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs mongodb implementation.
|
||||
throw new \Exception('getJti() for the MongoDB driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs mongodb implementation.
|
||||
throw new \Exception('setJti() for the MongoDB driver is currently unimplemented.');
|
||||
}
|
||||
}
|
543
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
vendored
Normal file
543
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
vendored
Normal file
|
@ -0,0 +1,543 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
* Simple PDO storage for all storage types
|
||||
*
|
||||
* NOTE: This class is meant to get users started
|
||||
* quickly. If your application requires further
|
||||
* customization, extend this class or create your own.
|
||||
*
|
||||
* NOTE: Passwords are stored in plaintext, which is never
|
||||
* a good idea. Be sure to override this for your application
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class Pdo implements
|
||||
AuthorizationCodeInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
UserCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
ScopeInterface,
|
||||
PublicKeyInterface,
|
||||
UserClaimsInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
protected $db;
|
||||
protected $config;
|
||||
|
||||
public function __construct($connection, $config = array())
|
||||
{
|
||||
if (!$connection instanceof \PDO) {
|
||||
if (is_string($connection)) {
|
||||
$connection = array('dsn' => $connection);
|
||||
}
|
||||
if (!is_array($connection)) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Pdo must be an instance of PDO, a DSN string, or a configuration array');
|
||||
}
|
||||
if (!isset($connection['dsn'])) {
|
||||
throw new \InvalidArgumentException('configuration array must contain "dsn"');
|
||||
}
|
||||
// merge optional parameters
|
||||
$connection = array_merge(array(
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
'options' => array(),
|
||||
), $connection);
|
||||
$connection = new \PDO($connection['dsn'], $connection['username'], $connection['password'], $connection['options']);
|
||||
}
|
||||
$this->db = $connection;
|
||||
|
||||
// debugging
|
||||
$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$this->config = array_merge(array(
|
||||
'client_table' => 'oauth_clients',
|
||||
'access_token_table' => 'oauth_access_tokens',
|
||||
'refresh_token_table' => 'oauth_refresh_tokens',
|
||||
'code_table' => 'oauth_authorization_codes',
|
||||
'user_table' => 'oauth_users',
|
||||
'jwt_table' => 'oauth_jwt',
|
||||
'jti_table' => 'oauth_jti',
|
||||
'scope_table' => 'oauth_scopes',
|
||||
'public_key_table' => 'oauth_public_keys',
|
||||
), $config);
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
|
||||
$stmt->execute(compact('client_id'));
|
||||
$result = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
// make this extensible
|
||||
return $result && $result['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
|
||||
$stmt->execute(compact('client_id'));
|
||||
|
||||
if (!$result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($result['client_secret']);
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
|
||||
$stmt->execute(compact('client_id'));
|
||||
|
||||
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
// if it exists, update it.
|
||||
if ($this->getClientDetails($client_id)) {
|
||||
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_secret=:client_secret, redirect_uri=:redirect_uri, grant_types=:grant_types, scope=:scope, user_id=:user_id where client_id=:client_id', $this->config['client_table']));
|
||||
} else {
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (client_id, client_secret, redirect_uri, grant_types, scope, user_id) VALUES (:client_id, :client_secret, :redirect_uri, :grant_types, :scope, :user_id)', $this->config['client_table']));
|
||||
}
|
||||
|
||||
return $stmt->execute(compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id'));
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
if (isset($details['grant_types'])) {
|
||||
$grant_types = explode(' ', $details['grant_types']);
|
||||
|
||||
return in_array($grant_type, (array) $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = :access_token', $this->config['access_token_table']));
|
||||
|
||||
$token = $stmt->execute(compact('access_token'));
|
||||
if ($token = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// convert date string back to timestamp
|
||||
$token['expires'] = strtotime($token['expires']);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
// if it exists, update it.
|
||||
if ($this->getAccessToken($access_token)) {
|
||||
$stmt = $this->db->prepare(sprintf('UPDATE %s SET client_id=:client_id, expires=:expires, user_id=:user_id, scope=:scope where access_token=:access_token', $this->config['access_token_table']));
|
||||
} else {
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (access_token, client_id, expires, user_id, scope) VALUES (:access_token, :client_id, :expires, :user_id, :scope)', $this->config['access_token_table']));
|
||||
}
|
||||
|
||||
return $stmt->execute(compact('access_token', 'client_id', 'user_id', 'expires', 'scope'));
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE access_token = :access_token', $this->config['access_token_table']));
|
||||
|
||||
return $stmt->execute(compact('access_token'));
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = :code', $this->config['code_table']));
|
||||
$stmt->execute(compact('code'));
|
||||
|
||||
if ($code = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// convert date string back to timestamp
|
||||
$code['expires'] = strtotime($code['expires']);
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
if (func_num_args() > 6) {
|
||||
// we are calling with an id token
|
||||
return call_user_func_array(array($this, 'setAuthorizationCodeWithIdToken'), func_get_args());
|
||||
}
|
||||
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
// if it exists, update it.
|
||||
if ($this->getAuthorizationCode($code)) {
|
||||
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope where authorization_code=:code', $this->config['code_table']));
|
||||
} else {
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope)', $this->config['code_table']));
|
||||
}
|
||||
|
||||
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
|
||||
}
|
||||
|
||||
private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
// if it exists, update it.
|
||||
if ($this->getAuthorizationCode($code)) {
|
||||
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token where authorization_code=:code', $this->config['code_table']));
|
||||
} else {
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token)', $this->config['code_table']));
|
||||
}
|
||||
|
||||
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'));
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE authorization_code = :code', $this->config['code_table']));
|
||||
|
||||
return $stmt->execute(compact('code'));
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
return $this->checkPassword($user, $password);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
/* UserClaimsInterface */
|
||||
public function getUserClaims($user_id, $claims)
|
||||
{
|
||||
if (!$userDetails = $this->getUserDetails($user_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$claims = explode(' ', trim($claims));
|
||||
$userClaims = array();
|
||||
|
||||
// for each requested claim, if the user has the claim, set it in the response
|
||||
$validClaims = explode(' ', self::VALID_CLAIMS);
|
||||
foreach ($validClaims as $validClaim) {
|
||||
if (in_array($validClaim, $claims)) {
|
||||
if ($validClaim == 'address') {
|
||||
// address is an object with subfields
|
||||
$userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
|
||||
} else {
|
||||
$userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
protected function getUserClaim($claim, $userDetails)
|
||||
{
|
||||
$userClaims = array();
|
||||
$claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
|
||||
$claimValues = explode(' ', $claimValuesString);
|
||||
|
||||
foreach ($claimValues as $value) {
|
||||
$userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
|
||||
}
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
|
||||
|
||||
$token = $stmt->execute(compact('refresh_token'));
|
||||
if ($token = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// convert expires to epoch time
|
||||
$token['expires'] = strtotime($token['expires']);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
$expires = date('Y-m-d H:i:s', $expires);
|
||||
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (refresh_token, client_id, user_id, expires, scope) VALUES (:refresh_token, :client_id, :user_id, :expires, :scope)', $this->config['refresh_token_table']));
|
||||
|
||||
return $stmt->execute(compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'));
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
|
||||
|
||||
return $stmt->execute(compact('refresh_token'));
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == sha1($password);
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT * from %s where username=:username', $this->config['user_table']));
|
||||
$stmt->execute(array('username' => $username));
|
||||
|
||||
if (!$userInfo = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// the default behavior is to use "username" as the user_id
|
||||
return array_merge(array(
|
||||
'user_id' => $username
|
||||
), $userInfo);
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $firstName = null, $lastName = null)
|
||||
{
|
||||
// do not store in plaintext
|
||||
$password = sha1($password);
|
||||
|
||||
// if it exists, update it.
|
||||
if ($this->getUser($username)) {
|
||||
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET password=:password, first_name=:firstName, last_name=:lastName where username=:username', $this->config['user_table']));
|
||||
} else {
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (username, password, first_name, last_name) VALUES (:username, :password, :firstName, :lastName)', $this->config['user_table']));
|
||||
}
|
||||
|
||||
return $stmt->execute(compact('username', 'password', 'firstName', 'lastName'));
|
||||
}
|
||||
|
||||
/* ScopeInterface */
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', $scope);
|
||||
$whereIn = implode(',', array_fill(0, count($scope), '?'));
|
||||
$stmt = $this->db->prepare(sprintf('SELECT count(scope) as count FROM %s WHERE scope IN (%s)', $this->config['scope_table'], $whereIn));
|
||||
$stmt->execute($scope);
|
||||
|
||||
if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return $result['count'] == count($scope);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT scope FROM %s WHERE is_default=:is_default', $this->config['scope_table']));
|
||||
$stmt->execute(array('is_default' => true));
|
||||
|
||||
if ($result = $stmt->fetchAll(\PDO::FETCH_ASSOC)) {
|
||||
$defaultScope = array_map(function ($row) {
|
||||
return $row['scope'];
|
||||
}, $result);
|
||||
|
||||
return implode(' ', $defaultScope);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* JWTBearerInterface */
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id AND subject=:subject', $this->config['jwt_table']));
|
||||
|
||||
$stmt->execute(array('client_id' => $client_id, 'subject' => $subject));
|
||||
|
||||
return $stmt->fetchColumn();
|
||||
}
|
||||
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT * FROM %s WHERE issuer=:client_id AND subject=:subject AND audience=:audience AND expires=:expires AND jti=:jti', $this->config['jti_table']));
|
||||
|
||||
$stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
|
||||
|
||||
if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return array(
|
||||
'issuer' => $result['issuer'],
|
||||
'subject' => $result['subject'],
|
||||
'audience' => $result['audience'],
|
||||
'expires' => $result['expires'],
|
||||
'jti' => $result['jti'],
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (issuer, subject, audience, expires, jti) VALUES (:client_id, :subject, :audience, :expires, :jti)', $this->config['jti_table']));
|
||||
|
||||
return $stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
|
||||
}
|
||||
|
||||
/* PublicKeyInterface */
|
||||
public function getPublicKey($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT public_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
|
||||
|
||||
$stmt->execute(compact('client_id'));
|
||||
if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return $result['public_key'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrivateKey($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT private_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
|
||||
|
||||
$stmt->execute(compact('client_id'));
|
||||
if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return $result['private_key'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getEncryptionAlgorithm($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT encryption_algorithm FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
|
||||
|
||||
$stmt->execute(compact('client_id'));
|
||||
if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return $result['encryption_algorithm'];
|
||||
}
|
||||
|
||||
return 'RS256';
|
||||
}
|
||||
|
||||
/**
|
||||
* DDL to create OAuth2 database and tables for PDO storage
|
||||
*
|
||||
* @see https://github.com/dsquier/oauth2-server-php-mysql
|
||||
*/
|
||||
public function getBuildSql($dbName = 'oauth2_server_php')
|
||||
{
|
||||
$sql = "
|
||||
CREATE TABLE {$this->config['client_table']} (
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
client_secret VARCHAR(80) NOT NULL,
|
||||
redirect_uri VARCHAR(2000),
|
||||
grant_types VARCHAR(80),
|
||||
scope VARCHAR(4000),
|
||||
user_id VARCHAR(80),
|
||||
PRIMARY KEY (client_id)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['access_token_table']} (
|
||||
access_token VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
PRIMARY KEY (access_token)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['code_table']} (
|
||||
authorization_code VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
redirect_uri VARCHAR(2000),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
id_token VARCHAR(1000),
|
||||
PRIMARY KEY (authorization_code)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['refresh_token_table']} (
|
||||
refresh_token VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
PRIMARY KEY (refresh_token)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['user_table']} (
|
||||
username VARCHAR(80),
|
||||
password VARCHAR(80),
|
||||
first_name VARCHAR(80),
|
||||
last_name VARCHAR(80),
|
||||
email VARCHAR(80),
|
||||
email_verified BOOLEAN,
|
||||
scope VARCHAR(4000)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['scope_table']} (
|
||||
scope VARCHAR(80) NOT NULL,
|
||||
is_default BOOLEAN,
|
||||
PRIMARY KEY (scope)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['jwt_table']} (
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
subject VARCHAR(80),
|
||||
public_key VARCHAR(2000) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['jti_table']} (
|
||||
issuer VARCHAR(80) NOT NULL,
|
||||
subject VARCHAR(80),
|
||||
audiance VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
jti VARCHAR(2000) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['public_key_table']} (
|
||||
client_id VARCHAR(80),
|
||||
public_key VARCHAR(2000),
|
||||
private_key VARCHAR(2000),
|
||||
encryption_algorithm VARCHAR(100) DEFAULT 'RS256'
|
||||
)
|
||||
";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
16
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/PublicKeyInterface.php
vendored
Normal file
16
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/PublicKeyInterface.php
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should get public/private key information
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface PublicKeyInterface
|
||||
{
|
||||
public function getPublicKey($client_id = null);
|
||||
public function getPrivateKey($client_id = null);
|
||||
public function getEncryptionAlgorithm($client_id = null);
|
||||
}
|
317
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Redis.php
vendored
Normal file
317
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Redis.php
vendored
Normal file
|
@ -0,0 +1,317 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
* redis storage for all storage types
|
||||
*
|
||||
* To use, install "predis/predis" via composer
|
||||
*
|
||||
* Register client:
|
||||
* <code>
|
||||
* $storage = new OAuth2\Storage\Redis($redis);
|
||||
* $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
|
||||
* </code>
|
||||
*/
|
||||
class Redis implements AuthorizationCodeInterface,
|
||||
AccessTokenInterface,
|
||||
ClientCredentialsInterface,
|
||||
UserCredentialsInterface,
|
||||
RefreshTokenInterface,
|
||||
JwtBearerInterface,
|
||||
ScopeInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
|
||||
private $cache;
|
||||
|
||||
/* The redis client */
|
||||
protected $redis;
|
||||
|
||||
/* Configuration array */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Redis Storage!
|
||||
*
|
||||
* @param \Predis\Client $redis
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($redis, $config=array())
|
||||
{
|
||||
$this->redis = $redis;
|
||||
$this->config = array_merge(array(
|
||||
'client_key' => 'oauth_clients:',
|
||||
'access_token_key' => 'oauth_access_tokens:',
|
||||
'refresh_token_key' => 'oauth_refresh_tokens:',
|
||||
'code_key' => 'oauth_authorization_codes:',
|
||||
'user_key' => 'oauth_users:',
|
||||
'jwt_key' => 'oauth_jwt:',
|
||||
'scope_key' => 'oauth_scopes:',
|
||||
), $config);
|
||||
}
|
||||
|
||||
protected function getValue($key)
|
||||
{
|
||||
if ( isset($this->cache[$key]) ) {
|
||||
return $this->cache[$key];
|
||||
}
|
||||
$value = $this->redis->get($key);
|
||||
if ( isset($value) ) {
|
||||
return json_decode($value, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function setValue($key, $value, $expire=0)
|
||||
{
|
||||
$this->cache[$key] = $value;
|
||||
$str = json_encode($value);
|
||||
if ($expire > 0) {
|
||||
$seconds = $expire - time();
|
||||
$ret = $this->redis->setex($key, $seconds, $str);
|
||||
} else {
|
||||
$ret = $this->redis->set($key, $str);
|
||||
}
|
||||
|
||||
// check that the key was set properly
|
||||
// if this fails, an exception will usually thrown, so this step isn't strictly necessary
|
||||
return is_bool($ret) ? $ret : $ret->getPayload() == 'OK';
|
||||
}
|
||||
|
||||
protected function expireValue($key)
|
||||
{
|
||||
unset($this->cache[$key]);
|
||||
|
||||
return $this->redis->del($key);
|
||||
}
|
||||
|
||||
/* AuthorizationCodeInterface */
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
return $this->getValue($this->config['code_key'] . $code);
|
||||
}
|
||||
|
||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['code_key'] . $authorization_code,
|
||||
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
|
||||
$expires
|
||||
);
|
||||
}
|
||||
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$key = $this->config['code_key'] . $code;
|
||||
unset($this->cache[$key]);
|
||||
|
||||
return $this->expireValue($key);
|
||||
}
|
||||
|
||||
/* UserCredentialsInterface */
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
$user = $this->getUserDetails($username);
|
||||
|
||||
return $user && $user['password'] === $password;
|
||||
}
|
||||
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// the default behavior is to use "username" as the user_id
|
||||
return array_merge(array(
|
||||
'user_id' => $username,
|
||||
), $userInfo);
|
||||
}
|
||||
|
||||
public function setUser($username, $password, $first_name = null, $last_name = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['user_key'] . $username,
|
||||
compact('username', 'password', 'first_name', 'last_name')
|
||||
);
|
||||
}
|
||||
|
||||
/* ClientCredentialsInterface */
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
if (!$client = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset($client['client_secret'])
|
||||
&& $client['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
if (!$client = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($result['client_secret']);
|
||||
}
|
||||
|
||||
/* ClientInterface */
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
return $this->getValue($this->config['client_key'] . $client_id);
|
||||
}
|
||||
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['client_key'] . $client_id,
|
||||
compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
|
||||
);
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
if (isset($details['grant_types'])) {
|
||||
$grant_types = explode(' ', $details['grant_types']);
|
||||
|
||||
return in_array($grant_type, (array) $grant_types);
|
||||
}
|
||||
|
||||
// if grant_types are not defined, then none are restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
/* RefreshTokenInterface */
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
|
||||
}
|
||||
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['refresh_token_key'] . $refresh_token,
|
||||
compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'),
|
||||
$expires
|
||||
);
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
return $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
|
||||
}
|
||||
|
||||
/* AccessTokenInterface */
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
return $this->getValue($this->config['access_token_key'].$access_token);
|
||||
}
|
||||
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
$this->config['access_token_key'].$access_token,
|
||||
compact('access_token', 'client_id', 'user_id', 'expires', 'scope'),
|
||||
$expires
|
||||
);
|
||||
}
|
||||
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
return $this->expireValue($this->config['access_token_key'] . $access_token);
|
||||
}
|
||||
|
||||
/* ScopeInterface */
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', $scope);
|
||||
|
||||
$result = $this->getValue($this->config['scope_key'].'supported:global');
|
||||
|
||||
$supportedScope = explode(' ', (string) $result);
|
||||
|
||||
return (count(array_diff($scope, $supportedScope)) == 0);
|
||||
}
|
||||
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
|
||||
$result = $this->getValue($this->config['scope_key'].'default:global');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setScope($scope, $client_id = null, $type = 'supported')
|
||||
{
|
||||
if (!in_array($type, array('default', 'supported'))) {
|
||||
throw new \InvalidArgumentException('"$type" must be one of "default", "supported"');
|
||||
}
|
||||
|
||||
if (is_null($client_id)) {
|
||||
$key = $this->config['scope_key'].$type.':global';
|
||||
} else {
|
||||
$key = $this->config['scope_key'].$type.':'.$client_id;
|
||||
}
|
||||
|
||||
return $this->setValue($key, $scope);
|
||||
}
|
||||
|
||||
/*JWTBearerInterface */
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($jwt['subject']) && $jwt['subject'] == $subject) {
|
||||
return $jwt['key'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setClientKey($client_id, $key, $subject = null)
|
||||
{
|
||||
return $this->setValue($this->config['jwt_key'] . $client_id, array(
|
||||
'key' => $key,
|
||||
'subject' => $subject
|
||||
));
|
||||
}
|
||||
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($clientDetails['scope'])) {
|
||||
return $clientDetails['scope'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs redis implementation.
|
||||
throw new \Exception('getJti() for the Redis driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
public function setJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs redis implementation.
|
||||
throw new \Exception('setJti() for the Redis driver is currently unimplemented.');
|
||||
}
|
||||
}
|
82
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/RefreshTokenInterface.php
vendored
Normal file
82
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/RefreshTokenInterface.php
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should get/save refresh tokens for the "Refresh Token"
|
||||
* grant type
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface RefreshTokenInterface
|
||||
{
|
||||
/**
|
||||
* Grant refresh access tokens.
|
||||
*
|
||||
* Retrieve the stored data for the given refresh token.
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_REFRESH_TOKEN.
|
||||
*
|
||||
* @param $refresh_token
|
||||
* Refresh token to be check with.
|
||||
*
|
||||
* @return
|
||||
* An associative array as below, and NULL if the refresh_token is
|
||||
* invalid:
|
||||
* - refresh_token: Refresh token identifier.
|
||||
* - client_id: Client identifier.
|
||||
* - user_id: User identifier.
|
||||
* - expires: Expiration unix timestamp, or 0 if the token doesn't expire.
|
||||
* - scope: (optional) Scope values in space-separated string.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-6
|
||||
*
|
||||
* @ingroup oauth2_section_6
|
||||
*/
|
||||
public function getRefreshToken($refresh_token);
|
||||
|
||||
/**
|
||||
* Take the provided refresh token values and store them somewhere.
|
||||
*
|
||||
* This function should be the storage counterpart to getRefreshToken().
|
||||
*
|
||||
* If storage fails for some reason, we're not currently checking for
|
||||
* any sort of success/failure, so you should bail out of the script
|
||||
* and provide a descriptive fail message.
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_REFRESH_TOKEN.
|
||||
*
|
||||
* @param $refresh_token
|
||||
* Refresh token to be stored.
|
||||
* @param $client_id
|
||||
* Client identifier to be stored.
|
||||
* @param $user_id
|
||||
* User identifier to be stored.
|
||||
* @param $expires
|
||||
* Expiration timestamp to be stored. 0 if the token doesn't expire.
|
||||
* @param $scope
|
||||
* (optional) Scopes to be stored in space-separated string.
|
||||
*
|
||||
* @ingroup oauth2_section_6
|
||||
*/
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null);
|
||||
|
||||
/**
|
||||
* Expire a used refresh token.
|
||||
*
|
||||
* This is not explicitly required in the spec, but is almost implied.
|
||||
* After granting a new refresh token, the old one is no longer useful and
|
||||
* so should be forcibly expired in the data store so it can't be used again.
|
||||
*
|
||||
* If storage fails for some reason, we're not currently checking for
|
||||
* any sort of success/failure, so you should bail out of the script
|
||||
* and provide a descriptive fail message.
|
||||
*
|
||||
* @param $refresh_token
|
||||
* Refresh token to be expirse.
|
||||
*
|
||||
* @ingroup oauth2_section_6
|
||||
*/
|
||||
public function unsetRefreshToken($refresh_token);
|
||||
}
|
46
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php
vendored
Normal file
46
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should retrieve data involving the relevent scopes associated
|
||||
* with this implementation.
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface ScopeInterface
|
||||
{
|
||||
/**
|
||||
* Check if the provided scope exists.
|
||||
*
|
||||
* @param $scope
|
||||
* A space-separated string of scopes.
|
||||
*
|
||||
* @return
|
||||
* TRUE if it exists, FALSE otherwise.
|
||||
*/
|
||||
public function scopeExists($scope);
|
||||
|
||||
/**
|
||||
* The default scope to use in the event the client
|
||||
* does not request one. By returning "false", a
|
||||
* request_error is returned by the server to force a
|
||||
* scope request by the client. By returning "null",
|
||||
* opt out of requiring scopes
|
||||
*
|
||||
* @param $client_id
|
||||
* An optional client id that can be used to return customized default scopes.
|
||||
*
|
||||
* @return
|
||||
* string representation of default scope, null if
|
||||
* scopes are not defined, or false to force scope
|
||||
* request by the client
|
||||
*
|
||||
* ex:
|
||||
* 'default'
|
||||
* ex:
|
||||
* null
|
||||
*/
|
||||
public function getDefaultScope($client_id = null);
|
||||
}
|
52
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/UserCredentialsInterface.php
vendored
Normal file
52
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/UserCredentialsInterface.php
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace OAuth2\Storage;
|
||||
|
||||
/**
|
||||
* Implement this interface to specify where the OAuth2 Server
|
||||
* should retrieve user credentials for the
|
||||
* "Resource Owner Password Credentials" grant type
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface UserCredentialsInterface
|
||||
{
|
||||
/**
|
||||
* Grant access tokens for basic user credentials.
|
||||
*
|
||||
* Check the supplied username and password for validity.
|
||||
*
|
||||
* You can also use the $client_id param to do any checks required based
|
||||
* on a client, if you need that.
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_USER_CREDENTIALS.
|
||||
*
|
||||
* @param $username
|
||||
* Username to be check with.
|
||||
* @param $password
|
||||
* Password to be check with.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the username and password are valid, and FALSE if it isn't.
|
||||
* Moreover, if the username and password are valid, and you want to
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4.3
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
public function checkUserCredentials($username, $password);
|
||||
|
||||
/**
|
||||
* @return
|
||||
* ARRAY the associated "user_id" and optional "scope" values
|
||||
* This function MUST return FALSE if the requested user does not exist or is
|
||||
* invalid. "scope" is a space-separated list of restricted scopes.
|
||||
* @code
|
||||
* return array(
|
||||
* "user_id" => USER_ID, // REQUIRED user_id to be stored with the authorization code or access token
|
||||
* "scope" => SCOPE // OPTIONAL space-separated list of restricted scopes
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
public function getUserDetails($username);
|
||||
}
|
Reference in a new issue