Author: agektmr Date: Mon Dec 28 03:26:22 2009 New Revision: 894127 URL: http://svn.apache.org/viewvc?rev=894127&view=rev Log: adding OAuth 1.0a functionality
Added: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthCallbackState.php Modified: incubator/shindig/trunk/php/src/common/ShindigOAuth.php incubator/shindig/trunk/php/src/gadgets/MakeRequestOptions.php incubator/shindig/trunk/php/src/gadgets/oauth/BasicOAuthStore.php incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php incubator/shindig/trunk/php/src/gadgets/oauth/OAuthRequestParams.php incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php incubator/shindig/trunk/php/src/gadgets/servlet/OAuthCallbackServlet.php Modified: incubator/shindig/trunk/php/src/common/ShindigOAuth.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/ShindigOAuth.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/common/ShindigOAuth.php (original) +++ incubator/shindig/trunk/php/src/common/ShindigOAuth.php Mon Dec 28 03:26:22 2009 @@ -56,6 +56,7 @@ public static $OAUTH_SIGNATURE = "oauth_signature"; public static $OAUTH_TIMESTAMP = "oauth_timestamp"; public static $OAUTH_NONCE = "oauth_nonce"; + public static $OAUTH_VERIFIER = "oauth_verifier"; public static $OAUTH_VERSION = "oauth_version"; public static $HMAC_SHA1 = "HMAC_SHA1"; public static $RSA_SHA1 = "RSA_SHA1"; @@ -230,4 +231,4 @@ } return $into; } -} \ No newline at end of file +} Modified: incubator/shindig/trunk/php/src/gadgets/MakeRequestOptions.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/MakeRequestOptions.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/MakeRequestOptions.php (original) +++ incubator/shindig/trunk/php/src/gadgets/MakeRequestOptions.php Mon Dec 28 03:26:22 2009 @@ -75,6 +75,7 @@ private $oauthRequestTokenSecret; private $oauthUseToken; private $oauthClientState; + private $oauthReceivedCallback; private $noCache; private $refreshInterval; private $numEntries; @@ -199,6 +200,7 @@ ->setOAuthRequestToken(MakeRequestOptions::getRequestParam('OAUTH_REQUEST_TOKEN')) ->setOAuthRequestTokenSecret(MakeRequestOptions::getRequestParam('OAUTH_REQUEST_TOKEN_SECRET')) ->setOAuthUseToken(MakeRequestOptions::getRequestParam('OAUTH_USE_TOKEN')) + ->setOAuthReceivedCallback(MakeRequestOptions::getRequestParam('OAUTH_RECEIVED_CALLBACK')) ->setOAuthClientState(MakeRequestOptions::getRequestParam('oauthState')) ->setSecurityTokenString(MakeRequestOptions::getRequestParam('st')); @@ -243,6 +245,7 @@ ->setOAuthRequestToken($request->getParameter('oauth_request_token')) ->setOAuthRequestTokenSecret($request->getParameter('oauth_request_token_secret')) ->setOAuthUseToken($request->getParameter('oauth_use_token')) + ->setOAuthReceivedCallback($request->getParameter('oauth_received_callback')) ->setOAuthClientState($request->getParameter('oauth_state')) // Not in osapi.http spec, but nice to support ->setSecurityTokenString(urlencode(base64_encode($request->getToken()->toSerialForm()))); @@ -608,6 +611,17 @@ return isset($this->oauthClientState) ? $this->oauthClientState : null; } + public function setOAuthReceivedCallback($oauthReceivedCallback) { + if (isset($oauthReceivedCallback)) { + $this->oauthReceivedCallback = $oauthReceivedCallback; + } + return $this; + } + + public function getOAuthReceivedCallback() { + return isset($this->oauthReceivedCallback) ? $this->oauthReceivedCallback : ""; + } + /** * Gets all of the configured OAuth parameters as an OAuthRequestParams * object. @@ -621,6 +635,7 @@ OAuthRequestParams::$REQUEST_TOKEN_PARAM => $this->getOAuthRequestToken(), OAuthRequestParams::$REQUEST_TOKEN_SECRET_PARAM => $this->getOAuthRequestTokenSecret(), OAuthRequestParams::$BYPASS_SPEC_CACHE_PARAM => $this->getNoCache(), + OAuthRequestParams::$RECEIVED_CALLBACK_PARAM => $this->getOAuthReceivedCallback(), OAuthRequestParams::$CLIENT_STATE_PARAM => $this->getOAuthClientState() )); } Modified: incubator/shindig/trunk/php/src/gadgets/oauth/BasicOAuthStore.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/BasicOAuthStore.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/oauth/BasicOAuthStore.php (original) +++ incubator/shindig/trunk/php/src/gadgets/oauth/BasicOAuthStore.php Mon Dec 28 03:26:22 2009 @@ -18,8 +18,6 @@ * under the License. */ -require 'src/common/ShindigOAuth.php'; - class BasicOAuthStore implements OAuthStore { private $consumerInfos = array(); @@ -106,8 +104,12 @@ $this->tokens[md5(serialize($tokenKey))] = $tokenInfo; } + public function removeTokenAndSecret($tokenKey) { + unset($this->tokens[md5(serialize($tokenKey))]); + } + private function getTokenInfo($tokenKey) { $key = md5(serialize($tokenKey)); return isset($this->tokens[$key]) ? $this->tokens[$key] : null; } -} \ No newline at end of file +} Modified: incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php (original) +++ incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php Mon Dec 28 03:26:22 2009 @@ -93,6 +93,10 @@ $this->store->setTokenAndSecret($tokenKey, $tokenInfo); } + public function removeTokenAndSecret(TokenKey $tokenKey) { + $this->store->removeTokenAndSecret($tokenKey); + } + /** * Retrieve an OAuthAccessor that is ready to sign OAuthMessages. * Added: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthCallbackState.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthCallbackState.php?rev=894127&view=auto ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthCallbackState.php (added) +++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthCallbackState.php Mon Dec 28 03:26:22 2009 @@ -0,0 +1,60 @@ +<?php +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Handles state passed on the OAuth callback URL. + */ +class OAuthCallbackState { + public static $CALLBACK_STATE_MAX_AGE_SECS = 600; + private static $REAL_CALLBACK_URL_KEY = "u"; + private $crypter; + private $state = array(); + + public function __construct($crypter, $stateBlob = null) { + $this->crypter = $crypter; + if ($stateBlob != null) { + try { + $state = $crypter->unwrap($stateBlob, self::$CALLBACK_STATE_MAX_AGE_SECS); + } catch (BlobCrypterException $e) { + // Probably too old, pretend we never saw it at all. + } + if ($state != null) { + $this->state = $state; + } + } + return; + } + + public function getEncryptedState() { + return $this->crypter->wrap($this->state); + } + + public function getRealCallbackUrl() { + if (isset($this->state[self::$REAL_CALLBACK_URL_KEY])) { + return $this->state[self::$REAL_CALLBACK_URL_KEY]; + } else { + return false; + } + } + + public function setRealCallbackUrl($callbackUrl) { + $this->state[self::$REAL_CALLBACK_URL_KEY] = $callbackUrl; + } +} 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=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php (original) +++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php Mon Dec 28 03:26:22 2009 @@ -44,6 +44,7 @@ public static $ERROR_TEXT = "oauthErrorText"; // names of additional OAuth parameters we include in outgoing requests public static $XOAUTH_APP_URL = "xoauth_app_url"; + public static $OAUTH_CALLBACK = "oauth_callback"; /** * @var RemoteContentFetcher @@ -302,6 +303,11 @@ $url = $accessor->consumer->callback_url->requestTokenURL; $msgParams = array(); self::addIdentityParams($msgParams, $request->getToken()); + $callbackState = new OAuthCallbackState($this->oauthCrypter); + $callbackUrl = "http://" . getenv('HTTP_HOST') . "/gadgets/oauthcallback"; + $callbackState->setRealCallbackUrl($callbackUrl); + $cs = $callbackState->getEncryptedState(); + $msgParams[self::$OAUTH_CALLBACK] = $callbackUrl . "?cs=" . urlencode($cs); $request = $this->newRequestMessageParams($url->url, $msgParams); $reply = $this->sendOAuthMessage($request); $reply->requireParameters(array(ShindigOAuth::$OAUTH_TOKEN, @@ -486,6 +492,18 @@ $msgParams = array(); $msgParams[ShindigOAuth::$OAUTH_TOKEN] = $accessor->requestToken; self::addIdentityParams($msgParams, $request->getToken()); + $callbackUrl = $this->requestParams->getReceivedCallback(); + if (strlen($callbackUrl) > 0) { + $parsed_url = parse_url($callbackUrl); + parse_str($parsed_url["query"], $url_params); + if (strlen($url_params["oauth_token"]) > 0 && + strlen($url_params["oauth_verifier"]) > 0 && + $url_params["oauth_token"] == $accessor->requestToken) { + $msgParams[ShindigOAuth::$OAUTH_VERIFIER] = $url_params["oauth_verifier"]; + } else { + throw new GadgetException("Invalid received callback URL: ".$callbackUrl); + } + } $request = $this->newRequestMessageParams($url->url, $msgParams); $reply = $this->sendOAuthMessage($request); $reply->requireParameters(array(ShindigOAuth::$OAUTH_TOKEN, @@ -542,7 +560,10 @@ $fetcher = new $remoteFetcherClass(); $content = $fetcher->fetchRequest($rcr); $statusCode = $content->getHttpCode(); - if ($statusCode >= 400 && $statusCode < 500) { + if ($statusCode == 401) { + $tokenKey = $this->buildTokenKey(); + $this->tokenStore->removeTokenAndSecret($tokenKey); + } else if ($statusCode >= 400 && $statusCode < 500) { $message = $this->parseAuthHeader(null, $content); if ($message->get_parameter(ShindigOAuth::$OAUTH_PROBLEM) != null) { throw new ShindigOAuthProtocolException($message); @@ -595,7 +616,7 @@ private function filterOAuthParams($message) { $result = array(); foreach ($message->get_parameters() as $key => $value) { - if (strstr(strtolower($key), "oauth") != - 1 || strstr(strtolower($key), "xoauth") != - 1) { + if (preg_match('/^(oauth|xoauth|opensocial)/', strtolower($key))) { $result[$key] = $value; } } Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthRequestParams.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthRequestParams.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthRequestParams.php (original) +++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthRequestParams.php Mon Dec 28 03:26:22 2009 @@ -27,12 +27,14 @@ public static $REQUEST_TOKEN_PARAM = "OAUTH_REQUEST_TOKEN"; public static $REQUEST_TOKEN_SECRET_PARAM = "OAUTH_REQUEST_TOKEN_SECRET"; public static $CLIENT_STATE_PARAM = "oauthState"; + public static $RECEIVED_CALLBACK_PARAM = "OAUTH_RECEIVED_CALLBACK"; public static $BYPASS_SPEC_CACHE_PARAM = "bypassSpecCache"; protected $serviceName; protected $tokenName; protected $requestToken; protected $requestTokenSecret; protected $origClientState; + protected $receivedCallback; protected $bypassSpecCache; public function __construct(array $arguments) { @@ -41,6 +43,7 @@ $this->requestToken = self::getParam($arguments, self::$REQUEST_TOKEN_PARAM, null); $this->requestTokenSecret = self::getParam($arguments, self::$REQUEST_TOKEN_SECRET_PARAM, null); $this->origClientState = self::getParam($arguments, self::$CLIENT_STATE_PARAM, null); + $this->receivedCallback = self::getParam($arguments, self::$RECEIVED_CALLBACK_PARAM, ""); $this->bypassSpecCache = '1' == self::getParam($arguments, self::$BYPASS_SPEC_CACHE_PARAM, null); } @@ -75,4 +78,8 @@ public function getOrigClientState() { return $this->origClientState; } + + public function getReceivedCallback() { + return $this->receivedCallback; + } } Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php (original) +++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php Mon Dec 28 03:26:22 2009 @@ -24,6 +24,8 @@ public function setTokenAndSecret($tokenKey, $tokenInfo); + public function removeTokenAndSecret($tokenKey); + /** * Retrieve an OAuthAccessor that is ready to sign OAuthMessages for * resource access. Modified: incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php (original) +++ incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php Mon Dec 28 03:26:22 2009 @@ -26,7 +26,7 @@ require 'src/common/RemoteContent.php'; require 'src/common/Cache.php'; require 'src/common/RemoteContentFetcher.php'; -require 'src/gadgets/oauth/OAuth.php'; +require 'src/common/ShindigOAuth.php'; require 'src/gadgets/oauth/OAuthStore.php'; class MakeRequestServlet extends HttpServlet { Modified: incubator/shindig/trunk/php/src/gadgets/servlet/OAuthCallbackServlet.php URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/OAuthCallbackServlet.php?rev=894127&r1=894126&r2=894127&view=diff ============================================================================== --- incubator/shindig/trunk/php/src/gadgets/servlet/OAuthCallbackServlet.php (original) +++ incubator/shindig/trunk/php/src/gadgets/servlet/OAuthCallbackServlet.php Mon Dec 28 03:26:22 2009 @@ -18,23 +18,47 @@ * under the License. */ +require_once 'src/gadgets/oauth/OAuthCallbackState.php'; + class OAuthCallbackServlet extends HttpServlet { public function doGet() { - $this->setCacheTime(3600); - //header('Cache-Control: public,max-age=3600'); - //header('Content-Type: text/html; charset=utf-8'); - echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" " . - "\"http://www.w3.org/TR/html4/loose.dtd\">" . - "<html>" . - "<head>" . - "<title>Close this window</title>" . - "</head>" . - "<body>" . - "<script type=\"text/javascript\">" . - "window.close();" . - "</script>" . - "Close this window." . - "</body>" . - "</html>"; + $cs = isset($_GET["cs"]) ? $_GET["cs"] : ""; + $token = isset($_GET["oauth_token"]) ? $_GET["oauth_token"] : ""; + $verifier = isset($_GET["oauth_verifier"]) ? $_GET["oauth_verifier"] : ""; + if (strlen($cs) > 0) { + $BBC = new BasicBlobCrypter(); + $crypter = new BasicBlobCrypter(srand($BBC->MASTER_KEY_MIN_LEN)); + $clientState = new OAuthCallbackState($crypter, $cs); + $url = $clientState->getRealCallbackUrl(); + $callbackUrl = "http://" . $_SERVER['HTTP_HOST'] . "/gadgets/oauthcallback"; + if ($url = $callbackUrl) { + unset($_GET['cs']); + header('Location: '.$callbackUrl.'?'.http_build_query($_GET)); + exit; + } + } else if (strlen($token) > 0 && strlen($cs) == 0 ) { + $this->setCacheTime(3600); + echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" " . + "\"http://www.w3.org/TR/html4/loose.dtd\">" . + "<html>" . + "<head>" . + "<title>Close this window</title>" . + "</head>" . + "<body>" . + "<script type=\"text/javascript\">" . + "try {" . + " window.opener.gadgets.io.oauthReceivedCallbackUrl_ = document.location.href;" . + "} catch (e) {" . + "}" . + "window.close();" . + "</script>" . + "Close this window." . + "</body>" . + "</html>"; + exit; + } + header("HTTP/1.0 400 Bad Request", true); + echo "<html><body><h1>" . "400 - Bad Request Error" . "</h1></body></html>"; + die(); } }