From 8bd355f55691d427bc48ae658dc9267960cd6ea8 Mon Sep 17 00:00:00 2001 From: Jacob Kiers Date: Mon, 11 Feb 2013 14:02:14 +0000 Subject: [PATCH] Use Interfaces anywhere. In practice, there were still too many concrete classes, which makes integration into a framework hard. To overcome this, the codebase has been refactored to use Interfaces when a resource is needed. All necessary Interfaces have been created, and the existing concrete classes now implement these interfaces. --- .../{Client.php => Consumer/Consumer.php} | 14 ++- .../OAuth/Consumer/ConsumerInterface.php | 48 ++++++++ .../OAuth/DataStore/DataStoreInterface.php | 81 +++++++++++++ src/JacobKiers/OAuth/DataStoreInterface.php | 78 ------------ .../OAuth/{ => Request}/Request.php | 49 ++++---- .../OAuth/{ => Request}/RequestInterface.php | 2 +- src/JacobKiers/OAuth/Server.php | 112 ++++++++++-------- src/JacobKiers/OAuth/SignatureMethod.php | 81 ------------- .../OAuth/{ => SignatureMethod}/HmacSha1.php | 18 +-- .../OAuth/{ => SignatureMethod}/PlainText.php | 18 +-- .../OAuth/{ => SignatureMethod}/RsaSha1.php | 30 +++-- .../OAuth/SignatureMethod/SignatureMethod.php | 86 ++++++++++++++ .../SignatureMethodInterface.php | 70 +++++++++++ .../OAuth/{ => Token}/NullToken.php | 8 +- src/JacobKiers/OAuth/{ => Token}/Token.php | 13 +- src/JacobKiers/OAuth/Token/TokenInterface.php | 34 ++++++ tests/ClientTest.php | 20 ---- tests/ConsumerTest.php | 20 ++++ tests/HmacSha1Test.php | 14 +-- tests/PlainTextTest.php | 14 +-- tests/RequestTest.php | 2 +- tests/SignatureMethodTest.php | 22 ++-- tests/TokenTest.php | 4 +- 23 files changed, 514 insertions(+), 324 deletions(-) rename src/JacobKiers/OAuth/{Client.php => Consumer/Consumer.php} (73%) create mode 100644 src/JacobKiers/OAuth/Consumer/ConsumerInterface.php create mode 100644 src/JacobKiers/OAuth/DataStore/DataStoreInterface.php delete mode 100644 src/JacobKiers/OAuth/DataStoreInterface.php rename src/JacobKiers/OAuth/{ => Request}/Request.php (88%) rename src/JacobKiers/OAuth/{ => Request}/RequestInterface.php (98%) delete mode 100644 src/JacobKiers/OAuth/SignatureMethod.php rename src/JacobKiers/OAuth/{ => SignatureMethod}/HmacSha1.php (71%) rename src/JacobKiers/OAuth/{ => SignatureMethod}/PlainText.php (66%) rename src/JacobKiers/OAuth/{ => SignatureMethod}/RsaSha1.php (74%) create mode 100644 src/JacobKiers/OAuth/SignatureMethod/SignatureMethod.php create mode 100644 src/JacobKiers/OAuth/SignatureMethod/SignatureMethodInterface.php rename src/JacobKiers/OAuth/{ => Token}/NullToken.php (73%) rename src/JacobKiers/OAuth/{ => Token}/Token.php (74%) create mode 100644 src/JacobKiers/OAuth/Token/TokenInterface.php delete mode 100644 tests/ClientTest.php create mode 100644 tests/ConsumerTest.php diff --git a/src/JacobKiers/OAuth/Client.php b/src/JacobKiers/OAuth/Consumer/Consumer.php similarity index 73% rename from src/JacobKiers/OAuth/Client.php rename to src/JacobKiers/OAuth/Consumer/Consumer.php index 51b3f6c..538926f 100644 --- a/src/JacobKiers/OAuth/Client.php +++ b/src/JacobKiers/OAuth/Consumer/Consumer.php @@ -9,15 +9,17 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\Consumer; + +use \JacobKiers\OAuth\Credential; /** - * Client holds the properties of a single client / consumer. + * Consumer holds the properties of a single Consumer / consumer. * * @package OAuth * @author Gary Jones */ -class Client extends Credential +class Consumer extends Credential implements ConsumerInterface { /** * URL to which authorized requests will redirect to. @@ -27,10 +29,10 @@ class Client extends Credential protected $callback_url; /** - * Constructs a new client object and populates the required parameters. + * Constructs a new Consumer object and populates the required parameters. * - * @param string $key Client key / identifier. - * @param string $secret Client shared-secret. + * @param string $key Consumer key / identifier. + * @param string $secret Consumer shared-secret. * @param string $callback_url URL to which authorized request will redirect to. */ public function __construct($key, $secret, $callback_url = null) diff --git a/src/JacobKiers/OAuth/Consumer/ConsumerInterface.php b/src/JacobKiers/OAuth/Consumer/ConsumerInterface.php new file mode 100644 index 0000000..2bf79dc --- /dev/null +++ b/src/JacobKiers/OAuth/Consumer/ConsumerInterface.php @@ -0,0 +1,48 @@ + + * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT + * @link https://github.com/jacobkiers/OAuth + */ + +namespace JacobKiers\OAuth\Consumer; + +/** + * Consumer holds the properties of a single Consumer / consumer. + * + * @package OAuth + * @author Jacob Kiers + */ +interface ConsumerInterface +{ + /** + * Get the callback URL. + * + * @return string + */ + public function getCallbackUrl(); + + /** + * Set the callbackURL + * + * @param string $callback_url + */ + public function setCallbackUrl($callback_url); + + /** + * Return the Consumer key. + * + * @return string Consumer key. + */ + public function getKey(); + + /** + * Return the Consumer secret + * + * @return string + */ + public function getSecret(); +} diff --git a/src/JacobKiers/OAuth/DataStore/DataStoreInterface.php b/src/JacobKiers/OAuth/DataStore/DataStoreInterface.php new file mode 100644 index 0000000..ef970bb --- /dev/null +++ b/src/JacobKiers/OAuth/DataStore/DataStoreInterface.php @@ -0,0 +1,81 @@ + + * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT + * @link https://github.com/jacobkiers/OAuth + */ + +namespace JacobKiers\OAuth\DataStore; + +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Consumer\ConsumerInterface; + +/** + * The actual implementation of validating and assigning tokens is left up to + * the system using this library. + * + * @package OAuth + * @author Gary Jones + */ +interface DataStoreInterface +{ + /** + * Validate the consumer. + * + * @param string $consumer_key + * + * @return JacobKiers\OAuth\Consumer\ConsumerInterface + */ + public function lookupConsumer($consumer_key); + + /** + * Validate a token. + * + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param string $token_type Request or access token + * @param string $token_key + * + * @return JacobKiers\OAuth\Token + */ + public function lookupToken(ConsumerInterface $consumer, $token_type, $token_key); + + /** + * Validate that a nonce has not been used with the same timestamp before. + * + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token $token + * @param string $nonce + * @param int $timestamp + * + * @return boolean + */ + public function lookupNonce(ConsumerInterface $consumer, TokenInterface $token, $nonce, $timestamp); + + /** + * Return a new token attached to this consumer. + * + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param string $callback URI to send the post-authorisation callback to. + * + * @return JacobKiers\OAuth\Token + */ + public function newRequestToken(ConsumerInterface $consumer, $callback = null); + + /** + * Return a new access token attached to this consumer for the user + * associated with this token if the request token is authorized. + * + * Should also invalidate the request token. + * + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token $token + * @param string $verifier + * + * @return JacobKiers\OAuth\Token + */ + public function newAccessToken(ConsumerInterface $consumer, TokenInterface $token, $verifier = null); +} diff --git a/src/JacobKiers/OAuth/DataStoreInterface.php b/src/JacobKiers/OAuth/DataStoreInterface.php deleted file mode 100644 index 0c7afe8..0000000 --- a/src/JacobKiers/OAuth/DataStoreInterface.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT - * @link https://github.com/jacobkiers/OAuth - */ - -namespace JacobKiers\OAuth; - -/** - * The actual implementation of validating and assigning tokens is left up to - * the system using this library. - * - * @package OAuth - * @author Gary Jones - */ -interface DataStoreInterface -{ - /** - * Validate the client. - * - * @param string $client_key - * - * @return JacobKiers\OAuth\Client - */ - public function lookupClient($client_key); - - /** - * Validate a token. - * - * @param JacobKiers\OAuth\Client $client - * @param string $token_type Request or access token - * @param string $token_key - * - * @return JacobKiers\OAuth\Token - */ - public function lookupToken(Client $client, $token_type, $token_key); - - /** - * Validate that a nonce has not been used with the same timestamp before. - * - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token - * @param string $nonce - * @param int $timestamp - * - * @return boolean - */ - public function lookupNonce(Client $client, Token $token, $nonce, $timestamp); - - /** - * Return a new token attached to this client. - * - * @param JacobKiers\OAuth\Client $client - * @param string $callback URI to send the post-authorisation callback to. - * - * @return JacobKiers\OAuth\Token - */ - public function newRequestToken(Client $client, $callback = null); - - /** - * Return a new access token attached to this consumer for the user - * associated with this token if the request token is authorized. - * - * Should also invalidate the request token. - * - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token - * @param string $verifier - * - * @return JacobKiers\OAuth\Token - */ - public function newAccessToken(Client $client, Token $token, $verifier = null); -} diff --git a/src/JacobKiers/OAuth/Request.php b/src/JacobKiers/OAuth/Request/Request.php similarity index 88% rename from src/JacobKiers/OAuth/Request.php rename to src/JacobKiers/OAuth/Request/Request.php index 20ef04f..bb4364f 100644 --- a/src/JacobKiers/OAuth/Request.php +++ b/src/JacobKiers/OAuth/Request/Request.php @@ -9,7 +9,12 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\Request; + +use \JacobKiers\OAuth\Util; +use \JacobKiers\OAuth\OAuthException; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Consumer\ConsumerInterface; /** * Handle an OAuth request. @@ -79,7 +84,7 @@ class Request implements RequestInterface * @param string $http_url Request URL. * @param array $parameters HTTP parameters. * - * @return JacobKiers\OAuth\RequestInterface + * @return JacobKiers\OAuth\Request\RequestInterface */ public static function fromRequest($http_method = null, $http_url = null, $parameters = null) { @@ -131,17 +136,17 @@ class Request implements RequestInterface /** * Helper function to set up the request. * - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token - * @param string $http_method - * @param string $http_url - * @param array $parameters + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * @param string $http_method + * @param string $http_url + * @param array $parameters * - * @return JacobKiers\OAuth\RequestInterface + * @return JacobKiers\OAuth\Request\RequestInterface */ - public static function fromClientAndToken( - Client $client, - Token $token, + public static function fromConsumerAndToken( + ConsumerInterface $consumer, + TokenInterface $token, $http_method, $http_url, array $parameters = null @@ -151,7 +156,7 @@ class Request implements RequestInterface 'oauth_version' => Request::$version, 'oauth_nonce' => Request::generateNonce(), 'oauth_timestamp' => Request::generateTimestamp(), - 'oauth_consumer_key' => $client->getKey()); + 'oauth_consumer_key' => $consumer->getKey()); if ($token) { $defaults['oauth_token'] = $token->getKey(); } @@ -374,29 +379,29 @@ class Request implements RequestInterface /** * Build signature and add it as parameter. * - * @param string $signature_method - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token + * @param string $signature_method + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token */ - public function signRequest($signature_method, Client $client, Token $token) + public function signRequest($signature_method, ConsumerInterface $consumer, TokenInterface $token) { $this->setParameter('oauth_signature_method', $signature_method->getName(), false); - $signature = $this->buildSignature($signature_method, $client, $token); + $signature = $this->buildSignature($signature_method, $consumer, $token); $this->setParameter('oauth_signature', $signature, false); } /** * Build signature. * - * @param string $signature_method - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token + * @param string $signature_method + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token * * @return string */ - public function buildSignature($signature_method, Client $client, Token $token) + public function buildSignature($signature_method, ConsumerInterface $consumer, TokenInterface $token) { - return $signature_method->buildSignature($this, $client, $token); + return $signature_method->buildSignature($this, $consumer, $token); } /** diff --git a/src/JacobKiers/OAuth/RequestInterface.php b/src/JacobKiers/OAuth/Request/RequestInterface.php similarity index 98% rename from src/JacobKiers/OAuth/RequestInterface.php rename to src/JacobKiers/OAuth/Request/RequestInterface.php index ef28e73..93d86b5 100644 --- a/src/JacobKiers/OAuth/RequestInterface.php +++ b/src/JacobKiers/OAuth/Request/RequestInterface.php @@ -8,7 +8,7 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\Request; /** * Interface providing the necessary methods to handle an OAuth request. diff --git a/src/JacobKiers/OAuth/Server.php b/src/JacobKiers/OAuth/Server.php index e485ae7..62432dc 100644 --- a/src/JacobKiers/OAuth/Server.php +++ b/src/JacobKiers/OAuth/Server.php @@ -11,6 +11,14 @@ namespace JacobKiers\OAuth; +use \JacobKiers\OAuth\Token\Token; +use \JacobKiers\OAuth\Token\NullToken; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\DataStore\DataStoreInterface; +use \JacobKiers\OAuth\Request\RequestInterface; +use \JacobKiers\OAuth\Consumer\ConsumerInterface; +use \JacobKiers\OAuth\SignatureMethod\SignatureMethodInterface; + /** * OAuth server. * @@ -45,14 +53,14 @@ class Server /** * Data store object reference. * - * @var JacobKiers\OAuth\DataStoreInterface + * @var JacobKiers\OAuth\DataStore\DataStoreInterface */ protected $data_store; /** * Construct OAuth server instance. * - * @param JacobKiers\OAuth\DataStoreInterface $data_store + * @param JacobKiers\OAuth\DataStore\DataStoreInterface $data_store */ public function __construct(DataStoreInterface $data_store) { @@ -62,9 +70,9 @@ class Server /** * Add a supported signature method. * - * @param JacobKiers\OAuth\SignatureMethod $signature_method + * @param JacobKiers\OAuth\SignatureMethod\SignatureMethodInterface $signature_method */ - public function addSignatureMethod(SignatureMethod $signature_method) + public function addSignatureMethod(SignatureMethodInterface $signature_method) { $this->signature_methods[$signature_method->getName()] = $signature_method; @@ -77,25 +85,25 @@ class Server * * Returns the request token on success * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request + * @param JacobKiers\OAuth\Request\RequestInterface $request * - * @return JacobKiers\OAuth\Token + * @return JacobKiers\OAuth\Token\TokenInterface */ public function fetchRequestToken(RequestInterface &$request) { $this->getVersion($request); - $client = $this->getClient($request); + $consumer = $this->getConsumer($request); // no token required for the initial token request $token = new NullToken; - $this->checkSignature($request, $client, $token); + $this->checkSignature($request, $consumer, $token); // Rev A change $callback = $request->getOAuthCallback(); - return $this->data_store->newRequestToken($client, $callback); + return $this->data_store->newRequestToken($consumer, $callback); } /** @@ -103,41 +111,41 @@ class Server * * Returns the access token on success. * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request + * @param JacobKiers\OAuth\Request\RequestInterface $request * - * @return JacobKiers\OAuth\Token + * @return JacobKiers\OAuth\Token\TokenInterface */ public function fetchAccessToken(RequestInterface &$request) { $this->getVersion($request); - $client = $this->getClient($request); + $consumer = $this->getConsumer($request); // requires authorized request token - $token = $this->getToken($request, $client, 'request'); + $token = $this->getToken($request, $consumer, 'request'); - $this->checkSignature($request, $client, $token); + $this->checkSignature($request, $consumer, $token); // Rev A change $verifier = $request->getOAuthVerifier(); - return $this->data_store->newAccessToken($client, $token, $verifier); + return $this->data_store->newAccessToken($consumer, $token, $verifier); } /** * Verify an api call, checks all the parameters. * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request + * @param JacobKiers\OAuth\Request\RequestInterface $request * - * @return array Client and Token + * @return array Consumer and Token */ public function verifyRequest(RequestInterface &$request) { $this->getVersion($request); - $client = $this->getClient($request); - $token = $this->getToken($request, $client, 'access'); - $this->checkSignature($request, $client, $token); - return array($client, $token); + $consumer = $this->getConsumer($request); + $token = $this->getToken($request, $consumer, 'access'); + $this->checkSignature($request, $consumer, $token); + return array($consumer, $token); } // Internals from here @@ -145,7 +153,7 @@ class Server /** * Check that version is 1.0. * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request + * @param JacobKiers\OAuth\Request\RequestInterface $request * * @return string * @@ -168,7 +176,7 @@ class Server /** * Get the signature method name, and if it is supported. * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request + * @param JacobKiers\OAuth\Request\RequestInterface $request * * @return string Signature method name. * @@ -194,46 +202,46 @@ class Server } /** - * Try to find the client for the provided request's client key. + * Try to find the consumer for the provided request's consumer key. * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request + * @param JacobKiers\OAuth\Request\RequestInterface $request * - * @return JacobKiers\OAuth\Client + * @return JacobKiers\OAuth\Consumer\ConsumerInterface * * @throws JacobKiers\OAuth\OAuthException */ - private function getClient(RequestInterface $request) + private function getConsumer(RequestInterface $request) { - $client_key = $request instanceof RequestInterface ? $request->getOAuthConsumerKey() : null; + $consumer_key = $request instanceof RequestInterface ? $request->getOAuthConsumerKey() : null; - if (!$client_key) { - throw new OAuthException('Invalid client key'); + if (!$consumer_key) { + throw new OAuthException('Invalid consumer key'); } - $client = $this->data_store->lookupClient($client_key); - if (!$client) { - throw new OAuthException('Invalid client'); + $consumer = $this->data_store->lookupConsumer($consumer_key); + if (!$consumer) { + throw new OAuthException('Invalid consumer'); } - return $client; + return $consumer; } /** * Try to find the token for the provided request's token key. * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request - * @param JacobKiers\OAuth\Client $client - * @param string $token_type + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param string $token_type * - * @return JacobKiers\OAuth\Token + * @return JacobKiers\OAuth\Token\TokenInterface * * @throws JacobKiers\OAuth\OAuthException */ - private function getToken(RequestInterface $request, Client $client, $token_type = 'access') + private function getToken(RequestInterface $request, ConsumerInterface $consumer, $token_type = 'access') { $token_key = $request instanceof RequestInterface ? $request->getOAuthToken() : null; - $token = $this->data_store->lookupToken($client, $token_type, $token_key); + $token = $this->data_store->lookupToken($consumer, $token_type, $token_key); if (!$token) { throw new OAuthException("Invalid $token_type token: $token_field"); } @@ -245,25 +253,25 @@ class Server * * Should determine the signature method appropriately * - * @param JacobKiers\OAuth\RequestInterfaceInterface $request - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token * * @throws JacobKiers\OAuth\OAuthException */ - private function checkSignature(RequestInterface $request, Client $client, Token $token) + private function checkSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token) { // this should probably be in a different method $timestamp = $request instanceof RequestInterface ? $request->getOAuthTimestamp() : null; $nonce = $request instanceof RequestInterface ? $request->getOAuthNonce() : null; $this->checkTimestamp($timestamp); - $this->checkNonce($client, $token, $nonce, $timestamp); + $this->checkNonce($consumer, $token, $nonce, $timestamp); $signature_method = $this->getSignatureMethod($request); $signature = $request->getOAuthSignature(); - $valid_sig = $signature_method->checkSignature($request, $client, $token, $signature); + $valid_sig = $signature_method->checkSignature($request, $consumer, $token, $signature); if (!$valid_sig) { throw new OAuthException('Invalid signature'); @@ -293,21 +301,21 @@ class Server /** * Check that the nonce is not repeated * - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token - * @param string $nonce - * @param int $timestamp + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * @param string $nonce + * @param int $timestamp * * @throws JacobKiers\OAuth\OAuthException */ - private function checkNonce(Client $client, Token $token, $nonce, $timestamp) + private function checkNonce(ConsumerInterface $consumer, TokenInterface $token, $nonce, $timestamp) { if (!$nonce) { throw new OAuthException('Missing nonce parameter. The parameter is required'); } // verify that the nonce is uniqueish - $found = $this->data_store->lookupNonce($client, $token, $nonce, $timestamp); + $found = $this->data_store->lookupNonce($consumer, $token, $nonce, $timestamp); if ($found) { throw new OAuthException('Nonce already used: ' . $nonce); } diff --git a/src/JacobKiers/OAuth/SignatureMethod.php b/src/JacobKiers/OAuth/SignatureMethod.php deleted file mode 100644 index 69cac4a..0000000 --- a/src/JacobKiers/OAuth/SignatureMethod.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT - * @link https://github.com/jacobkiers/OAuth - */ - -namespace JacobKiers\OAuth; - -/** - * A class for implementing a Signature Method. - * - * See section 9 ("Signing Requests") in the spec - * - * @package OAuth - * @author Andy Smith - * @author Gary Jones - */ -abstract class SignatureMethod -{ - /** - * Return the name of the Signature Method (ie HMAC-SHA1). - * - * @return string - */ - abstract public function getName(); - - /** - * Build up the signature. - * - * NOTE: The output of this function MUST NOT be urlencoded. - * the encoding is handled in OAuthRequest when the final - * request is serialized. - * - * @param JacobKiers\OAuth\RequestInterface $request - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token - * - * @return string - */ - abstract public function buildSignature(RequestInterface $request, Client $client, Token $token = null); - - /** - * Get the signature key, made up of client and optionally token shared secrets. - * - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token - * - * @return string - */ - public function getSignatureKey(Client $client, Token $token = null) - { - $key_parts = array( - $client->getSecret(), - ($token) ? $token->getSecret() : '', - ); - - $key_parts = Util::urlencodeRfc3986($key_parts); - return implode('&', $key_parts); - } - - /** - * Verifies that a given signature is correct. - * - * @param JacobKiers\OAuth\RequestInterface $request - * @param JacobKiers\OAuth\Consumer $client - * @param JacobKiers\OAuth\Token $token - * @param string $signature - * - * @return bool - */ - public function checkSignature(RequestInterface $request, Client $client, Token $token, $signature) - { - $built = $this->buildSignature($request, $client, $token); - return $built == $signature; - } -} diff --git a/src/JacobKiers/OAuth/HmacSha1.php b/src/JacobKiers/OAuth/SignatureMethod/HmacSha1.php similarity index 71% rename from src/JacobKiers/OAuth/HmacSha1.php rename to src/JacobKiers/OAuth/SignatureMethod/HmacSha1.php index 7fc823d..58d4c35 100644 --- a/src/JacobKiers/OAuth/HmacSha1.php +++ b/src/JacobKiers/OAuth/SignatureMethod/HmacSha1.php @@ -9,7 +9,11 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\SignatureMethod; + +use \JacobKiers\OAuth\Consumer\ConsumerInterface; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Request\RequestInterface; /** * The HMAC-SHA1 signature method. @@ -38,7 +42,7 @@ class HmacSha1 extends SignatureMethod /** * Build up the signature. * - * oauth_signature is set to the concatenated encoded values of the Client Secret and + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is * empty. The result MUST be encoded again. * - Chapter 9.4.1 ("Generating Signatures") @@ -46,16 +50,16 @@ class HmacSha1 extends SignatureMethod * Please note that the second encoding MUST NOT happen in the SignatureMethod, as * OAuthRequest handles this! * - * @param JacobKiers\OAuth\RequestInterface $request - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token * * @return string */ - public function buildSignature(RequestInterface $request, Client $client, Token $token = null) + public function buildSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token = null) { $base_string = $request->getOAuthSignatureBaseString(); - $key = $this->getSignatureKey($client, $token); + $key = $this->getSignatureKey($consumer, $token); return base64_encode(hash_hmac('sha1', $base_string, $key, true)); } diff --git a/src/JacobKiers/OAuth/PlainText.php b/src/JacobKiers/OAuth/SignatureMethod/PlainText.php similarity index 66% rename from src/JacobKiers/OAuth/PlainText.php rename to src/JacobKiers/OAuth/SignatureMethod/PlainText.php index fce18e6..4038831 100644 --- a/src/JacobKiers/OAuth/PlainText.php +++ b/src/JacobKiers/OAuth/SignatureMethod/PlainText.php @@ -9,7 +9,11 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\SignatureMethod; + +use \JacobKiers\OAuth\Consumer\ConsumerInterface; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Request\RequestInterface; /** * PLAINTEXT signature method. @@ -36,7 +40,7 @@ class PlainText extends SignatureMethod /** * Build up the signature. * - * oauth_signature is set to the concatenated encoded values of the Client Secret and + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is * empty. The result MUST be encoded again. * - Chapter 9.4.1 ("Generating Signatures") @@ -44,14 +48,14 @@ class PlainText extends SignatureMethod * Please note that the second encoding MUST NOT happen in the SignatureMethod, as * OAuthRequest handles this! * - * @param JacobKiers\OAuth\RequestInterface $request - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token * * @return string */ - public function buildSignature(RequestInterface $request, Client $client, Token $token = null) + public function buildSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token = null) { - return $this->getSignatureKey($client, $token); + return $this->getSignatureKey($consumer, $token); } } diff --git a/src/JacobKiers/OAuth/RsaSha1.php b/src/JacobKiers/OAuth/SignatureMethod/RsaSha1.php similarity index 74% rename from src/JacobKiers/OAuth/RsaSha1.php rename to src/JacobKiers/OAuth/SignatureMethod/RsaSha1.php index 5b14b7b..1020bad 100644 --- a/src/JacobKiers/OAuth/RsaSha1.php +++ b/src/JacobKiers/OAuth/SignatureMethod/RsaSha1.php @@ -9,14 +9,18 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\SignatureMethod; + +use \JacobKiers\OAuth\Consumer\ConsumerInterface; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Request\RequestInterface; /** * The RSA-SHA1 signature method. * * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for - * EMSA-PKCS1-v1_5. It is assumed that the Client has provided its RSA public key in a + * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a * verified way to the Service Provider, in a manner which is beyond the scope of this * specification. * - Chapter 9.3 ("RSA-SHA1") @@ -38,7 +42,7 @@ abstract class RsaSha1 extends SignatureMethod /** * Up to the SP to implement this lookup of keys. Possible ideas are: - * (1) do a lookup in a table of trusted certs keyed off of client + * (1) do a lookup in a table of trusted certs keyed off of consumer * (2) fetch via http using a url provided by the requester * (3) some sort of specific discovery code based on request * @@ -49,7 +53,7 @@ abstract class RsaSha1 extends SignatureMethod /** * Up to the SP to implement this lookup of keys. Possible ideas are: - * (1) do a lookup in a table of trusted certs keyed off of client + * (1) do a lookup in a table of trusted certs keyed off of consumer * * Either way should return a string representation of the certificate */ @@ -58,13 +62,13 @@ abstract class RsaSha1 extends SignatureMethod /** * Build up the signature. * - * @param JacobKiers\OAuth\RequestInterface $request - * @param JacobKiers\OAuth\Client $client - * @param JacobKiers\OAuth\Token $token + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token * * @return string */ - public function buildSignature(RequestInterface $request, Client $client, Token $token = null) + public function buildSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token = null) { $base_string = $request->getOAuthSignatureBaseString(); @@ -86,14 +90,14 @@ abstract class RsaSha1 extends SignatureMethod /** * Verifies that a given signature is correct. * - * @param JacobKiers\OAuth\RequestInterface $request - * @param JacobKiers\OAuth\Consumer $client - * @param JacobKiers\OAuth\Token $token - * @param string $signature + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * @param string $signature * * @return bool */ - public function checkSignature(RequestInterface $request, Client $client, Token $token, $signature) + public function checkSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token, $signature) { $base_string = $request->getOAuthSignatureBaseString(); diff --git a/src/JacobKiers/OAuth/SignatureMethod/SignatureMethod.php b/src/JacobKiers/OAuth/SignatureMethod/SignatureMethod.php new file mode 100644 index 0000000..067b5d1 --- /dev/null +++ b/src/JacobKiers/OAuth/SignatureMethod/SignatureMethod.php @@ -0,0 +1,86 @@ + + * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT + * @link https://github.com/jacobkiers/OAuth + */ + +namespace JacobKiers\OAuth\SignatureMethod; + +use \JacobKiers\OAuth\Util; +use \JacobKiers\OAuth\Consumer\ConsumerInterface; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Request\RequestInterface; + +/** + * A class for implementing a Signature Method. + * + * See section 9 ("Signing Requests") in the spec + * + * @package OAuth + * @author Andy Smith + * @author Gary Jones + */ +abstract class SignatureMethod implements SignatureMethodInterface +{ + /** + * Return the name of the Signature Method (ie HMAC-SHA1). + * + * @return string + */ + abstract public function getName(); + + /** + * Build up the signature. + * + * NOTE: The output of this function MUST NOT be urlencoded. + * the encoding is handled in OAuthRequest when the final + * request is serialized. + * + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * + * @return string + */ + abstract public function buildSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token = null); + + /** + * Get the signature key, made up of consumer and optionally token shared secrets. + * + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * + * @return string + */ + public function getSignatureKey(ConsumerInterface $consumer, TokenInterface $token = null) + { + $key_parts = array( + $consumer->getSecret(), + ($token) ? $token->getSecret() : '', + ); + + $key_parts = Util::urlencodeRfc3986($key_parts); + return implode('&', $key_parts); + } + + /** + * Verifies that a given signature is correct. + * + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * @param string $signature + * + * @return bool + */ + public function checkSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token, $signature) + { + $built = $this->buildSignature($request, $consumer, $token); + return $built == $signature; + } +} diff --git a/src/JacobKiers/OAuth/SignatureMethod/SignatureMethodInterface.php b/src/JacobKiers/OAuth/SignatureMethod/SignatureMethodInterface.php new file mode 100644 index 0000000..aa94706 --- /dev/null +++ b/src/JacobKiers/OAuth/SignatureMethod/SignatureMethodInterface.php @@ -0,0 +1,70 @@ + + * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT + * @link https://github.com/jacobkiers/OAuth + */ + +namespace JacobKiers\OAuth\SignatureMethod; + +use \JacobKiers\OAuth\Consumer\ConsumerInterface; +use \JacobKiers\OAuth\Token\TokenInterface; +use \JacobKiers\OAuth\Request\RequestInterface; + +/** + * A class for implementing a Signature Method. + * + * See section 9 ("Signing Requests") in the spec + * + * @package OAuth + * @author Jacob Kiers + */ +interface SignatureMethodInterface +{ + /** + * Return the name of the Signature Method (ie HMAC-SHA1). + * + * @return string + */ + public function getName(); + + /** + * Build up the signature. + * + * NOTE: The output of this function MUST NOT be urlencoded. + * the encoding is handled in OAuthRequest when the final + * request is serialized. + * + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * + * @return string + */ + public function buildSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token = null); + + /** + * Get the signature key, made up of consumer and optionally token shared secrets. + * + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * + * @return string + */ + public function getSignatureKey(ConsumerInterface $consumer, TokenInterface $token = null); + + /** + * Verifies that a given signature is correct. + * + * @param JacobKiers\OAuth\Request\RequestInterface $request + * @param JacobKiers\OAuth\Consumer\ConsumerInterface $consumer + * @param JacobKiers\OAuth\Token\TokenInterface $token + * @param string $signature + * + * @return bool + */ + public function checkSignature(RequestInterface $request, ConsumerInterface $consumer, TokenInterface $token, $signature); +} diff --git a/src/JacobKiers/OAuth/NullToken.php b/src/JacobKiers/OAuth/Token/NullToken.php similarity index 73% rename from src/JacobKiers/OAuth/NullToken.php rename to src/JacobKiers/OAuth/Token/NullToken.php index 9c7df1f..01ab4bb 100644 --- a/src/JacobKiers/OAuth/NullToken.php +++ b/src/JacobKiers/OAuth/Token/NullToken.php @@ -9,7 +9,7 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\Token; /** * Token holds the properties of a single token. @@ -22,10 +22,10 @@ namespace JacobKiers\OAuth; class NullToken extends Token { /** - * Constructs a new client object and populates the required parameters. + * Constructs a new Token object and populates the required parameters. * - * @param string $key Client key / identifier. - * @param string $secret Client shared-secret. + * @param string $key Token key / identifier. + * @param string $secret Token shared-secret. */ public function __construct() { diff --git a/src/JacobKiers/OAuth/Token.php b/src/JacobKiers/OAuth/Token/Token.php similarity index 74% rename from src/JacobKiers/OAuth/Token.php rename to src/JacobKiers/OAuth/Token/Token.php index ca9efbb..d3d777b 100644 --- a/src/JacobKiers/OAuth/Token.php +++ b/src/JacobKiers/OAuth/Token/Token.php @@ -9,7 +9,10 @@ * @link https://github.com/jacobkiers/OAuth */ -namespace JacobKiers\OAuth; +namespace JacobKiers\OAuth\Token; + +use \JacobKiers\OAuth\Credential; +use \JacobKiers\OAuth\Util; /** * Token holds the properties of a single token. @@ -19,13 +22,13 @@ namespace JacobKiers\OAuth; * @package OAuth * @author Gary Jones */ -class Token extends Credential +class Token extends Credential implements TokenInterface { /** - * Constructs a new client object and populates the required parameters. + * Constructs a new Token object and populates the required parameters. * - * @param string $key Client key / identifier. - * @param string $secret Client shared-secret. + * @param string $key Token key / identifier. + * @param string $secret Token shared-secret. */ public function __construct($key, $secret) { diff --git a/src/JacobKiers/OAuth/Token/TokenInterface.php b/src/JacobKiers/OAuth/Token/TokenInterface.php new file mode 100644 index 0000000..a983bea --- /dev/null +++ b/src/JacobKiers/OAuth/Token/TokenInterface.php @@ -0,0 +1,34 @@ + + * @license https://raw.github.com/jacobkiers/OAuth/master/LICENSE MIT + * @link https://github.com/jacobkiers/OAuth + */ + +namespace JacobKiers\OAuth\Token; + +/** + * Credential is the blueprint for all key + secret classes. + * + * @package OAuth + * @author Jacob Kiers + */ +interface TokenInterface +{ + /** + * Return the credential key. + * + * @return string Credential key. + */ + public function getKey(); + + /** + * Return the credential secret + * + * @return string + */ + public function getSecret(); +} diff --git a/tests/ClientTest.php b/tests/ClientTest.php deleted file mode 100644 index 5e4188a..0000000 --- a/tests/ClientTest.php +++ /dev/null @@ -1,20 +0,0 @@ -assertEquals('foo', $client->getKey()); - $this->assertEquals('bar', $client->getSecret()); - } - - public function testCallbackUrlIsSet() - { - $client = new Client('foo', 'bar', 'http://example.com/foobar'); - $this->assertEquals('http://example.com/foobar', $client->getCallbackUrl()); - } - -} diff --git a/tests/ConsumerTest.php b/tests/ConsumerTest.php new file mode 100644 index 0000000..6320ef0 --- /dev/null +++ b/tests/ConsumerTest.php @@ -0,0 +1,20 @@ +assertEquals('foo', $consumer->getKey()); + $this->assertEquals('bar', $consumer->getSecret()); + } + + public function testCallbackUrlIsSet() + { + $consumer = new consumer('foo', 'bar', 'http://example.com/foobar'); + $this->assertEquals('http://example.com/foobar', $consumer->getCallbackUrl()); + } + +} diff --git a/tests/HmacSha1Test.php b/tests/HmacSha1Test.php index ebc0513..27060a7 100644 --- a/tests/HmacSha1Test.php +++ b/tests/HmacSha1Test.php @@ -1,7 +1,7 @@ getRequest(); - $client = $this->getClient(); + $client = $this->getConsumer(); // Run method being tested $signature = $hmacsha1->buildSignature($request, $client); @@ -39,7 +39,7 @@ class HmacSha1Test extends PHPUnit_Framework_TestCase // Get mock objects $request = $this->getRequest(); - $client = $this->getClient(); + $client = $this->getConsumer(); $token = $this->getToken(); // Run method being tested @@ -56,23 +56,23 @@ class HmacSha1Test extends PHPUnit_Framework_TestCase private function getRequest() { - return m::mock('JacobKiers\OAuth\Request', function ($mock) { + return m::mock('JacobKiers\OAuth\Request\Request', function ($mock) { $mock->shouldReceive('getOAuthSignatureBaseString') ->withNoArgs() ->andReturn('POST&http%3A%2F%2Fexample.com%2Ffoobar&oauth_signature_method%3DHMAC-SHA1')->once(); }); } - private function getClient() + private function getConsumer() { - return m::mock('JacobKiers\OAuth\Client', function ($mock) { + return m::mock('JacobKiers\OAuth\Consumer\Consumer', function ($mock) { $mock->shouldReceive('getSecret')->withNoArgs()->andReturn('secret')->once(); }); } private function getToken() { - return m::mock('JacobKiers\OAuth\Token', function ($mock) { + return m::mock('JacobKiers\OAuth\Token\Token', function ($mock) { $mock->shouldReceive('getSecret')->withNoArgs()->andReturn('token_secret'); }); } diff --git a/tests/PlainTextTest.php b/tests/PlainTextTest.php index f16030f..0dd3ac7 100644 --- a/tests/PlainTextTest.php +++ b/tests/PlainTextTest.php @@ -1,7 +1,7 @@ getRequest(); - $client = $this->getClient(); + $client = $this->getConsumer(); // Run method being tested $signature = $plaintext->buildSignature($request, $client); @@ -39,7 +39,7 @@ class PlainTextTest extends PHPUnit_Framework_TestCase // Get mock objects $request = $this->getRequest(); - $client = $this->getClient(); + $client = $this->getConsumer(); $token = $this->getToken(); // Run method being tested @@ -56,19 +56,19 @@ class PlainTextTest extends PHPUnit_Framework_TestCase private function getRequest() { - return m::mock('JacobKiers\OAuth\Request'); + return m::mock('JacobKiers\OAuth\Request\Request'); } - private function getClient() + private function getConsumer() { - return m::mock('JacobKiers\OAuth\Client', function ($mock) { + return m::mock('JacobKiers\OAuth\Consumer\Consumer', function ($mock) { $mock->shouldReceive('getSecret')->withNoArgs()->andReturn('secret')->once(); }); } private function getToken() { - return m::mock('JacobKiers\OAuth\Token', function ($mock) { + return m::mock('JacobKiers\OAuth\Token\Token', function ($mock) { $mock->shouldReceive('getSecret')->withNoArgs()->andReturn('token_secret'); }); } diff --git a/tests/RequestTest.php b/tests/RequestTest.php index b24f118..cf3fa98 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -1,7 +1,7 @@ getSignatureMethod(); // Get mock objects - $client = $this->getClient(); + $consumer = $this->getConsumer(); // Run method being tested - $signature_key = $signature_method->getSignatureKey($client); + $signature_key = $signature_method->getSignatureKey($consumer); // Check results $this->assertEquals('secret&', $signature_key); @@ -49,11 +49,11 @@ class SignatureTest extends PHPUnit_Framework_TestCase $signature_method = $this->getSignatureMethod(); // Get mock objects - $client = $this->getClient(); + $consumer = $this->getConsumer(); $token = $this->getToken(); // Run method being tested - $signature_key = $signature_method->getSignatureKey($client, $token); + $signature_key = $signature_method->getSignatureKey($consumer, $token); // Check results $this->assertEquals('secret&token_secret', $signature_key); @@ -64,16 +64,16 @@ class SignatureTest extends PHPUnit_Framework_TestCase return new FooBarSignatureMethod; } - private function getClient() + private function getConsumer() { - return m::mock('JacobKiers\OAuth\Client', function ($mock) { + return m::mock('JacobKiers\OAuth\Consumer\Consumer', function ($mock) { $mock->shouldReceive('getSecret')->withNoArgs()->andReturn('secret')->once(); }); } private function getToken() { - return m::mock('JacobKiers\OAuth\Token', function ($mock) { + return m::mock('JacobKiers\OAuth\Token\Token', function ($mock) { $mock->shouldReceive('getSecret')->withNoArgs()->andReturn('token_secret'); }); } diff --git a/tests/TokenTest.php b/tests/TokenTest.php index 59acd7a..0ed7721 100644 --- a/tests/TokenTest.php +++ b/tests/TokenTest.php @@ -1,7 +1,7 @@