Merge branch '1.11.x' of https://github.com/chamilo/chamilo-lms into 1.11.x
commit
05cb0c85b9
@ -0,0 +1,42 @@ |
||||
|
||||
# Created by https://www.gitignore.io/api/osx,svn,composer |
||||
|
||||
### OSX ### |
||||
.DS_Store |
||||
.AppleDouble |
||||
.LSOverride |
||||
|
||||
# Icon must end with two \r |
||||
Icon
|
||||
|
||||
# Thumbnails |
||||
._* |
||||
|
||||
# Files that might appear in the root of a volume |
||||
.DocumentRevisions-V100 |
||||
.fseventsd |
||||
.Spotlight-V100 |
||||
.TemporaryItems |
||||
.Trashes |
||||
.VolumeIcon.icns |
||||
|
||||
# Directories potentially created on remote AFP share |
||||
.AppleDB |
||||
.AppleDesktop |
||||
Network Trash Folder |
||||
Temporary Items |
||||
.apdisk |
||||
|
||||
|
||||
### SVN ### |
||||
.svn/ |
||||
|
||||
|
||||
### Composer ### |
||||
composer.phar |
||||
/vendor/ |
||||
|
||||
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file |
||||
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file |
||||
# composer.lock |
||||
|
||||
@ -0,0 +1,44 @@ |
||||
### 2016.02.10 |
||||
---- |
||||
* Added composer.json |
||||
* Separated classes to separate files |
||||
|
||||
### 2008.08.04 |
||||
---- |
||||
* Added LICENSE.txt file with MIT license, copyright owner is perhaps |
||||
dubious however. |
||||
|
||||
### 2008.07.22 |
||||
---- |
||||
* Change to encoding to fix last change to encoding of spaces |
||||
|
||||
### 2008.07.15 |
||||
---- |
||||
* Another change to encoding per: |
||||
[http://groups.google.com/group/oauth/browse_thread/thread/d39931d39b4af4bd](http://groups.google.com/group/oauth/browse_thread/thread/d39931d39b4af4bd) |
||||
* A change to port handling to better deal with https and the like per: |
||||
[http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226](http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226) |
||||
* Fixed a small bug per: |
||||
[https://github.com/jtsternberg/oauth/issues/26](https://github.com/jtsternberg/oauth/issues/26) |
||||
* Added missing base_string debug info when using RSA-SHA1 |
||||
* Increased size of example endpoint input field and added note about |
||||
query strings |
||||
|
||||
### 2009-2011.03.28 |
||||
---- |
||||
* Heaps of bug-fixes |
||||
* Introduction of PHPUnit testcases (which aided in above mentioned bug-fixes) |
||||
* Added support Revision A auth flows. |
||||
* Possibly more, I've lost track.. |
||||
|
||||
### 2001.03.29 |
||||
---- |
||||
* Fixed issue with hosts not being normalized correctly |
||||
[http://tools.ietf.org/html/rfc5849#section-3.4.1.2](http://tools.ietf.org/html/rfc5849#section-3.4.1.2) |
||||
[https://github.com/jtsternberg/oauth/issues/176](https://github.com/jtsternberg/oauth/issues/176) |
||||
[https://github.com/jtsternberg/oauth/issues/187](https://github.com/jtsternberg/oauth/issues/187) |
||||
* Changed signature comparing to be timing insensitive |
||||
[https://github.com/jtsternberg/oauth/issues/178](https://github.com/jtsternberg/oauth/issues/178) |
||||
* Fixed issue with Host header on some servers on non-standard port includes the port-number |
||||
[https://github.com/jtsternberg/oauth/issues/170](https://github.com/jtsternberg/oauth/issues/170) |
||||
[https://github.com/jtsternberg/oauth/issues/192](https://github.com/jtsternberg/oauth/issues/192) |
||||
@ -0,0 +1,22 @@ |
||||
The MIT License |
||||
|
||||
Copyright (c) 2007 Andy Smith |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in |
||||
all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
THE SOFTWARE. |
||||
|
||||
@ -0,0 +1,6 @@ |
||||
# OAuth1 PHP |
||||
[Andy Smith](http://term.ie/)'s basic php library for OAuth. Original code taken from google code. For reference (and since google code is going away), I have ported the entire project to github. [You can find it here](https://github.com/jtsternberg/oauth). |
||||
|
||||
To use this, be sure to run `composer install` in the root of the lib. |
||||
|
||||
I have also split out the spec portion of the google code repo to [its own repo](https://github.com/jtsternberg/oauth-spec). |
||||
@ -0,0 +1,16 @@ |
||||
<?php |
||||
|
||||
class OAuthConsumer { |
||||
public $key; |
||||
public $secret; |
||||
|
||||
function __construct($key, $secret, $callback_url=NULL) { |
||||
$this->key = $key; |
||||
$this->secret = $secret; |
||||
$this->callback_url = $callback_url; |
||||
} |
||||
|
||||
function __toString() { |
||||
return "OAuthConsumer[key=$this->key,secret=$this->secret]"; |
||||
} |
||||
} |
||||
@ -0,0 +1,27 @@ |
||||
<?php |
||||
|
||||
class OAuthDataStore { |
||||
function lookup_consumer($consumer_key) { |
||||
// implement me |
||||
} |
||||
|
||||
function lookup_token($consumer, $token_type, $token) { |
||||
// implement me |
||||
} |
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) { |
||||
// implement me |
||||
} |
||||
|
||||
function new_request_token($consumer, $callback = null) { |
||||
// return a new token attached to this consumer |
||||
} |
||||
|
||||
function new_access_token($token, $consumer, $verifier = 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 |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,7 @@ |
||||
<?php |
||||
|
||||
/* Generic exception class |
||||
*/ |
||||
class OAuthException extends Exception { |
||||
// pass |
||||
} |
||||
@ -0,0 +1,260 @@ |
||||
<?php |
||||
class OAuthRequest { |
||||
protected $parameters; |
||||
protected $http_method; |
||||
protected $http_url; |
||||
// for debug purposes |
||||
public $base_string; |
||||
public static $version = '1.0'; |
||||
public static $POST_INPUT = 'php://input'; |
||||
|
||||
function __construct($http_method, $http_url, $parameters=NULL) { |
||||
$parameters = ($parameters) ? $parameters : array(); |
||||
$parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); |
||||
$this->parameters = $parameters; |
||||
$this->http_method = $http_method; |
||||
$this->http_url = $http_url; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* attempt to build up a request from what was passed to the server |
||||
*/ |
||||
public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { |
||||
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") |
||||
? 'http' |
||||
: 'https'; |
||||
$http_url = ($http_url) ? $http_url : $scheme . |
||||
'://' . $_SERVER['SERVER_NAME'] . |
||||
':' . |
||||
$_SERVER['SERVER_PORT'] . |
||||
$_SERVER['REQUEST_URI']; |
||||
$http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD']; |
||||
|
||||
// We weren't handed any parameters, so let's find the ones relevant to |
||||
// this request. |
||||
// If you run XML-RPC or similar you should use this to provide your own |
||||
// parsed parameter-list |
||||
if (!$parameters) { |
||||
// Find request headers |
||||
$request_headers = OAuthUtil::get_headers(); |
||||
|
||||
// Parse the query-string to find GET parameters |
||||
$parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); |
||||
|
||||
// It's a POST request of the proper content-type, so parse POST |
||||
// parameters and add those overriding any duplicates from GET |
||||
if ($http_method == "POST" |
||||
&& isset($request_headers['Content-Type']) |
||||
&& strstr($request_headers['Content-Type'], |
||||
'application/x-www-form-urlencoded') |
||||
) { |
||||
$post_data = OAuthUtil::parse_parameters( |
||||
file_get_contents(self::$POST_INPUT) |
||||
); |
||||
$parameters = array_merge($parameters, $post_data); |
||||
} |
||||
|
||||
// We have a Authorization-header with OAuth data. Parse the header |
||||
// and add those overriding any duplicates from GET or POST |
||||
if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') { |
||||
$header_parameters = OAuthUtil::split_header( |
||||
$request_headers['Authorization'] |
||||
); |
||||
$parameters = array_merge($parameters, $header_parameters); |
||||
} |
||||
|
||||
} |
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters); |
||||
} |
||||
|
||||
/** |
||||
* pretty much a helper function to set up the request |
||||
*/ |
||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { |
||||
$parameters = ($parameters) ? $parameters : array(); |
||||
$defaults = array("oauth_version" => OAuthRequest::$version, |
||||
"oauth_nonce" => OAuthRequest::generate_nonce(), |
||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(), |
||||
"oauth_consumer_key" => $consumer->key); |
||||
if ($token) |
||||
$defaults['oauth_token'] = $token->key; |
||||
|
||||
$parameters = array_merge($defaults, $parameters); |
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters); |
||||
} |
||||
|
||||
public function set_parameter($name, $value, $allow_duplicates = true) { |
||||
if ($allow_duplicates && isset($this->parameters[$name])) { |
||||
// We have already added parameter(s) with this name, so add to the list |
||||
if (is_scalar($this->parameters[$name])) { |
||||
// This is the first duplicate, so transform scalar (string) |
||||
// into an array so we can add the duplicates |
||||
$this->parameters[$name] = array($this->parameters[$name]); |
||||
} |
||||
|
||||
$this->parameters[$name][] = $value; |
||||
} else { |
||||
$this->parameters[$name] = $value; |
||||
} |
||||
} |
||||
|
||||
public function get_parameter($name) { |
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null; |
||||
} |
||||
|
||||
public function get_parameters() { |
||||
return $this->parameters; |
||||
} |
||||
|
||||
public function unset_parameter($name) { |
||||
unset($this->parameters[$name]); |
||||
} |
||||
|
||||
/** |
||||
* The request parameters, sorted and concatenated into a normalized string. |
||||
* @return string |
||||
*/ |
||||
public function get_signable_parameters() { |
||||
// Grab all parameters |
||||
$params = $this->parameters; |
||||
|
||||
// Remove oauth_signature if present |
||||
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") |
||||
if (isset($params['oauth_signature'])) { |
||||
unset($params['oauth_signature']); |
||||
} |
||||
|
||||
return OAuthUtil::build_http_query($params); |
||||
} |
||||
|
||||
/** |
||||
* Returns the base string of this request |
||||
* |
||||
* The base string defined as the method, the url |
||||
* and the parameters (normalized), each urlencoded |
||||
* and the concated with &. |
||||
*/ |
||||
public function get_signature_base_string() { |
||||
$parts = array( |
||||
$this->get_normalized_http_method(), |
||||
$this->get_normalized_http_url(), |
||||
$this->get_signable_parameters() |
||||
); |
||||
|
||||
$parts = OAuthUtil::urlencode_rfc3986($parts); |
||||
|
||||
return implode('&', $parts); |
||||
} |
||||
|
||||
/** |
||||
* just uppercases the http method |
||||
*/ |
||||
public function get_normalized_http_method() { |
||||
return strtoupper($this->http_method); |
||||
} |
||||
|
||||
/** |
||||
* parses the url and rebuilds it to be |
||||
* scheme://host/path |
||||
*/ |
||||
public function get_normalized_http_url() { |
||||
$parts = parse_url($this->http_url); |
||||
|
||||
$scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http'; |
||||
$port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80'); |
||||
$host = (isset($parts['host'])) ? strtolower($parts['host']) : ''; |
||||
$path = (isset($parts['path'])) ? $parts['path'] : ''; |
||||
|
||||
if (($scheme == 'https' && $port != '443') |
||||
|| ($scheme == 'http' && $port != '80')) { |
||||
$host = "$host:$port"; |
||||
} |
||||
return "$scheme://$host$path"; |
||||
} |
||||
|
||||
/** |
||||
* builds a url usable for a GET request |
||||
*/ |
||||
public function to_url() { |
||||
$post_data = $this->to_postdata(); |
||||
$out = $this->get_normalized_http_url(); |
||||
if ($post_data) { |
||||
$out .= '?'.$post_data; |
||||
} |
||||
return $out; |
||||
} |
||||
|
||||
/** |
||||
* builds the data one would send in a POST request |
||||
*/ |
||||
public function to_postdata() { |
||||
return OAuthUtil::build_http_query($this->parameters); |
||||
} |
||||
|
||||
/** |
||||
* builds the Authorization: header |
||||
*/ |
||||
public function to_header($realm=null) { |
||||
$first = true; |
||||
if($realm) { |
||||
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; |
||||
$first = false; |
||||
} else |
||||
$out = 'Authorization: OAuth'; |
||||
|
||||
$total = array(); |
||||
foreach ($this->parameters as $k => $v) { |
||||
if (substr($k, 0, 5) != "oauth") continue; |
||||
if (is_array($v)) { |
||||
throw new OAuthException('Arrays not supported in headers'); |
||||
} |
||||
$out .= ($first) ? ' ' : ','; |
||||
$out .= OAuthUtil::urlencode_rfc3986($k) . |
||||
'="' . |
||||
OAuthUtil::urlencode_rfc3986($v) . |
||||
'"'; |
||||
$first = false; |
||||
} |
||||
return $out; |
||||
} |
||||
|
||||
public function __toString() { |
||||
return $this->to_url(); |
||||
} |
||||
|
||||
|
||||
public function sign_request($signature_method, $consumer, $token) { |
||||
$this->set_parameter( |
||||
"oauth_signature_method", |
||||
$signature_method->get_name(), |
||||
false |
||||
); |
||||
$signature = $this->build_signature($signature_method, $consumer, $token); |
||||
$this->set_parameter("oauth_signature", $signature, false); |
||||
} |
||||
|
||||
public function build_signature($signature_method, $consumer, $token) { |
||||
$signature = $signature_method->build_signature($this, $consumer, $token); |
||||
return $signature; |
||||
} |
||||
|
||||
/** |
||||
* util function: current timestamp |
||||
*/ |
||||
private static function generate_timestamp() { |
||||
return time(); |
||||
} |
||||
|
||||
/** |
||||
* util function: current nonce |
||||
*/ |
||||
private static function generate_nonce() { |
||||
$mt = microtime(); |
||||
$rand = mt_rand(); |
||||
|
||||
return md5($mt . $rand); // md5s look nicer than numbers |
||||
} |
||||
} |
||||
@ -0,0 +1,223 @@ |
||||
<?php |
||||
|
||||
class OAuthServer { |
||||
protected $timestamp_threshold = 300; // in seconds, five minutes |
||||
protected $version = '1.0'; // hi blaine |
||||
protected $signature_methods = array(); |
||||
|
||||
protected $data_store; |
||||
|
||||
function __construct($data_store) { |
||||
$this->data_store = $data_store; |
||||
} |
||||
|
||||
public function add_signature_method($signature_method) { |
||||
$this->signature_methods[$signature_method->get_name()] = |
||||
$signature_method; |
||||
} |
||||
|
||||
// high level functions |
||||
|
||||
/** |
||||
* process a request_token request |
||||
* returns the request token on success |
||||
*/ |
||||
public function fetch_request_token(&$request) { |
||||
$this->get_version($request); |
||||
|
||||
$consumer = $this->get_consumer($request); |
||||
|
||||
// no token required for the initial token request |
||||
$token = NULL; |
||||
|
||||
$this->check_signature($request, $consumer, $token); |
||||
|
||||
// Rev A change |
||||
$callback = $request->get_parameter('oauth_callback'); |
||||
$new_token = $this->data_store->new_request_token($consumer, $callback); |
||||
|
||||
return $new_token; |
||||
} |
||||
|
||||
/** |
||||
* process an access_token request |
||||
* returns the access token on success |
||||
*/ |
||||
public function fetch_access_token(&$request) { |
||||
$this->get_version($request); |
||||
|
||||
$consumer = $this->get_consumer($request); |
||||
|
||||
// requires authorized request token |
||||
$token = $this->get_token($request, $consumer, "request"); |
||||
|
||||
$this->check_signature($request, $consumer, $token); |
||||
|
||||
// Rev A change |
||||
$verifier = $request->get_parameter('oauth_verifier'); |
||||
$new_token = $this->data_store->new_access_token($token, $consumer, $verifier); |
||||
|
||||
return $new_token; |
||||
} |
||||
|
||||
/** |
||||
* verify an api call, checks all the parameters |
||||
*/ |
||||
public function verify_request(&$request) { |
||||
$this->get_version($request); |
||||
$consumer = $this->get_consumer($request); |
||||
$token = $this->get_token($request, $consumer, "access"); |
||||
$this->check_signature($request, $consumer, $token); |
||||
return array($consumer, $token); |
||||
} |
||||
|
||||
// Internals from here |
||||
/** |
||||
* version 1 |
||||
*/ |
||||
private function get_version(&$request) { |
||||
$version = $request->get_parameter("oauth_version"); |
||||
if (!$version) { |
||||
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. |
||||
// Chapter 7.0 ("Accessing Protected Ressources") |
||||
$version = '1.0'; |
||||
} |
||||
if ($version !== $this->version) { |
||||
throw new OAuthException("OAuth version '$version' not supported"); |
||||
} |
||||
return $version; |
||||
} |
||||
|
||||
/** |
||||
* figure out the signature with some defaults |
||||
*/ |
||||
private function get_signature_method($request) { |
||||
$signature_method = $request instanceof OAuthRequest |
||||
? $request->get_parameter("oauth_signature_method") |
||||
: NULL; |
||||
|
||||
if (!$signature_method) { |
||||
// According to chapter 7 ("Accessing Protected Ressources") the signature-method |
||||
// parameter is required, and we can't just fallback to PLAINTEXT |
||||
throw new OAuthException('No signature method parameter. This parameter is required'); |
||||
} |
||||
|
||||
if (!in_array($signature_method, |
||||
array_keys($this->signature_methods))) { |
||||
throw new OAuthException( |
||||
"Signature method '$signature_method' not supported " . |
||||
"try one of the following: " . |
||||
implode(", ", array_keys($this->signature_methods)) |
||||
); |
||||
} |
||||
return $this->signature_methods[$signature_method]; |
||||
} |
||||
|
||||
/** |
||||
* try to find the consumer for the provided request's consumer key |
||||
*/ |
||||
private function get_consumer($request) { |
||||
$consumer_key = $request instanceof OAuthRequest |
||||
? $request->get_parameter("oauth_consumer_key") |
||||
: NULL; |
||||
|
||||
if (!$consumer_key) { |
||||
throw new OAuthException("Invalid consumer key"); |
||||
} |
||||
|
||||
$consumer = $this->data_store->lookup_consumer($consumer_key); |
||||
if (!$consumer) { |
||||
throw new OAuthException("Invalid consumer"); |
||||
} |
||||
|
||||
return $consumer; |
||||
} |
||||
|
||||
/** |
||||
* try to find the token for the provided request's token key |
||||
*/ |
||||
private function get_token($request, $consumer, $token_type="access") { |
||||
$token_field = $request instanceof OAuthRequest |
||||
? $request->get_parameter('oauth_token') |
||||
: NULL; |
||||
|
||||
$token = $this->data_store->lookup_token( |
||||
$consumer, $token_type, $token_field |
||||
); |
||||
if (!$token) { |
||||
throw new OAuthException("Invalid $token_type token: $token_field"); |
||||
} |
||||
return $token; |
||||
} |
||||
|
||||
/** |
||||
* all-in-one function to check the signature on a request |
||||
* should guess the signature method appropriately |
||||
*/ |
||||
private function check_signature($request, $consumer, $token) { |
||||
// this should probably be in a different method |
||||
$timestamp = $request instanceof OAuthRequest |
||||
? $request->get_parameter('oauth_timestamp') |
||||
: NULL; |
||||
$nonce = $request instanceof OAuthRequest |
||||
? $request->get_parameter('oauth_nonce') |
||||
: NULL; |
||||
|
||||
$this->check_timestamp($timestamp); |
||||
$this->check_nonce($consumer, $token, $nonce, $timestamp); |
||||
|
||||
$signature_method = $this->get_signature_method($request); |
||||
|
||||
$signature = $request->get_parameter('oauth_signature'); |
||||
$valid_sig = $signature_method->check_signature( |
||||
$request, |
||||
$consumer, |
||||
$token, |
||||
$signature |
||||
); |
||||
|
||||
if (!$valid_sig) { |
||||
throw new OAuthException("Invalid signature"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* check that the timestamp is new enough |
||||
*/ |
||||
private function check_timestamp($timestamp) { |
||||
if( ! $timestamp ) |
||||
throw new OAuthException( |
||||
'Missing timestamp parameter. The parameter is required' |
||||
); |
||||
|
||||
// verify that timestamp is recentish |
||||
$now = time(); |
||||
if (abs($now - $timestamp) > $this->timestamp_threshold) { |
||||
throw new OAuthException( |
||||
"Expired timestamp, yours $timestamp, ours $now" |
||||
); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* check that the nonce is not repeated |
||||
*/ |
||||
private function check_nonce($consumer, $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->lookup_nonce( |
||||
$consumer, |
||||
$token, |
||||
$nonce, |
||||
$timestamp |
||||
); |
||||
if ($found) { |
||||
throw new OAuthException("Nonce already used: $nonce"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,55 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* A class for implementing a Signature Method |
||||
* See section 9 ("Signing Requests") in the spec |
||||
*/ |
||||
abstract class OAuthSignatureMethod { |
||||
/** |
||||
* Needs to return the name of the Signature Method (ie HMAC-SHA1) |
||||
* @return string |
||||
*/ |
||||
abstract public function get_name(); |
||||
|
||||
/** |
||||
* 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 OAuthRequest $request |
||||
* @param OAuthConsumer $consumer |
||||
* @param OAuthToken $token |
||||
* @return string |
||||
*/ |
||||
abstract public function build_signature($request, $consumer, $token); |
||||
|
||||
/** |
||||
* Verifies that a given signature is correct |
||||
* @param OAuthRequest $request |
||||
* @param OAuthConsumer $consumer |
||||
* @param OAuthToken $token |
||||
* @param string $signature |
||||
* @return bool |
||||
*/ |
||||
public function check_signature($request, $consumer, $token, $signature) { |
||||
$built = $this->build_signature($request, $consumer, $token); |
||||
|
||||
// Check for zero length, although unlikely here |
||||
if (strlen($built) == 0 || strlen($signature) == 0) { |
||||
return false; |
||||
} |
||||
|
||||
if (strlen($built) != strlen($signature)) { |
||||
return false; |
||||
} |
||||
|
||||
// Avoid a timing leak with a (hopefully) time insensitive compare |
||||
$result = 0; |
||||
for ($i = 0; $i < strlen($signature); $i++) { |
||||
$result |= ord($built{$i}) ^ ord($signature{$i}); |
||||
} |
||||
|
||||
return $result == 0; |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as |
||||
* defined in [RFC2104] where the Signature Base String is the text and the |
||||
* key is the concatenated values (each first encoded per Parameter Encoding) |
||||
* of the Consumer Secret and Token Secret, separated by an '&' character |
||||
* (ASCII code 38) even if empty. |
||||
* - Chapter 9.2 ("HMAC-SHA1") |
||||
*/ |
||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { |
||||
function get_name() { |
||||
return "HMAC-SHA1"; |
||||
} |
||||
|
||||
public function build_signature($request, $consumer, $token) { |
||||
$base_string = $request->get_signature_base_string(); |
||||
$request->base_string = $base_string; |
||||
|
||||
$key_parts = array( |
||||
$consumer->secret, |
||||
($token) ? $token->secret : "" |
||||
); |
||||
|
||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts); |
||||
$key = implode('&', $key_parts); |
||||
|
||||
return base64_encode(hash_hmac('sha1', $base_string, $key, true)); |
||||
} |
||||
} |
||||
@ -0,0 +1,34 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* The PLAINTEXT method does not provide any security protection and SHOULD only be used |
||||
* over a secure channel such as HTTPS. It does not use the Signature Base String. |
||||
* - Chapter 9.4 ("PLAINTEXT") |
||||
*/ |
||||
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { |
||||
public function get_name() { |
||||
return "PLAINTEXT"; |
||||
} |
||||
|
||||
/** |
||||
* 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") |
||||
* |
||||
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as |
||||
* OAuthRequest handles this! |
||||
*/ |
||||
public function build_signature($request, $consumer, $token) { |
||||
$key_parts = array( |
||||
$consumer->secret, |
||||
($token) ? $token->secret : "" |
||||
); |
||||
|
||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts); |
||||
$key = implode('&', $key_parts); |
||||
$request->base_string = $key; |
||||
|
||||
return $key; |
||||
} |
||||
} |
||||
@ -0,0 +1,69 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* 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 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") |
||||
*/ |
||||
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { |
||||
public function get_name() { |
||||
return "RSA-SHA1"; |
||||
} |
||||
|
||||
// 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 consumer |
||||
// (2) fetch via http using a url provided by the requester |
||||
// (3) some sort of specific discovery code based on request |
||||
// |
||||
// Either way should return a string representation of the certificate |
||||
protected abstract function fetch_public_cert(&$request); |
||||
|
||||
// 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 consumer |
||||
// |
||||
// Either way should return a string representation of the certificate |
||||
protected abstract function fetch_private_cert(&$request); |
||||
|
||||
public function build_signature($request, $consumer, $token) { |
||||
$base_string = $request->get_signature_base_string(); |
||||
$request->base_string = $base_string; |
||||
|
||||
// Fetch the private key cert based on the request |
||||
$cert = $this->fetch_private_cert($request); |
||||
|
||||
// Pull the private key ID from the certificate |
||||
$privatekeyid = openssl_get_privatekey($cert); |
||||
|
||||
// Sign using the key |
||||
$ok = openssl_sign($base_string, $signature, $privatekeyid); |
||||
|
||||
// Release the key resource |
||||
openssl_free_key($privatekeyid); |
||||
|
||||
return base64_encode($signature); |
||||
} |
||||
|
||||
public function check_signature($request, $consumer, $token, $signature) { |
||||
$decoded_sig = base64_decode($signature); |
||||
|
||||
$base_string = $request->get_signature_base_string(); |
||||
|
||||
// Fetch the public key cert based on the request |
||||
$cert = $this->fetch_public_cert($request); |
||||
|
||||
// Pull the public key ID from the certificate |
||||
$publickeyid = openssl_get_publickey($cert); |
||||
|
||||
// Check the computed signature against the one passed in the query |
||||
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid); |
||||
|
||||
// Release the key resource |
||||
openssl_free_key($publickeyid); |
||||
|
||||
return $ok == 1; |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,13 @@ |
||||
<phpunit colors="true"> |
||||
<testsuite name="OAuth"> |
||||
<directory>tests</directory> |
||||
</testsuite> |
||||
<filter> |
||||
<blacklist> |
||||
<directory>tests</directory> |
||||
</blacklist> |
||||
</filter> |
||||
<logging> |
||||
<log type="coverage-html" target="./report" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/> |
||||
</logging> |
||||
</phpunit> |
||||
@ -0,0 +1,31 @@ |
||||
<?php |
||||
|
||||
class OAuthToken { |
||||
// access tokens and request tokens |
||||
public $key; |
||||
public $secret; |
||||
|
||||
/** |
||||
* key = the token |
||||
* secret = the token secret |
||||
*/ |
||||
function __construct($key, $secret) { |
||||
$this->key = $key; |
||||
$this->secret = $secret; |
||||
} |
||||
|
||||
/** |
||||
* generates the basic string serialization of a token that a server |
||||
* would respond to request_token and access_token calls with |
||||
*/ |
||||
function to_string() { |
||||
return "oauth_token=" . |
||||
oauthutil::urlencode_rfc3986($this->key) . |
||||
"&oauth_token_secret=" . |
||||
oauthutil::urlencode_rfc3986($this->secret); |
||||
} |
||||
|
||||
function __tostring() { |
||||
return $this->to_string(); |
||||
} |
||||
} |
||||
@ -0,0 +1,153 @@ |
||||
<?php |
||||
|
||||
class OAuthUtil { |
||||
public static function urlencode_rfc3986($input) { |
||||
if (is_array($input)) { |
||||
return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input); |
||||
} else if (is_scalar($input)) { |
||||
return str_replace( |
||||
'+', |
||||
' ', |
||||
str_replace('%7E', '~', rawurlencode($input)) |
||||
); |
||||
} else { |
||||
return ''; |
||||
} |
||||
} |
||||
|
||||
|
||||
// This decode function isn't taking into consideration the above |
||||
// modifications to the encoding process. However, this method doesn't |
||||
// seem to be used anywhere so leaving it as is. |
||||
public static function urldecode_rfc3986($string) { |
||||
return urldecode($string); |
||||
} |
||||
|
||||
// Utility function for turning the Authorization: header into |
||||
// parameters, has to do some unescaping |
||||
// Can filter out any non-oauth parameters if needed (default behaviour) |
||||
// May 28th, 2010 - method updated to tjerk.meesters for a speed improvement. |
||||
// see http://code.google.com/p/oauth/issues/detail?id=163 |
||||
public static function split_header($header, $only_allow_oauth_parameters = true) { |
||||
$params = array(); |
||||
if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) { |
||||
foreach ($matches[1] as $i => $h) { |
||||
$params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]); |
||||
} |
||||
if (isset($params['realm'])) { |
||||
unset($params['realm']); |
||||
} |
||||
} |
||||
return $params; |
||||
} |
||||
|
||||
// helper to try to sort out headers for people who aren't running apache |
||||
public static function get_headers() { |
||||
if (function_exists('apache_request_headers')) { |
||||
// we need this to get the actual Authorization: header |
||||
// because apache tends to tell us it doesn't exist |
||||
$headers = apache_request_headers(); |
||||
|
||||
// sanitize the output of apache_request_headers because |
||||
// we always want the keys to be Cased-Like-This and arh() |
||||
// returns the headers in the same case as they are in the |
||||
// request |
||||
$out = array(); |
||||
foreach ($headers AS $key => $value) { |
||||
$key = str_replace( |
||||
" ", |
||||
"-", |
||||
ucwords(strtolower(str_replace("-", " ", $key))) |
||||
); |
||||
$out[$key] = $value; |
||||
} |
||||
} else { |
||||
// otherwise we don't have apache and are just going to have to hope |
||||
// that $_SERVER actually contains what we need |
||||
$out = array(); |
||||
if( isset($_SERVER['CONTENT_TYPE']) ) |
||||
$out['Content-Type'] = $_SERVER['CONTENT_TYPE']; |
||||
if( isset($_ENV['CONTENT_TYPE']) ) |
||||
$out['Content-Type'] = $_ENV['CONTENT_TYPE']; |
||||
|
||||
foreach ($_SERVER as $key => $value) { |
||||
if (substr($key, 0, 5) == "HTTP_") { |
||||
// this is chaos, basically it is just there to capitalize the first |
||||
// letter of every word that is not an initial HTTP and strip HTTP |
||||
// code from przemek |
||||
$key = str_replace( |
||||
" ", |
||||
"-", |
||||
ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) |
||||
); |
||||
$out[$key] = $value; |
||||
} |
||||
} |
||||
} |
||||
return $out; |
||||
} |
||||
|
||||
// This function takes a input like a=b&a=c&d=e and returns the parsed |
||||
// parameters like this |
||||
// array('a' => array('b','c'), 'd' => 'e') |
||||
public static function parse_parameters( $input ) { |
||||
if (!isset($input) || !$input) return array(); |
||||
|
||||
$pairs = explode('&', $input); |
||||
|
||||
$parsed_parameters = array(); |
||||
foreach ($pairs as $pair) { |
||||
$split = explode('=', $pair, 2); |
||||
$parameter = OAuthUtil::urldecode_rfc3986($split[0]); |
||||
$value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; |
||||
|
||||
if (isset($parsed_parameters[$parameter])) { |
||||
// We have already recieved parameter(s) with this name, so add to the list |
||||
// of parameters with this name |
||||
|
||||
if (is_scalar($parsed_parameters[$parameter])) { |
||||
// This is the first duplicate, so transform scalar (string) into an array |
||||
// so we can add the duplicates |
||||
$parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); |
||||
} |
||||
|
||||
$parsed_parameters[$parameter][] = $value; |
||||
} else { |
||||
$parsed_parameters[$parameter] = $value; |
||||
} |
||||
} |
||||
return $parsed_parameters; |
||||
} |
||||
|
||||
public static function build_http_query($params) { |
||||
if (!$params) return ''; |
||||
|
||||
// Urlencode both keys and values |
||||
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); |
||||
$values = OAuthUtil::urlencode_rfc3986(array_values($params)); |
||||
$params = array_combine($keys, $values); |
||||
|
||||
// Parameters are sorted by name, using lexicographical byte value ordering. |
||||
// Ref: Spec: 9.1.1 (1) |
||||
uksort($params, 'strcmp'); |
||||
|
||||
$pairs = array(); |
||||
foreach ($params as $parameter => $value) { |
||||
if (is_array($value)) { |
||||
// If two or more parameters share the same name, they are sorted by their value |
||||
// Ref: Spec: 9.1.1 (1) |
||||
// June 12th, 2010 - changed to sort because of issue 164 by hidetaka |
||||
sort($value, SORT_STRING); |
||||
foreach ($value as $duplicate_value) { |
||||
$pairs[] = $parameter . '=' . $duplicate_value; |
||||
} |
||||
} else { |
||||
$pairs[] = $parameter . '=' . $value; |
||||
} |
||||
} |
||||
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) |
||||
// Each name-value pair is separated by an '&' character (ASCII code 38) |
||||
return implode('&', $pairs); |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,106 @@ |
||||
<?php //vim: foldmethod=marker
|
||||
//require_once("../init.php"); |
||||
|
||||
class TestOAuthServer extends OAuthServer { |
||||
public function get_signature_methods() { |
||||
return $this->signature_methods; |
||||
} |
||||
} |
||||
|
||||
class TestOAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod_RSA_SHA1 { |
||||
public function fetch_private_cert(&$request) { |
||||
$cert = <<<EOD |
||||
-----BEGIN PRIVATE KEY----- |
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V |
||||
A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d |
||||
7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ |
||||
hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H |
||||
X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm |
||||
uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw |
||||
rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z |
||||
zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn |
||||
qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG |
||||
WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno |
||||
cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+ |
||||
3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8 |
||||
AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54 |
||||
Lw03eHTNQghS0A== |
||||
-----END PRIVATE KEY----- |
||||
EOD; |
||||
return $cert; |
||||
} |
||||
|
||||
public function fetch_public_cert(&$request) { |
||||
$cert = <<<EOD |
||||
-----BEGIN CERTIFICATE----- |
||||
MIIBpjCCAQ+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAZMRcwFQYDVQQDDA5UZXN0 |
||||
IFByaW5jaXBhbDAeFw03MDAxMDEwODAwMDBaFw0zODEyMzEwODAwMDBaMBkxFzAV |
||||
BgNVBAMMDlRlc3QgUHJpbmNpcGFsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB |
||||
gQC0YjCwIfYoprq/FQO6lb3asXrxLlJFuCvtinTF5p0GxvQGu5O3gYytUvtC2JlY |
||||
zypSRjVxwxrsuRcP3e641SdASwfrmzyvIgP08N4S0IFzEURkV1wp/IpH7kH41Etb |
||||
mUmrXSwfNZsnQRE5SYSOhh+LcK2wyQkdgcMv11l4KoBkcwIDAQABMA0GCSqGSIb3 |
||||
DQEBBQUAA4GBAGZLPEuJ5SiJ2ryq+CmEGOXfvlTtEL2nuGtr9PewxkgnOjZpUy+d |
||||
4TvuXJbNQc8f4AMWL/tO9w0Fk80rWKp9ea8/df4qMq5qlFWlx6yOLQxumNOmECKb |
||||
WpkUQDIDJEoFUzKMVuJf4KO/FJ345+BNLGgbJ6WujreoM1X/gYfdnJ/J |
||||
-----END CERTIFICATE----- |
||||
EOD; |
||||
return $cert; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* A mock store for testing |
||||
*/ |
||||
class MockOAuthDataStore extends OAuthDataStore {/*{{{*/ |
||||
private $consumer; |
||||
private $request_token; |
||||
private $access_token; |
||||
private $nonce; |
||||
|
||||
function __construct() {/*{{{*/ |
||||
$this->consumer = new OAuthConsumer("key", "secret", NULL); |
||||
$this->request_token = new OAuthToken("requestkey", "requestsecret", 1); |
||||
$this->access_token = new OAuthToken("accesskey", "accesssecret", 1); |
||||
$this->nonce = "nonce"; |
||||
}/*}}}*/ |
||||
|
||||
function lookup_consumer($consumer_key) {/*{{{*/ |
||||
if ($consumer_key == $this->consumer->key) return $this->consumer; |
||||
return NULL; |
||||
}/*}}}*/ |
||||
|
||||
function lookup_token($consumer, $token_type, $token) {/*{{{*/ |
||||
$token_attrib = $token_type . "_token"; |
||||
if ($consumer->key == $this->consumer->key |
||||
&& $token == $this->$token_attrib->key) { |
||||
return $this->$token_attrib; |
||||
} |
||||
return NULL; |
||||
}/*}}}*/ |
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/ |
||||
if ($consumer->key == $this->consumer->key |
||||
&& (($token && $token->key == $this->request_token->key) |
||||
|| ($token && $token->key == $this->access_token->key)) |
||||
&& $nonce == $this->nonce) { |
||||
return $this->nonce; |
||||
} |
||||
return NULL; |
||||
}/*}}}*/ |
||||
|
||||
function new_request_token($consumer) {/*{{{*/ |
||||
if ($consumer->key == $this->consumer->key) { |
||||
return $this->request_token; |
||||
} |
||||
return NULL; |
||||
}/*}}}*/ |
||||
|
||||
function new_access_token($token, $consumer) {/*{{{*/ |
||||
if ($consumer->key == $this->consumer->key |
||||
&& $token->key == $this->request_token->key) { |
||||
return $this->access_token; |
||||
} |
||||
return NULL; |
||||
}/*}}}*/ |
||||
}/*}}}*/ |
||||
?> |
||||
@ -0,0 +1,30 @@ |
||||
{ |
||||
"name": "jtsternberg/oauth1-php", |
||||
"description": "Andy Smith's basic php library for OAuth.", |
||||
"license": "MIT", |
||||
"authors": [ |
||||
{ |
||||
"name": "Andy Smith", |
||||
"homepage": "http://term.ie/", |
||||
"role": "Developer" |
||||
}, |
||||
{ |
||||
"name": "Justin Sternberg", |
||||
"email": "justin@dsgnwrks.pro", |
||||
"homepage": "https://dsgnwrks.pro", |
||||
"role": "Developer" |
||||
} |
||||
], |
||||
"keywords": ["oauth", "oauth1", "php"], |
||||
"homepage": "https://github.com/jtsternberg/oauth1-php", |
||||
"support": { |
||||
"issues": "https://github.com/jtsternberg/oauth1-php/issues", |
||||
"source": "https://github.com/jtsternberg/oauth1-php" |
||||
}, |
||||
"require": { |
||||
"php": ">5.3" |
||||
}, |
||||
"autoload": { |
||||
"classmap": ["code"] |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@ |
||||
{ |
||||
"_readme": [ |
||||
"This file locks the dependencies of your project to a known state", |
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", |
||||
"This file is @generated automatically" |
||||
], |
||||
"hash": "9ec16f80a40b9ed7b9501632e2ab33c3", |
||||
"content-hash": "17d848aa0b54718b6bf5334fd7e94bcc", |
||||
"packages": [], |
||||
"packages-dev": [], |
||||
"aliases": [], |
||||
"minimum-stability": "stable", |
||||
"stability-flags": [], |
||||
"prefer-stable": false, |
||||
"prefer-lowest": false, |
||||
"platform": { |
||||
"php": ">5.3" |
||||
}, |
||||
"platform-dev": [] |
||||
} |
||||
@ -0,0 +1,73 @@ |
||||
## Interfaces: |
||||
|
||||
**OAuthConsumer** is a data type that represents the identity of the Consumer via its shared secret with the Service Provider. |
||||
|
||||
OAuthConsumer |
||||
- `key : str` |
||||
- `secret : str` |
||||
|
||||
**OAuthToken** is a data type that represents an End User via either an access or request token |
||||
|
||||
OAuthToken |
||||
- `token : str` |
||||
- `secret : str` |
||||
- `to_string() -> str` |
||||
- `(static) from_string() -> OAuthToken` |
||||
|
||||
**OAuthSignatureMethod** is a strategy class that implements a signature method |
||||
|
||||
OAuthSignatureMethod |
||||
- `get_name() -> str` |
||||
- `build_signature (OAuthRequest, OAuthConsumer, OAuthToken) -> str` |
||||
|
||||
**OAuthRequest** represents the request and can be seriali |
||||
|
||||
OAuthRequest: |
||||
- `OAuthRequest(str http_method, str http_url, [dict parameters]) -> constructor` |
||||
- `set_parameter(str parameter, str value) -> void` |
||||
- `example parameters: oauth_consumer_key, foo` |
||||
- `get_parameter(str parameter) -> str` |
||||
- `get_parameters() -> dict` |
||||
|
||||
- `get_normalized_http_method() -> str` |
||||
- `get_normalized_http_url() -> str` |
||||
- `get_signable_params() -> dict` |
||||
|
||||
- `to_header () -> str // serialize as a header for an HTTPAuth request` |
||||
- `to_postdata () -> str // serialize as post data for a POST request` |
||||
- `to_url () -> str // serialize as a url for a GET request` |
||||
- `sign_request(OAuthSignatureMethod, OAuthConsumer, OAuthToken) -> void` |
||||
- `build_signature(OAuthSignatureMethod, OAuthConsumer, OAuthToken) -> str` |
||||
- `(static) from_request([str http_method, str http_url, dict parameters])` |
||||
- `(static) from_consumer_and_token(OAuthConsumer, OAuthToken, str http_method, str http_url, [dict parameters]) -> OAuthRequest` |
||||
|
||||
|
||||
**OAuthServer** is a worker to check a requests validity against a data store |
||||
|
||||
OAuthServer: |
||||
- `OAuthServer(OAuthDataStore) -> constructor` |
||||
- `set_data_store(OAuthDataStore) -> void` |
||||
- `get_data_store() -> OAuthDataStore` |
||||
|
||||
- `fetch_request_token (OAuthRequest) -> OAuthToken` |
||||
- `fetch_access_token (OAuthRequest) -> OAuthToken` |
||||
- `verify_request (OAuthRequest) -> OAuthToken` |
||||
|
||||
**OAuthClient** is a worker to attempt to execute a request |
||||
|
||||
OAuthClient: |
||||
- `OAuthClient(OAuthConsumer, OAuthToken) -> constructor` |
||||
- `get_consumer() -> OAuthConsumer` |
||||
- `get_token() -> OAuthToken` |
||||
|
||||
- `fetch_request_token (OAuthRequest) -> OAuthToken` |
||||
- `fetch_access_token (OAuthRequest) -> OAuthToken` |
||||
|
||||
**OAuthDataStore** is a database abstraction used to lookup consumers and tokens |
||||
|
||||
OAuthDataStore: |
||||
- `lookup_consumer(str key) -> OAuthConsumer` |
||||
- `lookup_token(OAuthConsumer, str token_type, str token_token) -> OAuthToken` |
||||
- `lookup_nonce(OAuthConsumer, OAuthToken, str nonce, int timestamp) -> OAuthToken` |
||||
- `fetch_request_token(OAuthConsumer) -> OAuthToken` |
||||
- `fetch_access_token(OAuthConsumer, OAuthToken) -> OAuthToken` |
||||
@ -0,0 +1,74 @@ |
||||
<?php |
||||
|
||||
/* A very naive dbm-based oauth storage |
||||
* |
||||
* NOTE: This is for reference ONLY, |
||||
* and contains, amongst others, a hole |
||||
* where you can get the token secret |
||||
* easily.. |
||||
*/ |
||||
class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/ |
||||
private $dbh; |
||||
|
||||
function __construct($path = "oauth.gdbm") {/*{{{*/ |
||||
$this->dbh = dba_popen($path, 'c', 'gdbm'); |
||||
}/*}}}*/ |
||||
|
||||
function __destruct() {/*{{{*/ |
||||
dba_close($this->dbh); |
||||
}/*}}}*/ |
||||
|
||||
function lookup_consumer($consumer_key) {/*{{{*/ |
||||
$rv = dba_fetch("consumer_$consumer_key", $this->dbh); |
||||
if ($rv === FALSE) { |
||||
return NULL; |
||||
} |
||||
$obj = unserialize($rv); |
||||
if (!($obj instanceof OAuthConsumer)) { |
||||
return NULL; |
||||
} |
||||
return $obj; |
||||
}/*}}}*/ |
||||
|
||||
function lookup_token($consumer, $token_type, $token) {/*{{{*/ |
||||
$rv = dba_fetch("${token_type}_${token}", $this->dbh); |
||||
if ($rv === FALSE) { |
||||
return NULL; |
||||
} |
||||
$obj = unserialize($rv); |
||||
if (!($obj instanceof OAuthToken)) { |
||||
return NULL; |
||||
} |
||||
return $obj; |
||||
}/*}}}*/ |
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/ |
||||
if (dba_exists("nonce_$nonce", $this->dbh)) { |
||||
return TRUE; |
||||
} else { |
||||
dba_insert("nonce_$nonce", "1", $this->dbh); |
||||
return FALSE; |
||||
} |
||||
}/*}}}*/ |
||||
|
||||
function new_token($consumer, $type="request") {/*{{{*/ |
||||
$key = md5(time()); |
||||
$secret = time() + time(); |
||||
$token = new OAuthToken($key, md5(md5($secret))); |
||||
if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) { |
||||
throw new OAuthException("doooom!"); |
||||
} |
||||
return $token; |
||||
}/*}}}*/ |
||||
|
||||
function new_request_token($consumer) {/*{{{*/ |
||||
return $this->new_token($consumer, "request"); |
||||
}/*}}}*/ |
||||
|
||||
function new_access_token($token, $consumer) {/*{{{*/ |
||||
|
||||
$token = $this->new_token($consumer, 'access'); |
||||
dba_delete("request_" . $token->key, $this->dbh); |
||||
return $token; |
||||
}/*}}}*/ |
||||
}/*}}}*/ |
||||
@ -0,0 +1,14 @@ |
||||
<?php |
||||
require_once("common.inc.php"); |
||||
|
||||
try { |
||||
$req = OAuthRequest::from_request(); |
||||
$token = $test_server->fetch_access_token($req); |
||||
print $token; |
||||
} catch (OAuthException $e) { |
||||
print($e->getMessage() . "\n<hr />\n"); |
||||
print_r($req); |
||||
die(); |
||||
} |
||||
|
||||
?> |
||||
@ -0,0 +1,133 @@ |
||||
<?php |
||||
require_once("common.inc.php"); |
||||
|
||||
$key = @$_REQUEST['key']; |
||||
$secret = @$_REQUEST['secret']; |
||||
$token = @$_REQUEST['token']; |
||||
$token_secret = @$_REQUEST['token_secret']; |
||||
$endpoint = @$_REQUEST['endpoint']; |
||||
$action = @$_REQUEST['action']; |
||||
$dump_request = @$_REQUEST['dump_request']; |
||||
$user_sig_method = @$_REQUEST['sig_method']; |
||||
$sig_method = $hmac_method; |
||||
if ($user_sig_method) { |
||||
$sig_method = $sig_methods[$user_sig_method]; |
||||
} |
||||
|
||||
$test_consumer = new OAuthConsumer($key, $secret, NULL); |
||||
|
||||
$test_token = NULL; |
||||
if ($token) { |
||||
$test_token = new OAuthConsumer($token, $token_secret); |
||||
} |
||||
|
||||
|
||||
if ($action == "request_token") { |
||||
$parsed = parse_url($endpoint); |
||||
$params = array(); |
||||
parse_str($parsed['query'], $params); |
||||
|
||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $endpoint, $params); |
||||
$req_req->sign_request($sig_method, $test_consumer, NULL); |
||||
if ($dump_request) { |
||||
Header('Content-type: text/plain'); |
||||
print "request url: " . $req_req->to_url(). "\n"; |
||||
print_r($req_req); |
||||
exit; |
||||
} |
||||
Header("Location: $req_req"); |
||||
} |
||||
else if ($action == "authorize") { |
||||
$callback_url = "$base_url/client.php?key=$key&secret=$secret&token=$token&token_secret=$token_secret&endpoint=" . urlencode($endpoint); |
||||
$auth_url = $endpoint . "?oauth_token=$token&oauth_callback=".urlencode($callback_url); |
||||
if ($dump_request) { |
||||
Header('Content-type: text/plain'); |
||||
print("auth_url: " . $auth_url); |
||||
exit; |
||||
} |
||||
Header("Location: $auth_url"); |
||||
} |
||||
else if ($action == "access_token") { |
||||
$parsed = parse_url($endpoint); |
||||
$params = array(); |
||||
parse_str($parsed['query'], $params); |
||||
|
||||
$acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, "GET", $endpoint, $params); |
||||
$acc_req->sign_request($sig_method, $test_consumer, $test_token); |
||||
if ($dump_request) { |
||||
Header('Content-type: text/plain'); |
||||
print "request url: " . $acc_req->to_url() . "\n"; |
||||
print_r($acc_req); |
||||
exit; |
||||
} |
||||
Header("Location: $acc_req"); |
||||
} |
||||
|
||||
?> |
||||
<html> |
||||
<head> |
||||
<title>OAuth Test Client</title> |
||||
</head> |
||||
<body> |
||||
<div><a href="index.php">server</a> | <a href="client.php">client</a></div> |
||||
<h1>OAuth Test Client</h1> |
||||
<h2>Instructions for Use</h2> |
||||
<p>This is a test client that will let you test your OAuth server code. Enter the appropriate information below to test.</p> |
||||
<p>Note: we don't store any of the information you type in.</p> |
||||
|
||||
<form method="POST" name="oauth_client"> |
||||
<h3>Choose a Signature Method</h3> |
||||
<select name="sig_method"> |
||||
<?php |
||||
foreach ($sig_methods as $name=> $method) { |
||||
$selected = ""; |
||||
if ($name == $sig_method->get_name()) { |
||||
$selected = " selected='selected'"; |
||||
} |
||||
print "<option value='$name'$selected>$name</option>\n"; |
||||
} |
||||
?> |
||||
</select> |
||||
<h3>Enter The Endpoint to Test</h3> |
||||
endpoint: <input type="text" name="endpoint" value="<?php echo $endpoint; ?>" size="100"/><br />
|
||||
<small style="color: green">Note: You can include query parameters in there to have them parsed in and signed too</small> |
||||
<h3>Enter Your Consumer Key / Secret</h3> |
||||
consumer key: <input type="text" name="key" value="<?php echo $key; ?>" /><br />
|
||||
consumer secret: <input type="text" name="secret" value="<?php echo $secret;?>" /><br />
|
||||
dump request, don't redirect: <input type="checkbox" name="dump_request" value="1" <?php if ($dump_request) echo 'checked="checked"'; ?>/><br />
|
||||
make a token request (don't forget to copy down the values you get) |
||||
<input type="submit" name="action" value="request_token" /> |
||||
<h3>Enter Your Request Token / Secret</h3> |
||||
token: <input type="text" name="token" value="<?php echo $token; ?>" /><br />
|
||||
token secret: <input type="text" name="token_secret" value="<?php echo $token_secret; ?>" /><br />
|
||||
<p><strong>Don't forget to update your endpoint to point at the auth or access token url</strong></p> |
||||
try to authorize this token: <input type="submit" name="action" value="authorize" /><br /> |
||||
try to get an access token: <input type="submit" name="action" value="access_token" /><br /> |
||||
|
||||
<h3>Currently Supported Signature Methods</h3> |
||||
<p>Current signing method is: <?php echo $sig_method->get_name() ?></p>
|
||||
<ul> |
||||
<?php |
||||
foreach ($sig_methods as $key => $method) { |
||||
|
||||
print "<li>$key"; |
||||
if ($key != $sig_method->get_name()) { |
||||
print "(<a href='?sig_method=$key'>switch</a>)"; |
||||
} |
||||
print "</li>\n"; |
||||
} |
||||
?> |
||||
</ul> |
||||
|
||||
<?php
|
||||
if ("RSA-SHA1" == $sig_method->get_name()) { |
||||
// passing test_server as a dummy referecne |
||||
print "<pre>" . $sig_method->fetch_private_cert($test_server). "</pre>\n"; |
||||
print "<pre>" . $sig_method->fetch_public_cert($test_server) . "</pre>\n"; |
||||
} |
||||
?> |
||||
|
||||
<h3>Further Resources</h3> |
||||
<p>There is also a <a href="index.php">test server</a> implementation in here.</p> |
||||
<p>The code running this example can be downloaded from the PHP section of the OAuth google code project: <a href="http://code.google.com/p/oauth/">http://code.google.com/p/oauth/</a> |
||||
</body> |
||||
@ -0,0 +1,26 @@ |
||||
<?php |
||||
require_once("../init.php"); |
||||
require_once("../code/OAuth_TestServer.php"); |
||||
|
||||
/* |
||||
* Config Section |
||||
*/ |
||||
$domain = $_SERVER['HTTP_HOST']; |
||||
$base = "/oauth/example"; |
||||
$base_url = "http://$domain$base"; |
||||
|
||||
/** |
||||
* Some default objects |
||||
*/ |
||||
|
||||
$test_server = new TestOAuthServer(new MockOAuthDataStore()); |
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1(); |
||||
$plaintext_method = new OAuthSignatureMethod_PLAINTEXT(); |
||||
$rsa_method = new TestOAuthSignatureMethod_RSA_SHA1(); |
||||
|
||||
$test_server->add_signature_method($hmac_method); |
||||
$test_server->add_signature_method($plaintext_method); |
||||
$test_server->add_signature_method($rsa_method); |
||||
|
||||
$sig_methods = $test_server->get_signature_methods(); |
||||
?> |
||||
@ -0,0 +1,21 @@ |
||||
<?php |
||||
require_once("common.inc.php"); |
||||
|
||||
try { |
||||
$req = OAuthRequest::from_request(); |
||||
list($consumer, $token) = $test_server->verify_request($req); |
||||
|
||||
// lsit back the non-OAuth params |
||||
$total = array(); |
||||
foreach($req->get_parameters() as $k => $v) { |
||||
if (substr($k, 0, 5) == "oauth") continue; |
||||
$total[] = urlencode($k) . "=" . urlencode($v); |
||||
} |
||||
print implode("&", $total); |
||||
} catch (OAuthException $e) { |
||||
print($e->getMessage() . "\n<hr />\n"); |
||||
print_r($req); |
||||
die(); |
||||
} |
||||
|
||||
?> |
||||
@ -0,0 +1,108 @@ |
||||
<?php |
||||
require_once("common.inc.php"); |
||||
|
||||
|
||||
$test_consumer = new OAuthConsumer("key", "secret", NULL); |
||||
$req_token = new OAuthConsumer("requestkey", "requestsecret", 1); |
||||
$acc_token = new OAuthConsumer("accesskey", "accesssecret", 1); |
||||
|
||||
$sig_method = $hmac_method; |
||||
$user_sig_method = @$_GET['sig_method']; |
||||
if ($user_sig_method) { |
||||
$sig_method = $sig_methods[$user_sig_method]; |
||||
} |
||||
|
||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $base_url . "/request_token.php"); |
||||
$req_req->sign_request($sig_method, $test_consumer, NULL); |
||||
|
||||
$acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $req_token, "GET", $base_url . "/access_token.php"); |
||||
$acc_req->sign_request($sig_method, $test_consumer, $req_token); |
||||
|
||||
$echo_req = OAuthRequest::from_consumer_and_token($test_consumer, $acc_token, "GET", $base_url . "/echo_api.php", array("method"=> "foo%20bar", "bar" => "baz")); |
||||
$echo_req->sign_request($sig_method, $test_consumer, $acc_token); |
||||
|
||||
?> |
||||
<html> |
||||
<head> |
||||
<title>OAuth Test Server</title> |
||||
</head> |
||||
<body> |
||||
<div><a href="index.php">server</a> | <a href="client.php">client</a></div> |
||||
<h1>OAuth Test Server</h1> |
||||
<h2>Instructions for Use</h2> |
||||
<p>This is a test server with a predefined static set of keys and tokens, you can make your requests using them to test your code (and mine ;)).</p> |
||||
<h3>Your Consumer Key / Secret</h3> |
||||
<ul> |
||||
<li>consumer key: <code><strong>key</strong></code></li> |
||||
<li>consumer secret: <code><strong>secret</strong></code></li> |
||||
</ul> |
||||
<p>Use this key and secret for all your requests.</p> |
||||
<h3>Getting a Request Token</h3> |
||||
|
||||
<ul> |
||||
<li>request token endpoint: <code><strong><?php echo $base_url . "/request_token.php"; ?></strong></code></li>
|
||||
</ul> |
||||
|
||||
<p>A successful request will return the following:</p> |
||||
<p><code>oauth_token=requestkey&oauth_token_secret=requestsecret</code></p> |
||||
|
||||
<p>An unsuccessful request will attempt to describe what went wrong.</p> |
||||
|
||||
<h4>Example</h4> |
||||
<a href="<?php echo $req_req; ?>"><?php echo $req_req; ?></a>
|
||||
|
||||
<h3>Getting an Access Token</h3> |
||||
<p>The Request Token provided above is already authorized, you may use it to request an Access Token right away.</p> |
||||
|
||||
<ul> |
||||
<li>access token endpoint: <code><strong><?php echo $base_url . "/access_token.php"; ?></strong></code></li>
|
||||
</ul> |
||||
|
||||
<p>A successful request will return the following:</p> |
||||
<p><code>oauth_token=accesskey&oauth_token_secret=accesssecret</code></p> |
||||
|
||||
<p>An unsuccessful request will attempt to describe what went wrong.</p> |
||||
|
||||
<h4>Example</h4> |
||||
<a href="<?php echo $acc_req; ?>"><?php echo $acc_req; ?></a>
|
||||
|
||||
<h3>Making Authenticated Calls</h3> |
||||
<p>Using your Access Token you can make authenticated calls.</p> |
||||
|
||||
<ul> |
||||
<li>api endpoint: <code><strong><?php echo $base_url . "/echo_api.php"; ?></strong></code></li>
|
||||
</ul> |
||||
<p> |
||||
A successful request will echo the non-OAuth parameters sent to it, for example:</p> |
||||
<p><code>method=foo&bar=baz</code></p> |
||||
<p>An unsuccessful request will attempt to describe what went wrong.</p> |
||||
|
||||
<h4>Example</h4> |
||||
<a href="<?php echo $echo_req; ?>"><?php echo $echo_req; ?></a>
|
||||
|
||||
<h3>Currently Supported Signature Methods</h3> |
||||
<p>Current signing method is: <?php echo $user_sig_method ?></p>
|
||||
<ul> |
||||
<?php |
||||
$sig_methods = $test_server->get_signature_methods(); |
||||
foreach ($sig_methods as $key => $method) { |
||||
print "<li>$key"; |
||||
if ($key != $sig_method->get_name()) { |
||||
print "(<a href='?sig_method=$key'>switch</a>)"; |
||||
} |
||||
print "</li>\n"; |
||||
} |
||||
?> |
||||
</ul> |
||||
|
||||
<?php
|
||||
if ("RSA-SHA1" == $sig_method->get_name()) { |
||||
print "<pre>" . $sig_method->fetch_private_cert($req_req) . "</pre>\n"; |
||||
print "<pre>" . $sig_method->fetch_public_cert($req_req) . "</pre>\n"; |
||||
} |
||||
?> |
||||
|
||||
<h3>Further Resources</h3> |
||||
<p>There is also a <a href="client.php">test client</a> implementation in here.</p> |
||||
<p>The code running this example can be downloaded from the PHP section of the OAuth google code project: <a href="http://code.google.com/p/oauth/">http://code.google.com/p/oauth/</a> |
||||
</body> |
||||
@ -0,0 +1,14 @@ |
||||
<?php |
||||
require_once("common.inc.php"); |
||||
|
||||
try { |
||||
$req = OAuthRequest::from_request(); |
||||
$token = $test_server->fetch_request_token($req); |
||||
print $token; |
||||
} catch (OAuthException $e) { |
||||
print($e->getMessage() . "\n<hr />\n"); |
||||
print_r($req); |
||||
die(); |
||||
} |
||||
|
||||
?> |
||||
@ -0,0 +1,5 @@ |
||||
<?php |
||||
|
||||
// Include the autoloader to get started. |
||||
// (make sure to run `composer install`!) |
||||
require_once dirname( __FILE__ ) . '/vendor/autoload.php'; |
||||
@ -0,0 +1,12 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* A very simple class that you can pass a base-string, and then have it returned again. |
||||
* Used for testing the signature-methods |
||||
*/ |
||||
class Mock_OAuthBaseStringRequest { |
||||
private $provided_base_string; |
||||
public $base_string; // legacy |
||||
public function __construct($bs) { $this->provided_base_string = $bs; } |
||||
public function get_signature_base_string() { return $this->provided_base_string; } |
||||
} |
||||
@ -0,0 +1,57 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* A mock store for testing |
||||
*/ |
||||
class Mock_OAuthDataStore extends OAuthDataStore { |
||||
private $consumer; |
||||
private $request_token; |
||||
private $access_token; |
||||
private $nonce; |
||||
|
||||
function __construct() { |
||||
$this->consumer = new OAuthConsumer("key", "secret", NULL); |
||||
$this->request_token = new OAuthToken("requestkey", "requestsecret", 1); |
||||
$this->access_token = new OAuthToken("accesskey", "accesssecret", 1); |
||||
$this->nonce = "nonce"; |
||||
} |
||||
|
||||
function lookup_consumer($consumer_key) { |
||||
if ($consumer_key == $this->consumer->key) return $this->consumer; |
||||
return NULL; |
||||
} |
||||
|
||||
function lookup_token($consumer, $token_type, $token) { |
||||
$token_attrib = $token_type . "_token"; |
||||
if ($consumer->key == $this->consumer->key |
||||
&& $token == $this->$token_attrib->key) { |
||||
return $this->$token_attrib; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) { |
||||
if ($consumer->key == $this->consumer->key |
||||
&& (($token && $token->key == $this->request_token->key) |
||||
|| ($token && $token->key == $this->access_token->key)) |
||||
&& $nonce == $this->nonce) { |
||||
return $this->nonce; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
function new_request_token($consumer, $callback = null) { |
||||
if ($consumer->key == $this->consumer->key) { |
||||
return $this->request_token; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
function new_access_token($token, $consumer, $verifier = null) { |
||||
if ($consumer->key == $this->consumer->key |
||||
&& $token->key == $this->request_token->key) { |
||||
return $this->access_token; |
||||
} |
||||
return NULL; |
||||
} |
||||
} |
||||
@ -0,0 +1,47 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* A mock implementation of OAuthSignatureMethod_RSA_SHA1 |
||||
* Always returns the signatures described in |
||||
* http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1") |
||||
*/ |
||||
class Mock_OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod_RSA_SHA1 { |
||||
public function fetch_private_cert(&$request) { |
||||
$cert = <<<EOD |
||||
-----BEGIN PRIVATE KEY----- |
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V |
||||
A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d |
||||
7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ |
||||
hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H |
||||
X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm |
||||
uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw |
||||
rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z |
||||
zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn |
||||
qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG |
||||
WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno |
||||
cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+ |
||||
3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8 |
||||
AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54 |
||||
Lw03eHTNQghS0A== |
||||
-----END PRIVATE KEY----- |
||||
EOD; |
||||
return $cert; |
||||
} |
||||
|
||||
public function fetch_public_cert(&$request) { |
||||
$cert = <<<EOD |
||||
-----BEGIN CERTIFICATE----- |
||||
MIIBpjCCAQ+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAZMRcwFQYDVQQDDA5UZXN0 |
||||
IFByaW5jaXBhbDAeFw03MDAxMDEwODAwMDBaFw0zODEyMzEwODAwMDBaMBkxFzAV |
||||
BgNVBAMMDlRlc3QgUHJpbmNpcGFsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB |
||||
gQC0YjCwIfYoprq/FQO6lb3asXrxLlJFuCvtinTF5p0GxvQGu5O3gYytUvtC2JlY |
||||
zypSRjVxwxrsuRcP3e641SdASwfrmzyvIgP08N4S0IFzEURkV1wp/IpH7kH41Etb |
||||
mUmrXSwfNZsnQRE5SYSOhh+LcK2wyQkdgcMv11l4KoBkcwIDAQABMA0GCSqGSIb3 |
||||
DQEBBQUAA4GBAGZLPEuJ5SiJ2ryq+CmEGOXfvlTtEL2nuGtr9PewxkgnOjZpUy+d |
||||
4TvuXJbNQc8f4AMWL/tO9w0Fk80rWKp9ea8/df4qMq5qlFWlx6yOLQxumNOmECKb |
||||
WpkUQDIDJEoFUzKMVuJf4KO/FJ345+BNLGgbJ6WujreoM1X/gYfdnJ/J |
||||
-----END CERTIFICATE----- |
||||
EOD; |
||||
return $cert; |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
require 'common.php'; |
||||
|
||||
class OAuthConsumerTest extends PHPUnit_Framework_TestCase { |
||||
public function testConvertToString() { |
||||
$consumer = new OAuthConsumer('key', 'secret'); |
||||
$this->assertEquals('OAuthConsumer[key=key,secret=secret]', (string) $consumer); |
||||
} |
||||
} |
||||
@ -0,0 +1,329 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* Tests of OAuthRequest |
||||
* |
||||
* The tests works by using OAuthTestUtils::build_request |
||||
* to populare $_SERVER, $_GET & $_POST. |
||||
* |
||||
* Most of the base string and signature tests |
||||
* are either very simple or based upon |
||||
* http://wiki.oauth.net/TestCases |
||||
*/ |
||||
|
||||
require_once dirname(__FILE__) . '/common.php'; |
||||
|
||||
class OAuthRequestTest extends PHPUnit_Framework_TestCase { |
||||
public function testCanGetSingleParameter() { |
||||
// Yes, a awesomely boring test.. But if this doesn't work, the other tests is unreliable |
||||
$request = new OAuthRequest('', '', array('test'=>'foo')); |
||||
$this->assertEquals( 'foo', $request->get_parameter('test'), 'Failed to read back parameter'); |
||||
|
||||
$request = new OAuthRequest('', '', array('test'=>array('foo', 'bar'))); |
||||
$this->assertEquals( array('foo', 'bar'), $request->get_parameter('test'), 'Failed to read back parameter'); |
||||
|
||||
|
||||
$request = new OAuthRequest('', '', array('test'=>'foo', 'bar'=>'baz')); |
||||
$this->assertEquals( 'foo', $request->get_parameter('test'), 'Failed to read back parameter'); |
||||
$this->assertEquals( 'baz', $request->get_parameter('bar'), 'Failed to read back parameter'); |
||||
} |
||||
|
||||
public function testGetAllParameters() { |
||||
// Yes, a awesomely boring test.. But if this doesn't work, the other tests is unreliable |
||||
$request = new OAuthRequest('', '', array('test'=>'foo')); |
||||
$this->assertEquals( array('test'=>'foo'), $request->get_parameters(), 'Failed to read back parameters'); |
||||
|
||||
$request = new OAuthRequest('', '', array('test'=>'foo', 'bar'=>'baz')); |
||||
$this->assertEquals( array('test'=>'foo', 'bar'=>'baz'), $request->get_parameters(), 'Failed to read back parameters'); |
||||
|
||||
$request = new OAuthRequest('', '', array('test'=>array('foo', 'bar'))); |
||||
$this->assertEquals( array('test'=>array('foo', 'bar')), $request->get_parameters(), 'Failed to read back parameters'); |
||||
} |
||||
|
||||
public function testSetParameters() { |
||||
$request = new OAuthRequest('', ''); |
||||
$this->assertEquals( NULL, $request->get_parameter('test'), 'Failed to assert that non-existing parameter is NULL'); |
||||
|
||||
$request->set_parameter('test', 'foo'); |
||||
$this->assertEquals( 'foo', $request->get_parameter('test'), 'Failed to set single-entry parameter'); |
||||
|
||||
$request->set_parameter('test', 'bar'); |
||||
$this->assertEquals( array('foo', 'bar'), $request->get_parameter('test'), 'Failed to set single-entry parameter'); |
||||
|
||||
$request->set_parameter('test', 'bar', false); |
||||
$this->assertEquals( 'bar', $request->get_parameter('test'), 'Failed to set single-entry parameter'); |
||||
} |
||||
|
||||
public function testUnsetParameter() { |
||||
$request = new OAuthRequest('', ''); |
||||
$this->assertEquals( NULL, $request->get_parameter('test')); |
||||
|
||||
$request->set_parameter('test', 'foo'); |
||||
$this->assertEquals( 'foo', $request->get_parameter('test')); |
||||
|
||||
$request->unset_parameter('test'); |
||||
$this->assertEquals( NULL, $request->get_parameter('test'), 'Failed to unset parameter'); |
||||
} |
||||
|
||||
public function testCreateRequestFromConsumerAndToken() { |
||||
$cons = new OAuthConsumer('key', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('token', 'pfkkdhi9sl3r4s00'); |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token($cons, $token, 'POST', 'http://example.com'); |
||||
$this->assertEquals('POST', $request->get_normalized_http_method()); |
||||
$this->assertEquals('http://example.com', $request->get_normalized_http_url()); |
||||
$this->assertEquals('1.0', $request->get_parameter('oauth_version')); |
||||
$this->assertEquals($cons->key, $request->get_parameter('oauth_consumer_key')); |
||||
$this->assertEquals($token->key, $request->get_parameter('oauth_token')); |
||||
$this->assertEquals(time(), $request->get_parameter('oauth_timestamp')); |
||||
$this->assertRegExp('/[0-9a-f]{32}/', $request->get_parameter('oauth_nonce')); |
||||
// We don't know what the nonce will be, except it'll be md5 and hence 32 hexa digits |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token($cons, $token, 'POST', 'http://example.com', array('oauth_nonce'=>'foo')); |
||||
$this->assertEquals('foo', $request->get_parameter('oauth_nonce')); |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token($cons, NULL, 'POST', 'http://example.com', array('oauth_nonce'=>'foo')); |
||||
$this->assertNull($request->get_parameter('oauth_token')); |
||||
|
||||
// Test that parameters given in the $http_url instead of in the $parameters-parameter |
||||
// will still be picked up |
||||
$request = OAuthRequest::from_consumer_and_token($cons, $token, 'POST', 'http://example.com/?foo=bar'); |
||||
$this->assertEquals('http://example.com/', $request->get_normalized_http_url()); |
||||
$this->assertEquals('bar', $request->get_parameter('foo')); |
||||
} |
||||
|
||||
public function testBuildRequestFromPost() { |
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'foo=bar&baz=blargh'); |
||||
$this->assertEquals(array('foo'=>'bar','baz'=>'blargh'), OAuthRequest::from_request()->get_parameters(), 'Failed to parse POST parameters'); |
||||
} |
||||
|
||||
public function testBuildRequestFromGet() { |
||||
OAuthTestUtils::build_request('GET', 'http://testbed/test?foo=bar&baz=blargh'); |
||||
$this->assertEquals(array('foo'=>'bar','baz'=>'blargh'), OAuthRequest::from_request()->get_parameters(), 'Failed to parse GET parameters'); |
||||
} |
||||
|
||||
public function testBuildRequestFromHeader() { |
||||
$test_header = 'OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"'; |
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', '', $test_header); |
||||
$this->assertEquals(array('oauth_foo'=>'bar','oauth_baz'=>'bla,rgh'), OAuthRequest::from_request()->get_parameters(), 'Failed to split auth-header correctly'); |
||||
} |
||||
|
||||
public function testHasProperParameterPriority() { |
||||
$test_header = 'OAuth realm="",oauth_foo=header'; |
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test?oauth_foo=get', 'oauth_foo=post', $test_header); |
||||
$this->assertEquals('header', OAuthRequest::from_request()->get_parameter('oauth_foo'), 'Loaded parameters in with the wrong priorities'); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test?oauth_foo=get', 'oauth_foo=post'); |
||||
$this->assertEquals('post', OAuthRequest::from_request()->get_parameter('oauth_foo'), 'Loaded parameters in with the wrong priorities'); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test?oauth_foo=get'); |
||||
$this->assertEquals('get', OAuthRequest::from_request()->get_parameter('oauth_foo'), 'Loaded parameters in with the wrong priorities'); |
||||
} |
||||
|
||||
public function testNormalizeHttpMethod() { |
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test'); |
||||
$this->assertEquals('POST', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: POST'); |
||||
|
||||
OAuthTestUtils::build_request('post', 'http://testbed/test'); |
||||
$this->assertEquals('POST', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: post'); |
||||
|
||||
OAuthTestUtils::build_request('GET', 'http://testbed/test'); |
||||
$this->assertEquals('GET', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: GET'); |
||||
|
||||
OAuthTestUtils::build_request('PUT', 'http://testbed/test'); |
||||
$this->assertEquals('PUT', OAuthRequest::from_request()->get_normalized_http_method(), 'Failed to normalize HTTP method: PUT'); |
||||
} |
||||
|
||||
public function testNormalizeParameters() { |
||||
// This is mostly repeats of OAuthUtilTest::testParseParameters & OAuthUtilTest::TestBuildHttpQuery |
||||
|
||||
// Tests taken from |
||||
// http://wiki.oauth.net/TestCases ("Normalize Request Parameters") |
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'name'); |
||||
$this->assertEquals( 'name=', OAuthRequest::from_request()->get_signable_parameters()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=b'); |
||||
$this->assertEquals( 'a=b', OAuthRequest::from_request()->get_signable_parameters()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=b&c=d'); |
||||
$this->assertEquals( 'a=b&c=d', OAuthRequest::from_request()->get_signable_parameters()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=x%21y&a=x+y'); |
||||
$this->assertEquals( 'a=x%20y&a=x%21y', OAuthRequest::from_request()->get_signable_parameters()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'x%21y=a&x=a'); |
||||
$this->assertEquals( 'x=a&x%21y=a', OAuthRequest::from_request()->get_signable_parameters()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'a=1&c=hi there&f=25&f=50&f=a&z=p&z=t'); |
||||
$this->assertEquals( 'a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t', OAuthRequest::from_request()->get_signable_parameters()); |
||||
} |
||||
|
||||
public function testNormalizeHttpUrl() { |
||||
OAuthTestUtils::build_request('POST', 'http://example.com'); |
||||
$this->assertEquals('http://example.com', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'https://example.com'); |
||||
$this->assertEquals('https://example.com', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
|
||||
// Tests that http on !80 and https on !443 keeps the port |
||||
OAuthTestUtils::build_request('POST', 'http://example.com:8080'); |
||||
$this->assertEquals('http://example.com:8080', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'https://example.com:80'); |
||||
$this->assertEquals('https://example.com:80', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://example.com:443'); |
||||
$this->assertEquals('http://example.com:443', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://Example.COM'); |
||||
$this->assertEquals('http://example.com', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
|
||||
// Emulate silly behavior by some clients, where there Host header includes the port |
||||
OAuthTestUtils::build_request('POST', 'http://example.com'); |
||||
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT']; |
||||
$this->assertEquals('http://example.com', OAuthRequest::from_request()->get_normalized_http_url()); |
||||
} |
||||
|
||||
public function testBuildPostData() { |
||||
OAuthTestUtils::build_request('POST', 'http://example.com'); |
||||
$this->assertEquals('', OAuthRequest::from_request()->to_postdata()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar'); |
||||
$this->assertEquals('foo=bar', OAuthRequest::from_request()->to_postdata()); |
||||
|
||||
OAuthTestUtils::build_request('GET', 'http://example.com?foo=bar'); |
||||
$this->assertEquals('foo=bar', OAuthRequest::from_request()->to_postdata()); |
||||
} |
||||
|
||||
public function testBuildUrl() { |
||||
OAuthTestUtils::build_request('POST', 'http://example.com'); |
||||
$this->assertEquals('http://example.com', OAuthRequest::from_request()->to_url()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar'); |
||||
$this->assertEquals('http://example.com?foo=bar', OAuthRequest::from_request()->to_url()); |
||||
|
||||
OAuthTestUtils::build_request('GET', 'http://example.com?foo=bar'); |
||||
$this->assertEquals('http://example.com?foo=bar', OAuthRequest::from_request()->to_url()); |
||||
} |
||||
|
||||
public function testConvertToString() { |
||||
OAuthTestUtils::build_request('POST', 'http://example.com'); |
||||
$this->assertEquals('http://example.com', (string) OAuthRequest::from_request()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar'); |
||||
$this->assertEquals('http://example.com?foo=bar', (string) OAuthRequest::from_request()); |
||||
|
||||
OAuthTestUtils::build_request('GET', 'http://example.com?foo=bar'); |
||||
$this->assertEquals('http://example.com?foo=bar', (string) OAuthRequest::from_request()); |
||||
} |
||||
|
||||
public function testBuildHeader() { |
||||
OAuthTestUtils::build_request('POST', 'http://example.com'); |
||||
$this->assertEquals('Authorization: OAuth', OAuthRequest::from_request()->to_header()); |
||||
$this->assertEquals('Authorization: OAuth realm="test"', OAuthRequest::from_request()->to_header('test')); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://example.com', 'foo=bar'); |
||||
$this->assertEquals('Authorization: OAuth', OAuthRequest::from_request()->to_header()); |
||||
$this->assertEquals('Authorization: OAuth realm="test"', OAuthRequest::from_request()->to_header('test')); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://example.com', 'oauth_test=foo'); |
||||
$this->assertEquals('Authorization: OAuth oauth_test="foo"', OAuthRequest::from_request()->to_header()); |
||||
$this->assertEquals('Authorization: OAuth realm="test",oauth_test="foo"', OAuthRequest::from_request()->to_header('test')); |
||||
|
||||
// Is headers supposted to be Urlencoded. More to the point: |
||||
// Should it be baz = bla,rgh or baz = bla%2Crgh ?? |
||||
// - morten.fangel |
||||
OAuthTestUtils::build_request('POST', 'http://example.com', '', 'OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"'); |
||||
$this->assertEquals('Authorization: OAuth oauth_foo="bar",oauth_baz="bla%2Crgh"', OAuthRequest::from_request()->to_header()); |
||||
$this->assertEquals('Authorization: OAuth realm="test",oauth_foo="bar",oauth_baz="bla%2Crgh"', OAuthRequest::from_request()->to_header('test')); |
||||
} |
||||
|
||||
public function testWontBuildHeaderWithArrayInput() { |
||||
$this->setExpectedException('OAuthException'); |
||||
OAuthTestUtils::build_request('POST', 'http://example.com', 'oauth_foo=bar&oauth_foo=baz'); |
||||
OAuthRequest::from_request()->to_header(); |
||||
} |
||||
|
||||
public function testBuildBaseString() { |
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'n=v'); |
||||
$this->assertEquals('POST&http%3A%2F%2Ftestbed%2Ftest&n%3Dv', OAuthRequest::from_request()->get_signature_base_string()); |
||||
|
||||
OAuthTestUtils::build_request('POST', 'http://testbed/test', 'n=v&n=v2'); |
||||
$this->assertEquals('POST&http%3A%2F%2Ftestbed%2Ftest&n%3Dv%26n%3Dv2', OAuthRequest::from_request()->get_signature_base_string()); |
||||
|
||||
OAuthTestUtils::build_request('GET', 'http://example.com?n=v'); |
||||
$this->assertEquals('GET&http%3A%2F%2Fexample.com&n%3Dv', OAuthRequest::from_request()->get_signature_base_string()); |
||||
|
||||
$params = 'oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_timestamp=1191242090'; |
||||
$params .= '&oauth_nonce=hsu94j3884jdopsl&oauth_signature_method=PLAINTEXT&oauth_signature=ignored'; |
||||
OAuthTestUtils::build_request('POST', 'https://photos.example.net/request_token', $params); |
||||
$this->assertEquals('POST&https%3A%2F%2Fphotos.example.net%2Frequest_token&oauth_' |
||||
.'consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dhsu94j3884j' |
||||
.'dopsl%26oauth_signature_method%3DPLAINTEXT%26oauth_timestam' |
||||
.'p%3D1191242090%26oauth_version%3D1.0', |
||||
OAuthRequest::from_request()->get_signature_base_string()); |
||||
|
||||
$params = 'file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03'; |
||||
$params .= '&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh'; |
||||
$params .= '&oauth_signature=ignored&oauth_signature_method=HMAC-SHA1'; |
||||
OAuthTestUtils::build_request('GET', 'http://photos.example.net/photos?'.$params); |
||||
$this->assertEquals('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation' |
||||
.'.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%' |
||||
.'3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26o' |
||||
.'auth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jd' |
||||
.'k%26oauth_version%3D1.0%26size%3Doriginal', |
||||
OAuthRequest::from_request()->get_signature_base_string()); |
||||
} |
||||
|
||||
public function testBuildSignature() { |
||||
$params = 'file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03'; |
||||
$params .= '&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh'; |
||||
$params .= '&oauth_signature=ignored&oauth_signature_method=HMAC-SHA1'; |
||||
OAuthTestUtils::build_request('GET', 'http://photos.example.net/photos?'.$params); |
||||
$r = OAuthRequest::from_request(); |
||||
|
||||
$cons = new OAuthConsumer('key', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('token', 'pfkkdhi9sl3r4s00'); |
||||
|
||||
$hmac = new OAuthSignatureMethod_HMAC_SHA1(); |
||||
$plaintext = new OAuthSignatureMethod_PLAINTEXT(); |
||||
|
||||
$this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $r->build_signature($hmac, $cons, $token)); |
||||
$this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $r->build_signature($plaintext, $cons, $token)); |
||||
} |
||||
|
||||
public function testSign() { |
||||
$params = 'file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03'; |
||||
$params .= '&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh'; |
||||
$params .= '&oauth_signature=__ignored__&oauth_signature_method=HMAC-SHA1'; |
||||
OAuthTestUtils::build_request('GET', 'http://photos.example.net/photos?'.$params); |
||||
$r = OAuthRequest::from_request(); |
||||
|
||||
$cons = new OAuthConsumer('key', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('token', 'pfkkdhi9sl3r4s00'); |
||||
|
||||
$hmac = new OAuthSignatureMethod_HMAC_SHA1(); |
||||
$plaintext = new OAuthSignatureMethod_PLAINTEXT(); |
||||
|
||||
// We need to test both what the parameter is, and how the serialized request is.. |
||||
|
||||
$r->sign_request($hmac, $cons, $token); |
||||
$this->assertEquals('HMAC-SHA1', $r->get_parameter('oauth_signature_method')); |
||||
$this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $r->get_parameter('oauth_signature')); |
||||
$expectedPostdata = 'file=vacation.jpg&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=kllo9940pd9333jh&' |
||||
. 'oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D&oauth_signature_method=HMAC-SHA1&' |
||||
. 'oauth_timestamp=1191242096&oauth_token=nnch734d00sl2jdk&oauth_version=1.0&size=original'; |
||||
$this->assertEquals( $expectedPostdata, $r->to_postdata()); |
||||
|
||||
$r->sign_request($plaintext, $cons, $token); |
||||
$this->assertEquals('PLAINTEXT', $r->get_parameter('oauth_signature_method')); |
||||
$this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $r->get_parameter('oauth_signature')); |
||||
$expectedPostdata = 'file=vacation.jpg&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=kllo9940pd9333jh&' |
||||
. 'oauth_signature=kd94hf93k423kf44%26pfkkdhi9sl3r4s00&oauth_signature_method=PLAINTEXT&' |
||||
. 'oauth_timestamp=1191242096&oauth_token=nnch734d00sl2jdk&oauth_version=1.0&size=original'; |
||||
$this->assertEquals( $expectedPostdata, $r->to_postdata()); |
||||
|
||||
} |
||||
} |
||||
|
||||
?> |
||||
@ -0,0 +1,225 @@ |
||||
<?php |
||||
|
||||
require_once dirname(__FILE__) . '/common.php'; |
||||
require_once dirname(__FILE__) . '/Mock_OAuthDataStore.php'; |
||||
|
||||
/** |
||||
* Tests of OAuthUtil |
||||
*/ |
||||
class OAuthServerTest extends PHPUnit_Framework_TestCase { |
||||
private $consumer; |
||||
private $request_token; |
||||
private $access_token; |
||||
private $hmac_sha1; |
||||
private $plaintext; |
||||
private $server; |
||||
|
||||
public function setUp() { |
||||
$this->consumer = new OAuthConsumer('key', 'secret'); |
||||
$this->request_token = new OAuthToken('requestkey', 'requestsecret'); |
||||
$this->access_token = new OAuthToken('accesskey', 'accesssecret'); |
||||
|
||||
$this->hmac_sha1 = new OAuthSignatureMethod_HMAC_SHA1(); |
||||
$this->plaintext = new OAuthSignatureMethod_PLAINTEXT(); |
||||
|
||||
$this->server = new OAuthServer( new Mock_OAuthDataStore() ); |
||||
$this->server->add_signature_method( $this->hmac_sha1 ); |
||||
$this->server->add_signature_method( $this->plaintext ); |
||||
} |
||||
|
||||
public function testAcceptValidRequest() { |
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
list($consumer, $token) = $this->server->verify_request( $request ); |
||||
$this->assertEquals( $this->consumer, $consumer ); |
||||
$this->assertEquals( $this->access_token, $token ); |
||||
|
||||
$request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token ); |
||||
list($consumer, $token) = $this->server->verify_request( $request ); |
||||
$this->assertEquals( $this->consumer, $consumer ); |
||||
$this->assertEquals( $this->access_token, $token ); |
||||
} |
||||
|
||||
public function testAcceptRequestWithoutVersion() { |
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->unset_parameter('oauth_version'); |
||||
$request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token ); |
||||
|
||||
$this->server->verify_request( $request ); |
||||
} |
||||
|
||||
public function testRejectRequestSignedWithRequestToken() { |
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->request_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request( $request ); |
||||
} |
||||
|
||||
public function testRejectRequestWithMissingParameters() { |
||||
// The list of required parameters is taken from |
||||
// Chapter 7 ("Accessing Protected Resources") |
||||
|
||||
$required_parameters = array( |
||||
'oauth_consumer_key', |
||||
'oauth_token', |
||||
'oauth_signature_method', |
||||
'oauth_signature', |
||||
'oauth_timestamp', |
||||
'oauth_nonce' |
||||
); |
||||
|
||||
foreach( $required_parameters AS $required ) { |
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
try { |
||||
$request->unset_parameter( $required ); |
||||
$this->server->verify_request($request); |
||||
$this->fail('Allowed a request without `' . $required . '`'); |
||||
} catch( OAuthException $e ) { /* expected */ } |
||||
} |
||||
} |
||||
|
||||
public function testRejectPastTimestamp() { |
||||
// We change the timestamp to be 10 hours ago, it should throw an exception |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') - 10*60*60, false); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request($request); |
||||
} |
||||
|
||||
public function testRejectFutureTimestamp() { |
||||
// We change the timestamp to be 10 hours in the future, it should throw an exception |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') + 10*60*60, false); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request($request); |
||||
} |
||||
|
||||
public function testRejectUsedNonce() { |
||||
// We give a known nonce and should see an exception |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
// The Mock datastore is set to say that the `nonce` nonce is known |
||||
$request->set_parameter( 'oauth_nonce', 'nonce', false); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request($request); |
||||
} |
||||
|
||||
public function testRejectInvalidSignature() { |
||||
// We change the signature post-signing to be something invalid |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
$request->set_parameter( 'oauth_signature', '__whatever__', false); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request($request); |
||||
} |
||||
|
||||
public function testRejectInvalidConsumer() { |
||||
// We use the consumer-key "unknown", which isn't known by the datastore. |
||||
|
||||
$unknown_consumer = new OAuthConsumer('unknown', '__unused__'); |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $unknown_consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $unknown_consumer, $this->access_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request( $request ); |
||||
} |
||||
|
||||
public function testRejectInvalidToken() { |
||||
// We use the access-token "unknown" which isn't known by the datastore |
||||
|
||||
$unknown_token = new OAuthToken('unknown', '__unused__'); |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $unknown_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $unknown_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request( $request ); |
||||
} |
||||
|
||||
public function testRejectUnknownSignatureMethod() { |
||||
// We use a server that only supports HMAC-SHA1, but requests with PLAINTEXT signature |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
|
||||
$server = new OAuthServer( new Mock_OAuthDataStore() ); |
||||
$server->add_signature_method( $this->hmac_sha1 ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$server->verify_request( $request ); |
||||
} |
||||
|
||||
public function testRejectUnknownVersion() { |
||||
// We use the version "1.0a" which isn't "1.0", so reject the request |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
$request->set_parameter('oauth_version', '1.0a', false); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$this->server->verify_request( $request ); |
||||
} |
||||
|
||||
public function testCreateRequestToken() { |
||||
// We request a new Request Token |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, NULL ); |
||||
|
||||
$token = $this->server->fetch_request_token($request); |
||||
$this->assertEquals($this->request_token, $token); |
||||
} |
||||
|
||||
public function testRejectSignedRequestTokenRequest() { |
||||
// We request a new Request Token, but the request is signed with a token which should fail |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->request_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$token = $this->server->fetch_request_token($request); |
||||
} |
||||
|
||||
public function testCreateAccessToken() { |
||||
// We request a new Access Token |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->request_token ); |
||||
|
||||
$token = $this->server->fetch_access_token($request); |
||||
$this->assertEquals($this->access_token, $token); |
||||
} |
||||
|
||||
public function testRejectUnsignedAccessTokenRequest() { |
||||
// We request a new Access Token, but we didn't sign the request with a Access Token |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, NULL ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$token = $this->server->fetch_access_token($request); |
||||
} |
||||
|
||||
public function testRejectAccessTokenSignedAccessTokenRequest() { |
||||
// We request a new Access Token, but the request is signed with an access token, so fail! |
||||
|
||||
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com'); |
||||
$request->sign_request( $this->plaintext, $this->consumer, $this->access_token ); |
||||
|
||||
$this->setExpectedException('OAuthException'); |
||||
$token = $this->server->fetch_access_token($request); |
||||
} |
||||
} |
||||
@ -0,0 +1,60 @@ |
||||
<?php |
||||
|
||||
require_once 'common.php'; |
||||
require_once 'Mock_OAuthBaseStringRequest.php'; |
||||
|
||||
class OAuthSignatureMethodHmacSha1Test extends PHPUnit_Framework_TestCase { |
||||
private $method; |
||||
|
||||
public function setUp() { |
||||
$this->method = new OAuthSignatureMethod_HMAC_SHA1(); |
||||
} |
||||
|
||||
public function testIdentifyAsHmacSha1() { |
||||
$this->assertEquals('HMAC-SHA1', $this->method->get_name()); |
||||
} |
||||
|
||||
public function testBuildSignature() { |
||||
// Tests taken from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") |
||||
$request = new Mock_OAuthBaseStringRequest('bs'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = NULL; |
||||
$this->assertEquals('egQqG5AJep5sJ7anhXju1unge2I=', $this->method->build_signature( $request, $consumer, $token) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('bs'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = new OAuthToken('__unused__', 'ts'); |
||||
$this->assertEquals('VZVjXceV7JgPq/dOTnNmEfO0Fv8=', $this->method->build_signature( $request, $consumer, $token) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26' |
||||
. 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26' |
||||
. 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); |
||||
$consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); |
||||
$this->assertEquals('tR3+Ty81lMeYAr/Fid0kMTYa/WM=', $this->method->build_signature( $request, $consumer, $token) ); |
||||
} |
||||
|
||||
public function testVerifySignature() { |
||||
// Tests taken from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") |
||||
$request = new Mock_OAuthBaseStringRequest('bs'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = NULL; |
||||
$signature = 'egQqG5AJep5sJ7anhXju1unge2I='; |
||||
$this->assertTrue( $this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('bs'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = new OAuthToken('__unused__', 'ts'); |
||||
$signature = 'VZVjXceV7JgPq/dOTnNmEfO0Fv8='; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26' |
||||
. 'oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26' |
||||
. 'oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); |
||||
$consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); |
||||
$signature = 'tR3+Ty81lMeYAr/Fid0kMTYa/WM='; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,79 @@ |
||||
<?php |
||||
|
||||
require_once 'common.php'; |
||||
require_once 'Mock_OAuthBaseStringRequest.php'; |
||||
|
||||
class OAuthSignatureMethodPlaintextTest extends PHPUnit_Framework_TestCase { |
||||
private $method; |
||||
|
||||
public function setUp() { |
||||
$this->method = new OAuthSignatureMethod_PLAINTEXT(); |
||||
} |
||||
|
||||
public function testIdentifyAsPlaintext() { |
||||
$this->assertEquals('PLAINTEXT', $this->method->get_name()); |
||||
} |
||||
|
||||
public function testBuildSignature() { |
||||
// Tests based on from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") |
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = NULL; |
||||
$this->assertEquals('cs&', $this->method->build_signature( $request, $consumer, $token) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = new OAuthToken('__unused__', 'ts'); |
||||
$this->assertEquals('cs&ts', $this->method->build_signature( $request, $consumer, $token) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); |
||||
$this->assertEquals('kd94hf93k423kf44&pfkkdhi9sl3r4s00', $this->method->build_signature( $request, $consumer, $token) ); |
||||
|
||||
// Tests taken from Chapter 9.4.1 ("Generating Signature") from the spec |
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); |
||||
$token = new OAuthToken('__unused__', 'jjd999tj88uiths3'); |
||||
$this->assertEquals('djr9rjt0jd78jf88&jjd999tj88uiths3', $this->method->build_signature( $request, $consumer, $token) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); |
||||
$token = new OAuthToken('__unused__', 'jjd99$tj88uiths3'); |
||||
$this->assertEquals('djr9rjt0jd78jf88&jjd99%24tj88uiths3', $this->method->build_signature( $request, $consumer, $token) ); |
||||
} |
||||
|
||||
public function testVerifySignature() { |
||||
// Tests based on from http://wiki.oauth.net/TestCases section 9.2 ("HMAC-SHA1") |
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = NULL; |
||||
$signature = 'cs&'; |
||||
$this->assertTrue( $this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'cs'); |
||||
$token = new OAuthToken('__unused__', 'ts'); |
||||
$signature = 'cs&ts'; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'kd94hf93k423kf44'); |
||||
$token = new OAuthToken('__unused__', 'pfkkdhi9sl3r4s00'); |
||||
$signature = 'kd94hf93k423kf44&pfkkdhi9sl3r4s00'; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
// Tests taken from Chapter 9.4.1 ("Generating Signature") from the spec |
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); |
||||
$token = new OAuthToken('__unused__', 'jjd999tj88uiths3'); |
||||
$signature = 'djr9rjt0jd78jf88&jjd999tj88uiths3'; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
|
||||
$request = new Mock_OAuthBaseStringRequest('__unused__'); |
||||
$consumer = new OAuthConsumer('__unused__', 'djr9rjt0jd78jf88'); |
||||
$token = new OAuthToken('__unused__', 'jjd99$tj88uiths3'); |
||||
$signature = 'djr9rjt0jd78jf88&jjd99%24tj88uiths3'; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
} |
||||
} |
||||
@ -0,0 +1,43 @@ |
||||
<?php |
||||
|
||||
require_once 'common.php'; |
||||
require_once 'Mock_OAuthBaseStringRequest.php'; |
||||
require_once 'Mock_OAuthSignatureMethod_RSA_SHA1.php'; |
||||
|
||||
class OAuthSignatureMethodRsaSha1Test extends PHPUnit_Framework_TestCase { |
||||
private $method; |
||||
|
||||
public function setUp() { |
||||
$this->method = new Mock_OAuthSignatureMethod_RSA_SHA1(); |
||||
} |
||||
|
||||
public function testIdentifyAsRsaSha1() { |
||||
$this->assertEquals('RSA-SHA1', $this->method->get_name()); |
||||
} |
||||
|
||||
public function testBuildSignature() { |
||||
if( ! function_exists('openssl_get_privatekey') ) { |
||||
$this->markTestSkipped('OpenSSL not available, can\'t test RSA-SHA1 functionality'); |
||||
} |
||||
|
||||
// Tests taken from http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1") |
||||
$request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal'); |
||||
$consumer = new OAuthConsumer('dpf43f3p2l4k3l03', '__unused__'); |
||||
$token = NULL; |
||||
$signature = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE='; |
||||
$this->assertEquals($signature, $this->method->build_signature( $request, $consumer, $token) ); |
||||
} |
||||
|
||||
public function testVerifySignature() { |
||||
if( ! function_exists('openssl_get_privatekey') ) { |
||||
$this->markTestSkipped('OpenSSL not available, can\'t test RSA-SHA1 functionality'); |
||||
} |
||||
|
||||
// Tests taken from http://wiki.oauth.net/TestCases section 9.3 ("RSA-SHA1") |
||||
$request = new Mock_OAuthBaseStringRequest('GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal'); |
||||
$consumer = new OAuthConsumer('dpf43f3p2l4k3l03', '__unused__'); |
||||
$token = NULL; |
||||
$signature = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE='; |
||||
$this->assertTrue($this->method->check_signature( $request, $consumer, $token, $signature) ); |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
require_once 'common.php'; |
||||
|
||||
class OAuthTokenTest extends PHPUnit_Framework_TestCase { |
||||
public function testSerialize() { |
||||
$token = new OAuthToken('token', 'secret'); |
||||
$this->assertEquals('oauth_token=token&oauth_token_secret=secret', $token->to_string()); |
||||
|
||||
$token = new OAuthToken('token&', 'secret%'); |
||||
$this->assertEquals('oauth_token=token%26&oauth_token_secret=secret%25', $token->to_string()); |
||||
} |
||||
public function testConvertToString() { |
||||
$token = new OAuthToken('token', 'secret'); |
||||
$this->assertEquals('oauth_token=token&oauth_token_secret=secret', (string) $token); |
||||
|
||||
$token = new OAuthToken('token&', 'secret%'); |
||||
$this->assertEquals('oauth_token=token%26&oauth_token_secret=secret%25', (string) $token); |
||||
} |
||||
} |
||||
@ -0,0 +1,151 @@ |
||||
<?php |
||||
|
||||
require_once dirname(__FILE__) . '/common.php'; |
||||
|
||||
/** |
||||
* Tests of OAuthUtil |
||||
*/ |
||||
class OAuthUtilTest extends PHPUnit_Framework_TestCase { |
||||
public function testUrlencode() { |
||||
// Tests taken from |
||||
// http://wiki.oauth.net/TestCases ("Parameter Encoding") |
||||
$this->assertEquals('abcABC123', OAuthUtil::urlencode_rfc3986('abcABC123')); |
||||
$this->assertEquals('-._~', OAuthUtil::urlencode_rfc3986('-._~')); |
||||
$this->assertEquals('%25', OAuthUtil::urlencode_rfc3986('%')); |
||||
$this->assertEquals('%2B', OAuthUtil::urlencode_rfc3986('+')); |
||||
$this->assertEquals('%0A', OAuthUtil::urlencode_rfc3986("\n")); |
||||
$this->assertEquals('%20', OAuthUtil::urlencode_rfc3986(' ')); |
||||
$this->assertEquals('%7F', OAuthUtil::urlencode_rfc3986("\x7F")); |
||||
//$this->assertEquals('%C2%80', OAuthUtil::urlencode_rfc3986("\x00\x80")); |
||||
//$this->assertEquals('%E3%80%81', OAuthUtil::urlencode_rfc3986("\x30\x01")); |
||||
|
||||
// Last two checks disabled because of lack of UTF-8 support, or lack |
||||
// of knowledge from me (morten.fangel) on how to use it properly.. |
||||
|
||||
// A few tests to ensure code-coverage |
||||
$this->assertEquals( '', OAuthUtil::urlencode_rfc3986(NULL)); |
||||
$this->assertEquals( '', OAuthUtil::urlencode_rfc3986(new stdClass())); |
||||
} |
||||
|
||||
public function testUrldecode() { |
||||
// Tests taken from |
||||
// http://wiki.oauth.net/TestCases ("Parameter Encoding") |
||||
$this->assertEquals('abcABC123', OAuthUtil::urldecode_rfc3986('abcABC123')); |
||||
$this->assertEquals('-._~', OAuthUtil::urldecode_rfc3986('-._~')); |
||||
$this->assertEquals('%', OAuthUtil::urldecode_rfc3986('%25')); |
||||
$this->assertEquals('+', OAuthUtil::urldecode_rfc3986('%2B')); |
||||
$this->assertEquals("\n", OAuthUtil::urldecode_rfc3986('%0A')); |
||||
$this->assertEquals(' ', OAuthUtil::urldecode_rfc3986('%20')); |
||||
$this->assertEquals("\x7F", OAuthUtil::urldecode_rfc3986('%7F')); |
||||
//$this->assertEquals("\x00\x80", OAuthUtil::urldecode_rfc3986('%C2%80')); |
||||
//$this->assertEquals("\x30\x01", OAuthUtil::urldecode_rfc3986('%E3%80%81')); |
||||
|
||||
// Last two checks disabled because of lack of UTF-8 support, or lack |
||||
// of knowledge from me (morten.fangel) on how to use it properly.. |
||||
} |
||||
|
||||
public function testParseParameter() { |
||||
// Tests taken from |
||||
// http://wiki.oauth.net/TestCases ("Normalize Request Parameters") |
||||
|
||||
$this->assertEquals( |
||||
array('name'=>''), |
||||
OAuthUtil::parse_parameters('name') |
||||
); |
||||
$this->assertEquals( |
||||
array('a'=>'b'), |
||||
OAuthUtil::parse_parameters('a=b') |
||||
); |
||||
$this->assertEquals( |
||||
array('a'=>'b','c'=>'d'), |
||||
OAuthUtil::parse_parameters('a=b&c=d') |
||||
); |
||||
$this->assertEquals( |
||||
array('a'=>array('x!y','x y')), |
||||
OAuthUtil::parse_parameters('a=x!y&a=x+y') |
||||
); |
||||
$this->assertEquals( |
||||
array('x!y'=>'a', 'x' =>'a'), |
||||
OAuthUtil::parse_parameters('x!y=a&x=a') |
||||
); |
||||
} |
||||
|
||||
public function testBuildHttpQuery() { |
||||
// Tests taken from |
||||
// http://wiki.oauth.net/TestCases ("Normalize Request Parameters") |
||||
$this->assertEquals( |
||||
'name=', |
||||
OAuthUtil::build_http_query(array('name'=>'')) |
||||
); |
||||
$this->assertEquals( |
||||
'a=b', |
||||
OAuthUtil::build_http_query(array('a'=>'b')) |
||||
); |
||||
$this->assertEquals( |
||||
'a=b&c=d', |
||||
OAuthUtil::build_http_query(array('a'=>'b','c'=>'d')) |
||||
); |
||||
$this->assertEquals( |
||||
'a=x%20y&a=x%21y', |
||||
OAuthUtil::build_http_query(array('a'=>array('x!y','x y'))) |
||||
); |
||||
$this->assertEquals( |
||||
'x=a&x%21y=a', |
||||
OAuthUtil::build_http_query(array('x!y'=>'a', 'x' =>'a')) |
||||
); |
||||
|
||||
// Test taken from the Spec 9.1.1 |
||||
$this->assertEquals( |
||||
'a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t', |
||||
OAuthUtil::build_http_query(array('a'=>'1', 'c' =>'hi there', 'f'=>array(25, 50, 'a'), 'z'=>array('p','t'))) |
||||
); |
||||
|
||||
// From issue 164, by hidetaka |
||||
// Based on discussion at |
||||
// http://groups.google.com/group/oauth/browse_thread/thread/7c698004be0d536/dced7b6c82b917b2?lnk=gst&q=sort# |
||||
$this->assertEquals( |
||||
'x=200&x=25&y=B&y=a', |
||||
OAuthUtil::build_http_query(array('x'=>array(25, 200), 'y'=>array('a', 'B'))) |
||||
); |
||||
} |
||||
|
||||
public function testSplitHeader() { |
||||
$this->assertEquals( |
||||
array('oauth_foo'=>'bar','oauth_baz'=>'bla,rgh'), |
||||
OAuthUtil::split_header('OAuth realm="",oauth_foo=bar,oauth_baz="bla,rgh"') |
||||
); |
||||
$this->assertEquals( |
||||
array(), |
||||
OAuthUtil::split_header('OAuth realm="",foo=bar,baz="bla,rgh"') |
||||
); |
||||
$this->assertEquals( |
||||
array('foo'=>'bar', 'baz'=>'bla,rgh'), |
||||
OAuthUtil::split_header('OAuth realm="",foo=bar,baz="bla,rgh"', false) |
||||
); |
||||
$this->assertEquals( |
||||
array('oauth_foo' => 'hi there'), |
||||
OAuthUtil::split_header('OAuth realm="",oauth_foo=hi+there,foo=bar,baz="bla,rgh"') |
||||
); |
||||
|
||||
} |
||||
|
||||
public function testGetHeaders() { |
||||
if (function_exists('apache_request_headers')) { |
||||
$this->markTestSkipped('We assume the apache module is well tested. Since this module is present, no need testing our suplement'); |
||||
} |
||||
|
||||
$_SERVER['HTTP_HOST'] = 'foo'; |
||||
$_SERVER['HTTP_X_WHATEVER'] = 'bar'; |
||||
$this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar'), OAuthUtil::get_headers() ); |
||||
|
||||
// Test picking up the Content-Type of POST requests running as an Apache module but not having the ARH method |
||||
$_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; |
||||
$this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar', 'Content-Type'=>'application/x-www-form-urlencoded'), OAuthUtil::get_headers() ); |
||||
|
||||
// Test picking up the Content-Type of POST requests when using CGI |
||||
unset($_SERVER['CONTENT_TYPE']); |
||||
$this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar'), OAuthUtil::get_headers() ); |
||||
$_ENV['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; |
||||
$this->assertEquals( array('Host'=>'foo', 'X-Whatever'=>'bar', 'Content-Type'=>'application/x-www-form-urlencoded'), OAuthUtil::get_headers() ); |
||||
} |
||||
} |
||||
@ -0,0 +1,60 @@ |
||||
<?php |
||||
|
||||
require dirname(__FILE__).'/../init.php'; |
||||
|
||||
/** |
||||
* A simple utils class for methods needed |
||||
* during some of the tests |
||||
*/ |
||||
class OAuthTestUtils { |
||||
private static function reset_request_vars() { |
||||
$_SERVER = array(); |
||||
$_POST = array(); |
||||
$_GET = array(); |
||||
} |
||||
|
||||
/** |
||||
* Populates $_{SERVER,GET,POST} and whatever environment-variables needed to test everything.. |
||||
* |
||||
* @param string $method GET or POST |
||||
* @param string $uri What URI is the request to (eg http://example.com/foo?bar=baz) |
||||
* @param string $post_data What should the post-data be |
||||
* @param string $auth_header What to set the Authorization header to |
||||
*/ |
||||
public static function build_request( $method, $uri, $post_data = '', $auth_header = '' ) { |
||||
self::reset_request_vars(); |
||||
|
||||
$method = strtoupper($method); |
||||
|
||||
$parts = parse_url($uri); |
||||
|
||||
$scheme = $parts['scheme']; |
||||
$port = isset( $parts['port'] ) && $parts['port'] ? $parts['port'] : ( $scheme === 'https' ? '443' : '80' ); |
||||
$host = $parts['host']; |
||||
$path = isset( $parts['path'] ) ? $parts['path'] : NULL; |
||||
$query = isset( $parts['query'] ) ? $parts['query'] : NULL; |
||||
|
||||
if( $scheme == 'https') { |
||||
$_SERVER['HTTPS'] = 'on'; |
||||
} |
||||
|
||||
$_SERVER['REQUEST_METHOD'] = $method; |
||||
$_SERVER['HTTP_HOST'] = $host; |
||||
$_SERVER['SERVER_NAME'] = $host; |
||||
$_SERVER['SERVER_PORT'] = $port; |
||||
$_SERVER['SCRIPT_NAME'] = $path; |
||||
$_SERVER['REQUEST_URI'] = $path . '?' . $query; |
||||
$_SERVER['QUERY_STRING'] = $query.''; |
||||
parse_str($query, $_GET); |
||||
|
||||
if( $method == 'POST' ) { |
||||
$_SERVER['HTTP_CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; |
||||
$_POST = parse_str($post_data); |
||||
OAuthRequest::$POST_INPUT = 'data:application/x-www-form-urlencoded,'.$post_data; |
||||
} |
||||
|
||||
if( $auth_header != '' ) { |
||||
$_SERVER['HTTP_AUTHORIZATION'] = $auth_header; |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue