1
0
Fork 0

Reformat library/OAuth1

- Add type hints to Network\FKOAuthDataStore
This commit is contained in:
Hypolite Petovan 2019-12-03 23:24:32 -05:00
parent 010a7b7576
commit 17838366a0
2 changed files with 873 additions and 782 deletions

View file

@ -3,15 +3,20 @@
/* Generic exception class /* Generic exception class
*/ */
use Friendica\Network\FKOAuthDataStore;
if (!class_exists('OAuthException', false)) { if (!class_exists('OAuthException', false)) {
class OAuthException extends Exception class OAuthException extends Exception
{ } {
}
} }
class OAuthConsumer class OAuthConsumer
{ {
public $key; public $key;
public $secret; public $secret;
public $callback_url;
function __construct($key, $secret, $callback_url = NULL) function __construct($key, $secret, $callback_url = NULL)
{ {
@ -39,6 +44,9 @@ class OAuthToken
/** /**
* key = the token * key = the token
* secret = the token secret * secret = the token secret
*
* @param $key
* @param $secret
*/ */
function __construct($key, $secret) function __construct($key, $secret)
{ {
@ -72,6 +80,7 @@ abstract class OAuthSignatureMethod
{ {
/** /**
* Needs to return the name of the Signature Method (ie HMAC-SHA1) * Needs to return the name of the Signature Method (ie HMAC-SHA1)
*
* @return string * @return string
*/ */
abstract public function get_name(); abstract public function get_name();
@ -81,15 +90,17 @@ abstract class OAuthSignatureMethod
* NOTE: The output of this function MUST NOT be urlencoded. * NOTE: The output of this function MUST NOT be urlencoded.
* the encoding is handled in OAuthRequest when the final * the encoding is handled in OAuthRequest when the final
* request is serialized * request is serialized
*
* @param OAuthRequest $request * @param OAuthRequest $request
* @param OAuthConsumer $consumer * @param OAuthConsumer $consumer
* @param OAuthToken $token * @param OAuthToken $token
* @return string * @return string
*/ */
abstract public function build_signature($request, $consumer, $token); abstract public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token);
/** /**
* Verifies that a given signature is correct * Verifies that a given signature is correct
*
* @param OAuthRequest $request * @param OAuthRequest $request
* @param OAuthConsumer $consumer * @param OAuthConsumer $consumer
* @param OAuthToken $token * @param OAuthToken $token
@ -117,7 +128,13 @@ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
return "HMAC-SHA1"; return "HMAC-SHA1";
} }
public function build_signature($request, $consumer, $token) /**
* @param OAuthRequest $request
* @param OAuthConsumer $consumer
* @param OAuthToken $token
* @return string
*/
public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token)
{ {
$base_string = $request->get_signature_base_string(); $base_string = $request->get_signature_base_string();
$request->base_string = $base_string; $request->base_string = $base_string;
@ -156,8 +173,13 @@ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
* *
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
* OAuthRequest handles this! * OAuthRequest handles this!
*
* @param $request
* @param $consumer
* @param $token
* @return string
*/ */
public function build_signature($request, $consumer, $token) public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token)
{ {
$key_parts = array( $key_parts = array(
$consumer->secret, $consumer->secret,
@ -201,7 +223,7 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
// Either way should return a string representation of the certificate // Either way should return a string representation of the certificate
protected abstract function fetch_private_cert(&$request); protected abstract function fetch_private_cert(&$request);
public function build_signature($request, $consumer, $token) public function build_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token)
{ {
$base_string = $request->get_signature_base_string(); $base_string = $request->get_signature_base_string();
$request->base_string = $base_string; $request->base_string = $base_string;
@ -213,7 +235,7 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
$privatekeyid = openssl_get_privatekey($cert); $privatekeyid = openssl_get_privatekey($cert);
// Sign using the key // Sign using the key
$ok = openssl_sign($base_string, $signature, $privatekeyid); openssl_sign($base_string, $signature, $privatekeyid);
// Release the key resource // Release the key resource
openssl_free_key($privatekeyid); openssl_free_key($privatekeyid);
@ -265,6 +287,11 @@ class OAuthRequest
/** /**
* attempt to build up a request from what was passed to the server * attempt to build up a request from what was passed to the server
*
* @param string|null $http_method
* @param string|null $http_url
* @param string|null $parameters
* @return OAuthRequest
*/ */
public static function from_request($http_method = NULL, $http_url = NULL, $parameters = NULL) public static function from_request($http_method = NULL, $http_url = NULL, $parameters = NULL)
{ {
@ -323,8 +350,15 @@ class OAuthRequest
/** /**
* pretty much a helper function to set up the request * pretty much a helper function to set up the request
*
* @param OAuthConsumer $consumer
* @param OAuthToken $token
* @param string $http_method
* @param string $http_url
* @param array|null $parameters
* @return OAuthRequest
*/ */
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = NULL) public static function from_consumer_and_token(OAuthConsumer $consumer, OAuthToken $token, $http_method, $http_url, array $parameters = NULL)
{ {
@$parameters or $parameters = array(); @$parameters or $parameters = array();
$defaults = array( $defaults = array(
@ -374,6 +408,7 @@ class OAuthRequest
/** /**
* The request parameters, sorted and concatenated into a normalized string. * The request parameters, sorted and concatenated into a normalized string.
*
* @return string * @return string
*/ */
public function get_signable_parameters() public function get_signable_parameters()
@ -456,8 +491,11 @@ class OAuthRequest
/** /**
* builds the data one would send in a POST request * builds the data one would send in a POST request
*
* @param bool $raw
* @return array|string
*/ */
public function to_postdata($raw = false) public function to_postdata(bool $raw = false)
{ {
if ($raw) if ($raw)
return $this->parameters; return $this->parameters;
@ -467,6 +505,10 @@ class OAuthRequest
/** /**
* builds the Authorization: header * builds the Authorization: header
*
* @param string|null $realm
* @return string
* @throws OAuthException
*/ */
public function to_header($realm = null) public function to_header($realm = null)
{ {
@ -498,7 +540,7 @@ class OAuthRequest
} }
public function sign_request($signature_method, $consumer, $token) public function sign_request(OAuthSignatureMethod $signature_method, $consumer, $token)
{ {
$this->set_parameter( $this->set_parameter(
"oauth_signature_method", "oauth_signature_method",
@ -509,7 +551,7 @@ class OAuthRequest
$this->set_parameter("oauth_signature", $signature, false); $this->set_parameter("oauth_signature", $signature, false);
} }
public function build_signature($signature_method, $consumer, $token) public function build_signature(OAuthSignatureMethod $signature_method, $consumer, $token)
{ {
$signature = $signature_method->build_signature($this, $consumer, $token); $signature = $signature_method->build_signature($this, $consumer, $token);
return $signature; return $signature;
@ -536,16 +578,18 @@ class OAuthServer
{ {
protected $timestamp_threshold = 300; // in seconds, five minutes protected $timestamp_threshold = 300; // in seconds, five minutes
protected $version = '1.0'; // hi blaine protected $version = '1.0'; // hi blaine
/** @var OAuthSignatureMethod[] */
protected $signature_methods = array(); protected $signature_methods = array();
/** @var FKOAuthDataStore */
protected $data_store; protected $data_store;
function __construct($data_store) function __construct(FKOAuthDataStore $data_store)
{ {
$this->data_store = $data_store; $this->data_store = $data_store;
} }
public function add_signature_method($signature_method) public function add_signature_method(OAuthSignatureMethod $signature_method)
{ {
$this->signature_methods[$signature_method->get_name()] = $this->signature_methods[$signature_method->get_name()] =
$signature_method; $signature_method;
@ -556,8 +600,12 @@ class OAuthServer
/** /**
* process a request_token request * process a request_token request
* returns the request token on success * returns the request token on success
*
* @param OAuthRequest $request
* @return OAuthToken|null
* @throws OAuthException
*/ */
public function fetch_request_token(&$request) public function fetch_request_token(OAuthRequest $request)
{ {
$this->get_version($request); $this->get_version($request);
@ -578,8 +626,12 @@ class OAuthServer
/** /**
* process an access_token request * process an access_token request
* returns the access token on success * returns the access token on success
*
* @param OAuthRequest $request
* @return object
* @throws OAuthException
*/ */
public function fetch_access_token(&$request) public function fetch_access_token(OAuthRequest $request)
{ {
$this->get_version($request); $this->get_version($request);
@ -599,8 +651,12 @@ class OAuthServer
/** /**
* verify an api call, checks all the parameters * verify an api call, checks all the parameters
*
* @param OAuthRequest $request
* @return array
* @throws OAuthException
*/ */
public function verify_request(&$request) public function verify_request(OAuthRequest $request)
{ {
$this->get_version($request); $this->get_version($request);
$consumer = $this->get_consumer($request); $consumer = $this->get_consumer($request);
@ -610,10 +666,15 @@ class OAuthServer
} }
// Internals from here // Internals from here
/** /**
* version 1 * version 1
*
* @param OAuthRequest $request
* @return string
* @throws OAuthException
*/ */
private function get_version(&$request) private function get_version(OAuthRequest $request)
{ {
$version = $request->get_parameter("oauth_version"); $version = $request->get_parameter("oauth_version");
if (!$version) { if (!$version) {
@ -629,8 +690,12 @@ class OAuthServer
/** /**
* figure out the signature with some defaults * figure out the signature with some defaults
*
* @param OAuthRequest $request
* @return OAuthSignatureMethod
* @throws OAuthException
*/ */
private function get_signature_method(&$request) private function get_signature_method(OAuthRequest $request)
{ {
$signature_method = $signature_method =
@$request->get_parameter("oauth_signature_method"); @$request->get_parameter("oauth_signature_method");
@ -656,8 +721,12 @@ class OAuthServer
/** /**
* try to find the consumer for the provided request's consumer key * try to find the consumer for the provided request's consumer key
*
* @param OAuthRequest $request
* @return OAuthConsumer
* @throws OAuthException
*/ */
private function get_consumer(&$request) private function get_consumer(OAuthRequest $request)
{ {
$consumer_key = @$request->get_parameter("oauth_consumer_key"); $consumer_key = @$request->get_parameter("oauth_consumer_key");
if (!$consumer_key) { if (!$consumer_key) {
@ -674,8 +743,14 @@ class OAuthServer
/** /**
* try to find the token for the provided request's token key * try to find the token for the provided request's token key
*
* @param OAuthRequest $request
* @param $consumer
* @param string $token_type
* @return OAuthToken|null
* @throws OAuthException
*/ */
private function get_token(&$request, $consumer, $token_type = "access") private function get_token(OAuthRequest &$request, $consumer, $token_type = "access")
{ {
$token_field = @$request->get_parameter('oauth_token'); $token_field = @$request->get_parameter('oauth_token');
$token = $this->data_store->lookup_token( $token = $this->data_store->lookup_token(
@ -692,8 +767,13 @@ class OAuthServer
/** /**
* all-in-one function to check the signature on a request * all-in-one function to check the signature on a request
* should guess the signature method appropriately * should guess the signature method appropriately
*
* @param OAuthRequest $request
* @param OAuthConsumer $consumer
* @param OAuthToken|null $token
* @throws OAuthException
*/ */
private function check_signature(&$request, $consumer, $token) private function check_signature(OAuthRequest $request, OAuthConsumer $consumer, OAuthToken $token = null)
{ {
// this should probably be in a different method // this should probably be in a different method
$timestamp = @$request->get_parameter('oauth_timestamp'); $timestamp = @$request->get_parameter('oauth_timestamp');
@ -720,6 +800,9 @@ class OAuthServer
/** /**
* check that the timestamp is new enough * check that the timestamp is new enough
*
* @param int $timestamp
* @throws OAuthException
*/ */
private function check_timestamp($timestamp) private function check_timestamp($timestamp)
{ {
@ -739,8 +822,14 @@ class OAuthServer
/** /**
* check that the nonce is not repeated * check that the nonce is not repeated
*
* @param OAuthConsumer $consumer
* @param OAuthToken $token
* @param string $nonce
* @param int $timestamp
* @throws OAuthException
*/ */
private function check_nonce($consumer, $token, $nonce, $timestamp) private function check_nonce(OAuthConsumer $consumer, OAuthToken $token, $nonce, int $timestamp)
{ {
if (!$nonce) if (!$nonce)
throw new OAuthException( throw new OAuthException(
@ -767,22 +856,22 @@ class OAuthDataStore
// implement me // implement me
} }
function lookup_token($consumer, $token_type, $token) function lookup_token(OAuthConsumer $consumer, $token_type, $token_id)
{ {
// implement me // implement me
} }
function lookup_nonce($consumer, $token, $nonce, $timestamp) function lookup_nonce(OAuthConsumer $consumer, OAuthToken $token, $nonce, int $timestamp)
{ {
// implement me // implement me
} }
function new_request_token($consumer, $callback = null) function new_request_token(OAuthConsumer $consumer, $callback = null)
{ {
// return a new token attached to this consumer // return a new token attached to this consumer
} }
function new_access_token($token, $consumer, $verifier = null) function new_access_token(OAuthToken $token, OAuthConsumer $consumer, $verifier = null)
{ {
// return a new access token attached to this consumer // return a new access token attached to this consumer
// for the user associated with this token if the request token // for the user associated with this token if the request token

View file

@ -12,6 +12,7 @@ namespace Friendica\Network;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Util\Strings;
use OAuthConsumer; use OAuthConsumer;
use OAuthDataStore; use OAuthDataStore;
use OAuthToken; use OAuthToken;
@ -26,15 +27,16 @@ class FKOAuthDataStore extends OAuthDataStore
{ {
/** /**
* @return string * @return string
* @throws \Exception
*/ */
private static function genToken() private static function genToken()
{ {
return Friendica\Util\Strings::getRandomHex(32); return Strings::getRandomHex(32);
} }
/** /**
* @param string $consumer_key key * @param string $consumer_key key
* @return mixed * @return OAuthConsumer|null
* @throws \Exception * @throws \Exception
*/ */
public function lookup_consumer($consumer_key) public function lookup_consumer($consumer_key)
@ -52,17 +54,17 @@ class FKOAuthDataStore extends OAuthDataStore
} }
/** /**
* @param string $consumer consumer * @param OAuthConsumer $consumer
* @param string $token_type type * @param string $token_type
* @param string $token token * @param string $token_id
* @return mixed * @return OAuthToken|null
* @throws \Exception * @throws \Exception
*/ */
public function lookup_token($consumer, $token_type, $token) public function lookup_token(OAuthConsumer $consumer, $token_type, $token_id)
{ {
Logger::log(__function__ . ":" . $consumer . ", " . $token_type . ", " . $token); Logger::log(__function__ . ":" . $consumer . ", " . $token_type . ", " . $token_id);
$s = DBA::select('tokens', ['id', 'secret', 'scope', 'expires', 'uid'], ['client_id' => $consumer->key, 'scope' => $token_type, 'id' => $token]); $s = DBA::select('tokens', ['id', 'secret', 'scope', 'expires', 'uid'], ['client_id' => $consumer->key, 'scope' => $token_type, 'id' => $token_id]);
$r = DBA::toArray($s); $r = DBA::toArray($s);
if (DBA::isResult($r)) { if (DBA::isResult($r)) {
@ -77,14 +79,14 @@ class FKOAuthDataStore extends OAuthDataStore
} }
/** /**
* @param string $consumer consumer * @param OAuthConsumer $consumer
* @param string $token token * @param OAuthToken $token
* @param string $nonce nonce * @param string $nonce
* @param string $timestamp timestamp * @param int $timestamp
* @return mixed * @return mixed
* @throws \Exception * @throws \Exception
*/ */
public function lookup_nonce($consumer, $token, $nonce, $timestamp) public function lookup_nonce(OAuthConsumer $consumer, OAuthToken $token, $nonce, int $timestamp)
{ {
$token = DBA::selectFirst('tokens', ['id', 'secret'], ['client_id' => $consumer->key, 'id' => $nonce, 'expires' => $timestamp]); $token = DBA::selectFirst('tokens', ['id', 'secret'], ['client_id' => $consumer->key, 'id' => $nonce, 'expires' => $timestamp]);
if (DBA::isResult($token)) { if (DBA::isResult($token)) {
@ -95,12 +97,12 @@ class FKOAuthDataStore extends OAuthDataStore
} }
/** /**
* @param string $consumer consumer * @param OAuthConsumer $consumer
* @param string $callback optional, default null * @param string $callback
* @return mixed * @return OAuthToken|null
* @throws \Exception * @throws \Exception
*/ */
public function new_request_token($consumer, $callback = null) public function new_request_token(OAuthConsumer $consumer, $callback = null)
{ {
Logger::log(__function__ . ":" . $consumer . ", " . $callback); Logger::log(__function__ . ":" . $consumer . ", " . $callback);
$key = self::genToken(); $key = self::genToken();
@ -131,13 +133,13 @@ class FKOAuthDataStore extends OAuthDataStore
} }
/** /**
* @param string $token token * @param OAuthToken $token token
* @param string $consumer consumer * @param OAuthConsumer $consumer consumer
* @param string $verifier optional, defult null * @param string $verifier optional, defult null
* @return object * @return OAuthToken
* @throws HTTPException\InternalServerErrorException * @throws \Exception
*/ */
public function new_access_token($token, $consumer, $verifier = null) public function new_access_token(OAuthToken $token, OAuthConsumer $consumer, $verifier = null)
{ {
Logger::log(__function__ . ":" . $token . ", " . $consumer . ", " . $verifier); Logger::log(__function__ . ":" . $token . ", " . $consumer . ", " . $verifier);