Author: chabotc
Date: Mon Mar 23 15:26:31 2009
New Revision: 757414

URL: http://svn.apache.org/viewvc?rev=757414&view=rev
Log:
This adds initial support for the new invalidation service, and contains the
start of a refactored content fetching pipeline, which besides giving us 
prettier
code will also make this cleanly re-usable for situations other then the proxy/
makeRequest handlers (for example: proxied content). This is still on-going.

It also contains a start of the proxied content renderer, which *really* isn't
production ready yet (see above).


Added:
    incubator/shindig/trunk/php/src/common/AuthenticationMode.php
    incubator/shindig/trunk/php/src/social/sample/DefaultInvalidateService.php
    incubator/shindig/trunk/php/src/social/service/InvalidateHandler.php
    incubator/shindig/trunk/php/src/social/spi/InvalidateService.php
    incubator/shindig/trunk/php/test/social/DefaultInvalidateServiceTest.php
Modified:
    incubator/shindig/trunk/php/config/container.php
    incubator/shindig/trunk/php/src/common/Cache.php
    incubator/shindig/trunk/php/src/common/RemoteContentRequest.php
    incubator/shindig/trunk/php/src/common/SecurityToken.php
    incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php
    incubator/shindig/trunk/php/src/common/sample/BasicSecurityToken.php
    incubator/shindig/trunk/php/src/gadgets/Gadget.php
    incubator/shindig/trunk/php/src/gadgets/GadgetFactory.php
    incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php
    incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php
    incubator/shindig/trunk/php/src/gadgets/ProxyBase.php
    incubator/shindig/trunk/php/src/gadgets/SigningFetcher.php
    incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php
    incubator/shindig/trunk/php/src/social/oauth/OAuthSecurityToken.php
    incubator/shindig/trunk/php/src/social/service/RequestItem.php
    incubator/shindig/trunk/php/src/social/service/RestRequestItem.php
    incubator/shindig/trunk/php/src/social/servlet/ApiServlet.php
    incubator/shindig/trunk/php/src/social/servlet/DataServiceServlet.php

Modified: incubator/shindig/trunk/php/config/container.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/config/container.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/config/container.php (original)
+++ incubator/shindig/trunk/php/config/container.php Mon Mar 23 15:26:31 2009
@@ -130,6 +130,7 @@
   'activity_service' => 'JsonDbOpensocialService',
   'app_data_service' => 'JsonDbOpensocialService',
   'messages_service' => 'JsonDbOpensocialService',
+  'invalidate_service' => 'DefaultInvalidateService',
 
   // Also scan these directories when looking for <Class>.php files. You can 
include multiple paths by seperating them with a ,
   'extension_class_paths' => '',

Added: incubator/shindig/trunk/php/src/common/AuthenticationMode.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/AuthenticationMode.php?rev=757414&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/common/AuthenticationMode.php (added)
+++ incubator/shindig/trunk/php/src/common/AuthenticationMode.php Mon Mar 23 
15:26:31 2009
@@ -0,0 +1,49 @@
+<?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.
+ */
+
+class AuthenticationMode {
+  /**
+   * The request has no authentication associated with it. Used for anonymous 
requests
+   */
+  public static $UNAUTHENTICATED = 'unauthenticated';
+
+  /**
+   * Used by rendered gadgets to authenticate calls to the container
+   */
+  public static $SECURITY_TOKEN_URL_PARAMETER = 'security_token_url_parameter';
+
+  /**
+   * A fully validated 3-legged OAuth call by a 3rd party on behalf of a user 
of the
+   * receiving domain. viewerid should always be available
+   */
+  public static $OAUTH = 'oauth';
+
+  /**
+   * A call by a validated 3rd party on its own behalf. Can emulate a call on 
behalf of a user
+   * of the receiving domain subject to ACL checking but is not required to do 
so. viewerid may or
+   * may not be available
+   */
+  public static $OAUTH_CONSUMER_REQUEST = 'oauth_consumer_request';
+
+  /**
+   * The request is from a logged in user of the receiving domain
+   */
+  public static $COOKIE = 'cookie';
+}

Modified: incubator/shindig/trunk/php/src/common/Cache.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/Cache.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/Cache.php (original)
+++ incubator/shindig/trunk/php/src/common/Cache.php Mon Mar 23 15:26:31 2009
@@ -39,6 +39,9 @@
    */
   private $storage = null;
 
+  /**
+   * @return Cache
+   */
   static public function createCache($cacheClass, $name, RequestTime $time = 
null) {
     return new Cache($cacheClass, $name, $time);
   }

Modified: incubator/shindig/trunk/php/src/common/RemoteContentRequest.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/RemoteContentRequest.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/RemoteContentRequest.php (original)
+++ incubator/shindig/trunk/php/src/common/RemoteContentRequest.php Mon Mar 23 
15:26:31 2009
@@ -18,7 +18,6 @@
  * under the License.
  */
 
