You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ch...@apache.org on 2009/04/20 15:01:07 UTC

svn commit: r766678 - in /incubator/shindig/trunk/php: ./ config/ src/common/ src/common/sample/ src/gadgets/ src/gadgets/oauth/ src/gadgets/sample/

Author: chabotc
Date: Mon Apr 20 13:01:06 2009
New Revision: 766678

URL: http://svn.apache.org/viewvc?rev=766678&view=rev
Log:
Patch by Pan Jie,

Description:
It's an initial patch for fixing oauth fetcher in php shindig.

Here're what I did in this patch:
1. add /gadgets/oauthcallback for oauth callback entry.
2. add metadata to RemoteContentRequest for storing metadata used in
oauth fetching. such as client_state, approval_url. Also output
metadatas as json format when handling makeRequest.
3. add isStrictNoCache() to RemoteContentRequest, returns whether
response should be cached.
4. modify OAuth parsing in GadgetSpecParser.php
5. add 'Pragma: no-cache' and 'Cache-Control: no-cache' when  returning
oauth response with no data.
6. add opensocial identify to oauth request header
7. use BasicRemoteContentFetcher instead of SigningFetcher when sending
oauth request to oauth provider.

TODO items:
1. modify toHash() method for RemoteContentRequest. Aligning  with
AbstractHttpCache.createKey in Java.
2. remove BasicGadgetSpecFactory->fetcher
3. remove GadgetOAuthTokenStore::$SERVICE_NAME
4. add setStrictNoCache() and addIdentityParams() to OAuthFetcher


Modified:
    incubator/shindig/trunk/php/config/container.php
    incubator/shindig/trunk/php/index.php
    incubator/shindig/trunk/php/src/common/RemoteContentRequest.php
    incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php
    incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php
    incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php
    incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuthAccessor.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuthService.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php
    incubator/shindig/trunk/php/src/gadgets/sample/BasicGadgetSpecFactory.php

Modified: incubator/shindig/trunk/php/config/container.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/config/container.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/config/container.php (original)
+++ incubator/shindig/trunk/php/config/container.php Mon Apr 20 13:01:06 2009
@@ -153,7 +153,7 @@
 
   // If your development server is behind a proxy, enter the proxy details here in 'proxy.host.com:port' format.
   'proxy' => '',
-  
+
   // Container id, used for security token
   'container_id' => 'default'
 );

Modified: incubator/shindig/trunk/php/index.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/index.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/index.php (original)
+++ incubator/shindig/trunk/php/index.php Mon Apr 20 13:01:06 2009
@@ -84,6 +84,7 @@
     Config::get('web_prefix') . '/gadgets/makeRequest' => 'MakeRequestServlet',
     Config::get('web_prefix') . '/gadgets/ifr' => 'GadgetRenderingServlet',
     Config::get('web_prefix') . '/gadgets/metadata' => 'MetadataServlet',
+    Config::get('web_prefix') . '/gadgets/oauthcallback' => 'OAuthCallbackServlet',
     Config::get('web_prefix') . '/social/rest' => 'DataServiceServlet',
     Config::get('web_prefix') . '/social/rpc' => 'JsonRpcServlet',
     Config::get('web_prefix') . '/public.crt' => 'CertServlet',

Modified: incubator/shindig/trunk/php/src/common/RemoteContentRequest.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/RemoteContentRequest.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/RemoteContentRequest.php (original)
+++ incubator/shindig/trunk/php/src/common/RemoteContentRequest.php Mon Apr 20 13:01:06 2009
@@ -29,7 +29,8 @@
   // these fields are filled in once the request has completed
   private $responseContent = false;
   private $responseSize = false;
-  private $responseHeaders = false;
+  private $responseHeaders = array();
+  private $metadata = array();
   private $httpCode = false;
   private $contentType = null;
   private $created;
