Author: chabotc
Date: Tue Jun 3 07:40:47 2008
New Revision: 662814
URL: http://svn.apache.org/viewvc?rev=662814&view=rev
Log:
SHINDIG-330 adds gadget url to all oauth requests & some code reformatting
Modified:
incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php
incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php
Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php?rev=662814&r1=662813&r2=662814&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php Tue Jun 3 07:40:47
2008
@@ -38,6 +38,8 @@
*/
class OAuthException extends Exception {}
+class OAuthProblemException extends Exception {}
+
class OAuthConsumer {
public $key;
public $secret;
@@ -118,6 +120,13 @@
$key = implode('&', $key_parts);
return base64_encode(hash_hmac('sha1', $base_string, $key,
true));
}
+
+ //TODO: Double check this!
+ public function check_signature(&$request, $consumer, $token,
$signature)
+ {
+ $sign = $this->build_signature($request, $consumer, $token);
+ return $sign == $signature;
+ }
}
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
@@ -140,6 +149,16 @@
$request->base_string = $raw;
return OAuthUtil::urlencodeRFC3986($raw);
}
+
+ //TODO: Double check this!
+ public function check_signature(&$request, $consumer, $token,
$signature)
+ {
+ $raw = OAuthUtil::urldecodeRFC3986($request->base_string);
+ $sig = explode("&", $raw);
+ array_pop($sig);
+ $secret = array(OAuthUtil::urldecodeRFC3986($consumer->secret));
+ return $sig == $secret;
+ }
}
class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
@@ -174,19 +193,19 @@
{
$base_string = $request->get_signature_base_string();
// Fetch the private key cert based on the request
- $cert = $consumer->getProperty("RSA-SHA1.PrivateKey");
+ $cert =
$consumer->getProperty(OAuthSignatureMethod_RSA_SHA1::$PRIVATE_KEY);
// Pull the private key ID from the certificate
//FIXME this function seems to be called both for a oauth.json
action where
// there is no phrase required, but for signed requests too,
which do require it
// this is a dirty hack to make it work .. kinda
- if (!$privatekeyid = @openssl_pkey_get_private($cert)) {
- if (!$privatekeyid = @openssl_pkey_get_private($cert,
Config::get('private_key_phrase') != '' ? (Config::get('private_key_phrase')) :
null)) {
+ if (! $privatekeyid = @openssl_pkey_get_private($cert)) {
+ if (! $privatekeyid = @openssl_pkey_get_private($cert,
Config::get('private_key_phrase') != '' ? (Config::get('private_key_phrase')) :
null)) {
throw new Exception("Could not load private
key");
}
}
// Sign using the key
$ok = openssl_sign($base_string, $signature, $privatekeyid);
- // Release the key resource
+ // Release the key resource
openssl_free_key($privatekeyid);
return base64_encode($signature);
}
@@ -262,11 +281,8 @@
public static function from_consumer_and_token($consumer, $token,
$http_method, $http_url, $parameters = NULL)
{
$parameters = is_array($parameters) ? $parameters : array();
- $defaults = array("oauth_nonce" =>
OAuthRequest::generate_nonce(), "oauth_timestamp" =>
OAuthRequest::generate_timestamp(), "oauth_consumer_key" => $consumer->key,
- // quick hack to make this demo'able
- 'synd' => 'partuza',
- 'container' => 'partuza'
- );
+ $defaults = array("oauth_nonce" =>
OAuthRequest::generate_nonce(), "oauth_timestamp" =>
OAuthRequest::generate_timestamp(), "oauth_consumer_key" => $consumer->key, //
quick hack to make this demo'able
+ 'synd' => 'partuza', 'container' => 'partuza');
$parameters = array_merge($defaults, $parameters);
if (isset($token)) {
$parameters['oauth_token'] = $token;
@@ -291,12 +307,7 @@
public function set_parameters($params)
{
- $arrParams = array();
- foreach ($params as $param) {
- $keyValuePair = explode('=', $param);
- $arrParams[$keyValuePair[0]] = @$keyValuePair[1];
- }
- return $this->parameters = $arrParams;
+ return $this->parameters = $params;
}
//TODO double check if hash can be used
@@ -316,14 +327,14 @@
/**
* Returns the normalized parameters of the request
- *
+ *
* This will be all (except oauth_signature) parameters,
* sorted first by key, and if duplicate keys, then by
* value.
*
* The returned string will be all the key=value pairs
* concated by &.
- *
+ *
* @return string
*/
public function get_signable_parameters()
@@ -344,7 +355,7 @@
$pairs = array();
foreach ($params as $key => $value) {
if (is_array($value)) {
- // If the value is an array, it's because there
are multiple
+ // If the value is an array, it's because there
are multiple
// with the same key, sort them, then add all
the pairs
natsort($value);
foreach ($value as $v2) {
@@ -797,6 +808,21 @@
class OAuthUtil {
+ public static function getPostBodyString(Array $params)
+ {
+ $result = '';
+ $first = true;
+ foreach ($params as $key => $val) {
+ if ($first) {
+ $first = false;
+ } else {
+ $result .= '&';
+ }
+ $result .= OAuthUtil::urlencodeRFC3986($key) . "=" .
OAuthUtil::urlencodeRFC3986($val);
+ }
+ return $result;
+ }
+
public static function urlencodeRFC3986($string)
{
return str_replace('%7E', '~', rawurlencode($string));
@@ -813,14 +839,13 @@
if (! isset($contentType)) {
return false;
}
- $semi = strstr($contentType, ";");
+ $semi = strpos($contentType, ";");
if ($semi >= 0) {
$contentType = substr($contentType, 0, $semi);
}
return strtolower(OAuth::$FORM_ENCODED) ==
strtolower(trim($contentType));
}
- //TODO review foreach, use array_map
public static function addParameters($url, $oauthParams)
{
$url .= strchr($url, '?') === false ? '?' : '&';
@@ -832,13 +857,48 @@
public static function decodeForm($form)
{
+ $parameters = array();
$explodedForm = explode("&", $form);
-
- foreach ($explodedForm as $value) {
- $value = OAuthUtil::urlencodeRFC3986($value);
+ foreach ($explodedForm as $params) {
+ $value = explode("=", $params);
+ $parameters[OAuthUtil::urldecodeRFC3986($value[0])] =
OAuthUtil::urldecodeRFC3986($value[1]);
+ }
+ return $parameters;
+ }
+
+ /**
+ * Parse the parameters from an OAuth Authorization or WWW-Authenticate
+ * header. The realm is included as a parameter. If the given header
doesn't
+ * start with "OAuth ", return an empty list.
+ */
+ public static function decodeAuthorization($authorization)
+ {
+ $into = array();
+ if ($authorization != null) {
+ $m = ereg(OAuthUtil::$AUTHORIZATION, $authorization);
+ if ($m == 1) {
+ if (strpos($authorization,
OAuthUtil::$AUTH_SCHEME) == 0) {
+ $authorization = str_replace("OAuth ",
"", $authorization);
+ $authParams = explode(", ",
$authorization);
+ foreach ($authParams as $params) {
+ $m = ereg(OAuthUtil::$NVP,
$params);
+ if ($m == 1) {
+ $keyValue =
explode("=", $params);
+ $name =
OAuthUtil::urlencodeRFC3986($keyValue[0]);
+ $value =
OAuthUtil::urlencodeRFC3986(str_replace("\"", "", $keyValue[1]));
+ $into[$name] = $value;
+ }
+ }
+ }
+ }
}
-
- return $explodedForm;
+ return $into;
}
+
+ public static $AUTH_SCHEME = "OAuth";
+
+ static $AUTHORIZATION = "\\s*(\\w*)\\s+(.*)";
+
+ static $NVP = "(\\S*)\\s*\\=\\s*\"([^\"]*)\"";
}
\ No newline at end of file
Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php?rev=662814&r1=662813&r2=662814&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php Tue Jun 3
07:40:47 2008
@@ -38,6 +38,8 @@
// names for the JSON values we return to the client
public static $CLIENT_STATE = "oauthState";
public static $APPROVAL_URL = "approvalUrl";
+ // names of additional OAuth parameters we include in outgoing requests
+ public static $XOAUTH_APP_URL = "xoauth_app_url";
/**
* Maximum age for our client state; if this is exceeded we start over.
One
@@ -228,7 +230,9 @@
$accessor = $this->accessorInfo->getAccessor();
//TODO The implementations of oauth differs from the
one in JAVA. Fix the type OAuthMessage
$url =
$accessor->consumer->callback_url->requestTokenURL;
- $request = $this->newRequestMessage($url);
+ $msgParams = array();
+ $msgParams[OAuthFetcher::$XOAUTH_APP_URL] =
$this->authToken->getAppUrl();
+ $request = $this->newRequestMessageParams($url,
$msgParams);
$reply = $this->sendOAuthMessage($request);
$reply->requireParameters(array(OAuth::$OAUTH_TOKEN,
OAuth::$OAUTH_TOKEN_SECRET));
$accessor->requestToken =
$reply->get_parameter(OAuth::$OAUTH_TOKEN);
@@ -244,7 +248,7 @@
if (! isset($params)) {
throw new Exception("params was null in " +
"newRequestMessage " + "Use newRequesMessage if you don't have a params to
pass");
}
-
+
switch ($this->accessorInfo->getSignatureType()) {
case OAuth::$RSA_SHA1:
$params[OAuth::$OAUTH_SIGNATURE_METHOD] =
OAuth::$RSA_SHA1;
@@ -259,6 +263,10 @@
return $accessor->newRequestMessage($method, $url, $params);
}
+ /*
+ * @deprecated (All outgoing messages must send additional params
+ * like XOAUTH_APP_URL, so use newRequestMessageParams instead)
+ */
private function newRequestMessageUrlOnly($url)
{
$params = array();
@@ -304,7 +312,6 @@
{
$paramLocation = $this->accessorInfo->getParamLocation();
$newHeaders = array();
-
// paramLocation could be overriden by a run-time parameter to
fetchRequest
switch ($paramLocation) {
case OAuthStoreVars::$OAuthParamLocation['AUTH_HEADER']:
@@ -315,24 +322,23 @@
$authHeader =
$this->getAuthorizationHeader($oauthParams);
$newHeaders["Authorization"] = $authHeader;
break;
-
+
case OAuthStoreVars::$OAuthParamLocation['POST_BODY']:
if (! OAuthUtil::isFormEncoded($contentType)) {
throw new GadgetException("Invalid
param: OAuth param location can only " . "be post_body if post body if of type
x-www-form-urlencoded");
}
if (! isset($postBody) || count($postBody) ==
0) {
- $postBody =
OAuthUtil::urlencodeRFC3986($oauthParams);
+ $postBody =
OAuthUtil::getPostBodyString($oauthParams);
} else {
- $postBody = $postBody . "&" .
OAuthUtil::urlencodeRFC3986($oauthParams);
+ $postBody = $postBody . "&" .
OAuthUtil::getPostBodyString($oauthParams);
}
break;
-
+
case OAuthStoreVars::$OAuthParamLocation['URI_QUERY']:
$url = OAuthUtil::addParameters($url,
$oauthParams);
break;
}
-
- $postBodyBytes = ($postBody == null) ? null :
$postBody->getBytes("UTF-8");
+ $postBodyBytes = ($postBody == null) ? null : null
;//$postBody->getBytes("UTF-8"); //See what can we do with this?
$rcr = new RemoteContentRequest($url);
$rcr->createRemoteContentRequest($method, $url, $newHeaders,
$postBodyBytes, $options);
return $rcr;
@@ -343,7 +349,6 @@
*/
private function sendOAuthMessage(OAuthRequest $request)
{
-
$rcr =
$this->createRemoteContentRequest($this->filterOAuthParams($request),
$request->get_normalized_http_method(), $request->get_url(), null,
RemoteContentRequest::$DEFAULT_CONTENT_TYPE, null,
RemoteContentRequest::$DEFAULT_OPTIONS);
$content = $this->getNextFetcher()->fetchRequest($rcr);
$reply = OAuthRequest::from_request();
@@ -406,6 +411,7 @@
$accessor = $this->accessorInfo->getAccessor();
$url =
$accessor->consumer->callback_url->accessTokenURL;
$msgParams = array();
+ $msgParams[OAuthFetcher::$XOAUTH_APP_URL] =
$this->authToken->getAppUrl();
$msgParams[OAuth::$OAUTH_TOKEN] =
$accessor->requestToken;
$request = $this->newRequestMessageParams($url,
$msgParams);
$reply = $this->sendOAuthMessage($request);
@@ -456,6 +462,7 @@
try {
$msgParams =
OAuthUtil::isFormEncoded($this->realRequest->getContentType()) ?
OAuthUtil::urldecodeRFC3986($this->realRequest->getPostBody()) : array();
$method = $this->realRequest->getMethod();
+ $msgParams[OAuthFetcher::$XOAUTH_APP_URL] =
$this->authToken->getAppUrl();
// Build and sign the message.
$oauthRequest = $this->newRequestMessageMethod($method,
$this->realRequest->getUrl(), $msgParams);
$rcr =
$this->createRemoteContentRequest($this->filterOAuthParams($oauthRequest),
$this->realRequest->getMethod(), $this->realRequest->getUrl(),
$this->realRequest->getHeaders(), $this->realRequest->getContentType(),
$this->realRequest->getPostBody(), $this->realRequest->getOptions());