-
 class RemoteContentRequest {
   // these are used for making the request
   private $uri = '';
@@ -39,12 +38,32 @@
   public $handle = false;
   public static $DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded; 
charset=utf-8";
 
+  /**
+   * @var SecurityToken
+   */
+  private $token;
+
+  /**
+   * @var string
+   */
+  private $invalidation;
+
+  public static $AUTH_NONE = 'none';
+  public static $AUTH_SIGNED = 'signed';
+  public static $AUTH_OAUTH = 'oauth';
+
+  /**
+   * @var string
+   */
+  private $authType;
+
   public function __construct($uri, $headers = false, $postBody = false) {
     $this->uri = $uri;
     $this->notSignedUri = $uri;
     $this->headers = $headers;
     $this->postBody = $postBody;
     $this->created = time();
+    $this->authType = self::$AUTH_NONE;
   }
 
   public function createRemoteContentRequest($method, $uri, $headers, 
$postBody, $options) {
@@ -224,6 +243,33 @@
   public function setNotSignedUri($uri) {
     $this->notSignedUri = $uri;
   }
+
+  public function setInvalidation($invalidation) {
+    $this->invalidation = $invalidation;
+  }
+
+  public function getInvalidation() {
+    return $this->invalidation;
+  }
+
+  /**
+   * @param SecurityToken $token
+   */
+  public function setToken($token) {
+    $this->token = $token;
+  }
+
+  public function getToken() {
+    return $this->token;
+  }
+
+  public function setAuthType($type) {
+    $this->authType = $type;
+  }
+
+  public function getAuthType() {
+    return $this->authType;
+  }
 }
 
 /**
@@ -247,5 +293,4 @@
     $this->ownerSigned = $copyFrom->ownerSigned;
     $this->viewerSigned = $copyFrom->viewerSigned;
   }
-
 }

Modified: incubator/shindig/trunk/php/src/common/SecurityToken.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/SecurityToken.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/SecurityToken.php (original)
+++ incubator/shindig/trunk/php/src/common/SecurityToken.php Mon Mar 23 
15:26:31 2009
@@ -74,4 +74,11 @@
    * @return the module ID of the application
    */
   abstract public function getModuleId();
+  
+  /**
+   * @return string
+   */
+  abstract public function getAuthenticationMode();
+  
+  abstract public function setAuthenticationMode($mode);
 }

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=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php 
(original)
+++ incubator/shindig/trunk/php/src/common/sample/BasicRemoteContent.php Mon 
Mar 23 15:26:31 2009
@@ -23,21 +23,38 @@
    * @var BesicRemoteContentFetcher
    */
   private $basicFetcher = null;
-  
+
   /**
    * @var SigningFetcherFactory
    */
   private $signingFetcherFactory = null;
-  
+
   /**
    * @var SecurityTokenDecoder
    */
   private $signer = null;
 
