You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by bh...@apache.org on 2011/01/26 10:24:14 UTC
svn commit: r1063653 - in /shindig/trunk: extras/src/main/php/
extras/src/main/php/extras/ php/ php/config/ php/src/gadgets/servlet/
php/test/gadgets/
Author: bhofmann
Date: Wed Jan 26 09:24:14 2011
New Revision: 1063653
URL: http://svn.apache.org/viewvc?rev=1063653&view=rev
Log:
* Refactored PHP GadgetRenderingServlet to allow additional GadgetRenderer
* Added PHP extras package for experimental or not yet specified implementations
* Added GadgetUrlAuthRenderer to allow content type URL redirects to be authorized
* SHINDIG-952: Added further phpdoc comments for
Added:
shindig/trunk/extras/src/main/php/
shindig/trunk/extras/src/main/php/extras/
shindig/trunk/extras/src/main/php/extras/GadgetUrlAuthRenderer.php
shindig/trunk/php/test/gadgets/GadgetRenderingServletTest.php
Modified:
shindig/trunk/php/config/container.php
shindig/trunk/php/index.php
shindig/trunk/php/src/gadgets/servlet/ContentFilesServlet.php
shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php
shindig/trunk/php/src/gadgets/servlet/ResourcesFilesServlet.php
Added: shindig/trunk/extras/src/main/php/extras/GadgetUrlAuthRenderer.php
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/php/extras/GadgetUrlAuthRenderer.php?rev=1063653&view=auto
==============================================================================
--- shindig/trunk/extras/src/main/php/extras/GadgetUrlAuthRenderer.php (added)
+++ shindig/trunk/extras/src/main/php/extras/GadgetUrlAuthRenderer.php Wed Jan 26 09:24:14 2011
@@ -0,0 +1,170 @@
+<?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 GadgetUrlAuthRenderer extends GadgetRenderer {
+
+ /**
+ * Renders an 'URL' type view (where the iframe is redirected to the specified url)
+ * This is more a legacy iGoogle support feature than something that should be actually
+ * used. Proxied content is the socially aware (and higher performance) version of this
+ * See GadgetHrefRenderer for it's implementation.
+ *
+ * @param Gadget $gadget
+ * @param Array $view
+ */
+ public function renderGadget(Gadget $gadget, $view) {
+ $redirURI = $this->getSubstitutedUrl($gadget, $view);
+ header('Location: ' . $redirURI);
+ }
+
+ /**
+ * retrieves url of content tag and substitutes it
+ *
+ * @param Gadget $gadget
+ * @param string $view
+ * @return string
+ */
+ public function getSubstitutedUrl(Gadget $gadget, $view) {
+ // Preserve existing query string parameters.
+ $redirURI = $view['href'];
+ $query = $this->getPrefsQueryString($gadget->gadgetSpec->userPrefs);
+
+ // deal with features
+ $registry = $this->context->getRegistry();
+ // since the URL mode doesn't actually have the gadget XML body, it can't inline
+ // the javascript content anyway - thus could us just ignore the 'forcedJsLibs' part.
+ $sortedFeatures = array();
+ $registry->sortFeatures($gadget->features, $sortedFeatures);
+
+ $query .= $this->appendLibsToQuery($sortedFeatures);
+ $query .= '&lang=' . urlencode(isset($_GET['lang']) ? $_GET['lang'] : 'en');
+ $query .= '&country=' . urlencode(isset($_GET['country']) ? $_GET['country'] : 'US');
+
+ $redirURI = $gadget->substitutions->substituteUri(null, $redirURI);
+ if (strpos($redirURI, '?') !== false) {
+ $redirURI = $redirURI . $query;
+ } elseif (substr($query, 0, 1) == '&') {
+ $redirURI = $redirURI . '?' . substr($query, 1);
+ } else {
+ $redirURI = $redirURI . '?' . $query;
+ }
+
+ $authz = $this->getAuthz($view);
+
+ if ($authz === 'signed') {
+ $gadgetSigner = Config::get('security_token_signer');
+ $gadgetSigner = new $gadgetSigner();
+ $token = $gadget->gadgetContext->extractAndValidateToken($gadgetSigner);
+
+ $signingFetcherFactory = new SigningFetcherFactory(Config::get("private_key_file"));
+
+ $redirURI .= '&xoauth_signature_publickey=' . urlencode($signingFetcherFactory->getKeyName());
+ $redirURI .= '&xoauth_public_key=' . urlencode($signingFetcherFactory->getKeyName());
+
+ if ($this->getSignOwner($view)) {
+ $redirURI .= '&opensocial_owner_id=' . urlencode($token->getOwnerId());
+ }
+ if ($this->getSignViewer($view)) {
+ $redirURI .= '&opensocial_viewer_id=' . urlencode($token->getViewerId());
+ }
+
+ $redirURI .= '&opensocial_app_url=' . urlencode($token->getAppUrl());
+ $redirURI .= '&opensocial_app_id=' . urlencode($token->getAppId());
+ $redirURI .= '&opensocial_instance_id=' . urlencode($token->getModuleId());
+
+ $consumer = new OAuthConsumer(NULL, NULL, NULL);
+ $signatureMethod = new ShindigRsaSha1SignatureMethod($signingFetcherFactory->getPrivateKey(), null);
+ $req_req = OAuthRequest::from_consumer_and_token($consumer, NULL, 'GET', $redirURI);
+ $req_req->sign_request($signatureMethod, $consumer, NULL);
+ $redirURI = $req_req->to_url();
+
+
+ }
+
+ return $redirURI;
+ }
+
+
+ /**
+ * Returns the requested libs (from getjsUrl) with the libs_param_name prepended
+ * ie: in libs=core:caja:etc.js format
+ *
+ * @param string $libs the libraries
+ * @param Gadget $gadget
+ * @return string the libs=... string to append to the redirection url
+ */
+ private function appendLibsToQuery($features) {
+ $ret = "&";
+ $ret .= Config::get('libs_param_name');
+ $ret .= "=";
+ $ret .= str_replace('?', '&', $this->getJsUrl($features));
+ return $ret;
+ }
+
+ /**
+ * Returns the user preferences in &up_<name>=<val> format
+ *
+ * @param array $libs array of features this gadget requires
+ * @param Gadget $gadget
+ * @return string the up_<name>=<val> string to use in the redirection url
+ */
+ private function getPrefsQueryString($prefs) {
+ $ret = '';
+ foreach ($prefs as $pref) {
+ $ret .= '&';
+ $ret .= Config::get('userpref_param_prefix');
+ $ret .= urlencode($pref['name']);
+ $ret .= '=';
+ $ret .= urlencode($pref['value']);
+ }
+ return $ret;
+ }
+
+ /**
+ * Returns the authz attribute of the view, can be 'none', 'signed' or 'oauth'
+ *
+ * @param array $view
+ * @return string authz attribute
+ */
+ private function getAuthz($view) {
+ return ! empty($view['authz']) ? strtolower($view['authz']) : 'none';
+ }
+
+
+ /**
+ * Returns the signOwner attribute of the view (true or false, default is true)
+ *
+ * @param array $view
+ * @return string signOwner attribute
+ */
+ private function getSignOwner($view) {
+ return ! empty($view['signOwner']) && strcasecmp($view['signOwner'], 'false') == 0 ? false : true;
+ }
+
+ /**
+ * Returns the signViewer attribute of the view (true or false, default is true)
+ *
+ * @param array $view
+ * @return string signViewer attribute
+ */
+ private function getSignViewer($view) {
+ return ! empty($view['signViewer']) && strcasecmp($view['signViewer'], 'false') == 0 ? false : true;
+ }
+}
Modified: shindig/trunk/php/config/container.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/config/container.php?rev=1063653&r1=1063652&r2=1063653&view=diff
==============================================================================
--- shindig/trunk/php/config/container.php (original)
+++ shindig/trunk/php/config/container.php Wed Jan 26 09:24:14 2011
@@ -184,6 +184,16 @@ $shindigConfig = array(
'mediaitems' => array('class' => 'InputMediaItemsConverter', 'targetField' => 'mediaItem'),
),
+ // available gadget renderer with the class as key and the needed attributes in the
+ // view's content block to choose this renderer. If constraint's value is a string
+ // the attribute value has to match this string, if it's a boolean the attribute
+ // just has to be available or not available
+ 'gadget_renderer' => array(
+ 'GadgetHtmlRenderer' => array('type' => 'HTML', 'href' => false),
+ 'GadgetHrefRenderer' => array('type' => 'HTML', 'href' => true),
+ 'GadgetUrlRenderer' => array('type' => 'URL'),
+ //'GadgetUrlAuthRenderer' => array('type' => 'URL'),
+ ),
'gadget_class' => 'Gadget',
'gadget_context_class' => 'GadgetContext',
@@ -215,6 +225,8 @@ $shindigConfig = array(
'media_item_service' => 'JsonDbOpensocialService',
// Also scan these directories when looking for <Class>.php files. You can include multiple paths by seperating them with a ,
+ // To enable classes in the extras package you have to add this class path
+ // 'extension_class_paths' => '../extras/src/main/php/extras',
'extension_class_paths' => '',
'userpref_param_prefix' => 'up_',
Modified: shindig/trunk/php/index.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/index.php?rev=1063653&r1=1063652&r2=1063653&view=diff
==============================================================================
--- shindig/trunk/php/index.php (original)
+++ shindig/trunk/php/index.php Wed Jan 26 09:24:14 2011
@@ -56,7 +56,7 @@ if (Config::get('debug')) {
// To load these, we scan our entire directory structure
function __autoload($className) {
$locations = array('src/common', 'src/common/sample', 'src/gadgets', 'src/gadgets/servlet',
- 'src/gadgets/oauth', 'src/gadgets/sample', 'src/social', 'src/social/servlet',
+ 'src/gadgets/oauth', 'src/gadgets/render', 'src/gadgets/sample', 'src/social', 'src/social/servlet',
'src/social/service', 'src/social/opensocial', 'src/social/model', 'src/social/spi',
'src/social/converters', 'src/social/oauth', 'src/social/sample');
$extension_class_paths = Config::get('extension_class_paths');
Modified: shindig/trunk/php/src/gadgets/servlet/ContentFilesServlet.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/servlet/ContentFilesServlet.php?rev=1063653&r1=1063652&r2=1063653&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/servlet/ContentFilesServlet.php (original)
+++ shindig/trunk/php/src/gadgets/servlet/ContentFilesServlet.php Wed Jan 26 09:24:14 2011
@@ -20,6 +20,9 @@
class ContentFilesServlet extends FilesServlet
{
+ /**
+ * @return string
+ */
protected function getPath() {
return Config::get('javascript_path');
}
Modified: shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php?rev=1063653&r1=1063652&r2=1063653&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php (original)
+++ shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php Wed Jan 26 09:24:14 2011
@@ -39,8 +39,15 @@ require_once 'src/gadgets/rewrite/Gadget
require_once 'src/gadgets/rewrite/DomRewriter.php';
class GadgetRenderingServlet extends HttpServlet {
+ /**
+ *
+ * @var GadgetContext
+ */
protected $context;
+ /**
+ * @throws GadgetException
+ */
public function doGet() {
try {
if (empty($_GET['url'])) {
@@ -70,23 +77,58 @@ class GadgetRenderingServlet extends Htt
}
}
+ /**
+ *
+ * @param Gadget $gadget
+ * @throws GadgetException
+ */
protected function renderGadget(Gadget $gadget) {
$view = $gadget->getView($this->context->getView());
- if ($view['type'] == 'URL') {
- require_once "src/gadgets/render/GadgetUrlRenderer.php";
- $gadgetRenderer = new GadgetUrlRenderer($this->context);
- } elseif ($view['type'] == 'HTML' && empty($view['href'])) {
- require_once "src/gadgets/render/GadgetHtmlRenderer.php";
- $gadgetRenderer = new GadgetHtmlRenderer($this->context);
- } elseif (empty($view['type']) || ! empty($view['href'])) {
- require_once "src/gadgets/render/GadgetHrefRenderer.php";
- $gadgetRenderer = new GadgetHrefRenderer($this->context);
- } else {
- throw new GadgetException("Invalid view type");
+ $renderClasses = Config::get('gadget_renderer');
+
+ foreach ($renderClasses as $renderClass => $constraints) {
+ // if current view meets the configurated renderer constraints
+ // render the gadget and stop checking
+ if ($this->checkConstraints($view, $constraints)) {
+ $gadgetRenderer = new $renderClass($this->context);
+ $gadgetRenderer->renderGadget($gadget, $view);
+ return;
+ }
+ }
+
+ throw new GadgetException("Invalid view type");
+ }
+
+ /**
+ * checks if the current view meets the given gadget renderer constraints
+ *
+ * constraint format:
+ *
+ * array(
+ * attributeName => expectedValue or boolean to indicate if the attribute is
+ * required or not
+ * )
+ *
+ * @param array $view
+ * @param array $constraints
+ * @return boolean
+ */
+ public function checkConstraints($view, $constraints) {
+ foreach ($constraints as $attribute => $expected) {
+ if ($expected === false && isset($view[$attribute]) && $view[$attribute]) {
+ return false;
+ } else if ($expected === true && !(isset($view[$attribute]) && $view[$attribute])) {
+ return false;
+ } else if (! is_bool($expected) && $view[$attribute] !== $expected) {
+ return false;
+ }
}
- $gadgetRenderer->renderGadget($gadget, $view);
+ return true;
}
+ /**
+ *
+ */
protected function setCachingHeaders() {
$this->setContentType("text/html; charset=UTF-8");
if ($this->context->getIgnoreCache()) {
@@ -101,6 +143,10 @@ class GadgetRenderingServlet extends Htt
}
}
+ /**
+ *
+ * @param Exception $e
+ */
protected function showError($e) {
header("HTTP/1.0 400 Bad Request", true, 400);
echo "<html><body>";
Modified: shindig/trunk/php/src/gadgets/servlet/ResourcesFilesServlet.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/servlet/ResourcesFilesServlet.php?rev=1063653&r1=1063652&r2=1063653&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/servlet/ResourcesFilesServlet.php (original)
+++ shindig/trunk/php/src/gadgets/servlet/ResourcesFilesServlet.php Wed Jan 26 09:24:14 2011
@@ -20,6 +20,9 @@
class ResourcesFilesServlet extends FilesServlet
{
+ /**
+ * @return string
+ */
protected function getPath() {
return Config::get('resources_path');
}
Added: shindig/trunk/php/test/gadgets/GadgetRenderingServletTest.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/test/gadgets/GadgetRenderingServletTest.php?rev=1063653&view=auto
==============================================================================
--- shindig/trunk/php/test/gadgets/GadgetRenderingServletTest.php (added)
+++ shindig/trunk/php/test/gadgets/GadgetRenderingServletTest.php Wed Jan 26 09:24:14 2011
@@ -0,0 +1,65 @@
+<?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 GadgetRenderingServletTest extends PHPUnit_Framework_TestCase {
+ public function testCheckConstraints() {
+ $servlet = new GadgetRenderingServlet();
+ ob_end_flush();
+
+ $constraints = array('type' => 'HTML', 'href' => false);
+
+ $view = array('type' => 'HTML', 'foo' => 'bar');
+ $this->assertTrue($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'HTML', 'foo' => 'bar', 'href' => '');
+ $this->assertTrue($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'HTML', 'foo' => 'bar', 'href' => 'blub');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'URL', 'foo' => 'bar', 'href' => 'blub');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'URL', 'foo' => 'bar');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+
+ $constraints = array('type' => 'HTML', 'href' => true);
+
+ $view = array('type' => 'HTML', 'foo' => 'bar');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'HTML', 'foo' => 'bar', 'href' => '');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'HTML', 'foo' => 'bar', 'href' => 'blub');
+ $this->assertTrue($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'URL', 'foo' => 'bar', 'href' => 'blub');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'URL', 'foo' => 'bar');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+
+ $constraints = array('type' => 'URL');
+
+ $view = array('type' => 'HTML', 'foo' => 'bar');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'HTML', 'foo' => 'bar', 'href' => '');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'HTML', 'foo' => 'bar', 'href' => 'blub');
+ $this->assertFalse($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'URL', 'foo' => 'bar', 'href' => 'blub');
+ $this->assertTrue($servlet->checkConstraints($view, $constraints));
+ $view = array('type' => 'URL', 'foo' => 'bar');
+ $this->assertTrue($servlet->checkConstraints($view, $constraints));
+ }
+}