@@ -120,7 +121,7 @@
   // returns a hash code which identifies this request, used for caching
   // takes url and postbody into account for constructing the sha1 checksum
   public function toHash() {
-    return md5($this->uri . $this->postBody);
+    return md5($this->method . $this->uri . $this->authType . $this->postBody . $this->headers);
   }
 
   public static function getDefaultOptions() {
@@ -207,6 +208,10 @@
   public function setResponseContent($content) {
     $this->responseContent = $content;
   }
+  
+  public function setResponseHeader($headerName, $headerValue) {
+    $this->responseHeaders[$headerName] = $headerValue;
+  }
 
   public function setResponseHeaders($headers) {
     $this->responseHeaders = $headers;
@@ -270,7 +275,7 @@
   /**
    * Returns the SecurityToken for this request
    *
-   * @return unknown
+   * @return SecurityToken
    */
   public function getToken() {
     return $this->token;
@@ -314,6 +319,37 @@
   public function getRefreshInterval() {
     return $this->refreshInterval;
   }
+  
+  public function setMetadata($key, $value) {
+    $this->metadata[$key] = $value;
+  }
+  
+  public function getMetadatas() {
+    return $this->metadata;
+  }
+  
+  public function isStrictNoCache() {
+    $cacheControl = $this->getResponseHeader('Cache-Control');
+    if ($cacheControl != null) {
+      $directives = split(',', $cacheControl);
+      foreach ($directives as $directive) {
+        if (strcasecmp($directive, 'no-cache') == 0
+            || strcasecmp($directive, 'no-store') == 0
+            || strcasecmp($directive, 'private') == 0) {
+          return true;
+        }
+      }
+    }
+    $progmas = $this->getResponseHeader('Progma');
+    if ($progmas != null) {
+      foreach ($progmas as $progma) {
+        if (strcasecmp($progma, 'no-cache') == 0) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
 }
 
 /**

Modified: incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php (original)
+++ incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php Mon Apr 20 13:01:06 2009
@@ -64,19 +64,19 @@
   public function fetch(RemoteContentRequest $request) {
     $ignoreCache = $request->getOptions()->ignoreCache;
     if (!$ignoreCache && ! $request->isPost() && ($cachedRequest = $this->cache->get($request->toHash())) !== false && $this->invalidateService->isValid($cachedRequest)) {
-      $request = $cachedRequest;
+      $response = $cachedRequest;
     } else {
       $originalRequest = clone $request;
-      $request = $this->divertFetch($request);
-      if ($request->getHttpCode() != 200 && !$ignoreCache && !$request->isPost()) {
-        $cachedRequest = $this->cache->expiredGet($request->toHash());
+      $response = $this->divertFetch($request);
+      if ($response->getHttpCode() != 200 && !$ignoreCache && !$originalRequest->isPost()) {
+        $cachedRequest = $this->cache->expiredGet($originalRequest->toHash());
         if ($cachedRequest['found'] == true) {
           return $cachedRequest['data'];
         }
       }
-      $this->setRequestCache($originalRequest, $request, $this->cache);
+      $this->setRequestCache($originalRequest, $response, $this->cache);
     }
-    return $request;
+    return $response;
   }
 
   public function multiFetch(Array $requests) {
@@ -141,6 +141,9 @@
   }
 
   private function setRequestCache(RemoteContentRequest $originalRequest, RemoteContentRequest $request, Cache $cache) {
+    if ($request->isStrictNoCache()) {
+      return;
+    }
     $ignoreCache = $originalRequest->getOptions()->ignoreCache;
     if (!$request->isPost() && !$ignoreCache) {
       $ttl = Config::get('cache_time');

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php Mon Apr 20 13:01:06 2009
@@ -297,14 +297,8 @@
         $oauthNode = $oauthNodes->item(0);
         if (($serviceNodes = $oauthNode->getElementsByTagName('Service')) != null) {
           foreach ($serviceNodes as $service) {
-            if (($entryNodes = $service->getElementsByTagName('*')) != null) {
-              foreach ($entryNodes as $entry) {
-                $type = strtolower($entry->tagName);
-                $url = $entry->getAttribute('url');
-                $method = $entry->getAttribute('method') != null ? strtoupper($entry->getAttribute('method')) : 'GET';
-                $oauth[$type] = array('url' => $url, 'method' => $method);
-              }
-            }
+            $oauthService = new OAuthService($service);
+            $oauth[$oauthService->getName()] = $oauthService;
           }
         }
         $gadget->oauth = $oauth;

Modified: incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php Mon Apr 20 13:01:06 2009
@@ -64,9 +64,13 @@
     if (isset($_REQUEST['contentType']) && $_REQUEST['contentType'] == 'FEED' && $status == 200) {
       $this->parseFeed($result, $url);
     } else {
-      $resp = $result->getResponseContent();
+      $body = $result->getResponseContent();
     }
-    $json = array($url => array('body' => $resp, 'rc' => $status));
+    $responseArray = array('body' => $body, 'rc' => $status);
+    foreach ($result->getMetadatas() as $key => $value) {
+      $responseArray[$key] = $value;
+    }
+    $json = array($url => $responseArray);
     $json = json_encode($json);
     $output = UNPARSEABLE_CRUFT . $json;
     if ($status == 200) {

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=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/GadgetOAuthTokenStore.php Mon Apr 20 13:01:06 2009
@@ -138,16 +138,15 @@
    * @param spec
    * @return a GadgetInfo
    */
-  public static function getProviderInfo(Gadget $spec, $serviceName) {
-    $oauthSpec = $spec->getOAuthSpec();
+  public static function getProviderInfo(GadgetSpec $spec, $serviceName) {
+    $oauthSpec = $spec->oauth;
     if ($oauthSpec == null) {
       $message = "gadget spec is missing /ModulePrefs/OAuth section";
       throw new GadgetException($message);
     }
-    $services = $oauthSpec->getServices();
     $service = null;
-    if (isset($services[$serviceName])) {
-      $service = $services[$serviceName];
+    if (isset($oauthSpec[$serviceName])) {
+      $service = $oauthSpec[$serviceName];
     }
     if ($service == null) {
       $message = '';

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=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php Mon Apr 20 13:01:06 2009
@@ -268,12 +268,11 @@
 
   /**
    * pretty much a helper function to set up the request
+   * @return OAuthRequest
    */
   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);
+    $defaults = array("oauth_nonce" => OAuthRequest::generate_nonce(), "oauth_timestamp" => OAuthRequest::generate_timestamp(), "oauth_consumer_key" => $consumer->key);
     $parameters = array_merge($defaults, $parameters);
     if (isset($token)) {
       $parameters['oauth_token'] = $token;
@@ -371,8 +370,7 @@
       }
       $this->parameters[$key] = $value;
     }
-    $parts = array($this->get_normalized_http_method(), $this->get_normalized_http_url(),
-        $this->get_signable_parameters());
+    $parts = array($this->get_normalized_http_method(), $this->get_normalized_http_url(), $this->get_signable_parameters());
     $parts = array_map(array('OAuthUtil', 'urlencodeRFC3986'), $parts);
     $this->parameters = $tmp;
     return implode('&', $parts);

Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthAccessor.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthAccessor.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthAccessor.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthAccessor.php Mon Apr 20 13:01:06 2009
@@ -40,6 +40,9 @@
     $this->properties[$name] = $value;
   }
 
+  /**
+   * @return OAuthRequest
+   */
   public function newRequestMessage($method, $url, $parameters) {
     if (! isset($method)) {
       $method = $this->getProperty("httpMethod");

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=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php Mon Apr 20 13:01:06 2009
@@ -75,6 +75,7 @@
    * The accessor we use for signing messages. This also holds metadata about
    * the service provider, such as their URLs and the keys we use to access
    * those URLs.
+   * @var AccesorInfo
    */
   private $accessorInfo;
 
@@ -90,6 +91,7 @@
 
   /**
    * The request the client really wants to make.
+   * @var RemoteContentRequest
    */
   private $realRequest;
 
@@ -167,8 +169,15 @@
     return $this->buildNonDataResponse();
   }
 
+  /**
+   * @return RemoteContentRequest
+   */
   private function buildNonDataResponse() {
-    return $this->addResponseMetadata();
+    $response = new RemoteContentRequest($this->realRequest->getUrl());
+    $this->addResponseMetadata($response);
+    $response->setResponseHeader('Pragma', 'no-cache');
+    $response->setResponseHeader('Cache-Control', 'no-cache');
+    return $response;
   }
 
   /**
@@ -222,11 +231,14 @@
     return $response;
   }
 
-  public function fetchRequest($request) {
+  /**
+   * @return RemoteContentRequest
+   */
+  public function fetchRequest(RemoteContentRequest $request) {
     if ($this->needApproval()) {
       // This is section 6.1 of the OAuth spec.
       $this->checkCanApprove();
-      $this->fetchRequestToken();
+      $this->fetchRequestToken($request);
       // This is section 6.2 of the OAuth spec.
       $this->buildClientApprovalState();
       $this->buildAznUrl();
@@ -236,7 +248,7 @@
     } elseif ($this->needAccessToken()) {
       // This is section 6.3 of the OAuth spec
       $this->checkCanApprove();
-      $this->exchangeRequestToken();
+      $this->exchangeRequestToken($request);
       $this->saveAccessToken();
       $this->buildClientAccessState();
     }
@@ -268,10 +280,13 @@
     $pageOwner = $this->authToken->getOwnerId();
     $pageViewer = $this->authToken->getViewerId();
     $stateOwner = @$this->origClientState[self::$OWNER_KEY];
-    if (! $pageOwner == $pageViewer) {
+    if (!$pageOwner) {
+      throw new GadgetException('Unauthenticated');
+    }
+    if ($pageOwner != $pageViewer) {
       throw new GadgetException("Only page owners can grant OAuth approval");
     }
-    if ($stateOwner != null && ! $stateOwner == $pageOwner) {
+    if ($stateOwner != null && !$stateOwner == $pageOwner) {
       throw new GadgetException("Client state belongs to a different person.");
     }
   }
@@ -280,13 +295,16 @@
    *
    * @throws GadgetException
    */
-  private function fetchRequestToken() {
+  private function fetchRequestToken(RemoteContentRequest $request) {
     try {
       $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;
       $msgParams = array();
-      $msgParams[self::$XOAUTH_APP_URL] = $this->authToken->getAppUrl();
+      $msgParams['opensocial_owner_id'] = $request->getToken()->getOwnerId();
+      $msgParams['opensocial_viewer_id'] = $request->getToken()->getViewerId();
+      $msgParams['opensocial_app_id'] = $request->getToken()->getAppId();
+      $msgParams['opensocial_app_url'] = $request->getToken()->getAppUrl();
       $request = $this->newRequestMessageParams($url->url, $msgParams);
       $reply = $this->sendOAuthMessage($request);
       $reply->requireParameters(array(OAuth::$OAUTH_TOKEN, OAuth::$OAUTH_TOKEN_SECRET));
@@ -298,6 +316,9 @@
     }
   }
 
+  /**
+   * @return OAuthRequest
+   */
   private function newRequestMessageMethod($method, $url, $params) {
     if (! isset($params)) {
       throw new Exception("params was null in " . "newRequestMessage " . "Use newRequesMessage if you don't have a params to pass");
@@ -325,6 +346,9 @@
     return $this->newRequestMessageParams($url, $params);
   }
 
+  /**
+   * @return OAuthRequest
+   */
   private function newRequestMessageParams($url, $params) {
     $method = "POST";
     if ($this->accessorInfo->getHttpMethod() == OAuthStoreVars::$HttpMethod['GET']) {
@@ -357,6 +381,9 @@
     return $result;
   }
 
+  /**
+   * @return RemoteContentRequest
+   */
   private function createRemoteContentRequest($oauthParams, $method, $url, $headers, $contentType, $postBody, $options) {
     $paramLocation = $this->accessorInfo->getParamLocation();
     $newHeaders = array();
@@ -397,7 +424,9 @@
    */
   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::getDefaultOptions());
-    $content = $this->fetcher->fetchRequest($rcr);
+    $rcr->setToken($this->authToken);
+    $fetcher = new BasicRemoteContentFetcher();
+    $content = $fetcher->fetchRequest($rcr);
     $reply = OAuthRequest::from_request();
     $params = OAuthUtil::decodeForm($content->getResponseContent());
     $reply->set_parameters($params);
@@ -429,7 +458,7 @@
     $accessor = $this->accessorInfo->getAccessor();
     $azn = $accessor->consumer->callback_url->userAuthorizationURL;
     $authUrl = $azn->url;
-    if (strstr($authUrl, "?") != - 1) {
+    if (strstr($authUrl, "?") == FALSE ) {
       $authUrl .= "?";
     } else {
       $authUrl .= "&";
@@ -450,13 +479,16 @@
   /**
    * Implements section 6.3 of the OAuth spec.
    */
-  private function exchangeRequestToken() {
+  private function exchangeRequestToken(RemoteContentRequest $request) {
     try {
       $accessor = $this->accessorInfo->getAccessor();
       $url = $accessor->consumer->callback_url->accessTokenURL;
       $msgParams = array();
-      $msgParams[self::$XOAUTH_APP_URL] = $this->authToken->getAppUrl();
       $msgParams[OAuth::$OAUTH_TOKEN] = $accessor->requestToken;
+      $msgParams['opensocial_owner_id'] = $request->getToken()->getOwnerId();
+      $msgParams['opensocial_viewer_id'] = $request->getToken()->getViewerId();
+      $msgParams['opensocial_app_id'] = $request->getToken()->getAppId();
+      $msgParams['opensocial_app_url'] = $request->getToken()->getAppUrl();
       $request = $this->newRequestMessageParams($url->url, $msgParams);
       $reply = $this->sendOAuthMessage($request);
       $reply->requireParameters(array(OAuth::$OAUTH_TOKEN, OAuth::$OAUTH_TOKEN_SECRET));
@@ -507,8 +539,9 @@
       // 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());
-      $content = $this->fetcher->fetchRequest($rcr);
-      //TODO is there a better way to detect an SP error?
+      //TODO is there a better way to detect an SP error?
+      $fetcher = new BasicRemoteContentFetcher();
+      $content = $fetcher->fetchRequest($rcr);
       $statusCode = $content->getHttpCode();
       if ($statusCode >= 400 && $statusCode < 500) {
         $message = $this->parseAuthHeader(null, $content);
@@ -516,8 +549,8 @@
           throw new OAuthProtocolException($message);
         }
       }
-      // Track metadata on the response
-      $this->addResponseMetadata();
+      // Track metadata on the response
+      $this->addResponseMetadata($content);
       return $content;
     } catch (Exception $e) {
       throw new GadgetException("INTERNAL SERVER ERROR: " . $e);
@@ -574,18 +607,26 @@
     return $this->responseMetadata;
   }
 
-  public function addResponseMetadata() {
+  /**
+   * @var RemoteContentRequest $response
+   */
+  public function addResponseMetadata(RemoteContentRequest $response) {
+    $response->setHttpCode(200);
     if ($this->newClientState != null) {
       $this->responseMetadata[self::$CLIENT_STATE] = $this->newClientState;
+      $response->setMetadata(self::$CLIENT_STATE, $this->newClientState);
     }
     if ($this->aznUrl != null) {
       $this->responseMetadata[self::$APPROVAL_URL] = $this->aznUrl;
+      $response->setMetadata(self::$APPROVAL_URL, $this->aznUrl);
     }
     if ($this->error != null) {
       $this->responseMetadata[self::$ERROR_CODE] = $this->error;
+      $response->setMetadata(self::$ERROR_CODE, $this->error);
     }
     if ($this->errorText != null) {
       $this->responseMetadata[self::$ERROR_TEXT] = $this->errorText;
+      $response->setMetadata(self::$ERROR_TEXT, $this->errorText);
     }
   }
 

Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthService.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthService.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthService.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthService.php Mon Apr 20 13:01:06 2009
@@ -28,36 +28,80 @@
   private static $METHOD_ATTR = "method";
   
   private $name;
+  
+  /**
+   * @var EndPoint
+   */
   private $requestUrl;
+  
+  /**
+   * @var EndPoint
+   */
   private $authorizationUrl;
+  
+  /**
+   * @var EndPoint
+   */
   private $accessUrl;
 
-  public function __construct($service) {
-    $attrs = $service->attributes();
-    $this->name = (string)$attrs['name'];
-    if (isset($service->Request)) {
-      $this->requestUrl = $this->parseEndPoint($service->Request->attributes());
-    }
-    if (isset($service->Authorization)) {
-      $this->authorizationUrl = $this->parseEndPoint($service->Authorization->attributes());
-    }
-    if (isset($service->Access)) {
-      $this->accessUrl = $this->parseEndPoint($service->Access->attributes());
+  public function __construct(DOMElement $service) {
+    $this->name = (string)$service->getAttribute('name');
+    $elements = $service->getElementsByTagName('*');
+    foreach ($elements as $element) {
+      $type = $element->tagName;
+      if ($type == 'Request') {
+        if ($this->requestUrl) {
+          throw new SpecParserException("Multiple OAuth/Service/Request elements");
+        }
+        $this->requestUrl = $this->parseEndPoint($element);
+      } else if ($type == 'Authorization') {
+        if ($this->authorizationUrl) {
+          throw new SpecParserException("Multiple OAuth/Service/Authorization elements");
+        }
+        $this->authorizationUrl = $this->parseEndPoint($element);
+      } else if ($type == 'Access') {
+        if ($this->accessUrl) {
+          throw new SpecParserException("Multiple OAuth/Service/Access elements");
+        }
+        $this->accessUrl = $this->parseEndPoint($element);
+      }
+    }
+    if ($this->requestUrl == null) {
+      throw new SpecParserException("/OAuth/Service/Request is required");
+    }
+    if ($this->accessUrl == null) {
+      throw new SpecParserException("/OAuth/Service/Access is required");
+    }
+    if ($this->authorizationUrl == null) {
+      throw new SpecParserException("/OAuth/Service/Authorization is required");
+    }
+    if ($this->requestUrl->location != $this->accessUrl->location) {
+      throw new SpecParserException(
+          "Access@location must be identical to Request@location");
+    }
+    if ($this->requestUrl->method != $this->accessUrl->method) {
+      throw new SpecParserException(
+          "Access@method must be identical to Request@method");
+    }
+    if ($this->requestUrl->location == Location::$body &&
+        $this->requestUrl->method == Method::$GET) {
+      throw new SpecParserException("Incompatible parameter location, cannot" +
+          "use post-body with GET requests");
     }
   }
 
   private function parseEndPoint($element) {
-    $url = trim((string)$element[OAuthService::$URL_ATTR]);
+    $url = trim($element->getAttribute(OAuthService::$URL_ATTR));
     if (empty($url)) {
       throw new SpecParserException("Not an HTTP url");
     }
     $location = Location::$header;
-    $locationString = trim((string)$element[OAuthService::$PARAM_LOCATION_ATTR]);
+    $locationString = trim($element->getAttribute(OAuthService::$PARAM_LOCATION_ATTR));
     if (! empty($locationString)) {
       $location = $locationString;
     }
     $method = Method::$GET;
-    $methodString = trim((string)$element[OAuthService::$METHOD_ATTR]);
+    $methodString = trim($element->getAttribute(OAuthService::$METHOD_ATTR));
     if (! empty($methodString)) {
       $method = $methodString;
     }

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=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthStore.php Mon Apr 20 13:01:06 2009
@@ -61,6 +61,9 @@
 }
 
 class AccesorInfo {
+  /**
+   * @var OAuthAccessor
+   */
   public $accessor;
   public $httpMethod;
   public $signatureType;
@@ -74,6 +77,9 @@
     $this->paramLocation = $paramLocation;
   }
 
+  /**
+   * @return OAuthAccessor
+   */
   public function getAccessor() {
     return $this->accessor;
   }

Modified: incubator/shindig/trunk/php/src/gadgets/sample/BasicGadgetSpecFactory.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/sample/BasicGadgetSpecFactory.php?rev=766678&r1=766677&r2=766678&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/sample/BasicGadgetSpecFactory.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/sample/BasicGadgetSpecFactory.php Mon Apr 20 13:01:06 2009
@@ -21,7 +21,7 @@
 /**
  * Basic implementation of a gadget spec factory.
  */
-class BasicGadgetSpecFactory implements GadgetSpecFactory {
+class BasicGadgetSpecFactory {
 
   private $fetcher;
   private $cache;
@@ -48,13 +48,11 @@
   private function fetchFromWeb($url, $ignoreCache) {
     $remoteContentRequest = new RemoteContentRequest($url);
     $remoteContentRequest->getOptions()->ignoreCache = $ignoreCache;
-    $remoteContent = new BasicRemoteContent($this->fetcher);
+    $remoteContent = new BasicRemoteContent();
     $spec = $remoteContent->fetch($remoteContentRequest);
     
-    $spec = $this->fetcher->fetchRequest($remoteContentRequest);
-    $specParser = new GadgetSpecParser();
-    $context = new ProxyGadgetContext($url);
-    $gadgetSpec = $specParser->parse($spec->getResponseContent(), $context);
+    $gadgetSpecParser = new GadgetSpecParser();
+    $gadgetSpec = $gadgetSpecParser->parse($spec->getResponseContent());
     return $gadgetSpec;
   }