+  /**
+   * @var Cache
+   */
+  private $cache = null;
+
+  /**
+   * @var InvalidateService
+   */
+  private $invalidateService = null;
+
+  /**
+   * @param RemoteContentFetcher $basicFetcher
+   * @param SigningFetcherFactory $signingFetcherFactory
+   * @param SecurityTokenDecoder $signer
+   */
   public function __construct(RemoteContentFetcher $basicFetcher = null, 
$signingFetcherFactory = null, $signer = null) {
     $this->basicFetcher = $basicFetcher ? $basicFetcher : new 
BasicRemoteContentFetcher();
     $this->signingFetcherFactory = $signingFetcherFactory;
     $this->signer = $signer;
+    $this->cache = Cache::createCache(Config::get('data_cache'), 
'RemoteContent');
+    $this->invalidateService = new DefaultInvalidateService($this->cache);
   }
 
   public function setBasicFetcher(RemoteContentFetcher $basicFetcher) {
@@ -45,25 +62,23 @@
   }
 
   public function fetch(RemoteContentRequest $request, GadgetContext $context) 
{
-    $cache = Cache::createCache(Config::get('data_cache'), 'RemoteContent');
-    if (!$context->getIgnoreCache() && ! $request->isPost() && ($cachedRequest 
= $cache->get($request->toHash())) !== false) {
+    if (! $context->getIgnoreCache() && ! $request->isPost() && 
($cachedRequest = $this->cache->get($request->toHash())) !== false && 
$this->invalidateService->isValid($cachedRequest)) {
       $request = $cachedRequest;
     } else {
       $originalRequest = clone $request;
-      $request = $this->divertFetch($request, $context);
-      if ($request->getHttpCode() != 200 && !$context->getIgnoreCache() && 
!$request->isPost()) {
-        $cachedRequest = $cache->expiredGet($request->toHash());
+      $request = $this->divertFetch($request);
+      if ($request->getHttpCode() != 200 && ! $context->getIgnoreCache() && ! 
$request->isPost()) {
+        $cachedRequest = $this->cache->expiredGet($request->toHash());
         if ($cachedRequest['found'] == true) {
           return $cachedRequest['data'];
         }
       }
-      $this->setRequestCache($originalRequest, $request, $cache, $context);
+      $this->setRequestCache($originalRequest, $request, $this->cache, 
$context);
     }
     return $request;
   }
 
   public function multiFetch(Array $requests, Array $contexts) {
-    $cache = Cache::createCache(Config::get('data_cache'), 'RemoteContent');
     $rets = array();
     $requestsToProc = array();
     foreach ($requests as $request) {
@@ -72,7 +87,7 @@
         throw new RemoteContentException("Invalid request type in 
remoteContent");
       }
       // determine which requests we can load from cache, and which we have to 
actually fetch
-      if (!$context->getIgnoreCache() && ! $request->isPost() && 
($cachedRequest = $cache->get($request->toHash())) !== false) {
+      if (! $context->getIgnoreCache() && ! $request->isPost() && 
($cachedRequest = $this->cache->get($request->toHash())) !== false && 
$this->invalidateService->isValid($cachedRequest)) {
         $rets[] = $cachedRequest;
       } else {
         $originalRequest = clone $request;
@@ -80,18 +95,18 @@
         $originalRequestArray[] = $originalRequest;
       }
     }
-    
+
     if ($requestsToProc) {
       $newRets = $this->basicFetcher->multiFetchRequest($requestsToProc);
       foreach ($newRets as $request) {
         list(, $originalRequest) = each($originalRequestArray);
-        if ($request->getHttpCode() != 200 && !$context->getIgnoreCache() && 
!$request->isPost()) {
-          $cachedRequest = $cache->expiredGet($request->toHash());
+        if ($request->getHttpCode() != 200 && ! $context->getIgnoreCache() && 
! $request->isPost()) {
+          $cachedRequest = $this->cache->expiredGet($request->toHash());
           if ($cachedRequest['found'] == true) {
             $rets[] = $cachedRequest['data'];
           }
         } else {
-          $this->setRequestCache($originalRequest, $request, $cache, $context);
+          $this->setRequestCache($originalRequest, $request, $this->cache, 
$context);
           $rets[] = $request;
         }
       }
@@ -100,8 +115,7 @@
   }
 
   public function invalidate(RemoteContentRequest $request) {
-    $cache = Cache::createCache(Config::get('data_cache'), 'RemoteContent');
-    $cache->invalidate($request->toHash());
+    $this->cache->invalidate($request->toHash());
   }
 
   private function setRequestCache(RemoteContentRequest $originalRequest, 
RemoteContentRequest $request, Cache $cache, GadgetContext $context) {
@@ -134,28 +148,23 @@
       } else {
         $ttl = 5 * 60; // cache errors for 5 minutes, takes the denial of 
service attack type behaviour out of having an error :)
       }
-      $cache->set($originalRequest->toHash(), $request, $ttl);
+      $this->invalidateService->markResponse($request);
+      $this->cache->set($originalRequest->toHash(), $request, $ttl);
     }
   }
-  
-  private function divertFetch(RemoteContentRequest $request, GadgetContext 
$context) {
-    $authz = isset($_GET['authz']) ? $_GET['authz'] : (isset($_POST['authz']) 
? $_POST['authz'] : '');
-    switch (strtoupper($authz)) {
-      case 'SIGNED':
-        $token = $context->extractAndValidateToken($this->signer);
+
+  private function divertFetch(RemoteContentRequest $request) {
+    switch ($request->getAuthType()) {
+      case RemoteContentRequest::$AUTH_SIGNED:
+        $token = $request->getToken();
         $fetcher = 
$this->signingFetcherFactory->getSigningFetcher($this->basicFetcher, $token);
-        $url = $request->getUrl();
-        $method = $request->isPost() ? 'POST' : 'GET'; 
-        return $fetcher->fetch($url, $method);
-      case 'OAUTH':
+        return $fetcher->fetchRequest($request);
+      case RemoteContentRequest::$AUTH_OAUTH:
         $params = new OAuthRequestParams();
-        $token = $context->extractAndValidateToken($this->signer);
+        $token = $request->getToken();
         $fetcher = 
$this->signingFetcherFactory->getSigningFetcher($this->basicFetcher, $token);
         $oAuthFetcherFactory = new OAuthFetcherFactory($fetcher);
         $oauthFetcher = $oAuthFetcherFactory->getOAuthFetcher($fetcher, 
$token, $params);
-        $url = $request->getUrl();
-        $request = new RemoteContentRequest($url);
-        $request->createRemoteContentRequestWithUri($url);
         return $oauthFetcher->fetch($request);
       default:
         return $this->basicFetcher->fetchRequest($request);

Modified: incubator/shindig/trunk/php/src/common/sample/BasicSecurityToken.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/sample/BasicSecurityToken.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/sample/BasicSecurityToken.php 
(original)
+++ incubator/shindig/trunk/php/src/common/sample/BasicSecurityToken.php Mon 
Mar 23 15:26:31 2009
@@ -39,6 +39,8 @@
   private $APPURL_KEY = "u";
   private $MODULE_KEY = "m";
   private $CONTAINER_KEY = "c";
+  
+  private $authenticationMode;
 
   /**
    * {...@inheritdoc}
@@ -64,7 +66,8 @@
    * @param app application id
    * @param domain domain of the container
    * @param appUrl url where the application lives
-   * @param moduleId module id of this gadget 
+   * @param moduleId module id of this gadget
+   * @return BasicSecurityToken 
    * @throws BlobCrypterException 
    */
   static public function createFromValues($owner, $viewer, $app, $domain, 
$appUrl, $moduleId, $containerId) {
@@ -169,4 +172,15 @@
     }
     return $this->tokenData[$this->CONTAINER_KEY];
   }
+  
+  /**
+   * {...@inheritdoc}
+   */
+  public function getAuthenticationMode() {
+    return $this->authenticationMode;
+  }
+  
+  public function setAuthenticationMode($mode) {
+    $this->authenticationMode = $mode;
+  }
 }

Modified: incubator/shindig/trunk/php/src/gadgets/Gadget.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/Gadget.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/Gadget.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/Gadget.php Mon Mar 23 15:26:31 2009
@@ -20,10 +20,19 @@
 
 class Gadget {
   const DEFAULT_VIEW = 'profile';
+
+  /**
+   * @var GadgetSpec
+   */
   public $gadgetSpec;
+
   public $features;
   public $substitutions;
   public $rightToLeft;
+
+  /**
+   * @var GadgetContext
+   */
   public $gadgetContext;
 
   public function __construct(GadgetSpec $gadgetSpec, GadgetContext 
$gadgetContext) {

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetFactory.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetFactory.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetFactory.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetFactory.php Mon Mar 23 
15:26:31 2009
@@ -184,7 +184,7 @@
    */
   private function fetchResources(Gadget &$gadget) {
     $contextLocale = $this->context->getLocale();
-    $unsignedRequests = $unsignedContexts = $signedRequests = array();
+    $unsignedRequests = $unsignedContexts = $signedRequests = $signedContexts 
= array();
     foreach ($gadget->getLocales() as $key => $locale) {
       // Only fetch the locales that match the current context's language and 
country
       if (($locale['country'] == 'all' && $locale['lang'] == 'all') || 
($locale['lang'] == $contextLocale['lang'] && $locale['country'] == 'all') || 
($locale['lang'] == $contextLocale['lang'] && $locale['country'] == 
$contextLocale['country'])) {
@@ -230,17 +230,14 @@
     // Perform the signed requests
     foreach ($signedRequests as $key => $requestUrl) {
       $request = new RemoteContentRequest($requestUrl);
-      $request->createRemoteContentRequestWithUri($requestUrl);
+      $request->setAuthType(RemoteContentRequest::$AUTH_SIGNED);
+      $request->setNotSignedUri($requestUrl);
       $signedRequests[$key] = $request;
-      $signingFetcherFactory = new 
SigningFetcherFactory(Config::get("private_key_file"));
-      $fetcher = $signingFetcherFactory->getSigningFetcher(new 
BasicRemoteContentFetcher(), $this->token);
-      $req = $fetcher->signRequest($requestUrl, 'GET');
-      $req->setNotSignedUri($requestUrl);
-      $signedRequests[] = $req;
+      $signedContexts[$key] = $this->context;
     }
     if (count($signedRequests)) {
-      $fetcher = $signingFetcherFactory->getSigningFetcher(new 
BasicRemoteContentFetcher(), $this->token);
-      $resps = $fetcher->multiFetchRequest($signedRequests);
+      $remoteContent = new BasicRemoteContent(new BasicRemoteContentFetcher(), 
$signingFetcherFactory);
+      $resps = $remoteContent->multiFetch($signedRequests,$signedContexts);
       foreach ($resps as $response) {
         $responses[$response->getNotSignedUrl()] = array(
             'body' => $response->getResponseContent(),
@@ -299,6 +296,7 @@
    */
   protected function fetchGadget($gadgetUrl) {
     $request = new RemoteContentRequest($gadgetUrl);
+    $request->setToken($this->token);
     $xml = $this->context->getHttpFetcher()->fetch($request, $this->context);
     if ($xml->getHttpCode() != '200') {
       throw new GadgetException("Failed to retrieve gadget content (recieved 
http code " . $xml->getHttpCode() . ")");

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php Mon Mar 23 
15:26:31 2009
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -78,7 +79,10 @@
           $gadget->views[$view]['content'] .= $viewNode->nodeValue;
         } else {
           $gadget->views[$view] = array('view' => $view, 'type' => 
strtoupper($viewNode->getAttribute('type')), 'href' => 
$viewNode->getAttribute('href'), 'preferedHeight' => 
$viewNode->getAttribute('prefered_height'),
-              'preferedWidth' => $viewNode->getAttribute('prefered_width'), 
'quirks' => $viewNode->getAttribute('quirks'), 'content' => 
$viewNode->nodeValue);
+              'preferedWidth' => $viewNode->getAttribute('prefered_width'), 
'quirks' => $viewNode->getAttribute('quirks'), 'content' => 
$viewNode->nodeValue, 'authz' => $viewNode->getAttribute('authz'),
+              'oauthServiceName' => 
$viewNode->getAttribute('oauth_service_name'), 'oauthTokenName' => 
$viewNode->getAttribute('oauth_token_name'), 'oauthRequestToken' => 
$viewNode->getAttribute('oauth_request_token'),
+              'oauthRequestTokenSecret' => 
$viewNode->getAttribute('oauth_request_token_secret'), 'signOwner' => 
$viewNode->getAttribute('sign_owner'), 'signViewer' => 
$viewNode->getAttribute('sign_viewer'),
+              'refreshInterval' => 
$viewNode->getAttribute('refresh_interval'));
         }
       }
     }

Modified: incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php Mon Mar 23 
15:26:31 2009
@@ -87,7 +87,7 @@
   private function fetchContentDivert($url, $method, $signer) {
     $basicFetcher = new BasicRemoteContentFetcher();
     $basicRemoteContent = new BasicRemoteContent($basicFetcher, 
$this->signingFetcherFactory, $signer);
-    $request = $this->buildRequest($url, $method);
+    $request = $this->buildRequest($url, $method, $signer);
     return $basicRemoteContent->fetch($request, $this->context);
   }
 

Modified: incubator/shindig/trunk/php/src/gadgets/ProxyBase.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/ProxyBase.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/ProxyBase.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/ProxyBase.php Mon Mar 23 15:26:31 
2009
@@ -37,9 +37,11 @@
    * Retrieves the actual content
    *
    * @param string $url the url to fetch
+   * @param string $method http method
+   * @param SecurityTokenDecoder $signer
    * @return the filled in request (RemoteContentRequest)
    */
-  protected function buildRequest($url, $method = 'GET') {
+  protected function buildRequest($url, $method = 'GET', $signer = null) {
     // Check the protocol requested - curl doesn't really support file://
     // requests but the 'error' should be handled properly
     $protocolSplit = explode('://', $url, 2);
@@ -78,6 +80,20 @@
     } else {
       $request = new RemoteContentRequest($url);
     }
+    
+    if ($signer) {
+      $authz = isset($_GET['authz']) ? $_GET['authz'] : 
(isset($_POST['authz']) ? $_POST['authz'] : '');
+      switch (strtoupper($authz)) {
+        case 'SIGNED':
+          $request->setAuthType(RemoteContentRequest::$AUTH_SIGNED);
+          break;
+        case 'OAUTH':
+          $request->setAuthType(RemoteContentRequest::$AUTH_OAUTH);
+          break;
+      }
+      $token = $this->context->extractAndValidateToken($signer);
+      $request->setToken($token);
+    }
     return $request;
   }
 

Modified: incubator/shindig/trunk/php/src/gadgets/SigningFetcher.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/SigningFetcher.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/SigningFetcher.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/SigningFetcher.php Mon Mar 23 
15:26:31 2009
@@ -36,7 +36,8 @@
   protected static $ALLOWED_PARAM_NAME = '^[-_[:alnum:]]+$';
 
   /**
-   * Authentication token for the user and gadget making the request.
+   * Authentication token for the user and gadget making the request.
+   * @var SecurityToken
    */
   protected $authToken;
 
@@ -64,7 +65,7 @@
    * @param keyName name of the key to include in the request
    * @param privateKey the key to use for the signing
    */
-  public static function makeFromPrivateKey($fetcher, $authToken, $keyName, 
$privateKey) {
+  public static function makeFromPrivateKey(RemoteContentFetcher $fetcher, 
SecurityToken $authToken, $keyName, $privateKey) {
     return new SigningFetcher($fetcher, $authToken, $keyName, $privateKey);
   }
 
@@ -75,7 +76,7 @@
    * @param keyName name of the key to include in the request
    * @param privateKey base64 encoded private key
    */
-  public static function makeFromB64PrivateKey($fetcher, $authToken, $keyName, 
$privateKey) {
+  public static function makeFromB64PrivateKey(RemoteContentFetcher $fetcher, 
SecurityToken $authToken, $keyName, $privateKey) {
     return new SigningFetcher($fetcher, $authToken, $keyName, $privateKey);
   }
 
@@ -86,11 +87,11 @@
    * @param keyName name of the key to include in the request
    * @param privateKey DER encoded private key
    */
-  public static function makeFromPrivateKeyBytes($fetcher, $authToken, 
$keyName, $privateKey) {
+  public static function makeFromPrivateKeyBytes(RemoteContentFetcher 
$fetcher, SecurityToken $authToken, $keyName, $privateKey) {
     return new SigningFetcher($fetcher, $authToken, $keyName, $privateKey);
   }
 
-  protected function __construct($fetcher, $authToken, $keyName, 
$privateKeyObject) {
+  protected function __construct(RemoteContentFetcher $fetcher, SecurityToken 
$authToken, $keyName, $privateKeyObject) {
     $this->fetcher = $fetcher;
     $this->authToken = $authToken;
     $this->keyName = $keyName;
@@ -98,19 +99,20 @@
   }
 
   public function fetchRequest(RemoteContentRequest $request) {
+    $this->signRequest($request);
     return $this->fetcher->fetchRequest($request);
   }
 
-  public function fetch($url, $method) {
-    $signed = $this->signRequest($url, $method);
-    return $this->fetcher->fetchRequest($signed);
-  }
-
   public function multiFetchRequest(Array $requests) {
+    foreach ($requests as $request) {
+      $this->signRequest($requests);
+    }
     return $this->fetcher->multiFetchRequest($requests);
   }
 
-  public function signRequest($url, $method) {
+  private function signRequest(RemoteContentRequest $request) {
+    $url = $request->getUrl();
+    $method = $request->getMethod();
     try {
       // Parse the request into parameters for OAuth signing, stripping out
       // any OAuth or OpenSocial parameters injected by the client
@@ -181,7 +183,9 @@
       // The headers are transmitted in the POST-data array in the field 
'headers'
       // if no post should be made, the value should be false for this 
parameter
       $postHeaders = ((isset($_POST['headers']) && $method == 'POST') ? 
$_POST['headers'] : false);
-      return new RemoteContentRequest($url, $postHeaders, $postData);
+      $request->setUri($url);
+      $request->setHeaders($postHeaders);
+      $request->setPostBody($postData);
     } catch (Exception $e) {
       throw new GadgetException($e);
     }

Modified: incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php 
(original)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php Mon 
Mar 23 15:26:31 2009
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,7 +20,66 @@
  */
 
 class GadgetHrefRenderer extends GadgetRenderer {
+
   public function renderGadget(Gadget $gadget, $view) {
-    echo "render href";
+    /* TODO
+     * We should really re-add OAuth fetching support some day, uses these 
view atributes:
+     * $view['oauthServiceName'], $view['oauthTokenName'], 
$view['oauthRequestToken'], $view['oauthRequestTokenSecret'];
+    */
+
+    $gadgetSigner = Config::get('security_token_signer');
+    $gadgetSigner = new $gadgetSigner();
+    $token = $gadget->gadgetContext->extractAndValidateToken($gadgetSigner);
+
+    $authz = $this->getAuthz($view);
+    $refreshInterval = $this->getRefreshInterval($view);
+    $href = $this->buildHref($view, $token);
+
+    $signingFetcherFactory = false;
+    $request = new RemoteContentRequest($href);
+    $request->setToken($token);
+    if ($authz != 'NONE') {
+      $signingFetcherFactory = new 
SigningFetcherFactory(Config::get("private_key_file"));
+      $request->setAuthType($authz);
+    }
+
+    //TODO Currently our signing fetcher assumes it's being called from the 
makeRequest handler and the $_GET and $_POST should be relayed.
+    // Here that's not the case, so we reset our super globals. We should 
refactor the signing fetcher to not make this assumption anymore.
+    $_GET = array('st' => $_GET['st']);
+    $_POST = array();
+
+    $basicFetcher = new BasicRemoteContentFetcher();
+    $basicRemoteContent = new BasicRemoteContent($basicFetcher, 
$signingFetcherFactory, $gadgetSigner);
+    $response = $basicRemoteContent->fetch($request, $gadget->gadgetContext, 
$authz);
+    echo $response->getResponseContent();
+  }
+
+  private function buildHref($view, $token) {
+    $href = $view['href'];
+    if (empty($href)) {
+      throw new Exception("Invalid empty href in the gadget view");
+    }    // add the required country and lang param to the URL
+    $lang = isset($_GET['lang']) ? $_GET['lang'] : 'en';
+    $country = isset($_GET['country']) ? $_GET['country'] : 'US';
+    $firstSeperator = strpos($href, '?') === false ? '?' : '&';
+    $href .= $firstSeperator . 'lang=' . urlencode($lang);
+    $href .= '&country=' . urlencode($country);
+
+    // our internal caching is based on the raw url, but the spec states that 
the container should only cache for a
+    // unique url + lang + country + owner + viewer + appid, so we add those 
to the url too, so caching works as it should
+    // (so in essense we *always* signOwner and signViewer)
+    $href .= '&opensocial_owner_id=' . urlencode($token->getOwnerId());
+    $href .= '&opensocial_viewer_id=' . urlencode($token->getViewerId());
+    $href .= '&opensocial_app_id=' . urlencode($token->getAppId());
+    $href .= "&opensocial_app_url=" . urlencode($token->getAppUrl());
+    return $href;
+  }
+
+  private function getRefreshInterval($view) {
+    return ! empty($view['refreshInterval']) && 
is_numeric($view['refreshInterval']) ? $view['refreshInterval'] : 3500;
+  }
+
+  private function getAuthz($view) {
+    return ! empty($view['authz']) ? strtoupper($view['authz']) : 'NONE';
   }
 }

Modified: incubator/shindig/trunk/php/src/social/oauth/OAuthSecurityToken.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/oauth/OAuthSecurityToken.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social/oauth/OAuthSecurityToken.php 
(original)
+++ incubator/shindig/trunk/php/src/social/oauth/OAuthSecurityToken.php Mon Mar 
23 15:26:31 2009
@@ -26,6 +26,8 @@
   private $appUrl;
   private $appId;
   private $domain;
+  
+  private $authenticationMode;
 
   public function __construct($userId, $appUrl, $appId, $domain) {
     $this->userId = $userId;
@@ -65,4 +67,12 @@
   public function toSerialForm() {
     return 
"OAuthSecurityToken[userId=$userId,appUrl=$appUrl,appId=$appId,domain=$domain]";
   }
+  
+  public function getAuthenticationMode() {
+    return $this->authenticationMode;
+  }
+  
+  public function setAuthenticationMode($mode) {
+    $this->authenticationMode = $mode;
+  }
 }

Added: 
incubator/shindig/trunk/php/src/social/sample/DefaultInvalidateService.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/sample/DefaultInvalidateService.php?rev=757414&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/social/sample/DefaultInvalidateService.php 
(added)
+++ incubator/shindig/trunk/php/src/social/sample/DefaultInvalidateService.php 
Mon Mar 23 15:26:31 2009
@@ -0,0 +1,145 @@
+<?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.
+ */
+
+class DefaultInvalidateService implements InvalidateService {
+
+  /**
+   * @var Cache
+   */
+  private $invalidationEntry;
+  
+  /**
+   * @var Cache
+   */
+  private $cache;
+  
+  private static $marker = null;
+  
+  /**
+   * @var Cache
+   */
+  private static $makerCache = null;
+  
+  private static $TOKEN_PREFIX = 'INV_TOK_';
+  
+  public function __construct(Cache $cache) {
+    $this->cache = $cache;
+    $this->invalidationEntry = Cache::createCache(Config::get('data_cache'), 
'InvalidationEntry');
+    if (self::$makerCache == null) {
+      self::$makerCache = Cache::createCache(Config::get('data_cache'), 
'MarkerCache');
+      $value = self::$makerCache->expiredGet('marker');
+      if ($value['found']) {
+        self::$marker = $value['data'];
+      } else {
+        self::$marker = 0;
+        self::$makerCache->set('marker', self::$marker);
+      }
+    }
+  }
+  /**
+   * Invalidate a set of cached resources that are part of the application 
specification itself.
+   * This includes gadget specs, manifests and message bundles
+   * @param uris of content to invalidate
+   * @param token identifying the calling application
+   */
+  function invalidateApplicationResources(Array $uris, SecurityToken $token) {
+    foreach($uris as $uri) {
+      $request = new RemoteContentRequest($uri);
+      $this->cache->invalidate($request->toHash());
+    }
+  }
+
+  /**
+   * Invalidate all cached resources where the specified user ids were used as 
either the
+   * owner or viewer id when a signed or OAuth request was made for the 
content by the application
+   * identified in the security token.
+   * @param opensocialIds Set of user ids to invalidate authenticated/signed 
content for
+   * @param token identifying the calling application
+   */
+  function invalidateUserResources(Array $opensocialIds, SecurityToken $token) 
{
+    foreach($opensocialIds as $opensocialId) {
+      ++self::$marker;
+      self::$makerCache->set('marker', self::$marker);
+      $this->invalidationEntry->set($this->getKey($opensocialId, $token), 
self::$marker);
+    }
+  }
+
+  /**
+   * Is the specified request still valid. If the request is signed or 
authenticated
+   * has its content been invalidated by a call to invalidateUserResource 
subsequent to the
+   * response being cached.
+   */
+  function isValid(RemoteContentRequest $request) {
+    if ($request->getAuthType() == RemoteContentRequest::$AUTH_NONE) {
+      return true;
+    }
+    return $request->getInvalidation() == $this->getInvalidationMark($request);
+  }
+
+  /**
+   * Mark the request prior to caching it so that subsequent calls to isValid 
can detect
+   * if it has been invalidated.
+   */
+  function markResponse(RemoteContentRequest $request) {
+    $mark = $this->getInvalidationMark($request);
+    if ($mark) {
+      $request->setInvalidation($mark);
+    }
+  }
+  
+  /**
+   * @return string
+   */
+  private function getKey($userId, SecurityToken $token) {
+    $pos = strrpos($userId, ':');
+    if ($pos !== false) {
+      $userId = substr($userId, $pos + 1);
+    }
+    
+    if ($token->getAppId()) {
+      return DefaultInvalidateService::$TOKEN_PREFIX . $token->getAppId() . 
'_' . $userId;
+    }
+  }
+  
+  private function getInvalidationMark(RemoteContentRequest $request) {
+    $token = $request->getToken();
+    if (!$token) {
+      return null;
+    }
+    $currentInvalidation = '';
+    if ($token->getOwnerId()) {
+      $ownerKey = $this->getKey($token->getOwnerId(), $token);
+      $cached = $this->invalidationEntry->expiredGet($ownerKey);
+      $ownerStamp = $cached['found'] ? $cached['data'] : false;
+    }
+    if ($token->getViewerId()) {
+      $viewerKey = $this->getKey($token->getViewerId(), $token);
+      $cached = $this->invalidationEntry->expiredGet($viewerKey);
+      $viewerStamp = $cached['found'] ? $cached['data'] : false;
+    }
+    if ($ownerStamp) {
+      $currentInvalidation = $currentInvalidation . 'o=' . $ownerStamp . ';'; 
+    }
+    if ($viewerStamp) {
+      $currentInvalidation = $currentInvalidation . 'v=' . $viewerStamp . ';'; 
+    }
+    return $currentInvalidation;
+  }
+}

Added: incubator/shindig/trunk/php/src/social/service/InvalidateHandler.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/service/InvalidateHandler.php?rev=757414&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/social/service/InvalidateHandler.php (added)
+++ incubator/shindig/trunk/php/src/social/service/InvalidateHandler.php Mon 
Mar 23 15:26:31 2009
@@ -0,0 +1,81 @@
+<?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.
+ */
+
+class InvalidateHandler extends DataRequestHandler {
+  
+  /**
+   * @var InvalidateService
+   */
+  private $invalidateService;
+  
+  private static $INVALIDATE_PATH = "/invalidate";
+  
+  private static $KEYS_PARAM = "invalidationKeys";
+
+  public function __construct() {
+    $service = Config::get('invalidate_service');
+    $cache = Cache::createCache(Config::get('data_cache'), 'RemoteContent');
+    $this->invalidateService = new $service($cache);
+  }
+
+  public function handleDelete(RequestItem $request) {
+    $this->handleGet($request);
+  }
+
+  public function handlePut(RequestItem $request) {
+    $this->handleGet($request);
+  }
+
+  public function handlePost(RequestItem $request) {
+    $this->handleGet($request);
+  }
+
+  public function handleGet(RequestItem $request) {
+    if (!$request->getToken()->getAppId() && 
!$request->getToken()->getAppUrl()) {
+      throw new SocialSpiException("Can't invalidate content without 
specifying application", ResponseError::$BAD_REQUEST);
+    }
+    
+    $isBackendInvalidation = AuthenticationMode::$OAUTH_CONSUMER_REQUEST == 
$request->getToken()->getAuthenticationMode();
+    $invalidationKeys = $request->getListParameter('invalidationKey');
+    $resources = array();
+    $userIds = array();
+    if ($request->getToken()->getViewerId()) {
+      $userIds[] = $request->getToken()->getViewerId();
+    }
+    foreach($invalidationKeys as $key) {
+      if (strpos($key, 'http') !== false) {
+        if (!$isBackendInvalidation) {
+          throw new SocialSpiException('Cannot flush application resources 
from a gadget. Must use OAuth consumer request'); 
+        }
+        $resources[] = $key;
+      } else {
+        if ($key == '@viewer') {
+          continue;
+        }
+        if (!$isBackendInvalidation) {
+          throw new SocialSpiException('Cannot invalidate the content for a 
user other than the viewer from a gadget.');
+        }
+        $userIds[] = $key;
+      }
+    }
+    $this->invalidateService->invalidateApplicationResources($resources, 
$request->getToken());
+    $this->invalidateService->invalidateUserResources($userIds, 
$request->getToken());
+  }
+}

Modified: incubator/shindig/trunk/php/src/social/service/RequestItem.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/service/RequestItem.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social/service/RequestItem.php (original)
+++ incubator/shindig/trunk/php/src/social/service/RequestItem.php Mon Mar 23 
15:26:31 2009
@@ -50,6 +50,9 @@
   
   public static $APP_SUBSTITUTION_TOKEN = "@app";
   
+  /**
+   * @var SecurityToken
+   */
   protected $token;
   
   protected $operation;
@@ -179,6 +182,9 @@
     return $this->service;
   }
 
+  /**
+   * @return SecurityToken
+   */
   public function getToken() {
     return $this->token;
   }

Modified: incubator/shindig/trunk/php/src/social/service/RestRequestItem.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/service/RestRequestItem.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social/service/RestRequestItem.php 
(original)
+++ incubator/shindig/trunk/php/src/social/service/RestRequestItem.php Mon Mar 
23 15:26:31 2009
@@ -80,12 +80,23 @@
   
   }
 
+  /**
+   * '/people/@me/@self' => 'people'
+   * '/invalidate?invalidationKey=1' => 'invalidate'
+   */
   static function getServiceFromPath($pathInfo) {
     $pathInfo = substr($pathInfo, 1);
     $indexOfNextPathSeparator = strpos($pathInfo, '/');
+    $indexOfNextQuestionMark = strpos($pathInfo, '?');
+    if ($indexOfNextPathSeparator !== false && $indexOfNextQuestionMark !== 
false) {
+      return substr($pathInfo, 0, min($indexOfNextPathSeparator, 
$indexOfNextQuestionMark));
+    }
     if ($indexOfNextPathSeparator !== false) {
       return substr($pathInfo, 0, $indexOfNextPathSeparator);
     }
+    if ($indexOfNextQuestionMark !== false) {
+      return substr($pathInfo, 0, $indexOfNextQuestionMark);
+    }
     return $pathInfo;
   }
 

Modified: incubator/shindig/trunk/php/src/social/servlet/ApiServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/servlet/ApiServlet.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social/servlet/ApiServlet.php (original)
+++ incubator/shindig/trunk/php/src/social/servlet/ApiServlet.php Mon Mar 23 
15:26:31 2009
@@ -63,6 +63,7 @@
   public static $ACTIVITY_ROUTE = "activities";
   public static $APPDATA_ROUTE = "appdata";
   public static $MESSAGE_ROUTE = "messages";
+  public static $INVALIDATE_ROUTE = "invalidate";
 
   public function __construct() {
     parent::__construct();
@@ -71,6 +72,7 @@
     $this->handlers[self::$ACTIVITY_ROUTE] = new ActivityHandler();
     $this->handlers[self::$APPDATA_ROUTE] = new AppDataHandler();
     $this->handlers[self::$MESSAGE_ROUTE] = new MessagesHandler();
+    $this->handlers[self::$INVALIDATE_ROUTE] = new InvalidateHandler();
   }
 
   public function getSecurityToken() {
@@ -86,6 +88,7 @@
       $oauthLookupService = new $oauthLookupService();
       $token = $oauthLookupService->getSecurityToken($request, $appUrl, 
$userId);
       if ($token) {
+        
$token->setAuthenticationMode(AuthenticationMode::$OAUTH_CONSUMER_REQUEST);
         return $token;
       } else {
         return null; // invalid oauth request, or 3rd party doesn't have 
access to this user

Modified: incubator/shindig/trunk/php/src/social/servlet/DataServiceServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/servlet/DataServiceServlet.php?rev=757414&r1=757413&r2=757414&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social/servlet/DataServiceServlet.php 
(original)
+++ incubator/shindig/trunk/php/src/social/servlet/DataServiceServlet.php Mon 
Mar 23 15:26:31 2009
@@ -29,6 +29,7 @@
   public static $ACTIVITY_ROUTE = "activities";
   public static $APPDATA_ROUTE = "appdata";
   public static $MESSAGE_ROUTE = "messages";
+  public static $INVALIDATE_ROUTE = "invalidate";
 
   public function doGet() {
     $this->doPost();

Added: incubator/shindig/trunk/php/src/social/spi/InvalidateService.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social/spi/InvalidateService.php?rev=757414&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/social/spi/InvalidateService.php (added)
+++ incubator/shindig/trunk/php/src/social/spi/InvalidateService.php Mon Mar 23 
15:26:31 2009
@@ -0,0 +1,52 @@
+<?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.
+ */
+
+interface InvalidateService {
+  /**
+   * Invalidate a set of cached resources that are part of the application 
specification itself.
+   * This includes gadget specs, manifests and message bundles
+   * @param uris of content to invalidate
+   * @param token identifying the calling application
+   */
+  function invalidateApplicationResources(Array $uris, SecurityToken $token);
+
+  /**
+   * Invalidate all cached resources where the specified user ids were used as 
either the
+   * owner or viewer id when a signed or OAuth request was made for the 
content by the application
+   * identified in the security token.
+   * @param opensocialIds Set of user ids to invalidate authenticated/signed 
content for
+   * @param token identifying the calling application
+   */
+  function invalidateUserResources(Array $opensocialIds, SecurityToken $token);
+
+  /**
+   * Is the specified request still valid. If the request is signed or 
authenticated
+   * has its content been invalidated by a call to invalidateUserResource 
subsequent to the
+   * response being cached.
+   */
+  function isValid(RemoteContentRequest $request);
+
+  /**
+   * Mark the request prior to caching it so that subsequent calls to isValid 
can detect
+   * if it has been invalidated.
+   */
+  function markResponse(RemoteContentRequest $request);
+}
+

Added: incubator/shindig/trunk/php/test/social/DefaultInvalidateServiceTest.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/test/social/DefaultInvalidateServiceTest.php?rev=757414&view=auto
==============================================================================
--- incubator/shindig/trunk/php/test/social/DefaultInvalidateServiceTest.php 
(added)
+++ incubator/shindig/trunk/php/test/social/DefaultInvalidateServiceTest.php 
Mon Mar 23 15:26:31 2009
@@ -0,0 +1,88 @@
+<?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.
+ */
+
+/**
+ * DefaultInvalidateService test case.
+ */
+class DefaultInvalidateServiceTest extends PHPUnit_Framework_TestCase {
+
+  /**
+   * @var DefaultInvalidateService
+   */
+  private $service;
+  
+  /**
+   * @var Cache
+   */
+  private $cache;
+
+  /**
+   * Prepares the environment before running a test.
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->cache = Cache::createCache('CacheStorageFile', 'TestCache');
+    $this->service = new DefaultInvalidateService($this->cache);
+  }
+
+  /**
+   * Cleans up the environment after running a test.
+   */
+  protected function tearDown() {
+    $this->service = null;
+    $this->cache = null;
+    parent::tearDown();
+  }
+
+  public function testInvalidateApplicationResources() {
+    $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 
'domain', 'appUrl', '1', 'default');
+    $request1 = new RemoteContentRequest('http://url1');
+    $request1->setToken($token);
+    $request2 = new RemoteContentRequest('http://url2');
+    $request2->setToken($token);
+    $this->service->markResponse($request1);
+    $this->service->markResponse($request2);
+    $this->cache->set($request1->toHash(), $request1);
+    $this->cache->set($request2->toHash(), $request2);
+    $this->assertTrue($this->service->isValid($request1));
+    $this->assertTrue($this->service->isValid($request2));
+    $this->assertEquals($request1, $this->cache->get($request1->toHash()));
+    $this->assertEquals($request2, $this->cache->get($request2->toHash()));
+    $resource = array('http://url1', 'http://url2');
+    $this->service->invalidateApplicationResources($resource, $token);
+    $this->assertFalse($this->cache->get($request1->toHash()));
+    $this->assertFalse($this->cache->get($request2->toHash()));
+  }
+  
+  public function testInvalidateUserResources() {
+    $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 
'domain', 'appUrl', '1', 'default');
+    $token->setAuthenticationMode(AuthenticationMode::$OAUTH_CONSUMER_REQUEST);
+    $request = new RemoteContentRequest('http://url');
+    $request->setToken($token);
+    $request->setAuthType(RemoteContentRequest::$AUTH_SIGNED);
+    $this->service->markResponse($request);
+    $opensocialIds = array('owner');
+    $this->service->invalidateUserResources($opensocialIds, $token);
+    $this->assertFalse($this->service->isValid($request));
+    $this->service->markResponse($request);
+    $this->assertTrue($this->service->isValid($request));
+  }
+
+}


Reply via email to