Created
November 30, 2011 21:34
-
-
Save joeyblake/1410996 to your computer and use it in GitHub Desktop.
Wordpress Oauth Baseclass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SquidooStatsDashboard_WordPressOAuthSupport { | |
function oauth_template_redirect() { | |
if (preg_match( sprintf('#^/oauth/%s/([^/\?]+)#', get_class($this)), $_SERVER['REQUEST_URI'], $matches )) { | |
do_action('oauth_request', $matches[1]); | |
do_action('oauth_request_'.$matches[1]); | |
} | |
} | |
static function _sign_hmac_sha1($signature_base, $consumer, $token) { | |
$key_parts = array( | |
$consumer->secret, | |
($token) ? $token->secret : '' | |
); | |
$key_parts = self::_urlencode_rfc3986($key_parts); | |
$key = implode('&', $key_parts); | |
return base64_encode(hash_hmac('sha1', $signature_base, $key, true)); | |
} | |
static function _generate_timestamp() { | |
return time(); | |
} | |
static function _generate_nonce($seed = null) { | |
return wp_create_nonce( ((string) $seed) . 'oauth' ); | |
} | |
static function _urlencode_rfc3986($input) { | |
if (is_array($input)) { | |
return array_map(array(__CLASS__, '_urlencode_rfc3986'), $input); | |
} else if (is_scalar($input)) { | |
return str_replace( | |
'+', | |
' ', | |
str_replace('%7E', '~', rawurlencode($input)) | |
); | |
} else { | |
return ''; | |
} | |
} | |
static function _urldecode_rfc3986($string) { | |
return urldecode($string); | |
} | |
static function _assertNotEmpty($var, $msg = null) { | |
if (empty($var) && $var !== 0 && $var !== '0') { | |
wp_die(!is_null($msg) ? $msg : 'A required argument was empty.'); | |
} | |
} | |
static function _get_signable_params($params) { | |
$P = array_merge($params, array()); // inliue of an array copy function | |
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") | |
if (isset($P['oauth_signature'])) { | |
unset($P['oauth_signature']); | |
} | |
return self::_build_http_query($P); | |
} | |
static function _get_normalized_http_url($url) { | |
$parts = parse_url($url); | |
$port = @$parts['port']; | |
$scheme = $parts['scheme']; | |
$host = $parts['host']; | |
$path = @$parts['path']; | |
$port or $port = ($scheme == 'https') ? '443' : '80'; | |
if (($scheme == 'https' && $port != '443') | |
|| ($scheme == 'http' && $port != '80')) { | |
$host = "$host:$port"; | |
} | |
return "$scheme://$host$path"; | |
} | |
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 = self::_urldecode_rfc3986($split[0]); | |
$value = isset($split[1]) ? self::_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; | |
} | |
static function _build_http_query($params = '') { | |
if (!$params) { | |
return ''; | |
} | |
// Urlencode both keys and values | |
$keys = self::_urlencode_rfc3986(array_keys($params)); | |
$values = self::_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) | |
natsort($value); | |
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); | |
} | |
function _get_callback_url($request_url, $callback_url, $consumer_key, $consumer_secret, $params) { | |
if (is_null($callback_url)) { | |
$callback_url = get_bloginfo('siteurl').'/oauth/'.get_class($this).'/'.parse_url($request_url, PHP_URL_HOST); | |
} | |
return apply_filters('oauth_callback_url', $callback_url, $request_url, $consumer_key, $consumer_secret, $params); | |
} | |
function oAuthGet($url, $consumer, $token = null, $params = null) { | |
return self::oAuthRequest($url, 'GET', $consumer, $token, $params); | |
} | |
function oAuthPost($url, $consumer, $token = null, $params = null) { | |
return self::oAuthRequest($url, 'POST', $consumer, $token, $params); | |
} | |
function oAuthRequestToken($request_token_url, $consumer, $callback_url = null, $params = array()) { | |
$consumer = (object) $consumer; | |
$callback_url = $this->_get_callback_url($request_token_url, $callback_url, $consumer->key, $consumer->secret, $params); | |
$params['oauth_callback'] = $callback_url; | |
$response = $this->oAuthGet( | |
$request_token_url, | |
$consumer, | |
null, | |
$params | |
); | |
if (is_wp_error($response)) { | |
do_action('oauth_request_token_error', $request_token_url, $consumer_key, $consumer_secret, $callback_url, $params); | |
return false; | |
} else { | |
$token = wp_parse_args($response['body']); | |
return (object) array( | |
'key' => $token['oauth_token'], | |
'secret' => $token['oauth_token_secret'], | |
'callback_url' => $callback_url | |
); | |
} | |
} | |
function oAuthAccessToken($access_token_url, $consumer, $token, $verifier, $params = array()) { | |
$consumer = (object) $consumer; | |
if (is_string($token)) { | |
$params['oauth_token'] = $token; | |
} else { | |
$params['oauth_token'] = $token->key; | |
} | |
$params['oauth_verifier'] = $verifier; | |
$response = $this->oAuthPost( | |
$access_token_url, | |
$consumer, | |
$token, | |
$params | |
); | |
if (is_wp_error($response)) { | |
do_action('oauth_access_token_error', $access_token_url, $consumer->key, $consumer->secret, $callback_url, $params); | |
return false; | |
} else { | |
$token = wp_parse_args($response['body']); | |
return (object) array( | |
'key' => $token['oauth_token'], | |
'secret' => $token['oauth_token_secret'], | |
'response' => $token | |
); | |
} | |
$request = self::_get_oauth_request( | |
$access_token_url, | |
'GET', | |
$consumer, | |
$token, | |
$params | |
); | |
return $request->url.'?'.$request->query_string; | |
} | |
private static function _get_oauth_request($url, $method, $consumer, $token, $params = array()) { | |
$args = func_get_args(); | |
if (count($args) < 5) { | |
$token = isset($params['token']) ? $params['token'] : null; | |
unset($params['token']); | |
} | |
$consumer = (object) $consumer; | |
if (is_string($token)) { | |
$token = (object) array( | |
'key' => $token, | |
'secret' => null | |
); | |
} else { | |
$token = (object) $token; | |
} | |
$defaults = array( | |
'oauth_version' => '1.0', | |
'oauth_nonce' => self::_generate_nonce(), | |
'oauth_timestamp' => self::_generate_timestamp(), | |
'oauth_consumer_key' => $consumer->key | |
); | |
$params = array_merge( $defaults, $params ); | |
$params = array_merge( self::_parse_parameters( parse_url($url, PHP_URL_QUERY) ), $params ); | |
$params['oauth_signature_method'] = 'HMAC-SHA1'; | |
$signature_base = implode('&', self::_urlencode_rfc3986(array( | |
strtoupper($method), | |
$normalized_url = self::_get_normalized_http_url($url), | |
$signed_params = self::_get_signable_params($params) | |
))); | |
$signature = self::_sign_hmac_sha1($signature_base, $consumer, $token); | |
print_r($signature); | |
$params['oauth_signature'] = $signature; | |
return (object) array( | |
'url' => $normalized_url, | |
'query_string' => self::_build_http_query($params), | |
'params' => $params | |
); | |
} | |
static function oAuthRequest($url, $method, $consumer, $token, $params = null) { | |
$request = self::_get_oauth_request($url, $method, $consumer, $token, $params); | |
$http = _wp_http_get_object(); | |
$url = ($method == 'GET') ? $request->url.'?'.$request->query_string : $request->url; | |
print_r($url); | |
return $http->request($url, array( | |
'method' => $method, | |
'body' => ($method == 'POST') ? $request->query_string : null, | |
'headers' => array('Authorization' => 'OAuth') | |
)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment