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