You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ag...@apache.org on 2009/12/28 04:26:30 UTC

svn commit: r894127 - in /incubator/shindig/trunk/php/src: common/ gadgets/ gadgets/oauth/ gadgets/servlet/

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();
   }
 }