]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Moved oauth from plugins to core since twitterservices is core and it depends upon...
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 1 Jul 2010 16:42:24 +0000 (16:42 +0000)
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 1 Jul 2010 16:42:24 +0000 (16:42 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@6604 36083f99-b078-4883-b0ff-0f9b5a30f544

43 files changed:
mod/oauth/manifest.xml [new file with mode: 0644]
mod/oauth/start.php [new file with mode: 0644]
mod/oauth/vendors/oauth/LICENSE [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/INSTALL [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/core/init.php [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/core/templates/inc/footer.tpl [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/core/templates/inc/header.tpl [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/core/templates/index.tpl [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/core/templates/logon.tpl [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/core/templates/register.tpl [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/www/hello.php [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/www/index.php [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/www/logon.php [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/www/oauth.php [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/www/register.php [new file with mode: 0644]
mod/oauth/vendors/oauth/example/server/www/services.xrds.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthDiscovery.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthException.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthRequest.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthRequestLogger.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthRequestSigner.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthRequestVerifier.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthRequester.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthServer.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/OAuthStore.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/body/OAuthBodyContentDisposition.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/discovery/xrds_parse.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/discovery/xrds_parse.txt [new file with mode: 0644]
mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/store/OAuthStoreAbstract.class.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/store/OAuthStoreAnyMeta.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/store/OAuthStoreMySQL.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/store/mysql/install.php [new file with mode: 0644]
mod/oauth/vendors/oauth/library/store/mysql/mysql.sql [new file with mode: 0644]
mod/oauth/vendors/oauth/test/discovery/xrds-fireeagle.xrds [new file with mode: 0644]
mod/oauth/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds [new file with mode: 0644]
mod/oauth/vendors/oauth/test/discovery/xrds-magnolia.xrds [new file with mode: 0644]
mod/oauth/vendors/oauth/test/oauth_test.php [new file with mode: 0644]

diff --git a/mod/oauth/manifest.xml b/mod/oauth/manifest.xml
new file mode 100644 (file)
index 0000000..d0668dd
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin_manifest>
+       <field key="name" value="OAuth Libraries" />
+       <field key="author" value="Curverider" />
+       <field key="version" value="1.8" />
+       <field key="description" value="OAuth libraries" />
+       <field key="category" value="service" />
+       <field key="category" value="official" />
+       <field key="website" value="http://www.elgg.org/" />
+       <field key="copyright" value="(C) Curverider 2010" />
+       <field key="licence" value="GNU Public License version 2" />
+       <field key="elgg_version" value="2010040201" />
+       <field key="provides" value="oauth" />
+</plugin_manifest>
diff --git a/mod/oauth/start.php b/mod/oauth/start.php
new file mode 100644 (file)
index 0000000..6ba5c98
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+/**
+ * 
+ */
+
+// require all vendor libraries
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/OAuthDiscovery.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/OAuthRequest.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/OAuthRequester.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/OAuthRequestVerifier.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/OAuthServer.php";
+
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php";
+
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php";
+require_once "{$CONFIG->pluginspath}oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php";
diff --git a/mod/oauth/vendors/oauth/LICENSE b/mod/oauth/vendors/oauth/LICENSE
new file mode 100644 (file)
index 0000000..f64bcd5
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2007-2008 Mediamatic Lab
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/example/server/INSTALL b/mod/oauth/vendors/oauth/example/server/INSTALL
new file mode 100644 (file)
index 0000000..249c85e
--- /dev/null
@@ -0,0 +1,53 @@
+In this example I assume that oauth-php lives in /home/john/src/oauth-php
+
+
+1) Create a virtual host and set the DB_DSN VARIABLE to the DSN of your (mysql) database.
+
+Example
+<VirtualHost *>
+        ServerAdmin admin@localhost
+        ServerName hello.local
+        DocumentRoot /home/john/src/oauth-php/example/server/www
+
+        UseCanonicalName Off
+        ServerSignature On
+
+        SetEnv DB_DSN mysql://foo:bar@localhost/oauth_example_server_db
+
+        <Directory "home/john/src/oauth-php/example/server/www">
+                Options Indexes FollowSymLinks MultiViews
+                AllowOverride None
+                Order allow,deny
+                Allow from all
+
+                <IfModule mod_php5.c>
+                  php_value magic_quotes_gpc                0
+                  php_value register_globals                0
+                  php_value session.auto_start              0
+                </IfModule>
+
+        </Directory>
+</VirtualHost>
+
+
+2) Create the database structure for the server:
+
+# mysql -u foo -p bar -h localhost < /home/john/src/oauth-php/library/store/mysql/mysql.sql
+
+
+
+3) Download and install smarty into the smarty/core/smarty directory:
+
+# cd /home/john/src/oauth-php/example/server/core
+# wget 'http://www.smarty.net/do_download.php?download_file=Smarty-2.6.19.tar.gz'
+# tar zxf Smarty-2.6.19.tar.gz
+# mv Smarty-2.6.19 smarty
+
+
+4) That's it! Point your browser to 
+
+  http://hello.local/
+
+To get started.
+
+Arjan Scherpenisse <arjan@mediamatic.nl>, July 2008
diff --git a/mod/oauth/vendors/oauth/example/server/core/init.php b/mod/oauth/vendors/oauth/example/server/core/init.php
new file mode 100644 (file)
index 0000000..e5bb9de
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+
+/**
+ * oauth-php: Example OAuth server
+ *
+ * Global initialization file for the server, defines some helper
+ * functions, required includes, and starts the session.
+ *
+ * @author Arjan Scherpenisse <arjan@scherpenisse.net>
+ *
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+/*
+ * Simple 'user management'
+ */
+define ('USERNAME', 'sysadmin');
+define ('PASSWORD', 'sysadmin');
+
+
+/*
+ * Always announce XRDS OAuth discovery
+ */
+header('X-XRDS-Location: http://' . $_SERVER['SERVER_NAME'] . '/services.xrds');
+
+
+/*
+ * Initialize the database connection
+ */
+$info = parse_url(getenv('DB_DSN'));
+($GLOBALS['db_conn'] = mysql_connect($info['host'], $info['user'], $info['pass'])) || die(mysql_error());
+mysql_select_db(basename($info['path']), $GLOBALS['db_conn']) || die(mysql_error());
+unset($info);
+
+
+require_once '../../../library/OAuthServer.php';
+
+/*
+ * Initialize OAuth store
+ */
+require_once '../../../library/OAuthStore.php';
+OAuthStore::instance('MySQL', array('conn' => $GLOBALS['db_conn']));
+
+
+/*
+ * Session
+ */
+session_start();
+
+
+/*
+ * Template handling
+ */
+require_once 'smarty/libs/Smarty.class.php';
+function session_smarty()
+{
+       if (!isset($GLOBALS['smarty']))
+       {
+               $GLOBALS['smarty'] = new Smarty;
+               $GLOBALS['smarty']->template_dir = dirname(__FILE__) . '/templates/';
+               $GLOBALS['smarty']->compile_dir = dirname(__FILE__) . '/../cache/templates_c';
+       }
+       
+       return $GLOBALS['smarty'];
+}
+
+function assert_logged_in()
+{
+       if (empty($_SESSION['authorized']))
+       {
+               $uri = $_SERVER['REQUEST_URI'];
+               header('Location: /logon?goto=' . urlencode($uri));
+       }
+}
+
+function assert_request_vars()
+{
+       foreach(func_get_args() as $a)
+       {
+               if (!isset($_REQUEST[$a]))
+               {
+                       header('HTTP/1.1 400 Bad Request');
+                       echo 'Bad request.';
+                       exit;
+               }
+       }
+}
+
+function assert_request_vars_all()
+{
+       foreach($_REQUEST as $row)
+       {
+               foreach(func_get_args() as $a)
+               {
+                       if (!isset($row[$a]))
+                       {
+                               header('HTTP/1.1 400 Bad Request');
+                               echo 'Bad request.';
+                               exit;
+                       }
+               }
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/example/server/core/templates/inc/footer.tpl b/mod/oauth/vendors/oauth/example/server/core/templates/inc/footer.tpl
new file mode 100644 (file)
index 0000000..308b1d0
--- /dev/null
@@ -0,0 +1,2 @@
+</body>
+</html>
diff --git a/mod/oauth/vendors/oauth/example/server/core/templates/inc/header.tpl b/mod/oauth/vendors/oauth/example/server/core/templates/inc/header.tpl
new file mode 100644 (file)
index 0000000..5046f54
--- /dev/null
@@ -0,0 +1,2 @@
+<html>
+    <body>
diff --git a/mod/oauth/vendors/oauth/example/server/core/templates/index.tpl b/mod/oauth/vendors/oauth/example/server/core/templates/index.tpl
new file mode 100644 (file)
index 0000000..7b06553
--- /dev/null
@@ -0,0 +1,13 @@
+{include file='inc/header.tpl'}
+
+<h1>OAuth server</h1>
+Go to:
+
+<ul>
+  <li><a href="/logon">Logon</a></li>
+  <li><a href="/register">Register your consumer</a></li>
+</ul>
+
+Afterwards, make an OAuth test request to <strong>http://{$smarty.server.name}/hello</strong> to test your connection.</p>
+
+{include file='inc/footer.tpl'}
diff --git a/mod/oauth/vendors/oauth/example/server/core/templates/logon.tpl b/mod/oauth/vendors/oauth/example/server/core/templates/logon.tpl
new file mode 100644 (file)
index 0000000..5ccd432
--- /dev/null
@@ -0,0 +1,21 @@
+{include file='inc/header.tpl'}
+
+<h1>Login</h1>
+
+<form method="post">
+    <input type="hidden" name="goto" value="{$smarty.request.goto}" />
+
+    <label for="username">User name</label><br />
+    <input type="text" name="username" id="username" />
+    
+    <br /><br />
+
+    <label for="password">Password</label><br />
+    <input type="text" name="password" id="password" />
+
+    <br /><br />
+    
+    <input type="submit" value="Login" />
+</form>
+
+{include file='inc/footer.tpl'}
diff --git a/mod/oauth/vendors/oauth/example/server/core/templates/register.tpl b/mod/oauth/vendors/oauth/example/server/core/templates/register.tpl
new file mode 100644 (file)
index 0000000..0e28c15
--- /dev/null
@@ -0,0 +1,41 @@
+{include file='inc/header.tpl'}
+
+<h1>Register server</h1>
+
+<p>Register a server which is gonna act as an identity client.</p>
+
+<form method="post">
+
+    <fieldset>
+       <legend>About You</legend>
+       
+       <p>
+           <label for="requester_name">Your name</label><br/>
+           <input class="text" id="requester_name"  name="requester_name" type="text" value="{$consumer.requester_name|default:$smarty.request.requester_name|escape}" />
+       </p>
+       
+       <p>
+           <label for="requester_email">Your email address</label><br/>
+           <input class="text" id="requester_email"  name="requester_email" type="text" value="{$consumer.requester_email|default:$smarty.request.requester_email|escape}" />
+       </p>
+    </fieldset>
+    
+    <fieldset>
+       <legend>Location Of Your Application Or Site</legend>
+       
+       <p>
+           <label for="application_uri">URL of your application or site</label><br/>
+           <input id="application_uri" class="text" name="application_uri" type="text" value="{$consumer.application_uri|default:$smarty.request.application_uri|escape}" />
+       </p>
+       
+       <p>
+           <label for="callback_uri">Callback URL</label><br/>
+           <input id="callback_uri" class="text" name="callback_uri" type="text" value="{$consumer.callback_uri|default:$smarty.request.callback_uri|escape}" />
+       </p>
+    </fieldset>
+
+    <br />
+    <input type="submit" value="Register server" />
+</form>
+
+{include file='inc/footer.tpl'}
diff --git a/mod/oauth/vendors/oauth/example/server/www/hello.php b/mod/oauth/vendors/oauth/example/server/www/hello.php
new file mode 100644 (file)
index 0000000..8cb94bb
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * oauth-php: Example OAuth server
+ *
+ * An example service, http://hostname/hello. You will only get the
+ * 'Hello, world!' string back if you have signed your request with
+ * oauth.
+ *
+ * @author Arjan Scherpenisse <arjan@scherpenisse.net>
+ *
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once '../core/init.php';
+
+$authorized = false;
+$server = new OAuthServer();
+try
+{
+       if ($server->verifyIfSigned())
+       {
+               $authorized = true;
+       }
+}
+catch (OAuthException $e)
+{
+}
+
+if (!$authorized)
+{
+       header('HTTP/1.1 401 Unauthorized');
+       header('Content-Type: text/plain');
+       
+       echo "OAuth Verification Failed: " . $e->getMessage();
+       die;
+}
+
+// From here on we are authenticated with OAuth.
+
+header('Content-type: text/plain');
+echo 'Hello, world!';
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/example/server/www/index.php b/mod/oauth/vendors/oauth/example/server/www/index.php
new file mode 100644 (file)
index 0000000..f5cadbe
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * oauth-php: Example OAuth server
+ *
+ * @author Arjan Scherpenisse <arjan@scherpenisse.net>
+ *
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require '../core/init.php';
+
+$smarty = session_smarty();
+$smarty->display('index.tpl');
+
+?>
diff --git a/mod/oauth/vendors/oauth/example/server/www/logon.php b/mod/oauth/vendors/oauth/example/server/www/logon.php
new file mode 100644 (file)
index 0000000..5c937b7
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * oauth-php: Example OAuth server
+ *
+ * Simple logon for consumer registration at this server.
+ *
+ * @author Arjan Scherpenisse <arjan@scherpenisse.net>
+ *
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once '../core/init.php';
+
+if (isset($_POST['username']) && isset($_POST['password']))
+{
+       if ($_POST['username'] == USERNAME && $_POST['password'] == PASSWORD)
+       {
+               $_SESSION['authorized'] = true;
+               if (!empty($_REQUEST['goto']))
+               {
+                       header('Location: ' . $_REQUEST['goto']);
+                       die;
+               }
+
+               echo "Logon succesfull.";
+               die;
+       }
+}
+
+$smarty = session_smarty();
+$smarty->display('logon.tpl');
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/example/server/www/oauth.php b/mod/oauth/vendors/oauth/example/server/www/oauth.php
new file mode 100644 (file)
index 0000000..e0badcc
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * oauth-php: Example OAuth server
+ *
+ * This file implements the OAuth server endpoints. The most basic
+ * implementation of an OAuth server.
+ *
+ * Call with: /oauth/request_token, /oauth/authorize, /oauth/access_token
+ *
+ * @author Arjan Scherpenisse <arjan@scherpenisse.net>
+ *
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once '../core/init.php';
+
+$server = new OAuthServer();
+
+switch($_SERVER['PATH_INFO'])
+{
+case '/request_token':
+       $server->requestToken();
+       exit;
+
+case '/access_token':
+       $server->accessToken();
+       exit;
+
+case '/authorize':
+       # logon
+
+       assert_logged_in();
+
+       try
+       {
+               $server->authorizeVerify();
+               $server->authorizeFinish(true, 1);
+       }
+       catch (OAuthException $e)
+       {
+               header('HTTP/1.1 400 Bad Request');
+               header('Content-Type: text/plain');
+               
+               echo "Failed OAuth Request: " . $e->getMessage();
+       }
+       exit;
+
+       
+default:
+       header('HTTP/1.1 500 Internal Server Error');
+       header('Content-Type: text/plain');
+       echo "Unknown request";
+}
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/example/server/www/register.php b/mod/oauth/vendors/oauth/example/server/www/register.php
new file mode 100644 (file)
index 0000000..c5785c2
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+require_once '../core/init.php';
+
+assert_logged_in();
+
+if ($_SERVER['REQUEST_METHOD'] == 'POST')
+{
+       try
+       {
+               $store = OAuthStore::instance();
+               $key   = $store->updateConsumer($_POST, 1, true);
+
+               $c = $store->getConsumer($key);
+               echo 'Your consumer key is: <strong>' . $c['consumer_key'] . '</strong><br />';
+               echo 'Your consumer secret is: <strong>' . $c['consumer_secret'] . '</strong><br />';
+       }
+       catch (OAuthException $e)
+       {
+               echo '<strong>Error: ' . $e->getMessage() . '</strong><br />';
+       }
+}
+               
+
+$smarty = session_smarty();
+$smarty->display('register.tpl');
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/example/server/www/services.xrds.php b/mod/oauth/vendors/oauth/example/server/www/services.xrds.php
new file mode 100644 (file)
index 0000000..4c50aa1
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * oauth-php: Example OAuth server
+ *
+ * XRDS discovery for OAuth. This file helps the consumer program to
+ * discover where the OAuth endpoints for this server are.
+ *
+ * @author Arjan Scherpenisse <arjan@scherpenisse.net>
+ *
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+header('Content-Type: application/xrds+xml');
+
+$server = $_SERVER['SERVER_NAME'];
+
+echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
+
+?>
+<XRDS xmlns="xri://$xrds">
+    <XRD xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" xmlns:openid="http://openid.net/xmlns/1.0" version="2.0" xml:id="main">
+       <Type>xri://$xrds*simple</Type>
+       <Service>
+           <Type>http://oauth.net/discovery/1.0</Type>
+           <URI>#main</URI>
+       </Service>
+       <Service>
+           <Type>http://oauth.net/core/1.0/endpoint/request</Type>
+           <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+           <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+           <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+           <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+           <URI>http://<?=$server?>/oauth/request_token</URI>
+       </Service>
+       <Service>
+           <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
+           <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+           <URI>http://<?=$server?>/oauth/authorize</URI>
+       </Service>
+       <Service>
+           <Type>http://oauth.net/core/1.0/endpoint/access</Type>
+           <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+           <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+           <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+           <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+           <URI>http://<?=$server?>/oauth/access_token</URI>
+       </Service>
+    </XRD>
+</XRDS>
diff --git a/mod/oauth/vendors/oauth/library/OAuthDiscovery.php b/mod/oauth/vendors/oauth/library/OAuthDiscovery.php
new file mode 100644 (file)
index 0000000..d097756
--- /dev/null
@@ -0,0 +1,226 @@
+<?php
+
+/**
+ * Handle the discovery of OAuth service provider endpoints and static consumer identity.
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Sep 4, 2008 5:05:19 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__).'/discovery/xrds_parse.php';
+
+require_once dirname(__FILE__).'/OAuthException.php';
+require_once dirname(__FILE__).'/OAuthRequestLogger.php';
+
+
+class OAuthDiscovery
+{
+       /**
+        * Return a description how we can do a consumer allocation.  Prefers static allocation if
+        * possible.  If static allocation is possible
+        * 
+        * See also: http://oauth.net/discovery/#consumer_identity_types
+        * 
+        * @param string uri
+        * @return array                provider description
+        */
+       static function discover ( $uri )
+       {
+               // See what kind of consumer allocations are available
+               $xrds_file = self::discoverXRDS($uri);
+               if (!empty($xrds_file))
+               {
+                       $xrds = xrds_parse($xrds_file);
+                       if (empty($xrds))
+                       {
+                               throw new OAuthException('Could not discover OAuth information for '.$uri);
+                       }
+               }
+               else
+               {
+                       throw new OAuthException('Could not discover XRDS file at '.$uri);
+               }
+
+               // Fill an OAuthServer record for the uri found
+               $ps                     = parse_url($uri);
+               $host           = isset($ps['host']) ? $ps['host'] : 'localhost';
+               $server_uri = $ps['scheme'].'://'.$host.'/';
+
+               $p = array(
+                               'user_id'                       => null,
+                               'consumer_key'          => '',
+                               'consumer_secret'       => '',
+                               'signature_methods'     => '',
+                               'server_uri'            => $server_uri,
+                               'request_token_uri'     => '',
+                               'authorize_uri'         => '',
+                               'access_token_uri'      => ''
+                       );
+
+
+               // Consumer identity (out of bounds or static)
+               if (isset($xrds['consumer_identity']))
+               {
+                       // Try to find a static consumer allocation, we like those :)
+                       foreach ($xrds['consumer_identity'] as $ci)
+                       {
+                               if ($ci['method'] == 'static' && !empty($ci['consumer_key']))
+                               {
+                                       $p['consumer_key']    = $ci['consumer_key'];
+                                       $p['consumer_secret'] = '';
+                               }
+                               else if ($ci['method'] == 'oob' && !empty($ci['uri']))
+                               {
+                                       // TODO: Keep this uri somewhere for the user?
+                                       $p['consumer_oob_uri'] = $ci['uri'];
+                               }
+                       }
+               }
+
+               // The token uris
+               if (isset($xrds['request'][0]['uri']))
+               {
+                       $p['request_token_uri'] = $xrds['request'][0]['uri'];
+                       if (!empty($xrds['request'][0]['signature_method']))
+                       {
+                               $p['signature_methods'] = $xrds['request'][0]['signature_method'];
+                       }
+               }
+               if (isset($xrds['authorize'][0]['uri']))
+               {
+                       $p['authorize_uri'] = $xrds['authorize'][0]['uri'];
+                       if (!empty($xrds['authorize'][0]['signature_method']))
+                       {
+                               $p['signature_methods'] = $xrds['authorize'][0]['signature_method'];
+                       }
+               }
+               if (isset($xrds['access'][0]['uri']))
+               {
+                       $p['access_token_uri'] = $xrds['access'][0]['uri'];
+                       if (!empty($xrds['access'][0]['signature_method']))
+                       {
+                               $p['signature_methods'] = $xrds['access'][0]['signature_method'];
+                       }
+               }
+               return $p;
+       }
+       
+       
+       /**
+        * Discover the XRDS file at the uri.  This is a bit primitive, you should overrule
+        * this function so that the XRDS file can be cached for later referral.
+        * 
+        * @param string uri
+        * @return string               false when no XRDS file found
+        */
+       static protected function discoverXRDS ( $uri, $recur = 0 )
+       {
+               // Bail out when we are following redirects
+               if ($recur > 10)
+               {
+                       return false;
+               }
+               
+               $data = self::curl($uri);
+
+               // Check what we got back, could be:
+               // 1. The XRDS discovery file itself (check content-type)
+               // 2. The X-XRDS-Location header
+               
+               if (is_string($data) && !empty($data))
+               {
+                       list($head,$body) = explode("\r\n\r\n", $data);
+                       $body = trim($body);
+                       $m        = false;
+
+                       // See if we got the XRDS file itself or we have to follow a location header
+                       if (    preg_match('/^Content-Type:\s*application\/xrds+xml/im', $head)
+                               ||      preg_match('/^<\?xml[^>]*\?>\s*<xrds\s/i', $body)
+                               ||      preg_match('/^<xrds\s/i', $body)
+                               )
+                       {
+                               $xrds = $body;
+                       }
+                       else if (       preg_match('/^X-XRDS-Location:\s*(.*)$/im', $head, $m)
+                                       ||      preg_match('/^Location:\s*(.*)$/im', $head, $m))
+                       {
+                               // Recurse to the given location
+                               if ($uri != $m[1])
+                               {
+                                       $xrds = self::discoverXRDS($m[1], $recur+1);
+                               }
+                               else
+                               {
+                                       // Referring to the same uri, bail out
+                                       $xrds = false;
+                               }
+                       }
+                       else
+                       {
+                               // Not an XRDS file an nowhere else to check
+                               $xrds = false;
+                       }
+               }
+               else
+               {
+                       $xrds = false;
+               }
+               return $xrds;
+       }
+       
+       
+       /**
+        * Try to fetch an XRDS file at the given location.  Sends an accept header preferring the xrds file.
+        * 
+        * @param string uri
+        * @return array        (head,body), false on an error
+        */
+       static protected function curl ( $uri )
+       {
+               $ch = curl_init();
+
+               curl_setopt($ch, CURLOPT_HTTPHEADER,     array('Accept: application/xrds+xml, */*;q=0.1'));
+               curl_setopt($ch, CURLOPT_USERAGENT,              'anyMeta/OAuth 1.0 - (OAuth Discovery $LastChangedRevision: 45 $)');
+               curl_setopt($ch, CURLOPT_URL,                    $uri);
+               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+               curl_setopt($ch, CURLOPT_HEADER,                 true);
+
+               $txt = curl_exec($ch);
+               curl_close($ch);
+
+               // Tell the logger what we requested and what we received back
+               $data = "GET $uri";
+               OAuthRequestLogger::setSent($data, "");
+               OAuthRequestLogger::setReceived($txt);
+
+               return $txt;
+       }
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthException.php b/mod/oauth/vendors/oauth/library/OAuthException.php
new file mode 100644 (file)
index 0000000..cadd1d0
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Simple exception wrapper for OAuth
+ * 
+ * @version $Id: OAuthException.php 49 2008-10-01 09:43:19Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 29, 2007 5:33:54 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// TODO: something with the HTTP return code matching to the problem
+
+require_once dirname(__FILE__) . '/OAuthRequestLogger.php';
+
+class OAuthException extends Exception
+{
+       function __construct ( $message )
+       {
+               Exception::__construct($message);
+               OAuthRequestLogger::addNote('OAuthException: '.$message);
+       }
+
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthRequest.php b/mod/oauth/vendors/oauth/library/OAuthRequest.php
new file mode 100644 (file)
index 0000000..c0d6ddb
--- /dev/null
@@ -0,0 +1,801 @@
+<?php
+
+/**
+ * Request wrapper class.  Prepares a request for consumption by the OAuth routines
+ * 
+ * @version $Id: OAuthRequest.php 50 2008-10-01 15:11:08Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 16, 2007 12:20:31 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+require_once dirname(__FILE__) . '/OAuthException.php';
+
+/**
+ * Object to parse an incoming OAuth request or prepare an outgoing OAuth request
+ */
+class OAuthRequest 
+{
+       /* the realm for this request */
+       protected $realm;
+       
+       /* all the parameters, RFC3986 encoded name/value pairs */
+       protected $param = array();
+
+       /* the parsed request uri */
+       protected $uri_parts;
+
+       /* the raw request uri */
+       protected $uri;
+
+       /* the request headers */
+       protected $headers;
+
+       /* the request method */
+       protected $method;
+       
+       /* the body of the OAuth request */
+       protected $body;
+       
+
+       /**
+        * Construct from the current request. Useful for checking the signature of a request.
+        * When not supplied with any parameters this will use the current request.
+        * 
+        * @param string        uri                             might include parameters
+        * @param string        method                  GET, PUT, POST etc.
+        * @param string        parameters              additional post parameters, urlencoded (RFC1738)
+        * @param array         headers                 headers for request
+        * @param string        body                    optional body of the OAuth request (POST or PUT)
+        */
+       function __construct ( $uri = null, $method = 'GET', $parameters = '', $headers = array(), $body = null )
+       {
+               if (empty($uri))
+               {
+                       if (is_object($_SERVER))
+                       {
+                               // Tainted arrays - the normal stuff in anyMeta
+                               $method = $_SERVER->REQUEST_METHOD->getRawUnsafe();
+                               $uri    = $_SERVER->REQUEST_URI->getRawUnsafe();
+                       }
+                       else
+                       {
+                               // non anyMeta systems
+                               $method = $_SERVER['REQUEST_METHOD'];
+                               $uri    = $_SERVER['REQUEST_URI'];
+                       }
+                       $headers      = getallheaders();
+                       $parameters   = '';
+                       $this->method = strtoupper($method);
+                       
+                       // If this is a post then also check the posted variables
+                       if (strcasecmp($method, 'POST') == 0)
+                       {
+                               /*
+                               // TODO: what to do with 'multipart/form-data'?
+                               if ($this->getRequestContentType() == 'multipart/form-data')
+                               {
+                                       throw new OAuthException('Unsupported POST content type, expected "application/x-www-form-urlencoded" got "'.@$_SERVER['CONTENT_TYPE'].'"');
+                               }
+                               */
+                               if ($this->getRequestContentType() == 'application/x-www-form-urlencoded')
+                               {
+                                       // Get the posted body (when available)
+                                       if (!isset($headers['X-OAuth-Test']))
+                                       {
+                                               $parameters .= $this->getRequestBody();
+                                       }
+                               }
+                               else
+                               {
+                                       $body = $this->getRequestBody();
+                               }
+                       }
+                       else if (strcasecmp($method, 'PUT') == 0)
+                       {
+                               $body = $this->getRequestBody();
+                       }
+               }
+
+               $this->method  = strtoupper($method);
+               $this->headers = $headers;
+               // Store the values, prepare for oauth
+               $this->uri     = $uri;
+               $this->body    = $body;
+               $this->parseUri($parameters);
+               $this->parseHeaders();
+               $this->transcodeParams();
+       }
+
+
+       /**
+        * Return the signature base string.
+        * Note that we can't use rawurlencode due to specified use of RFC3986.
+        * 
+        * @return string
+        */
+       function signatureBaseString ()
+       {
+               $sig    = array();
+               $sig[]  = $this->method;
+               $sig[]  = $this->getRequestUrl();
+               $sig[]  = $this->getNormalizedParams();
+               
+               return implode('&', array_map(array($this, 'urlencode'), $sig));
+       }
+       
+       
+       /**
+        * Calculate the signature of the request, using the method in oauth_signature_method.
+        * The signature is returned encoded in the form as used in the url.  So the base64 and
+        * urlencoding has been done.
+        * 
+        * @param string consumer_secret
+        * @param string token_secret
+        * @exception when not all parts available
+        * @return string
+        */
+       function calculateSignature ( $consumer_secret, $token_secret, $token_type = 'access' )
+       {
+               $required = array(
+                                               'oauth_consumer_key',
+                                               'oauth_signature_method',
+                                               'oauth_timestamp',
+                                               'oauth_nonce'
+                                       );
+
+               if ($token_type !== false)
+               {
+                       $required[] = 'oauth_token';
+               }
+
+               foreach ($required as $req)
+               {
+                       if (!isset($this->param[$req]))
+                       {
+                               throw new OAuthException('Can\'t sign request, missing parameter "'.$req.'"');
+                       }
+               }
+
+               $this->checks();
+
+               $base      = $this->signatureBaseString();
+               $signature = $this->calculateDataSignature($base, $consumer_secret, $token_secret, $this->param['oauth_signature_method']);
+               return $signature;
+       }
+
+       
+       /**
+        * Calculate the signature of a string.
+        * Uses the signature method from the current parameters.
+        * 
+        * @param string        data
+        * @param string        consumer_secret
+        * @param string        token_secret
+        * @param string        signature_method
+        * @exception OAuthException thrown when the signature method is unknown 
+        * @return string signature
+        */
+       function calculateDataSignature ( $data, $consumer_secret, $token_secret, $signature_method )
+       {
+               if (is_null($data))
+               {
+                       $data = '';
+               }
+
+               $sig = $this->getSignatureMethod($signature_method);
+               return $sig->signature($this, $data, $consumer_secret, $token_secret);
+       }
+
+
+       /**
+        * Select a signature method from the list of available methods.
+        * We try to check the most secure methods first.
+        * 
+        * @todo Let the signature method tell us how secure it is
+        * @param array methods
+        * @exception OAuthException when we don't support any method in the list
+        * @return string
+        */
+       public function selectSignatureMethod ( $methods )
+       {
+               if (in_array('HMAC-SHA1', $methods))
+               {
+                       $method = 'HMAC-SHA1';
+               }
+               else if (in_array('MD5', $methods))
+               {
+                       $method = 'MD5';
+               }
+               else
+               {
+                       $method = false;
+                       foreach ($methods as $m)
+                       {
+                               $m = strtoupper($m);
+                               $m = preg_replace('/[^A-Z0-9]/', '_', $m);
+                               if (file_exists(dirname(__FILE__).'/signature_method/OAuthSignatureMethod_'.$m.'.php'))
+                               {
+                                       $method = $m;
+                                       break;
+                               }
+                       }
+                       
+                       if (empty($method))
+                       {
+                               throw new OAuthException('None of the signing methods is supported.');
+                       }
+               }
+               return $method;
+       }
+
+       
+       /**
+        * Fetch the signature object used for calculating and checking the signature base string
+        * 
+        * @param string method
+        * @return OAuthSignatureMethod object
+        */
+       function getSignatureMethod ( $method )
+       {
+               $m     = strtoupper($method);
+               $m     = preg_replace('/[^A-Z0-9]/', '_', $m);
+               $class = 'OAuthSignatureMethod_'.$m;
+
+               if (file_exists(dirname(__FILE__).'/signature_method/'.$class.'.php'))
+               {
+                       require_once dirname(__FILE__).'/signature_method/'.$class.'.php';
+                       $sig = new $class();
+               }
+               else
+               {
+                       throw new OAuthException('Unsupported signature method "'.$m.'".');
+               }
+               return $sig;
+       }
+
+
+       /**
+        * Perform some sanity checks.
+        * 
+        * @exception OAuthException thrown when sanity checks failed
+        */
+       function checks ()
+       {
+               if (isset($this->param['oauth_version']))
+               {
+                       $version = $this->urldecode($this->param['oauth_version']);
+                       if ($version != '1.0')
+                       {
+                               throw new OAuthException('Expected OAuth version 1.0, got "'.$this->param['oauth_version'].'"');
+                       }
+               }
+       }
+
+
+       /**
+        * Return the request method
+        * 
+        * @return string
+        */
+       function getMethod ()
+       {
+               return $this->method;
+       }
+
+       /**
+        * Return the complete parameter string for the signature check.
+        * All parameters are correctly urlencoded and sorted on name and value
+        * 
+        * @return string
+        */
+       function getNormalizedParams ()
+       {
+               /*
+               // sort by name, then by value 
+               // (needed when we start allowing multiple values with the same name)
+               $keys   = array_keys($this->param);
+               $values = array_values($this->param);
+               array_multisort($keys, SORT_ASC, $values, SORT_ASC);
+        */
+        $params     = $this->param;
+               $normalized = array();
+
+               ksort($params);
+               foreach ($params as $key => $value)
+               {
+                   // all names and values are already urlencoded, exclude the oauth signature
+                   if ($key != 'oauth_signature')
+                       {
+                               if (is_array($value))
+                               {
+                                       $value_sort = $value;
+                                       sort($value_sort);
+                                       foreach ($value_sort as $v)
+                                       {
+                                               $normalized[] = $key.'='.$v;
+                                       }
+                               }
+                               else
+                               {
+                                       $normalized[] = $key.'='.$value;
+                               }
+                       }
+               }
+               return implode('&', $normalized);
+       }
+
+
+       /**
+        * Return the normalised url for signature checks
+        */
+       function getRequestUrl ()
+       {
+        $url =  $this->uri_parts['scheme'] . '://'
+              . $this->uri_parts['user'] . (!empty($this->uri_parts['pass']) ? ':' : '')
+              . $this->uri_parts['pass'] . (!empty($this->uri_parts['user']) ? '@' : '')
+                         . $this->uri_parts['host'];
+                         
+               if (    $this->uri_parts['port'] 
+                       &&      $this->uri_parts['port'] != $this->defaultPortForScheme($this->uri_parts['scheme']))
+               {
+                       $url .= ':'.$this->uri_parts['port'];
+               }
+               if (!empty($this->uri_parts['path']))
+               {
+                       $url .= $this->uri_parts['path'];
+               }
+               return $url;
+       }
+       
+       
+       /**
+        * Get a parameter, value is always urlencoded
+        * 
+        * @param string        name
+        * @param boolean       urldecode       set to true to decode the value upon return
+        * @return string value         false when not found
+        */
+       function getParam ( $name, $urldecode = false )
+       {
+               if (isset($this->param[$name]))
+               {
+                       $s = $this->param[$name];
+               }
+               else if (isset($this->param[$this->urlencode($name)]))
+               {
+                       $s = $this->param[$this->urlencode($name)];
+               }
+               else
+               {
+                       $s = false;
+               }
+               if (!empty($s) && $urldecode)
+               {
+                       if (is_array($s))
+                       {
+                               $s = array_map(array($this,'urldecode'), $s);
+                       }
+                       else
+                       {
+                               $s = $this->urldecode($s);
+                       }
+               }
+               return $s;
+       }
+
+       /**
+        * Set a parameter
+        * 
+        * @param string        name
+        * @param string        value
+        * @param boolean       encoded set to true when the values are already encoded
+        */
+       function setParam ( $name, $value, $encoded = false )
+       {
+               if (!$encoded)
+               {
+                       $name_encoded = $this->urlencode($name);
+                       if (is_array($value))
+                       {
+                               foreach ($value as $v)
+                               {
+                                       $this->param[$name_encoded][] = $this->urlencode($v);
+                               }
+                       }
+                       else
+                       {
+                               $this->param[$name_encoded] = $this->urlencode($value);
+                       }
+               }
+               else
+               {
+                       $this->param[$name] = $value;
+               }
+       }
+
+
+       /**
+        * Re-encode all parameters so that they are encoded using RFC3986.
+        * Updates the $this->param attribute.
+        */
+       protected function transcodeParams ()
+       {
+               $params      = $this->param;
+               $this->param = array();
+               
+               foreach ($params as $name=>$value)
+               {
+                       if (is_array($value))
+                       {
+                               $this->param[$this->urltranscode($name)] = array_map(array($this,'urltranscode'), $value);
+                       }
+                       else
+                       {
+                               $this->param[$this->urltranscode($name)] = $this->urltranscode($value);
+                       }
+               }
+       }
+
+
+
+       /**
+        * Return the body of the OAuth request.
+        * 
+        * @return string               null when no body
+        */
+       function getBody ()
+       {
+               return $this->body;
+       }
+
+
+       /**
+        * Return the body of the OAuth request.
+        * 
+        * @return string               null when no body
+        */
+       function setBody ( $body )
+       {
+               $this->body = $body;
+       }
+
+
+       /**
+        * Parse the uri into its parts.  Fill in the missing parts.
+        * 
+        * @todo  check for the use of https, right now we default to http
+        * @todo  support for multiple occurences of parameters
+        * @param string $parameters  optional extra parameters (from eg the http post)
+        */
+       protected function parseUri ( $parameters )
+       {
+               $ps = parse_url($this->uri);
+
+               // Get the current/requested method
+               if (empty($ps['scheme']))
+               {
+                       $ps['scheme'] = 'http';
+               }
+               else
+               {
+                       $ps['scheme'] = strtolower($ps['scheme']);
+               }
+
+               // Get the current/requested host
+               if (empty($ps['host']))
+               {
+                       if (isset($_SERVER['HTTP_HOST']))
+                       {
+                               $ps['host'] = $_SERVER['HTTP_HOST'];
+                       }
+                       else
+                       {
+                               $ps['host'] = '';
+                       }
+               }
+               $ps['host'] = mb_strtolower($ps['host']);
+               if (!preg_match('/^[a-z0-9\.\-]+$/', $ps['host']))
+               {
+                       throw new OAuthException('Unsupported characters in host name');
+               }
+
+               // Get the port we are talking on
+               if (empty($ps['port']))
+               {
+                       $ps['port'] = $this->defaultPortForScheme($ps['scheme']);
+               }
+
+               if (empty($ps['user']))
+               {
+                       $ps['user'] = '';
+               }
+               if (empty($ps['pass']))
+               {
+                       $ps['pass'] = '';
+               }
+               if (empty($ps['path']))
+               {
+                       $ps['path'] = '/';
+               }
+               if (empty($ps['query']))
+               {
+                       $ps['query'] = '';
+               }
+               if (empty($ps['fragment']))
+               {
+                       $ps['fragment'] = '';
+               }
+
+               // Now all is complete - parse all parameters
+               foreach (array($ps['query'], $parameters) as $params)
+               {
+                       if (strlen($params) > 0)
+                       {
+                               $params = explode('&', $params);
+                               foreach ($params as $p)
+                               {
+                                       @list($name, $value) = explode('=', $p, 2);
+                                       $this->param[$name]  = $value;
+                               }
+                       }
+               }
+               $this->uri_parts = $ps;
+       }
+
+
+       /**
+        * Return the default port for a scheme
+        * 
+        * @param string scheme
+        * @return int
+        */
+       protected function defaultPortForScheme ( $scheme )
+       {
+               switch ($scheme)
+               {
+               case 'http':    return 80;
+               case 'https':   return 43;
+               default:
+                       throw new OAuthException('Unsupported scheme type, expected http or https, got "'.$scheme.'"');
+                       break;
+               }
+       }
+       
+       
+       /**
+        * Encode a string according to the RFC3986
+        * 
+        * @param string s
+        * @return string
+        */
+       function urlencode ( $s )
+       {
+               if ($s === false)
+               {
+                       return $s;
+               }
+               else
+               {
+                       return str_replace('%7E', '~', rawurlencode($s));
+               }
+       }
+       
+       /**
+        * Decode a string according to RFC3986.
+        * Also correctly decodes RFC1738 urls.
+        * 
+        * @param string s
+        * @return string
+        */
+       function urldecode ( $s )
+       {
+               if ($s === false)
+               {
+                       return $s;
+               }
+               else
+               {
+                       return rawurldecode($s);
+               }
+       }
+
+       /**
+        * urltranscode - make sure that a value is encoded using RFC3986.
+        * We use a basic urldecode() function so that any use of '+' as the
+        * encoding of the space character is correctly handled.
+        * 
+        * @param string s
+        * @return string
+        */
+       function urltranscode ( $s )
+       {
+               if ($s === false)
+               {
+                       return $s;
+               }
+               else
+               {
+                       return $this->urlencode(urldecode($s));
+               }
+       }
+
+
+       /**
+        * Parse the oauth parameters from the request headers
+        * Looks for something like:
+        *
+     * Authorization: OAuth realm="http://photos.example.net/authorize",
+     *           oauth_consumer_key="dpf43f3p2l4k3l03",
+     *           oauth_token="nnch734d00sl2jdk",
+     *           oauth_signature_method="HMAC-SHA1",
+     *           oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",
+     *           oauth_timestamp="1191242096",
+     *           oauth_nonce="kllo9940pd9333jh",
+     *           oauth_version="1.0"
+     */
+       private function parseHeaders ()
+       {
+/*
+               $this->headers['Authorization'] = 'OAuth realm="http://photos.example.net/authorize",
+                oauth_consumer_key="dpf43f3p2l4k3l03",
+                oauth_token="nnch734d00sl2jdk",
+                oauth_signature_method="HMAC-SHA1",
+                oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",
+                oauth_timestamp="1191242096",
+                oauth_nonce="kllo9940pd9333jh",
+                oauth_version="1.0"';
+*/             
+               if (isset($this->headers['Authorization']))
+               {
+                       $auth = trim($this->headers['Authorization']);
+                       if (strncasecmp($auth, 'OAuth', 4) == 0)
+                       {
+                               $vs = explode(',', substr($auth, 6));
+                               foreach ($vs as $v)
+                               {
+                                       if (strpos($v, '='))
+                                       {
+                                               $v = trim($v);
+                                               list($name,$value) = explode('=', $v, 2);
+                                               if (!empty($value) && $value{0} == '"' && substr($value, -1) == '"')
+                                               {
+                                                       $value = substr(substr($value, 1), 0, -1);
+                                               }
+                                               
+                                               if (strcasecmp($name, 'realm') == 0)
+                                               {
+                                                       $this->realm = $value;
+                                               }
+                                               else
+                                               {
+                                                       $this->param[$name] = $value;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+
+       /**
+        * Fetch the content type of the current request
+        * 
+        * @return string
+        */
+       private function getRequestContentType ()
+       {
+               $content_type = 'application/octet-stream';
+               if (!empty($_SERVER) && array_key_exists('CONTENT_TYPE', $_SERVER))
+               {
+                       list($content_type) = explode(';', $_SERVER['CONTENT_TYPE']);
+               }
+               return trim($content_type);
+       }
+
+
+       /**
+        * Get the body of a POST or PUT.
+        * 
+        * Used for fetching the post parameters and to calculate the body signature.
+        * 
+        * @return string               null when no body present (or wrong content type for body)
+        */
+       private function getRequestBody ()
+       {
+               $body = null;
+               if ($this->method == 'POST' || $this->method == 'PUT')
+               {
+                       $body = '';
+                       $fh   = @fopen('php://input', 'r');
+                       if ($fh)
+                       {
+                               while (!feof($fh))
+                               {
+                                       $s = fread($fh, 1024);
+                                       if (is_string($s))
+                                       {
+                                               $body .= $s;
+                                       }
+                               }
+                               fclose($fh);
+                       }
+               }
+               return $body;
+       }
+
+       
+       /**
+        * Simple function to perform a redirect (GET).
+        * Redirects the User-Agent, does not return.
+        * 
+        * @param string uri
+        * @param array params          parameters, urlencoded
+        * @exception OAuthException when redirect uri is illegal
+        */
+       public function redirect ( $uri, $params )
+       {
+               if (!empty($params))
+               {
+                       $q = array();
+                       foreach ($params as $name=>$value)
+                       {
+                               $q[] = $name.'='.$value;
+                       }
+                       $q_s = implode('&', $q);
+                       
+                       if (strpos($uri, '?'))
+                       {
+                               $uri .= '&'.$q_s;
+                       }
+                       else
+                       {
+                               $uri .= '?'.$q_s;
+                       }
+               }
+               
+               // simple security - multiline location headers can inject all kinds of extras
+               $uri = preg_replace('/\s/', '%20', $uri);
+               if (strncasecmp($uri, 'http://', 7) && strncasecmp($uri, 'https://', 8))
+               {
+                       if (strpos($uri, '://'))
+                       {
+                               throw new OAuthException('Illegal protocol in redirect uri '.$uri);
+                       }
+                       $uri = 'http://'.$uri;
+               }
+               
+               header('HTTP/1.1 302 Found');
+               header('Location: '.$uri);
+               echo '';
+               exit();
+       }
+       
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthRequestLogger.php b/mod/oauth/vendors/oauth/library/OAuthRequestLogger.php
new file mode 100644 (file)
index 0000000..5b88e9d
--- /dev/null
@@ -0,0 +1,274 @@
+<?php
+
+/**
+ * Log OAuth requests
+ * 
+ * @version $Id: OAuthRequestLogger.php 55 2009-01-14 15:27:36Z scherpenisse $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Dec 7, 2007 12:22:43 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+class OAuthRequestLogger 
+{
+       static private $logging                 = 0;
+       static private $enable_logging  = null;
+       static private $store_log               = null;
+       static private $note                    = '';
+       static private $user_id                 = null;
+       static private $request_object  = null;
+       static private $sent                    = null;
+       static private $received                = null;
+       static private $log                             = array();
+       
+       /**
+        * Start any logging, checks the system configuration if logging is needed.
+        * 
+        * @param OAuthRequest  $request_object
+        */
+       static function start ( $request_object = null )
+       {
+               if (defined('OAUTH_LOG_REQUEST'))
+               {
+                       if (is_null(OAuthRequestLogger::$enable_logging))
+                       {
+                               OAuthRequestLogger::$enable_logging = true;
+                       }
+                       if (is_null(OAuthRequestLogger::$store_log))
+                       {
+                               OAuthRequestLogger::$store_log = true;
+                       }
+               }
+
+               if (OAuthRequestLogger::$enable_logging && !OAuthRequestLogger::$logging)
+               {
+                       OAuthRequestLogger::$logging        = true;
+                       OAuthRequestLogger::$request_object = $request_object;
+                       ob_start();
+
+                       // Make sure we flush our log entry when we stop the request (eg on an exception)
+                       register_shutdown_function(array('OAuthRequestLogger','flush'));                
+               }
+       }
+       
+
+       /**
+        * Force logging, needed for performing test connects independent from the debugging setting.
+        * 
+        * @param boolean  store_log            (optional) true to store the log in the db
+        */
+       static function enableLogging ( $store_log = null )
+       {
+               OAuthRequestLogger::$enable_logging = true;
+               if (!is_null($store_log))
+               {
+                       OAuthRequestLogger::$store_log = $store_log;
+               }
+       }       
+
+
+       /**
+        * Logs the request to the database, sends any cached output.
+        * Also called on shutdown, to make sure we always log the request being handled.
+        */
+       static function flush ()
+       {
+               if (OAuthRequestLogger::$logging)
+               {
+                       OAuthRequestLogger::$logging = false;
+
+                       if (is_null(OAuthRequestLogger::$sent))
+                       {
+                               // What has been sent to the user-agent?
+                               $data  = ob_get_contents();
+                               if (strlen($data) > 0)
+                               {
+                                       ob_end_flush();
+                               }
+                               elseif (ob_get_level())
+                               {
+                                       ob_end_clean();
+                               }
+                               $hs    = headers_list();
+                               $sent  = implode("\n", $hs) . "\n\n" . $data;
+                       }
+                       else
+                       {
+                               // The request we sent
+                               $sent  = OAuthRequestLogger::$sent;
+                       }
+                       
+                       if (is_null(OAuthRequestLogger::$received))
+                       {
+                               // Build the request we received
+                               $hs0   = getallheaders();
+                               $hs    = array();
+                               foreach ($hs0 as $h => $v)
+                               {
+                                       $hs[] = "$h: $v";
+                               }
+
+                               $data  = '';
+                               $fh    = @fopen('php://input', 'r');
+                               if ($fh)
+                               {
+                                       while (!feof($fh))
+                                       {
+                                               $s = fread($fh, 1024);
+                                               if (is_string($s))
+                                               {
+                                                       $data .= $s;
+                                               }
+                                       }
+                                       fclose($fh);
+                               }
+                               $received = implode("\n", $hs) . "\n\n" . $data;
+                       }
+                       else
+                       {
+                               // The answer we received
+                               $received  = OAuthRequestLogger::$received;
+                       }
+
+                       // The request base string
+                       if (OAuthRequestLogger::$request_object)
+                       {
+                               $base_string = OAuthRequestLogger::$request_object->signatureBaseString();
+                       }
+                       else
+                       {
+                               $base_string = '';
+                       }
+
+                       // Figure out to what keys we want to log this request
+                       $keys = array();
+                       if (OAuthRequestLogger::$request_object)
+                       {
+                               $consumer_key = OAuthRequestLogger::$request_object->getParam('oauth_consumer_key', true);
+                               $token        = OAuthRequestLogger::$request_object->getParam('oauth_token',        true);
+
+                               switch (get_class(OAuthRequestLogger::$request_object))
+                               {
+                               // tokens are access/request tokens by a consumer
+                               case 'OAuthServer':
+                               case 'OAuthRequestVerifier':
+                                       $keys['ocr_consumer_key'] = $consumer_key;
+                                       $keys['oct_token']        = $token;
+                                       break;
+
+                               // tokens are access/request tokens to a server
+                               case 'OAuthRequester':
+                               case 'OAuthRequestSigner':
+                                       $keys['osr_consumer_key'] = $consumer_key;
+                                       $keys['ost_token']        = $token;
+                                       break;
+                               }
+                       }
+                       
+                       // Log the request
+                       if (OAuthRequestLogger::$store_log)
+                       {
+                               $store = elggconnect_get_oauth_store();//OAuthStore::instance();
+                               $store->addLog($keys, $received, $sent, $base_string, OAuthRequestLogger::$note, OAuthRequestLogger::$user_id);
+                       }
+                       
+                       OAuthRequestLogger::$log[] = array(
+                                       'keys'                  => $keys,
+                                       'received'              => $received,
+                                       'sent'                  => $sent,
+                                       'base_string'   => $base_string,
+                                       'note'                  => OAuthRequestLogger::$note
+                                       );
+               }
+       }
+
+
+       /**
+        * Add a note, used by the OAuthException to log all exceptions.
+        * 
+        * @param string note
+        */
+       static function addNote ( $note )
+       {
+               OAuthRequestLogger::$note .= $note . "\n\n";
+       }
+
+       /**
+        * Set the OAuth request object being used
+        * 
+        * @param OAuthRequest request_object
+        */
+       static function setRequestObject ( $request_object )
+       {
+               OAuthRequestLogger::$request_object = $request_object;
+       }
+
+
+       /**
+        * Set the relevant user (defaults to the current user)
+        * 
+        * @param int user_id
+        */
+       static function setUser ( $user_id )
+       {
+               OAuthRequestLogger::$user_id = $user_id;
+       }
+       
+       
+       /**
+        * Set the request we sent
+        * 
+        * @param string request
+        */
+       static function setSent ( $request )
+       {
+               OAuthRequestLogger::$sent = $request;
+       }
+
+       /**
+        * Set the reply we received
+        * 
+        * @param string request
+        */
+       static function setReceived ( $reply )
+       {
+               OAuthRequestLogger::$received = $reply;
+       }
+       
+       
+       /**
+        * Get the the log till now
+        * 
+        * @return array
+        */
+       static function getLog ()
+       {
+               return OAuthRequestLogger::$log;
+       }
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthRequestSigner.php b/mod/oauth/vendors/oauth/library/OAuthRequestSigner.php
new file mode 100644 (file)
index 0000000..a33d140
--- /dev/null
@@ -0,0 +1,209 @@
+<?php
+
+/**
+ * Sign requests before performing the request.
+ * 
+ * @version $Id: OAuthRequestSigner.php 58 2009-02-23 01:47:23Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 16, 2007 4:02:49 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+require_once dirname(__FILE__) . '/OAuthStore.php';
+require_once dirname(__FILE__) . '/OAuthRequest.php';
+
+
+class OAuthRequestSigner extends OAuthRequest
+{
+       protected $request;
+       protected $store;
+       protected $usr_id = 0;
+       private   $signed = false;
+
+       
+       /**
+        * Construct the request to be signed.  Parses or appends the parameters in the params url.
+        * When you supply an params array, then the params should not be urlencoded.
+        * When you supply a string, then it is assumed it is of the type application/x-www-form-urlencoded
+        * 
+        * @param string request        url
+        * @param string method         PUT, GET, POST etc.
+        * @param mixed params          string (for urlencoded data, or array with name/value pairs)
+        * @param string body           optional body for PUT and/or POST requests
+        */
+       function __construct ( $request, $method = 'GET', $params = null, $body = null )
+       {
+               $this->store = elggconnect_get_oauth_store();//OAuthStore::instance();
+               
+               if (is_string($params))
+               {
+                       parent::__construct($request, $method, $params);
+               }
+               else
+               {
+                       parent::__construct($request, $method);
+                       if (is_array($params))
+                       {
+                               foreach ($params as $name => $value)
+                               {
+                                       $this->setParam($name, $value);
+                               }
+                       }
+               }
+               
+               // With put/ post we might have a body (not for application/x-www-form-urlencoded requests)
+               if ($method == 'PUT' || $method == 'POST')
+               {
+                       $this->setBody($body);
+               }
+       }
+
+
+       /**
+        * Reset the 'signed' flag, so that any changes in the parameters force a recalculation
+        * of the signature.
+        */
+       function setUnsigned ()
+       {
+               $this->signed = false;
+       }
+
+
+       /**
+        * Sign our message in the way the server understands.
+        * Set the needed oauth_xxxx parameters.
+        * 
+        * @param int usr_id            (optional) user that wants to sign this request
+        * @param array secrets         secrets used for signing, when empty then secrets will be fetched from the token registry
+        * @param string name           name of the token to be used for signing
+        * @exception OAuthException when there is no oauth relation with the server
+        * @exception OAuthException when we don't support the signing methods of the server
+        */     
+       function sign ( $usr_id = 0, $secrets = null, $name = '' )
+       {
+               $url = $this->getRequestUrl();
+               if (empty($secrets))
+               {
+                       // get the access tokens for the site (on an user by user basis)
+                       $secrets = $this->store->getSecretsForSignature($url, $usr_id, $name);
+               }
+               if (empty($secrets))
+               {
+                       throw new OAuthException('No OAuth relation with the server for at "'.$url.'"');
+               }
+
+               $signature_method = $this->selectSignatureMethod($secrets['signature_methods']);
+
+               $token            = isset($secrets['token'])        ? $secrets['token']        : '';
+               $token_secret = isset($secrets['token_secret']) ? $secrets['token_secret'] : '';
+
+               $this->setParam('oauth_signature_method',$signature_method);
+               $this->setParam('oauth_signature',               '');
+               $this->setParam('oauth_nonce',                   !empty($secrets['nonce'])     ? $secrets['nonce']     : uniqid(''));
+               $this->setParam('oauth_timestamp',               !empty($secrets['timestamp']) ? $secrets['timestamp'] : time());
+               $this->setParam('oauth_token',                   $token);
+               $this->setParam('oauth_consumer_key',    $secrets['consumer_key']);
+               $this->setParam('oauth_version',                 '1.0');
+               
+               $body = $this->getBody();
+               if (!is_null($body))
+               {
+                       // We also need to sign the body, use the default signature method
+                       $body_signature = $this->calculateDataSignature($body, $secrets['consumer_secret'], $token_secret, $signature_method);
+                       $this->setParam('xoauth_body_signature', $body_signature, true);
+               }
+               
+               $signature = $this->calculateSignature($secrets['consumer_secret'], $token_secret);
+               $this->setParam('oauth_signature',               $signature, true);
+               
+               $this->signed = true;
+               $this->usr_id = $usr_id;
+       }
+
+
+       /**
+        * Builds the Authorization header for the request.
+        * Adds all oauth_ and xoauth_ parameters to the Authorization header.
+        * 
+        * @return string
+        */
+       function getAuthorizationHeader ()
+       {
+               if (!$this->signed)
+               {
+                       $this->sign($this->usr_id);
+               }
+               $h   = array();
+               $h[] = 'Authorization: OAuth realm=""';
+               foreach ($this->param as $name => $value)
+               {
+                       if (strncmp($name, 'oauth_', 6) == 0 || strncmp($name, 'xoauth_', 7) == 0)
+               {
+                               $h[] = $name.'="'.$value.'"';
+                       }
+               }
+               $hs = implode(', ', $h);
+               return $hs;
+       }
+
+
+       /**
+        * Builds the application/x-www-form-urlencoded parameter string.  Can be appended as
+        * the query part to a GET or inside the request body for a POST.
+        * 
+        * @param boolean oauth_as_header               (optional) set to false to include oauth parameters
+        * @return string
+        */     
+       function getQueryString ( $oauth_as_header = true )
+       {
+               $parms = array();
+               foreach ($this->param as $name => $value)
+               {
+                       if (    !$oauth_as_header 
+                               ||      (strncmp($name, 'oauth_', 6) != 0 && strncmp($name, 'xoauth_', 7) != 0))
+                       {
+                               if (is_array($value))
+                               {
+                                       foreach ($value as $v)
+                                       {
+                                               $parms[] = $name.'='.$v;
+                                       }
+                               }
+                               else
+                               {
+                                       $parms[] = $name.'='.$value;
+                               }
+                       }
+               }
+               return implode('&', $parms);
+       }
+
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthRequestVerifier.php b/mod/oauth/vendors/oauth/library/OAuthRequestVerifier.php
new file mode 100644 (file)
index 0000000..5b346b3
--- /dev/null
@@ -0,0 +1,262 @@
+<?php
+
+/**
+ * Verify the current request.  Checks if signed and if the signature is correct.
+ * When correct then also figures out on behalf of which user this request is being made.
+ *  
+ * @version $Id: OAuthRequestVerifier.php 51 2008-10-15 15:15:47Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 16, 2007 4:35:03 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__) . '/OAuthStore.php';
+require_once dirname(__FILE__) . '/OAuthRequest.php';
+
+
+class OAuthRequestVerifier extends OAuthRequest
+{
+       private $request;
+       private $store;
+       
+       /**
+        * Construct the request to be verified
+        * 
+        * @param string request
+        * @param string method
+        */
+       function __construct ( $uri = null, $method = 'GET' )
+       {
+               $this->store = elggconnect_get_oauth_store();//OAuthStore::instance();
+               parent::__construct($uri, $method);
+               
+               OAuthRequestLogger::start($this);
+       }
+       
+       
+       /**
+        * See if the current request is signed with OAuth
+        * 
+        * @return boolean
+        */
+       static public function requestIsSigned ()
+       {
+               if (isset($_REQUEST['oauth_signature']))
+               {
+                       $signed = true;
+               }
+               else
+               {
+                       $hs = getallheaders();
+                       if (isset($hs['Authorization']) && strpos($hs['Authorization'], 'oauth_signature') !== false)
+                       {
+                               $signed = true;
+                       }
+                       else
+                       {
+                               $signed = false;
+                       }
+               }
+               return $signed;
+       }
+
+
+       /**
+        * Verify the request if it seemed to be signed.
+        * 
+        * @param string token_type the kind of token needed, defaults to 'access'
+        * @exception OAuthException thrown when the request did not verify
+        * @return boolean      true when signed, false when not signed
+        */
+       public function verifyIfSigned ( $token_type = 'access' )
+       {
+               if ($this->getParam('oauth_consumer_key'))
+               {
+                       OAuthRequestLogger::start($this);
+                       $this->verify($token_type);
+                       $signed = true;
+                       OAuthRequestLogger::flush();
+               }
+               else
+               {
+                       $signed = false;
+               }
+               return $signed;
+       }
+
+       
+       /**
+        * Verify the request
+        * 
+        * @param string token_type the kind of token needed, defaults to 'access' (false, 'access', 'request')
+        * @exception OAuthException thrown when the request did not verify
+        * @return int user_id associated with token (false when no user associated)
+        */
+       public function verify ( $token_type = 'access' )
+       {
+               $consumer_key = $this->getParam('oauth_consumer_key');
+               $token        = $this->getParam('oauth_token');
+               $user_id      = false;
+
+               if ($consumer_key && ($token_type === false || $token))
+               {
+                       $secrets = $this->store->getSecretsForVerify(   $this->urldecode($consumer_key), 
+                                                                                                                       $this->urldecode($token), 
+                                                                                                                       $token_type);
+
+                       $this->store->checkServerNonce( $this->urldecode($consumer_key),
+                                                                                       $this->urldecode($token),
+                                                                                       $this->getParam('oauth_timestamp', true),
+                                                                                       $this->getParam('oauth_nonce', true));
+
+                       $oauth_sig = $this->getParam('oauth_signature');
+                       if (empty($oauth_sig))
+                       {
+                               throw new OAuthException('Verification of signature failed (no oauth_signature in request).');
+                       } 
+                       
+                       try
+                       {
+                               $this->verifySignature($secrets['consumer_secret'], $secrets['token_secret'], $token_type);
+                       }
+                       catch (OAuthException $e)
+                       {
+                               throw new OAuthException('Verification of signature failed (signature base string was "'.$this->signatureBaseString().'").');
+                       }
+                       
+                       // Check the optional body signature
+                       if ($this->getParam('xoauth_body_signature'))
+                       {
+                               $method = $this->getParam('xoauth_body_signature_method');
+                               if (empty($method))
+                               {
+                                       $method = $this->getParam('oauth_signature_method');
+                               }
+
+                               try
+                               {
+                                       $this->verifyDataSignature($this->getBody(), $secrets['consumer_secret'], $secrets['token_secret'], $method, $this->getParam('xoauth_body_signature'));
+                               }
+                               catch (OAuthException $e)
+                               {
+                                       throw new OAuthException('Verification of body signature failed.');
+                               }
+                       }
+                       
+                       // All ok - fetch the user associated with this request
+                       if (isset($secrets['user_id']))
+                       {
+                               $user_id = $secrets['user_id'];
+                       }
+                       
+                       // Check if the consumer wants us to reset the ttl of this token
+                       $ttl = $this->getParam('xoauth_token_ttl', true);
+                       if (is_numeric($ttl))
+                       {
+                               $this->store->setConsumerAccessTokenTtl($this->urldecode($token), $ttl);
+                       }
+               }
+               else
+               {
+                       throw new OAuthException('Can\'t verify request, missing oauth_consumer_key or oauth_token');
+               }
+               return $user_id;
+       }
+
+
+
+       /**
+        * Verify the signature of the request, using the method in oauth_signature_method.
+        * The signature is returned encoded in the form as used in the url.  So the base64 and
+        * urlencoding has been done.
+        * 
+        * @param string consumer_secret
+        * @param string token_secret
+        * @exception OAuthException thrown when the signature method is unknown 
+        * @exception OAuthException when not all parts available
+        * @exception OAuthException when signature does not match
+        */
+       public function verifySignature ( $consumer_secret, $token_secret, $token_type = 'access' )
+       {
+               $required = array(
+                                               'oauth_consumer_key',
+                                               'oauth_signature_method',
+                                               'oauth_timestamp',
+                                               'oauth_nonce',
+                                               'oauth_signature'
+                                       );
+
+               if ($token_type !== false)
+               {
+                       $required[] = 'oauth_token';
+               }
+
+               foreach ($required as $req)
+               {
+                       if (!isset($this->param[$req]))
+                       {
+                               throw new OAuthException('Can\'t verify request signature, missing parameter "'.$req.'"');
+                       }
+               }
+
+               $this->checks();
+
+               $base = $this->signatureBaseString();
+               $this->verifyDataSignature($base, $consumer_secret, $token_secret, $this->param['oauth_signature_method'], $this->param['oauth_signature']);
+       }
+
+
+
+       /**
+        * Verify the signature of a string.
+        * 
+        * @param string        data
+        * @param string        consumer_secret
+        * @param string        token_secret
+        * @param string        signature_method
+        * @param string        signature
+        * @exception OAuthException thrown when the signature method is unknown 
+        * @exception OAuthException when signature does not match
+        */
+       public function verifyDataSignature ( $data, $consumer_secret, $token_secret, $signature_method, $signature )
+       {
+               if (is_null($data))
+               {
+                       $data = '';
+               }
+
+               $sig = $this->getSignatureMethod($signature_method);
+               if (!$sig->verify($this, $data, $consumer_secret, $token_secret, $signature))
+               {
+                       throw new OAuthException('Signature verification failed ('.$signature_method.')');
+               }
+       }
+
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthRequester.php b/mod/oauth/vendors/oauth/library/OAuthRequester.php
new file mode 100644 (file)
index 0000000..c6f5617
--- /dev/null
@@ -0,0 +1,508 @@
+<?php
+
+/**
+ * Perform a signed OAuth request with a GET, POST, PUT or DELETE operation.
+ * 
+ * @version $Id: OAuthRequester.php 63 2009-02-25 10:24:33Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 20, 2007 1:41:38 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__) . '/OAuthRequestSigner.php';
+require_once dirname(__FILE__) . '/body/OAuthBodyContentDisposition.php';
+
+
+class OAuthRequester extends OAuthRequestSigner
+{
+       protected $files;
+
+       /**
+        * Construct a new request signer.  Perform the request with the doRequest() method below.
+        * 
+        * A request can have either one file or a body, not both. 
+        * 
+        * The files array consists of arrays:
+        * - file                       the filename/path containing the data for the POST/PUT
+        * - data                       data for the file, omit when you have a file
+        * - mime                       content-type of the file
+        * - filename           filename for content disposition header
+        * 
+        * When OAuth (and PHP) can support multipart/form-data then we can handle more than one file.
+        * For now max one file, with all the params encoded in the query string.
+        * 
+        * @param string request
+        * @param string method         http method.  GET, PUT, POST etc.
+        * @param array params          name=>value array with request parameters
+        * @param string body           optional body to send
+        * @param array files           optional files to send (max 1 till OAuth support multipart/form-data posts)
+        */
+       function __construct ( $request, $method = 'GET', $params = null, $body = null, $files = null )
+       {
+               parent::__construct($request, $method, $params, $body);
+
+               // When there are files, then we can construct a POST with a single file
+               if (!empty($files))
+               {
+                       $empty = true;
+                       foreach ($files as $f)
+                       {
+                               $empty = $empty && empty($f['file']) && !isset($f['data']);
+                       }
+                       
+                       if (!$empty)
+                       {
+                               if (!is_null($body))
+                               {
+                                       throw new OAuthException('When sending files, you can\'t send a body as well.');
+                               }
+                               $this->files = $files;
+                       }
+               }
+       }
+
+
+       /**
+        * Perform the request, returns the response code, headers and body.
+        * 
+        * @param int usr_id                    optional user id for which we make the request
+        * @param array curl_options    optional extra options for curl request
+        * @param array options                 options like name and token_ttl
+        * @exception OAuthException when authentication not accepted
+        * @exception OAuthException when signing was not possible
+        * @return array (code=>int, headers=>array(), body=>string)
+        */
+       function doRequest ( $usr_id = 0, $curl_options = array(), $options = array() )
+       {
+               $name = isset($options['name']) ? $options['name'] : '';
+               if (isset($options['token_ttl']))
+               {
+                       $this->setParam('xoauth_token_ttl', intval($options['token_ttl']));
+               }
+
+               if (!empty($this->files))
+               {
+                       // At the moment OAuth does not support multipart/form-data, so try to encode
+                       // the supplied file (or data) as the request body and add a content-disposition header.
+                       list($extra_headers, $body) = OAuthBodyContentDisposition::encodeBody($this->files);
+                       $this->setBody($body);
+                       $curl_options = $this->prepareCurlOptions($curl_options, $extra_headers);
+               }
+               $this->sign($usr_id, null, $name);
+               $text   = $this->curl_raw($curl_options);
+               $result = $this->curl_parse($text);     
+               if ($result['code'] >= 400)
+               {
+                       throw new OAuthException('Request failed with code ' . $result['code'] . ': ' . $result['body']);
+               }
+
+               // Record the token time to live for this server access token, immediate delete iff ttl <= 0
+               // Only done on a succesful request.    
+               $token_ttl = $this->getParam('xoauth_token_ttl', false);
+               if (is_numeric($token_ttl))
+               {
+                       $this->store->setServerTokenTtl($this->getParam('oauth_consumer_key',true), $this->getParam('oauth_token',true), $token_ttl);
+               }
+
+               return $result;
+       }
+
+       
+       /**
+        * Request a request token from the site belonging to consumer_key
+        * 
+        * @param string consumer_key
+        * @param int usr_id
+        * @param array params (optional) extra arguments for when requesting the request token
+        * @param string method (optional) change the method of the request, defaults to POST (as it should be)
+        * @param array options (optional) options like name and token_ttl
+        * @exception OAuthException when no key could be fetched
+        * @exception OAuthException when no server with consumer_key registered
+        * @return array (authorize_uri, token)
+        */
+       static function requestRequestToken ( $consumer_key, $usr_id, $params = null, $method = 'POST', $options = array() )
+       {
+               OAuthRequestLogger::start();
+
+               if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
+               {
+                       $params['xoauth_token_ttl'] = intval($options['token_ttl']);
+               }
+
+               $store  = elggconnect_get_oauth_store();//OAuthStore::instance();
+               $r              = $store->getServer($consumer_key, $usr_id);
+               $uri    = $r['request_token_uri'];
+
+               $oauth  = new OAuthRequester($uri, $method, $params);
+               $oauth->sign($usr_id, $r);
+               $text   = $oauth->curl_raw();
+
+               if (empty($text))
+               {
+                       throw new OAuthException('No answer from the server "'.$uri.'" while requesting a request token');
+               }
+               $data   = $oauth->curl_parse($text);
+               if ($data['code'] != 200)
+               {
+                       throw new OAuthException('Unexpected result from the server "'.$uri.'" ('.$data['code'].') while requesting a request token');
+               }
+               $token  = array();
+               $params = explode('&', $data['body']);
+               foreach ($params as $p)
+               {
+                       @list($name, $value) = explode('=', $p, 2);
+                       $token[$name] = $oauth->urldecode($value);
+               }
+               
+               if (!empty($token['oauth_token']) && !empty($token['oauth_token_secret']))
+               {
+                       $opts = array();
+                       if (isset($options['name']))
+                       {
+                               $opts['name'] = $options['name'];
+                       }
+                       if (isset($token['xoauth_token_ttl']))
+                       {
+                               $opts['token_ttl'] = $token['xoauth_token_ttl'];
+                       }
+                       $store->addServerToken($consumer_key, 'request', $token['oauth_token'], $token['oauth_token_secret'], $usr_id, $opts);
+               }
+               else
+               {
+                       throw new OAuthException('The server "'.$uri.'" did not return the oauth_token or the oauth_token_secret');
+               }
+
+               OAuthRequestLogger::flush();
+
+               // Now we can direct a browser to the authorize_uri
+               return array(
+                                       'authorize_uri' => $r['authorize_uri'],
+                                       'token'                 => $token['oauth_token']
+                               );
+       }
+
+
+       /**
+        * Request an access token from the site belonging to consumer_key.
+        * Before this we got an request token, now we want to exchange it for
+        * an access token.
+        * 
+        * @param string consumer_key
+        * @param string token
+        * @param int usr_id            user requesting the access token
+        * @param string method (optional) change the method of the request, defaults to POST (as it should be)
+        * @param array options (optional) extra options for request, eg token_ttl
+        * @exception OAuthException when no key could be fetched
+        * @exception OAuthException when no server with consumer_key registered
+        */
+       static function requestAccessToken ( $consumer_key, $token, $usr_id, $method = 'POST', $options = array() )
+       {
+               OAuthRequestLogger::start();
+
+               $store      = elggconnect_get_oauth_store();//OAuthStore::instance();
+               $r                  = $store->getServerTokenSecrets($consumer_key, $token, 'request', $usr_id);
+               $uri        = $r['access_token_uri'];
+               $token_name     = $r['token_name'];
+
+               // Delete the server request token, this one was for one use only
+               $store->deleteServerToken($consumer_key, $r['token'], 0, true);
+
+               // Try to exchange our request token for an access token
+               $oauth  = new OAuthRequester($uri, $method);
+
+               if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
+               {
+                       $oauth->setParam('xoauth_token_ttl', intval($options['token_ttl']));
+               }
+
+               OAuthRequestLogger::setRequestObject($oauth);
+
+               $oauth->sign($usr_id, $r);
+               $text   = $oauth->curl_raw();
+               if (empty($text))
+               {
+                       throw new OAuthException('No answer from the server "'.$uri.'" while requesting a request token');
+               }
+               $data   = $oauth->curl_parse($text);
+
+               if ($data['code'] != 200)
+               {
+                       throw new OAuthException('Unexpected result from the server "'.$uri.'" ('.$data['code'].') while requesting a request token');
+               }
+
+               $token  = array();
+               $params = explode('&', $data['body']);
+               foreach ($params as $p)
+               {
+                       @list($name, $value) = explode('=', $p, 2);
+                       $token[$oauth->urldecode($name)] = $oauth->urldecode($value);
+               }
+               
+               if (!empty($token['oauth_token']) && !empty($token['oauth_token_secret']))
+               {
+                       $opts         = array();
+                       $opts['name'] = $token_name;
+                       if (isset($token['xoauth_token_ttl']))
+                       {
+                               $opts['token_ttl'] = $token['xoauth_token_ttl'];
+                       }
+                       $store->addServerToken($consumer_key, 'access', $token['oauth_token'], $token['oauth_token_secret'], $usr_id, $opts);
+               }
+               else
+               {
+                       throw new OAuthException('The server "'.$uri.'" did not return the oauth_token or the oauth_token_secret');
+               }
+
+               OAuthRequestLogger::flush();
+       }
+
+
+
+       /**
+        * Open and close a curl session passing all the options to the curl libs
+        * 
+        * @param string url the http address to fetch
+        * @exception OAuthException when temporary file for PUT operation could not be created
+        * @return string the result of the curl action
+        */
+       protected function curl_raw ( $opts = array() )
+       {
+               if (isset($opts[CURLOPT_HTTPHEADER]))
+               {
+                       $header = $opts[CURLOPT_HTTPHEADER];
+               }
+               else
+               {
+                       $header = array();
+               }
+
+               $ch             = curl_init();
+               $method         = $this->getMethod();
+               $url            = $this->getRequestUrl();
+               $header[]       = $this->getAuthorizationHeader();
+               $query          = $this->getQueryString();
+               $body           = $this->getBody();
+
+               $has_content_type = false;
+               foreach ($header as $h)
+               {
+                       if (strncasecmp($h, 'Content-Type:', 13) == 0)
+                       {
+                               $has_content_type = true;
+                       }
+               }
+               
+               if (!is_null($body))
+               {
+                       if ($method == 'TRACE')
+                       {
+                               throw new OAuthException('A body can not be sent with a TRACE operation');
+                       }
+
+                       // PUT and POST allow a request body
+                       if (!empty($query))
+                       {
+                               $url .= '?'.$query;
+                       }
+
+                       // Make sure that the content type of the request is ok
+                       if (!$has_content_type)
+                       {
+                               $header[]         = 'Content-Type: application/octet-stream';
+                               $has_content_type = true;
+                       }
+                       
+                       // When PUTting, we need to use an intermediate file (because of the curl implementation)
+                       if ($method == 'PUT')
+                       {
+                               /*
+                               if (version_compare(phpversion(), '5.2.0') >= 0)
+                               {
+                                       // Use the data wrapper to create the file expected by the put method
+                                       $put_file = fopen('data://application/octet-stream;base64,'.base64_encode($body));
+                               }
+                               */
+                               
+                               $put_file = @tmpfile();
+                               if (!$put_file)
+                               {
+                                       throw new OAuthException('Could not create tmpfile for PUT operation');
+                               }
+                               fwrite($put_file, $body);
+                               fseek($put_file, 0);
+
+                               curl_setopt($ch, CURLOPT_PUT,             true);
+                               curl_setopt($ch, CURLOPT_INFILE,          $put_file);
+                               curl_setopt($ch, CURLOPT_INFILESIZE,  strlen($body));
+                       }
+                       else
+                       {
+                               curl_setopt($ch, CURLOPT_POST,            true);
+                               curl_setopt($ch, CURLOPT_POSTFIELDS,  $body);
+                       }
+               }
+               else
+               {
+                       // a 'normal' request, no body to be send
+                       if ($method == 'POST')
+                       {
+                               if (!$has_content_type)
+                               {
+                                       $header[]         = 'Content-Type: application/x-www-form-urlencoded';
+                                       $has_content_type = true;
+                               }
+
+                               curl_setopt($ch, CURLOPT_POST,            true);
+                               curl_setopt($ch, CURLOPT_POSTFIELDS,  $query);
+                       }
+                       else
+                       {
+                               if (!empty($query))
+                               {
+                                       $url .= '?'.$query;
+                               }
+                               if ($method != 'GET')
+                               {
+                                       curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+                               }
+                       }
+               }
+
+               curl_setopt($ch, CURLOPT_HTTPHEADER,     $header);
+               curl_setopt($ch, CURLOPT_USERAGENT,              'anyMeta/OAuth 1.0 - ($LastChangedRevision: 63 $)');
+               curl_setopt($ch, CURLOPT_URL,                    $url);
+               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+               curl_setopt($ch, CURLOPT_HEADER,                 true);
+       
+               foreach ($opts as $k => $v)
+               {
+                       if ($k != CURLOPT_HTTPHEADER)
+                       {
+                               curl_setopt($ch, $k, $v);
+                       }
+               }
+
+               $txt = curl_exec($ch);
+               curl_close($ch);
+               
+               if (!empty($put_file))
+               {
+                       fclose($put_file);
+               }
+
+               // Tell the logger what we requested and what we received back
+               $data = $method . " $url\n".implode("\n",$header);
+               if (is_string($body))
+               {
+                       $data .= "\n\n".$body;
+               }
+               else if ($method == 'POST')
+               {
+                       $data .= "\n\n".$query;
+               }
+
+               OAuthRequestLogger::setSent($data, $body);
+               OAuthRequestLogger::setReceived($txt);
+
+               return $txt;
+       }
+       
+       
+       /**
+        * Parse an http response
+        * 
+        * @param string response the http text to parse
+        * @return array (code=>http-code, headers=>http-headers, body=>body)
+        */
+       protected function curl_parse ( $response )
+       {
+               if (empty($response))
+               {
+                       return array();
+               }
+       
+               @list($headers,$body) = explode("\r\n\r\n",$response,2);
+               $lines = explode("\r\n",$headers);
+
+               if (preg_match('@^HTTP/[0-9]\.[0-9] +100@', $lines[0]))
+               {
+                       /* HTTP/1.x 100 Continue
+                        * the real data is on the next line
+                        */
+                       @list($headers,$body) = explode("\r\n\r\n",$body,2);
+                       $lines = explode("\r\n",$headers);
+               }
+       
+               // first line of headers is the HTTP response code 
+               $http_line = array_shift($lines);
+               if (preg_match('@^HTTP/[0-9]\.[0-9] +([0-9]{3})@', $http_line, $matches))
+               {
+                       $code = $matches[1];
+               }
+       
+               // put the rest of the headers in an array
+               $headers = array();
+               foreach ($lines as $l)
+               {
+                       list($k, $v) = explode(': ', $l, 2);
+                       $headers[strtolower($k)] = $v;
+               }
+       
+               return array( 'code' => $code, 'headers' => $headers, 'body' => $body);
+       }
+
+
+       /**
+        * Mix the given headers into the headers that were given to curl
+        * 
+        * @param array curl_options
+        * @param array extra_headers
+        * @return array new curl options
+        */
+       protected function prepareCurlOptions ( $curl_options, $extra_headers )
+       {
+               $hs = array();
+               if (!empty($curl_options[CURLOPT_HTTPHEADER]) && is_array($curl_options[CURLOPT_HTTPHEADER]))
+               {
+                       foreach ($curl_options[CURLOPT_HTTPHEADER] as $h)
+                       {
+                               list($opt, $val) = explode(':', $h, 2);
+                               $opt      = str_replace(' ', '-', ucwords(str_replace('-', ' ', $opt)));
+                               $hs[$opt] = $val;
+                       }
+               }
+
+               $curl_options[CURLOPT_HTTPHEADER] = array();
+               $hs = array_merge($hs, $extra_headers);         
+               foreach ($hs as $h => $v)
+               {
+                       $curl_options[CURLOPT_HTTPHEADER][] = "$h: $v";
+               }
+               return $curl_options;
+       }
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthServer.php b/mod/oauth/vendors/oauth/library/OAuthServer.php
new file mode 100644 (file)
index 0000000..d86cc5f
--- /dev/null
@@ -0,0 +1,232 @@
+<?php
+
+/**
+ * Server layer over the OAuthRequest handler
+ * 
+ * @version $Id: OAuthServer.php 51 2008-10-15 15:15:47Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 27, 2007 12:36:38 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once 'OAuthRequestVerifier.php';
+
+class OAuthServer extends OAuthRequestVerifier
+{
+       /**
+        * Handle the request_token request.
+        * Returns the new request token and request token secret.
+        * 
+        * TODO: add correct result code to exception
+        * 
+        * @return string       returned request token, false on an error
+        */
+       public function requestToken ()
+       {
+               OAuthRequestLogger::start($this);
+               try
+               {
+                       $this->verify(false);
+                       
+                       $options = array();
+                       $ttl     = $this->getParam('xoauth_token_ttl', false);
+                       if ($ttl)
+                       {
+                               $options['token_ttl'] = $ttl;
+                       }
+
+                       // Create a request token
+                       $store  = elggconnect_get_oauth_store();//OAuthStore::instance();
+                       $token  = $store->addConsumerRequestToken($this->getParam('oauth_consumer_key', true), $options);
+                       $result = 'oauth_token='.$this->urlencode($token['token'])
+                                       .'&oauth_token_secret='.$this->urlencode($token['token_secret']);
+
+                       if (!empty($token['token_ttl']))
+                       {
+                               $result .= '&xoauth_token_ttl='.$this->urlencode($token['token_ttl']);
+                       }
+
+                       $request_token = $token['token'];
+                                       
+                       header('HTTP/1.1 200 OK');
+                       header('Content-Length: '.strlen($result));
+                       header('Content-Type: application/x-www-form-urlencoded');
+
+                       echo $result;
+               }
+               catch (OAuthException $e)
+               {
+                       $request_token = false;
+
+                       header('HTTP/1.1 401 Unauthorized');
+                       header('Content-Type: text/plain');
+
+                       echo "OAuth Verification Failed: " . $e->getMessage();
+               }
+
+               OAuthRequestLogger::flush();
+               return $request_token;
+       }
+       
+       
+       /**
+        * Verify the start of an authorization request.  Verifies if the request token is valid.
+        * Next step is the method authorizeFinish()
+        * 
+        * Nota bene: this stores the current token, consumer key and callback in the _SESSION
+        * 
+        * @exception OAuthException thrown when not a valid request
+        * @return array token description
+        */
+       public function authorizeVerify ( )
+       {
+               OAuthRequestLogger::start($this);
+
+               $store = elggconnect_get_oauth_store();//OAuthStore::instance();
+               $token = $this->getParam('oauth_token', true);
+               $rs    = $store->getConsumerRequestToken($token);
+               if (empty($rs))
+               {
+                       throw new OAuthException('Unknown request token "'.$token.'"');
+               }
+
+               // We need to remember the callback             
+               if (    empty($_SESSION['verify_oauth_token'])
+                       ||      strcmp($_SESSION['verify_oauth_token'], $rs['token']))
+               {
+                       $_SESSION['verify_oauth_token']                 = $rs['token'];
+                       $_SESSION['verify_oauth_consumer_key']  = $rs['consumer_key'];
+                       $_SESSION['verify_oauth_callback']              = $this->getParam('oauth_callback', true);
+               }
+               OAuthRequestLogger::flush();
+               return $rs;
+       }
+       
+       
+       /**
+        * Overrule this method when you want to display a nice page when
+        * the authorization is finished.  This function does not know if the authorization was
+        * succesfull, you need to check the token in the database.
+        * 
+        * @param boolean authorized    if the current token (oauth_token param) is authorized or not
+        * @param int user_id                   user for which the token was authorized (or denied)
+        */
+       public function authorizeFinish ( $authorized, $user_id )
+       {
+               OAuthRequestLogger::start($this);
+
+               $token = $this->getParam('oauth_token', true);
+               if (    isset($_SESSION['verify_oauth_token']) 
+                       &&      $_SESSION['verify_oauth_token'] == $token)
+               {
+                       // Flag the token as authorized, or remove the token when not authorized
+                       $store = elggconnect_get_oauth_store();//OAuthStore::instance();
+
+                       // Fetch the referrer host from the oauth callback parameter
+                       $referrer_host  = '';
+                       $oauth_callback = false;
+                       if (!empty($_SESSION['verify_oauth_callback']))
+                       {
+                               $oauth_callback = $_SESSION['verify_oauth_callback'];
+                               $ps = parse_url($oauth_callback);
+                               if (isset($ps['host']))
+                               {
+                                       $referrer_host = $ps['host'];
+                               }
+                       }
+                       
+                       if ($authorized)
+                       {
+                               OAuthRequestLogger::addNote('Authorized token "'.$token.'" for user '.$user_id.' with referrer "'.$referrer_host.'"');
+                               $store->authorizeConsumerRequestToken($token, $user_id, $referrer_host);
+                       }
+                       else
+                       {
+                               OAuthRequestLogger::addNote('Authorization rejected for token "'.$token.'" for user '.$user_id."\nToken has been deleted");
+                               $store->deleteConsumerRequestToken($token);
+                       }
+                       
+                       if (!empty($oauth_callback))
+                       {
+                               $this->redirect($oauth_callback, array('oauth_token'=>rawurlencode($token)));
+                       }
+               }
+               OAuthRequestLogger::flush();
+       }
+       
+       
+       /**
+        * Exchange a request token for an access token.
+        * The exchange is only succesful iff the request token has been authorized.
+        * 
+        * Never returns, calls exit() when token is exchanged or when error is returned.
+        */
+       public function accessToken ()
+       {
+               OAuthRequestLogger::start($this);
+
+               try
+               {
+                       $this->verify('request');
+
+                       $options = array();
+                       $ttl     = $this->getParam('xoauth_token_ttl', false);
+                       if ($ttl)
+                       {
+                               $options['token_ttl'] = $ttl;
+                       }
+                       
+                       $store  = elggconnect_get_oauth_store();//OAuthStore::instance();
+                       $token  = $store->exchangeConsumerRequestForAccessToken($this->getParam('oauth_token', true), $options);
+                       $result = 'oauth_token='.$this->urlencode($token['token'])
+                                       .'&oauth_token_secret='.$this->urlencode($token['token_secret']);
+                                       
+                       if (!empty($token['token_ttl']))
+                       {
+                               $result .= '&xoauth_token_ttl='.$this->urlencode($token['token_ttl']);
+                       }
+                                       
+                       header('HTTP/1.1 200 OK');
+                       header('Content-Length: '.strlen($result));
+                       header('Content-Type: application/x-www-form-urlencoded');
+
+                       echo $result;
+               }
+               catch (OAuthException $e)
+               {
+                       header('HTTP/1.1 401 Access Denied');
+                       header('Content-Type: text/plain');
+
+                       echo "OAuth Verification Failed: " . $e->getMessage();
+               }
+               
+               OAuthRequestLogger::flush();
+               exit();
+       }       
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/OAuthStore.php b/mod/oauth/vendors/oauth/library/OAuthStore.php
new file mode 100644 (file)
index 0000000..1841ab5
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * Storage container for the oauth credentials, both server and consumer side.
+ * This is the factory to select the store you want to use
+ * 
+ * @version $Id: OAuthStore.php 49 2008-10-01 09:43:19Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 16, 2007 4:03:30 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__) . '/OAuthException.php';
+
+class OAuthStore
+{
+       static private $instance = false;
+
+       /**
+        * Request an instance of the OAuthStore
+        */
+       public static function instance ( $store = 'MySQL', $options = array() )
+       {
+           if (!OAuthStore::$instance)
+           {
+                       // Select the store you want to use
+                       if (strpos($store, '/') === false)
+                       {
+                               $class = 'OAuthStore'.$store;
+                               $file  = dirname(__FILE__) . '/store/'.$class.'.php';
+                       }
+                       else
+                       {
+                               $file  = $store;
+                               $store = basename($file, '.php');
+                               $class = $store;
+                       }
+
+                       if (is_file($file))
+                       {
+                               require_once $file;
+                               
+                               if (class_exists($class))
+                               {
+                                       OAuthStore::$instance = new $class($options);
+                               }
+                               else
+                               {
+                                       throw new OAuthException('Could not find class '.$class.' in file '.$file);
+                               }
+                       }
+                       else
+                       {
+                               throw new OAuthException('No OAuthStore for '.$store.' (file '.$file.')');
+                       }
+           }
+           return OAuthStore::$instance;       
+       }
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/body/OAuthBodyContentDisposition.php b/mod/oauth/vendors/oauth/library/body/OAuthBodyContentDisposition.php
new file mode 100644 (file)
index 0000000..84123b6
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * Add the extra headers for a PUT or POST request with a file.
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+class OAuthBodyContentDisposition
+{
+    /**
+     * Builds the request string.
+     * 
+     * The files array can be a combination of the following (either data or file):
+     * 
+     * file => "path/to/file", filename=, mime=, data=
+     *
+     * @param array files              (name => filedesc) (not urlencoded)
+     * @return array (headers, body)
+     */
+    static function encodeBody ( $files )
+    {
+       $headers        = array();
+               $body           = null;
+
+               // 1. Add all the files to the post
+               if (!empty($files))
+               {
+                       foreach ($files as $name => $f)
+                       {
+                               $data     = false;
+                               $filename = false;
+
+                               if (isset($f['filename']))
+                               {
+                                       $filename = $f['filename'];
+                               }
+
+                               if (!empty($f['file']))
+                               {
+                                       $data = @file_get_contents($f['file']);
+                                       if ($data === false)
+                                       {
+                                               throw new OAuthException(sprintf('Could not read the file "%s" for request body', $f['file']));
+                                       }
+                                       if (empty($filename))
+                                       {
+                                               $filename = basename($f['file']);
+                                       }
+                               }
+                               else if (isset($f['data']))
+                               {
+                                       $data = $f['data'];
+                               }
+                               
+                               // When there is data, add it as a request body, otherwise silently skip the upload
+                               if ($data !== false)
+                               {
+                                       if (isset($headers['Content-Disposition']))
+                                       {
+                                               throw new OAuthException('Only a single file (or data) allowed in a signed PUT/POST request body.');
+                                       }
+
+                                       if (empty($filename))
+                                       {
+                                               $filename = 'untitled';
+                                       }
+                                       $mime  = !empty($f['mime']) ? $f['mime'] : 'application/octet-stream';
+                                       
+                                       $headers['Content-Disposition'] = 'attachment; filename="'.OAuthBodyContentDisposition::encodeParameterName($filename).'"';
+                                       $headers['Content-Type']                = $mime;
+
+                                       $body = $data;
+                               }
+                               
+                       }
+
+                       // When we have a body, add the content-length
+                       if (!is_null($body))
+                       {
+                               $headers['Content-Length'] = strlen($body);
+                       }
+               }
+               return array($headers, $body);
+       }
+       
+       
+       /**
+        * Encode a parameter's name for use in a multipart header.
+        * For now we do a simple filter that removes some unwanted characters.
+        * We might want to implement RFC1522 here.  See http://tools.ietf.org/html/rfc1522
+        * 
+        * @param string name
+        * @return string
+        */
+       static function encodeParameterName ( $name )
+       {
+               return preg_replace('/[^\x20-\x7f]|"/', '-', $name);
+       }
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php b/mod/oauth/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php
new file mode 100644 (file)
index 0000000..048fdeb
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+
+/**
+ * Create the body for a multipart/form-data message.
+ * 
+ * @version $Id: OAuthMultipartFormdata.php 6 2008-02-13 12:35:09Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Jan 31, 2008 12:50:05 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+class OAuthBodyMultipartFormdata
+{
+    /**
+     * Builds the request string.
+     * 
+     * The files array can be a combination of the following (either data or file):
+     * 
+     * file => "path/to/file", filename=, mime=, data=
+     *
+     * @param array params             (name => value) (all names and values should be urlencoded)
+     * @param array files              (name => filedesc) (not urlencoded)
+     * @return array (headers, body)
+     */
+    static function encodeBody ( $params, $files )
+    {
+       $headers        = array();
+               $body           = '';
+               $boundary       = 'OAuthRequester_'.md5(uniqid('multipart') . microtime());
+               $headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary;
+
+
+               // 1. Add the parameters to the post
+               if (!empty($params))
+               {
+                       foreach ($params as $name => $value)
+                       {
+                               $body .= '--'.$boundary."\r\n";
+                               $body .= 'Content-Disposition: form-data; name="'.OAuthBodyMultipartFormdata::encodeParameterName(rawurldecode($name)).'"';
+                               $body .= "\r\n\r\n";
+                               $body .= urldecode($value);
+                               $body .= "\r\n";
+                       }
+               }
+               
+               // 2. Add all the files to the post
+               if (!empty($files))
+               {
+                       $untitled = 1;
+                       
+                       foreach ($files as $name => $f)
+                       {
+                               $data     = false;
+                               $filename = false;
+
+                               if (isset($f['filename']))
+                               {
+                                       $filename = $f['filename'];
+                               }
+
+                               if (!empty($f['file']))
+                               {
+                                       $data = @file_get_contents($f['file']);
+                                       if ($data === false)
+                                       {
+                                               throw new OAuthException(sprintf('Could not read the file "%s" for form-data part', $f['file']));
+                                       }
+                                       if (empty($filename))
+                                       {
+                                               $filename = basename($f['file']);
+                                       }
+                               }
+                               else if (isset($f['data']))
+                               {
+                                       $data = $f['data'];
+                               }
+                               
+                               // When there is data, add it as a form-data part, otherwise silently skip the upload
+                               if ($data !== false)
+                               {
+                                       if (empty($filename))
+                                       {
+                                               $filename = sprintf('untitled-%d', $untitled++);
+                                       }
+                                       $mime  = !empty($f['mime']) ? $f['mime'] : 'application/octet-stream';
+                                       $body .= '--'.$boundary."\r\n";
+                                       $body .= 'Content-Disposition: form-data; name="'.OAuthBodyMultipartFormdata::encodeParameterName($name).'"; filename="'.OAuthBodyMultipartFormdata::encodeParameterName($filename).'"'."\r\n";
+                                       $body .= 'Content-Type: '.$mime;
+                                       $body .= "\r\n\r\n";
+                                       $body .= $data;
+                                       $body .= "\r\n";
+                               }
+                               
+                       }
+               }
+               $body .= '--'.$boundary."--\r\n";
+
+               $headers['Content-Length'] = strlen($body);
+               return array($headers, $body);
+       }
+       
+       
+       /**
+        * Encode a parameter's name for use in a multipart header.
+        * For now we do a simple filter that removes some unwanted characters.
+        * We might want to implement RFC1522 here.  See http://tools.ietf.org/html/rfc1522
+        * 
+        * @param string name
+        * @return string
+        */
+       static function encodeParameterName ( $name )
+       {
+               return preg_replace('/[^\x20-\x7f]|"/', '-', $name);
+       }
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/discovery/xrds_parse.php b/mod/oauth/vendors/oauth/library/discovery/xrds_parse.php
new file mode 100644 (file)
index 0000000..c9cf949
--- /dev/null
@@ -0,0 +1,304 @@
+<?php
+
+/**
+ * Parse a XRDS discovery description to a simple array format.
+ * 
+ * For now a simple parse of the document. Better error checking
+ * in a later version.
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* example of use:
+
+header('content-type: text/plain');
+$file = file_get_contents('../../test/discovery/xrds-magnolia.xrds');
+$xrds = xrds_parse($file);
+print_r($xrds);
+
+ */ 
+
+/**
+ * Parse the xrds file in the argument.  The xrds description must have been 
+ * fetched via curl or something else.
+ * 
+ * TODO: more robust checking, support for more service documents
+ * TODO: support for URIs to definition instead of local xml:id
+ * 
+ * @param string data contents of xrds file
+ * @exception Exception when the file is in an unknown format
+ * @return array
+ */
+function xrds_parse ( $data )
+{
+       $oauth = array();
+       $doc   = @DOMDocument::loadXML($data);
+       if ($doc === false)
+       {
+               throw new Exception('Error in XML, can\'t load XRDS document');
+       }
+       
+       $xpath = new DOMXPath($doc);
+       $xpath->registerNamespace('xrds',       'xri://$xrds');
+       $xpath->registerNamespace('xrd',        'xri://$XRD*($v*2.0)');
+       $xpath->registerNamespace('simple', 'http://xrds-simple.net/core/1.0');
+
+       // Yahoo! uses this namespace, with lowercase xrd in it
+       $xpath->registerNamespace('xrd2',       'xri://$xrd*($v*2.0)');
+
+       $uris = xrds_oauth_service_uris($xpath);
+
+       foreach ($uris as $uri)
+       {
+               // TODO: support uris referring to service documents outside this one
+               if ($uri{0} == '#')
+               {
+                       $id    = substr($uri, 1);
+                       $oauth = xrds_xrd_oauth($xpath, $id);
+                       if (is_array($oauth) && !empty($oauth))
+                       {
+                               return $oauth;
+                       }
+               }
+       }
+
+       return false;
+}
+
+
+/**
+ * Parse a XRD definition for OAuth and return the uris etc.
+ * 
+ * @param XPath xpath
+ * @param string id
+ * @return array
+ */
+function xrds_xrd_oauth ( $xpath, $id )
+{
+       $oauth = array();
+       $xrd   = $xpath->query('//xrds:XRDS/xrd:XRD[@xml:id="'.$id.'"]');
+       if ($xrd->length == 0)
+       {
+               // Yahoo! uses another namespace
+               $xrd = $xpath->query('//xrds:XRDS/xrd2:XRD[@xml:id="'.$id.'"]');
+       }
+
+       if ($xrd->length >= 1)
+       {
+               $x                = $xrd->item(0);
+               $services = array();
+               foreach ($x->childNodes as $n)
+               {
+                       switch ($n->nodeName)
+                       {
+                       case 'Type':
+                               if ($n->nodeValue != 'xri://$xrds*simple')
+                               {
+                                       // Not a simple XRDS document
+                                       return false;
+                               }
+                               break;
+                       case 'Expires':
+                               $oauth['expires'] = $n->nodeValue;
+                               break;
+                       case 'Service':
+                               list($type,$service) = xrds_xrd_oauth_service($n);
+                               if ($type)
+                               {
+                                       $services[$type][xrds_priority($n)][] = $service;
+                               }
+                               break;
+                       }
+               }
+               
+               // Flatten the services on priority
+               foreach ($services as $type => $service)
+               {
+                       $oauth[$type] = xrds_priority_flatten($service);
+               }
+       }
+       else
+       {
+               $oauth = false;
+       }
+       return $oauth;
+}
+
+
+/**
+ * Parse a service definition for OAuth in a simple xrd element
+ * 
+ * @param DOMElement n
+ * @return array (type, service desc)
+ */
+function xrds_xrd_oauth_service ( $n )
+{
+       $service = array(
+                               'uri'                           => '',
+                               'signature_method'      => array(),
+                               'parameters'            => array()
+                               );
+
+       $type    = false;
+       foreach ($n->childNodes as $c)
+       {
+               $name  = $c->nodeName;
+               $value = $c->nodeValue;
+               
+               if ($name == 'URI')
+               {
+                       $service['uri'] = $value;
+               }
+               else if ($name == 'Type')
+               {
+                       if (strncmp($value, 'http://oauth.net/core/1.0/endpoint/', 35) == 0)
+                       {
+                               $type = basename($value);
+                       }
+                       else if (strncmp($value, 'http://oauth.net/core/1.0/signature/', 36) == 0)
+                       {
+                               $service['signature_method'][] = basename($value);
+                       }
+                       else if (strncmp($value, 'http://oauth.net/core/1.0/parameters/', 37) == 0)
+                       {
+                               $service['parameters'][] = basename($value);
+                       }
+                       else if (strncmp($value, 'http://oauth.net/discovery/1.0/consumer-identity/', 49) == 0)
+                       {
+                               $type = 'consumer_identity';
+                               $service['method'] = basename($value);
+                               unset($service['signature_method']);
+                               unset($service['parameters']);
+                       }
+                       else
+                       {
+                               $service['unknown'][] = $value;
+                       }
+               }
+               else if ($name == 'LocalID')
+               {
+                       $service['consumer_key'] = $value;
+               }
+               else if ($name{0} != '#')
+               {
+                       $service[strtolower($name)] = $value;
+               }
+       }
+       return array($type, $service);
+}
+
+
+/**
+ * Return the OAuth service uris in order of the priority.
+ * 
+ * @param XPath xpath
+ * @return array
+ */
+function xrds_oauth_service_uris ( $xpath )
+{
+       $uris      = array();
+       $xrd_oauth = $xpath->query('//xrds:XRDS/xrd:XRD/xrd:Service/xrd:Type[.=\'http://oauth.net/discovery/1.0\']');
+       if ($xrd_oauth->length > 0)
+       {
+               $service = array();
+               foreach ($xrd_oauth as $xo)
+               {
+                       // Find the URI of the service definition
+                       $cs = $xo->parentNode->childNodes;
+                       foreach ($cs as $c)
+                       {
+                               if ($c->nodeName == 'URI')
+                               {
+                                       $prio                     = xrds_priority($xo);
+                                       $service[$prio][] = $c->nodeValue;
+                               }
+                       }
+               }
+               $uris = xrds_priority_flatten($service);
+       }
+       return $uris;
+}
+
+
+
+/**
+ * Flatten an array according to the priority
+ * 
+ * @param array  ps buckets per prio
+ * @return array one dimensional array
+ */
+function xrds_priority_flatten ( $ps )
+{
+       $prio = array();
+       $null = array();
+       ksort($ps);
+       foreach ($ps as $idx => $bucket)
+       {
+               if (!empty($bucket))
+               {
+                       if ($idx == 'null')
+                       {
+                               $null = $bucket;
+                       }
+                       else
+                       {
+                               $prio = array_merge($prio, $bucket);
+                       }
+               }
+       }
+       $prio = array_merge($prio, $bucket);
+       return $prio;
+}
+
+
+/**
+ * Fetch the priority of a element
+ * 
+ * @param DOMElement elt
+ * @return mixed               'null' or int
+ */
+function xrds_priority ( $elt )
+{
+       if ($elt->hasAttribute('priority'))
+       {
+               $prio = $elt->getAttribute('priority');
+               if (is_numeric($prio))
+               {
+                       $prio = intval($prio);
+               }
+       }
+       else
+       {
+               $prio = 'null';
+       }
+       return $prio;
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/discovery/xrds_parse.txt b/mod/oauth/vendors/oauth/library/discovery/xrds_parse.txt
new file mode 100644 (file)
index 0000000..fd867ea
--- /dev/null
@@ -0,0 +1,101 @@
+The xrds_parse.php script contains the function:
+
+        function xrds_parse ( $data. )
+
+$data Contains the contents of a XRDS XML file.
+When the data is invalid XML then this will throw an exception.
+
+After parsing a XRDS definition it will return a datastructure much like the one below.
+
+Array
+(
+    [expires] => 2008-04-13T07:34:58Z
+    [request] => Array
+        (
+            [0] => Array
+                (
+                    [uri] => https://ma.gnolia.com/oauth/get_request_token
+                    [signature_method] => Array
+                        (
+                            [0] => HMAC-SHA1
+                            [1] => RSA-SHA1
+                            [2] => PLAINTEXT
+                        )
+
+                    [parameters] => Array
+                        (
+                            [0] => auth-header
+                            [1] => post-body
+                            [2] => uri-query
+                        )
+                )
+        )
+
+    [authorize] => Array
+        (
+            [0] => Array
+                (
+                    [uri] => http://ma.gnolia.com/oauth/authorize
+                    [signature_method] => Array
+                        (
+                        )
+
+                    [parameters] => Array
+                        (
+                            [0] => auth-header
+                            [1] => uri-query
+                        )
+                )
+        )
+
+    [access] => Array
+        (
+            [0] => Array
+                (
+                    [uri] => https://ma.gnolia.com/oauth/get_access_token
+                    [signature_method] => Array
+                        (
+                            [0] => HMAC-SHA1
+                            [1] => RSA-SHA1
+                            [2] => PLAINTEXT
+                        )
+
+                    [parameters] => Array
+                        (
+                            [0] => auth-header
+                            [1] => post-body
+                            [2] => uri-query
+                        )
+                )
+        )
+
+    [resource] => Array
+        (
+            [0] => Array
+                (
+                    [uri] => 
+                    [signature_method] => Array
+                        (
+                            [0] => HMAC-SHA1
+                            [1] => RSA-SHA1
+                        )
+
+                    [parameters] => Array
+                        (
+                            [0] => auth-header
+                            [1] => post-body
+                            [2] => uri-query
+                        )
+                )
+        )
+
+    [consumer_identity] => Array
+        (
+            [0] => Array
+                (
+                    [uri] => http://ma.gnolia.com/applications/new
+                    [method] => oob
+                )
+        )
+)
+
diff --git a/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php b/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php
new file mode 100644 (file)
index 0000000..34ccb42
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * Interface for OAuth signature methods
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Sep 8, 2008 12:04:35 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+abstract class OAuthSignatureMethod
+{
+       /**
+        * Return the name of this signature
+        * 
+        * @return string
+        */
+       abstract public function name();
+       
+       /**
+        * Return the signature for the given request
+        * 
+        * @param OAuthRequest request
+        * @param string base_string
+        * @param string consumer_secret
+        * @param string token_secret
+        * @return string  
+        */
+       abstract public function signature ( $request, $base_string, $consumer_secret, $token_secret );
+
+       /**
+        * Check if the request signature corresponds to the one calculated for the request.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string    data to be signed, usually the base string, can be a request body
+        * @param string consumer_secret
+        * @param string token_secret
+        * @param string signature              from the request, still urlencoded
+        * @return string
+        */
+       abstract public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature );
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php b/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php
new file mode 100644 (file)
index 0000000..4bc949c
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * OAuth signature implementation using HMAC-SHA1
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Sep 8, 2008 12:21:19 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+require_once dirname(__FILE__).'/OAuthSignatureMethod.class.php';
+
+
+class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
+{
+       public function name ()
+       {
+               return 'HMAC-SHA1';
+       }
+
+
+       /**
+        * Calculate the signature using HMAC-SHA1
+        * This function is copyright Andy Smith, 2007.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string
+        * @param string consumer_secret
+        * @param string token_secret
+        * @return string  
+        */
+       function signature ( $request, $base_string, $consumer_secret, $token_secret )
+       {
+               $key = $request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret);
+               if (function_exists('hash_hmac'))
+               {
+                       $signature = base64_encode(hash_hmac("sha1", $base_string, $key, true));
+               }
+               else
+               {
+                   $blocksize  = 64;
+                   $hashfunc   = 'sha1';
+                   if (strlen($key) > $blocksize)
+                   {
+                       $key = pack('H*', $hashfunc($key));
+                   }
+                   $key        = str_pad($key,$blocksize,chr(0x00));
+                   $ipad       = str_repeat(chr(0x36),$blocksize);
+                   $opad       = str_repeat(chr(0x5c),$blocksize);
+                   $hmac       = pack(
+                               'H*',$hashfunc(
+                                   ($key^$opad).pack(
+                                       'H*',$hashfunc(
+                                           ($key^$ipad).$base_string
+                                       )
+                                   )
+                               )
+                           );
+                       $signature = base64_encode($hmac);
+               }
+               return $request->urlencode($signature);
+       }
+
+
+       /**
+        * Check if the request signature corresponds to the one calculated for the request.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string    data to be signed, usually the base string, can be a request body
+        * @param string consumer_secret
+        * @param string token_secret
+        * @param string signature              from the request, still urlencoded
+        * @return string
+        */
+       public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
+       {
+               $a = $request->urldecode($signature);
+               $b = $request->urldecode($this->signature($request, $base_string, $consumer_secret, $token_secret));
+
+               // We have to compare the decoded values
+               $valA  = base64_decode($a);
+               $valB  = base64_decode($b);
+
+               // Crude binary comparison
+               return rawurlencode($a) == rawurlencode($b);
+       }
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php b/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php
new file mode 100644 (file)
index 0000000..6f593a4
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * OAuth signature implementation using MD5
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Sep 8, 2008 12:09:43 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__).'/OAuthSignatureMethod.class.php';
+
+
+class OAuthSignatureMethod_MD5 extends OAuthSignatureMethod
+{
+       public function name ()
+       {
+               return 'MD5';
+       }
+
+
+       /**
+        * Calculate the signature using MD5
+        * Binary md5 digest, as distinct from PHP's built-in hexdigest.
+        * This function is copyright Andy Smith, 2007.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string
+        * @param string consumer_secret
+        * @param string token_secret
+        * @return string  
+        */
+       function signature ( $request, $base_string, $consumer_secret, $token_secret )
+       {
+               $s  .= '&'.$request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret);
+               $md5 = md5($base_string);
+               $bin = '';
+               
+               for ($i = 0; $i < strlen($md5); $i += 2)
+               {
+                   $bin .= chr(hexdec($md5{$i+1}) + hexdec($md5{$i}) * 16);
+               }
+               return $request->urlencode(base64_encode($bin));
+       }
+
+
+       /**
+        * Check if the request signature corresponds to the one calculated for the request.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string    data to be signed, usually the base string, can be a request body
+        * @param string consumer_secret
+        * @param string token_secret
+        * @param string signature              from the request, still urlencoded
+        * @return string
+        */
+       public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
+       {
+               $a = $request->urldecode($signature);
+               $b = $request->urldecode($this->signature($request, $base_string, $consumer_secret, $token_secret));
+
+               // We have to compare the decoded values
+               $valA  = base64_decode($a);
+               $valB  = base64_decode($b);
+
+               // Crude binary comparison
+               return rawurlencode($a) == rawurlencode($b);
+       }
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php b/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php
new file mode 100644 (file)
index 0000000..92ef308
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * OAuth signature implementation using PLAINTEXT
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Sep 8, 2008 12:09:43 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__).'/OAuthSignatureMethod.class.php';
+
+
+class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
+{
+       public function name ()
+       {
+               return 'PLAINTEXT';
+       }
+
+
+       /**
+        * Calculate the signature using PLAINTEXT
+        * 
+        * @param OAuthRequest request
+        * @param string base_string
+        * @param string consumer_secret
+        * @param string token_secret
+        * @return string  
+        */
+       function signature ( $request, $base_string, $consumer_secret, $token_secret )
+       {
+               return $request->urlencode($request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret));
+       }
+
+
+       /**
+        * Check if the request signature corresponds to the one calculated for the request.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string    data to be signed, usually the base string, can be a request body
+        * @param string consumer_secret
+        * @param string token_secret
+        * @param string signature              from the request, still urlencoded
+        * @return string
+        */
+       public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
+       {
+               $a = $request->urldecode($signature);
+               $b = $request->urldecode($this->signature($request, $base_string, $consumer_secret, $token_secret));
+
+               return $request->urldecode($a) == $request->urldecode($b);
+       }
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php b/mod/oauth/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php
new file mode 100644 (file)
index 0000000..3bbde7d
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * OAuth signature implementation using PLAINTEXT
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Sep 8, 2008 12:00:14 PM
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
+{
+       public function name() 
+       {
+               return 'RSA-SHA1';
+       }
+       
+
+       /**
+        * Fetch the public CERT key for the signature
+        * 
+        * @param OAuthRequest request
+        * @return string public key
+        */
+       protected function fetch_public_cert ( $request )
+       {
+               // not implemented yet, ideas are:
+               // (1) do a lookup in a table of trusted certs keyed off of consumer
+               // (2) fetch via http using a url provided by the requester
+               // (3) some sort of specific discovery code based on request
+               //
+               // either way should return a string representation of the certificate
+               throw OAuthException("OAuthSignatureMethod_RSA_SHA1::fetch_public_cert not implemented");
+       }
+       
+       
+       /**
+        * Fetch the private CERT key for the signature
+        * 
+        * @param OAuthRequest request
+        * @return string private key
+        */
+       protected function fetch_private_cert ( $request )
+       {
+               // not implemented yet, ideas are:
+               // (1) do a lookup in a table of trusted certs keyed off of consumer
+               //
+               // either way should return a string representation of the certificate
+               throw OAuthException("OAuthSignatureMethod_RSA_SHA1::fetch_private_cert not implemented");
+       }
+
+
+       /**
+        * Calculate the signature using RSA-SHA1
+        * This function is copyright Andy Smith, 2008.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string
+        * @param string consumer_secret
+        * @param string token_secret
+        * @return string  
+        */
+       public function signature ( $request, $base_string, $consumer_secret, $token_secret )
+       {
+               // Fetch the private key cert based on the request
+               $cert = $this->fetch_private_cert($request);
+               
+               // Pull the private key ID from the certificate
+               $privatekeyid = openssl_get_privatekey($cert);
+               
+               // Sign using the key
+               $sig = false;
+               $ok  = openssl_sign($base_string, $sig, $privatekeyid);   
+               
+               // Release the key resource
+               openssl_free_key($privatekeyid);
+                 
+               return $request->urlencode(base64_encode($sig));
+       }
+       
+
+       /**
+        * Check if the request signature is the same as the one calculated for the request.
+        * 
+        * @param OAuthRequest request
+        * @param string base_string
+        * @param string consumer_secret
+        * @param string token_secret
+        * @param string signature
+        * @return string  
+        */
+       public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
+       {
+               $decoded_sig = base64_decode($request->urldecode($signature));
+                 
+               // Fetch the public key cert based on the request
+               $cert = $this->fetch_public_cert($request);
+               
+               // Pull the public key ID from the certificate
+               $publickeyid = openssl_get_publickey($cert);
+               
+               // Check the computed signature against the one passed in the query
+               $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);   
+               
+               // Release the key resource
+               openssl_free_key($publickeyid);
+               return $ok == 1;
+       }
+
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/store/OAuthStoreAbstract.class.php b/mod/oauth/vendors/oauth/library/store/OAuthStoreAbstract.class.php
new file mode 100644 (file)
index 0000000..e7cca98
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * Abstract base class for OAuthStore implementations
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+abstract class OAuthStoreAbstract
+{
+       abstract public function getSecretsForVerify ( $consumer_key, $token, $token_type = 'access' );
+       abstract public function getSecretsForSignature ( $uri, $user_id );
+       abstract public function getServerTokenSecrets ( $consumer_key, $token, $token_type, $user_id, $name = '' );
+       abstract public function addServerToken ( $consumer_key, $token_type, $token, $token_secret, $user_id, $options = array() );
+
+       abstract public function deleteServer ( $consumer_key, $user_id, $user_is_admin = false );
+       abstract public function getServer( $consumer_key, $user_id, $user_is_admin = false );
+       abstract public function getServerForUri ( $uri, $user_id );
+       abstract public function listServerTokens ( $user_id );
+       abstract public function countServerTokens ( $consumer_key );
+       abstract public function getServerToken ( $consumer_key, $token, $user_id );
+       abstract public function deleteServerToken ( $consumer_key, $token, $user_id, $user_is_admin = false );
+       abstract public function listServers ( $q = '', $user_id );
+       abstract public function updateServer ( $server, $user_id, $user_is_admin = false );
+
+       abstract public function updateConsumer ( $consumer, $user_id, $user_is_admin = false );
+       abstract public function deleteConsumer ( $consumer_key, $user_id, $user_is_admin = false );
+       abstract public function getConsumer ( $consumer_key, $user_id, $user_is_admin = false );
+       abstract public function getConsumerStatic ();
+
+       abstract public function addConsumerRequestToken ( $consumer_key, $options = array() );
+       abstract public function getConsumerRequestToken ( $token );
+       abstract public function deleteConsumerRequestToken ( $token );
+       abstract public function authorizeConsumerRequestToken ( $token, $user_id, $referrer_host = '' );
+       abstract public function countConsumerAccessTokens ( $consumer_key );
+       abstract public function exchangeConsumerRequestForAccessToken ( $token, $options = array() );
+       abstract public function getConsumerAccessToken ( $token, $user_id );
+       abstract public function deleteConsumerAccessToken ( $token, $user_id, $user_is_admin = false );
+       abstract public function setConsumerAccessTokenTtl ( $token, $ttl );
+       
+       abstract public function listConsumers ( $user_id );
+       abstract public function listConsumerTokens ( $user_id );
+
+       abstract public function checkServerNonce ( $consumer_key, $token, $timestamp, $nonce );
+       
+       abstract public function addLog ( $keys, $received, $sent, $base_string, $notes, $user_id = null );
+       abstract public function listLog ( $options, $user_id );
+       
+       abstract public function install ();    
+       
+       /**
+        * Fetch the current static consumer key for this site, create it when it was not found.
+        * The consumer secret for the consumer key is always empty.
+        * 
+        * @return string       consumer key 
+        */
+       
+       
+       /* ** Some handy utility functions ** */
+       
+       /**
+        * Generate a unique key
+        * 
+        * @param boolean unique        force the key to be unique
+        * @return string
+        */
+       public function generateKey ( $unique = false )
+       {
+               $key = md5(uniqid(rand(), true));
+               if ($unique)
+               {
+                       list($usec,$sec) = explode(' ',microtime());
+                       $key .= dechex($usec).dechex($sec);
+               }
+               return $key;
+       }
+
+       /**
+        * Check to see if a string is valid utf8
+        * 
+        * @param string $s
+        * @return boolean
+        */
+       protected function isUTF8 ( $s )
+       {
+               return preg_match('%(?:
+              [\xC2-\xDF][\x80-\xBF]              # non-overlong 2-byte
+              |\xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
+              |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
+              |\xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
+              |\xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
+              |[\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
+              |\xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
+              )+%xs', $s);
+       }
+       
+       
+       /**
+        * Make a string utf8, replacing all non-utf8 chars with a '.'
+        * 
+        * @param string
+        * @return string
+        */
+       protected function makeUTF8 ( $s )
+       {
+               if (function_exists('iconv'))
+               {
+                       do
+                       {
+                               $ok   = true;
+                               $text = @iconv('UTF-8', 'UTF-8//TRANSLIT', $s);
+                               if (strlen($text) != strlen($s))
+                               {
+                                       // Remove the offending character...
+                                       $s  = $text . '.' . substr($s, strlen($text) + 1);
+                                       $ok = false;
+                               }
+                       }
+                       while (!$ok);
+               }
+               return $s;
+       }
+       
+}
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/store/OAuthStoreAnyMeta.php b/mod/oauth/vendors/oauth/library/store/OAuthStoreAnyMeta.php
new file mode 100644 (file)
index 0000000..9c97173
--- /dev/null
@@ -0,0 +1,265 @@
+<?php
+
+/**
+ * Storage container for the oauth credentials, both server and consumer side.
+ * This file can only be used in conjunction with anyMeta.
+ * 
+ * @version $Id: OAuthStoreAnyMeta.php 49 2008-10-01 09:43:19Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 16, 2007 4:03:30 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__) . '/../../../../core/inc/any_database.inc.php';
+require_once dirname(__FILE__) . '/OAuthStoreMySQL.php';
+
+
+class OAuthStoreAnymeta extends OAuthStoreMySQL
+{
+       /**
+        * Construct the OAuthStoreAnymeta
+        * 
+        * @param array options
+        */
+       function __construct ( $options = array() )
+       {
+               parent::__construct(array('conn' => any_db_conn()));
+       }
+
+
+       /**
+        * Add an entry to the log table
+        * 
+        * @param array keys (osr_consumer_key, ost_token, ocr_consumer_key, oct_token)
+        * @param string received
+        * @param string sent
+        * @param string base_string
+        * @param string notes
+        * @param int (optional) user_id
+        */
+       public function addLog ( $keys, $received, $sent, $base_string, $notes, $user_id = null )
+       {
+               if (is_null($user_id) && isset($GLOBALS['any_auth']))
+               {
+                       $user_id = $GLOBALS['any_auth']->getUserId();
+               }
+               parent::addLog($keys, $received, $sent, $base_string, $notes, $user_id);
+       }
+       
+       
+       /**
+        * Get a page of entries from the log.  Returns the last 100 records
+        * matching the options given.
+        * 
+        * @param array options
+        * @param int user_id   current user
+        * @return array log records
+        */
+       public function listLog ( $options, $user_id )
+       {
+               $where = array();
+               $args  = array();
+               if (empty($options))
+               {
+                       $where[] = 'olg_usa_id_ref = %d';
+                       $args[]  = $user_id;
+               }
+               else
+               {
+                       foreach ($options as $option => $value)
+                       {
+                               if (strlen($value) > 0)
+                               {
+                                       switch ($option)
+                                       {
+                                       case 'osr_consumer_key':
+                                       case 'ocr_consumer_key':
+                                       case 'ost_token':
+                                       case 'oct_token':
+                                               $where[] = 'olg_'.$option.' = \'%s\'';
+                                               $args[]  = $value;      
+                                               break;                          
+                                       }
+                               }
+                       }
+                       
+                       $where[] = '(olg_usa_id_ref IS NULL OR olg_usa_id_ref = %d)';
+                       $args[]  = $user_id;
+               }
+
+               $rs = any_db_query_all_assoc('
+                                       SELECT olg_id,
+                                                       olg_osr_consumer_key    AS osr_consumer_key,
+                                                       olg_ost_token                   AS ost_token,
+                                                       olg_ocr_consumer_key    AS ocr_consumer_key,
+                                                       olg_oct_token                   AS oct_token,
+                                                       olg_usa_id_ref                  AS user_id,
+                                                       olg_received                    AS received,
+                                                       olg_sent                                AS sent,
+                                                       olg_base_string                 AS base_string,
+                                                       olg_notes                               AS notes,
+                                                       olg_timestamp                   AS timestamp,
+                                                       INET_NTOA(olg_remote_ip) AS remote_ip
+                                       FROM oauth_log
+                                       WHERE '.implode(' AND ', $where).'
+                                       ORDER BY olg_id DESC
+                                       LIMIT 0,100', $args);
+
+               return $rs;
+       }
+
+
+
+       /**
+        * Initialise the database
+        */
+       public function install ()
+       {
+               parent::install();
+
+               any_db_query("ALTER TABLE oauth_consumer_registry MODIFY ocr_usa_id_ref int(11) unsigned");
+               any_db_query("ALTER TABLE oauth_consumer_token    MODIFY oct_usa_id_ref int(11) unsigned not null");
+               any_db_query("ALTER TABLE oauth_server_registry   MODIFY osr_usa_id_ref int(11) unsigned");
+               any_db_query("ALTER TABLE oauth_server_token      MODIFY ost_usa_id_ref int(11) unsigned not null");
+               any_db_query("ALTER TABLE oauth_log               MODIFY olg_usa_id_ref int(11) unsigned");
+
+               any_db_alter_add_fk('oauth_consumer_registry', 'ocr_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete set null');
+               any_db_alter_add_fk('oauth_consumer_token',    'oct_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete cascade');
+               any_db_alter_add_fk('oauth_server_registry',   'osr_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete set null');
+               any_db_alter_add_fk('oauth_server_token',      'ost_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete cascade');
+               any_db_alter_add_fk('oauth_log',               'olg_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete cascade');
+       }
+
+       
+       
+       /** Some simple helper functions for querying the mysql db **/
+
+       /**
+        * Perform a query, ignore the results
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        */
+       protected function query ( $sql )
+       {
+               list($sql, $args) = $this->sql_args(func_get_args());
+               any_db_query($sql, $args);
+       }
+       
+
+       /**
+        * Perform a query, ignore the results
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return array
+        */
+       protected function query_all_assoc ( $sql )
+       {
+               list($sql, $args) = $this->sql_args(func_get_args());
+               return any_db_query_all_assoc($sql, $args);
+       }
+       
+       
+       /**
+        * Perform a query, return the first row
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return array
+        */
+       protected function query_row_assoc ( $sql )
+       {
+               list($sql, $args) = $this->sql_args(func_get_args());
+               return any_db_query_row_assoc($sql, $args);
+       }
+
+       
+       /**
+        * Perform a query, return the first row
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return array
+        */
+       protected function query_row ( $sql )
+       {
+               list($sql, $args) = $this->sql_args(func_get_args());
+               return any_db_query_row($sql, $args);
+       }
+       
+               
+       /**
+        * Perform a query, return the first column of the first row
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return mixed
+        */
+       protected function query_one ( $sql )
+       {
+               list($sql, $args) = $this->sql_args(func_get_args());
+               return any_db_query_one($sql, $args);
+       }
+       
+       
+       /**
+        * Return the number of rows affected in the last query
+        * 
+        * @return int
+        */
+       protected function query_affected_rows ()
+       {
+               return any_db_affected_rows();
+       }
+
+
+       /**
+        * Return the id of the last inserted row
+        * 
+        * @return int
+        */
+       protected function query_insert_id ()
+       {
+               return any_db_insert_id();
+       }
+       
+       
+       private function sql_args ( $args )
+       {
+               $sql = array_shift($args);
+               if (count($args) == 1 && is_array($args[0]))
+               {
+                       $args = $args[0];
+               }
+               return array($sql, $args);
+       }
+
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/store/OAuthStoreMySQL.php b/mod/oauth/vendors/oauth/library/store/OAuthStoreMySQL.php
new file mode 100644 (file)
index 0000000..a1b04c5
--- /dev/null
@@ -0,0 +1,1879 @@
+<?php
+
+/**
+ * Storage container for the oauth credentials, both server and consumer side.
+ * Based on MySQL
+ * 
+ * @version $Id: OAuthStoreMySQL.php 64 2009-08-16 19:37:00Z marcw@pobox.com $
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 16, 2007 4:03:30 PM
+ * 
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+require_once dirname(__FILE__) . '/OAuthStoreAbstract.class.php';
+
+
+class OAuthStoreMySQL extends OAuthStoreAbstract
+{
+       /**
+        * The MySQL connection 
+        */
+       protected $conn;
+
+       /**
+        * Maximum delta a timestamp may be off from a previous timestamp.
+        * Allows multiple consumers with some clock skew to work with the same token.
+        * Unit is seconds, default max skew is 10 minutes.
+        */
+       protected $max_timestamp_skew = 600;
+
+       /**
+        * Default ttl for request tokens
+        */
+       protected $max_request_token_ttl = 3600;
+       
+
+       /**
+        * Construct the OAuthStoreMySQL.
+        * In the options you have to supply either:
+        * - server, username, password and database (for a mysql_connect)
+        * - conn (for the connection to be used)
+        * 
+        * @param array options
+        */
+       function __construct ( $options = array() )
+       {
+               if (isset($options['conn']))
+               {
+                       $this->conn = $options['conn'];
+               }
+               else
+               {
+                       if (isset($options['server']))
+                       {
+                               $server   = $options['server'];
+                               $username = $options['username'];
+                               
+                               if (isset($options['password']))
+                               {
+                                       $this->conn = mysql_connect($server, $username, $options['password']);
+                               }
+                               else
+                               {
+                                       $this->conn = mysql_connect($server, $username);
+                               }
+                       }
+                       else
+                       {
+                               // Try the default mysql connect
+                               $this->conn = mysql_connect();
+                       }
+
+                       if ($this->conn === false)
+                       {
+                               throw new OAuthException('Could not connect to MySQL database: ' . mysql_error());
+                       }
+
+                       if (isset($options['database']))
+                       {
+                               if (!mysql_select_db($options['database'], $this->conn))
+                               {
+                                       $this->sql_errcheck();
+                               }
+                       }
+                       $this->query('set character set utf8');
+               }
+       }
+
+
+       /**
+        * Find stored credentials for the consumer key and token. Used by an OAuth server
+        * when verifying an OAuth request.
+        * 
+        * @param string consumer_key
+        * @param string token
+        * @param string token_type             false, 'request' or 'access'
+        * @exception OAuthException when no secrets where found
+        * @return array        assoc (consumer_secret, token_secret, osr_id, ost_id, user_id)
+        */
+       public function getSecretsForVerify ( $consumer_key, $token, $token_type = 'access' )
+       {
+               if ($token_type === false)
+               {
+                       $rs = $this->query_row_assoc('
+                                               SELECT  osr_id, 
+                                                               osr_consumer_key                as consumer_key,
+                                                               osr_consumer_secret             as consumer_secret
+                                               FROM oauth_server_registry
+                                               WHERE osr_consumer_key  = \'%s\'
+                                                 AND osr_enabled               = 1
+                                               ', 
+                                               $consumer_key);
+                       
+                       if ($rs)
+                       {
+                               $rs['token']            = false;
+                               $rs['token_secret']     = false;
+                               $rs['user_id']          = false;
+                               $rs['ost_id']           = false;
+                       }
+               }
+               else
+               {
+                       $rs = $this->query_row_assoc('
+                                               SELECT  osr_id, 
+                                                               ost_id,
+                                                               ost_usa_id_ref                  as user_id,
+                                                               osr_consumer_key                as consumer_key,
+                                                               osr_consumer_secret             as consumer_secret,
+                                                               ost_token                               as token,
+                                                               ost_token_secret                as token_secret
+                                               FROM oauth_server_registry
+                                                               JOIN oauth_server_token
+                                                               ON ost_osr_id_ref = osr_id
+                                               WHERE ost_token_type    = \'%s\'
+                                                 AND osr_consumer_key  = \'%s\'
+                                                 AND ost_token                 = \'%s\'
+                                                 AND osr_enabled               = 1
+                                                 AND ost_token_ttl     >= NOW()
+                                               ',
+                                               $token_type, $consumer_key, $token);
+               }
+               
+               if (empty($rs))
+               {
+                       throw new OAuthException('The consumer_key "'.$consumer_key.'" token "'.$token.'" combination does not exist or is not enabled.');
+               }
+               return $rs;
+       }
+
+
+       /**
+        * Find the server details for signing a request, always looks for an access token.
+        * The returned credentials depend on which local user is making the request.
+        * 
+        * The consumer_key must belong to the user or be public (user id is null)
+        * 
+        * For signing we need all of the following:
+        * 
+        * consumer_key                 consumer key associated with the server
+        * consumer_secret              consumer secret associated with this server
+        * token                                access token associated with this server
+        * token_secret                 secret for the access token
+        * signature_methods    signing methods supported by the server (array)
+        * 
+        * @todo filter on token type (we should know how and with what to sign this request, and there might be old access tokens)
+        * @param string uri    uri of the server
+        * @param int user_id   id of the logged on user
+        * @param string name   (optional) name of the token (case sensitive)
+        * @exception OAuthException when no credentials found
+        * @return array
+        */
+       public function getSecretsForSignature ( $uri, $user_id, $name = '' )
+       {
+               // Find a consumer key and token for the given uri
+               $ps             = parse_url($uri);
+               $host   = isset($ps['host']) ? $ps['host'] : 'localhost';
+               $path   = isset($ps['path']) ? $ps['path'] : '';
+               
+               if (empty($path) || substr($path, -1) != '/')
+               {
+                       $path .= '/';
+               }
+
+               // The owner of the consumer_key is either the user or nobody (public consumer key)
+               $secrets = $this->query_row_assoc('
+                                       SELECT  ocr_consumer_key                as consumer_key,
+                                                       ocr_consumer_secret             as consumer_secret,
+                                                       oct_token                               as token,
+                                                       oct_token_secret                as token_secret,
+                                                       ocr_signature_methods   as signature_methods
+                                       FROM oauth_consumer_registry
+                                               JOIN oauth_consumer_token ON oct_ocr_id_ref = ocr_id
+                                       WHERE ocr_server_uri_host = \'%s\'
+                                         AND ocr_server_uri_path = LEFT(\'%s\', LENGTH(ocr_server_uri_path))
+                                         AND (ocr_usa_id_ref = %s OR ocr_usa_id_ref IS NULL)
+                                         AND oct_usa_id_ref      = %d
+                                         AND oct_token_type      = \'access\'
+                                         AND oct_name                    = \'%s\'
+                                         AND oct_token_ttl       >= NOW()
+                                       ORDER BY ocr_usa_id_ref DESC, ocr_consumer_secret DESC, LENGTH(ocr_server_uri_path) DESC
+                                       LIMIT 0,1
+                                       ', $host, $path, $user_id, $user_id, $name
+                                       );
+               
+               if (empty($secrets))
+               {
+                       throw new OAuthException('No server tokens available for '.$uri);
+               }
+               $secrets['signature_methods'] = explode(',', $secrets['signature_methods']);
+               return $secrets;
+       }
+
+
+       /**
+        * Get the token and token secret we obtained from a server.
+        * 
+        * @param string        consumer_key
+        * @param string        token
+        * @param string        token_type
+        * @param int           user_id                 the user owning the token
+        * @param string        name                    optional name for a named token
+        * @exception OAuthException when no credentials found
+        * @return array
+        */
+       public function getServerTokenSecrets ( $consumer_key, $token, $token_type, $user_id, $name = '' )
+       {
+               if ($token_type != 'request' && $token_type != 'access')
+               {
+                       throw new OAuthException('Unkown token type "'.$token_type.'", must be either "request" or "access"');
+               }
+
+               // Take the most recent token of the given type
+               $r = $this->query_row_assoc('
+                                       SELECT  ocr_consumer_key                as consumer_key,
+                                                       ocr_consumer_secret             as consumer_secret,
+                                                       oct_token                               as token,
+                                                       oct_token_secret                as token_secret,
+                                                       oct_name                                as token_name,
+                                                       ocr_signature_methods   as signature_methods,
+                                                       ocr_server_uri                  as server_uri,
+                                                       ocr_request_token_uri   as request_token_uri,
+                                                       ocr_authorize_uri               as authorize_uri,
+                                                       ocr_access_token_uri    as access_token_uri,
+                                                       IF(oct_token_ttl >= \'9999-12-31\', NULL, UNIX_TIMESTAMP(oct_token_ttl) - UNIX_TIMESTAMP(NOW())) as token_ttl
+                                       FROM oauth_consumer_registry
+                                                       JOIN oauth_consumer_token
+                                                       ON oct_ocr_id_ref = ocr_id
+                                       WHERE ocr_consumer_key = \'%s\'
+                                         AND oct_token_type   = \'%s\'
+                                         AND oct_token        = \'%s\'
+                                         AND oct_usa_id_ref   = %d
+                                         AND oct_token_ttl    >= NOW()
+                                       ', $consumer_key, $token_type, $token, $user_id
+                                       );
+                                       
+               if (empty($r))
+               {
+                       throw new OAuthException('Could not find a "'.$token_type.'" token for consumer "'.$consumer_key.'" and user '.$user_id);
+               }
+               if (isset($r['signature_methods']) && !empty($r['signature_methods']))
+               {
+                       $r['signature_methods'] = explode(',',$r['signature_methods']);
+               }
+               else
+               {
+                       $r['signature_methods'] = array();
+               }
+               return $r;              
+       }
+
+
+       /**
+        * Add a request token we obtained from a server.
+        * 
+        * @todo remove old tokens for this user and this ocr_id
+        * @param string consumer_key   key of the server in the consumer registry
+        * @param string token_type             one of 'request' or 'access'
+        * @param string token
+        * @param string token_secret
+        * @param int    user_id                        the user owning the token
+        * @param array  options                        extra options, name and token_ttl
+        * @exception OAuthException when server is not known
+        * @exception OAuthException when we received a duplicate token
+        */
+       public function addServerToken ( $consumer_key, $token_type, $token, $token_secret, $user_id, $options = array() )
+       {
+               if ($token_type != 'request' && $token_type != 'access')
+               {
+                       throw new OAuthException('Unknown token type "'.$token_type.'", must be either "request" or "access"');
+               }
+
+               // Maximum time to live for this token
+               if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
+               {
+                       $ttl = 'DATE_ADD(NOW(), INTERVAL '.intval($options['token_ttl']).' SECOND)';
+               }
+               else if ($token == 'request')
+               {
+                       $ttl = 'DATE_ADD(NOW(), INTERVAL '.$this->max_request_token_ttl.' SECOND)';
+               }
+               else
+               {
+                       $ttl = "'9999-12-31'";
+               }
+               
+               $ocr_id = $this->query_one('
+                                       SELECT ocr_id
+                                       FROM oauth_consumer_registry
+                                       WHERE ocr_consumer_key = \'%s\'
+                                       ', $consumer_key);
+                                       
+               if (empty($ocr_id))
+               {
+                       throw new OAuthException('No server associated with consumer_key "'.$consumer_key.'"');
+               }
+               
+               // Named tokens, unique per user/consumer key
+               if (isset($options['name']) && $options['name'] != '')
+               {
+                       $name = $options['name'];
+               }
+               else
+               {
+                       $name = '';
+               }
+
+               // Delete any old tokens with the same type and name for this user/server combination
+               $this->query('
+                                       DELETE FROM oauth_consumer_token
+                                       WHERE oct_ocr_id_ref = %d
+                                         AND oct_usa_id_ref = %d
+                                         AND oct_token_type = LOWER(\'%s\')
+                                         AND oct_name       = \'%s\'
+                                       ',
+                                       $ocr_id,
+                                       $user_id,
+                                       $token_type,
+                                       $name);
+
+               // Insert the new token
+               $this->query('
+                                       INSERT IGNORE INTO oauth_consumer_token
+                                       SET oct_ocr_id_ref      = %d,
+                                               oct_usa_id_ref  = %d,
+                                               oct_name                = \'%s\',
+                                               oct_token               = \'%s\',
+                                               oct_token_secret= \'%s\',
+                                               oct_token_type  = LOWER(\'%s\'),
+                                               oct_timestamp   = NOW(),
+                                               oct_token_ttl   = '.$ttl.'
+                                       ',
+                                       $ocr_id,
+                                       $user_id,
+                                       $name,
+                                       $token,
+                                       $token_secret,
+                                       $token_type);
+               
+               if (!$this->query_affected_rows())
+               {
+                       throw new OAuthException('Received duplicate token "'.$token.'" for the same consumer_key "'.$consumer_key.'"');
+               }
+       }
+
+
+       /**
+        * Delete a server key.  This removes access to that site.
+        * 
+        * @param string consumer_key
+        * @param int user_id   user registering this server
+        * @param boolean user_is_admin
+        */
+       public function deleteServer ( $consumer_key, $user_id, $user_is_admin = false )
+       {
+               if ($user_is_admin)
+               {
+                       $this->query('
+                                       DELETE FROM oauth_consumer_registry
+                                       WHERE ocr_consumer_key = \'%s\'
+                                         AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
+                                       ', $consumer_key, $user_id);
+               }
+               else
+               {
+                       $this->query('
+                                       DELETE FROM oauth_consumer_registry
+                                       WHERE ocr_consumer_key = \'%s\'
+                                         AND ocr_usa_id_ref   = %d
+                                       ', $consumer_key, $user_id);
+               }
+       }
+       
+       
+       /**
+        * Get a server from the consumer registry using the consumer key
+        * 
+        * @param string consumer_key
+        * @param int user_id
+        * @param boolean user_is_admin (optional)
+        * @exception OAuthException when server is not found
+        * @return array
+        */     
+       public function getServer ( $consumer_key, $user_id, $user_is_admin = false )
+       {
+               $r = $this->query_row_assoc('
+                               SELECT  ocr_id                                  as id,
+                                               ocr_usa_id_ref                  as user_id,
+                                               ocr_consumer_key                as consumer_key,
+                                               ocr_consumer_secret     as consumer_secret,
+                                               ocr_signature_methods   as signature_methods,
+                                               ocr_server_uri                  as server_uri,
+                                               ocr_request_token_uri   as request_token_uri,
+                                               ocr_authorize_uri               as authorize_uri,
+                                               ocr_access_token_uri    as access_token_uri
+                               FROM oauth_consumer_registry
+                               WHERE ocr_consumer_key = \'%s\'
+                                 AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
+                               ',      $consumer_key, $user_id);
+               
+               if (empty($r))
+               {
+                       throw new OAuthException('No server with consumer_key "'.$consumer_key.'" has been registered (for this user)');
+               }
+                       
+               if (isset($r['signature_methods']) && !empty($r['signature_methods']))
+               {
+                       $r['signature_methods'] = explode(',',$r['signature_methods']);
+               }
+               else
+               {
+                       $r['signature_methods'] = array();
+               }
+               return $r;
+       }
+
+
+
+       /**
+        * Find the server details that might be used for a request
+        * 
+        * The consumer_key must belong to the user or be public (user id is null)
+        * 
+        * @param string uri    uri of the server
+        * @param int user_id   id of the logged on user
+        * @exception OAuthException when no credentials found
+        * @return array
+        */
+       public function getServerForUri ( $uri, $user_id )
+       {
+               // Find a consumer key and token for the given uri
+               $ps             = parse_url($uri);
+               $host   = isset($ps['host']) ? $ps['host'] : 'localhost';
+               $path   = isset($ps['path']) ? $ps['path'] : '';
+               
+               if (empty($path) || substr($path, -1) != '/')
+               {
+                       $path .= '/';
+               }
+
+               // The owner of the consumer_key is either the user or nobody (public consumer key)
+               $server = $this->query_row_assoc('
+                                       SELECT  ocr_id                                  as id,
+                                                       ocr_usa_id_ref                  as user_id,
+                                                       ocr_consumer_key                as consumer_key,
+                                                       ocr_consumer_secret             as consumer_secret,
+                                                       ocr_signature_methods   as signature_methods,
+                                                       ocr_server_uri                  as server_uri,
+                                                       ocr_request_token_uri   as request_token_uri,
+                                                       ocr_authorize_uri               as authorize_uri,
+                                                       ocr_access_token_uri    as access_token_uri
+                                       FROM oauth_consumer_registry
+                                       WHERE ocr_server_uri_host = \'%s\'
+                                         AND ocr_server_uri_path = LEFT(\'%s\', LENGTH(ocr_server_uri_path))
+                                         AND (ocr_usa_id_ref = %s OR ocr_usa_id_ref IS NULL)
+                                       ORDER BY ocr_usa_id_ref DESC, consumer_secret DESC, LENGTH(ocr_server_uri_path) DESC
+                                       LIMIT 0,1
+                                       ', $host, $path, $user_id
+                                       );
+               
+               if (empty($server))
+               {
+                       throw new OAuthException('No server available for '.$uri);
+               }
+               $server['signature_methods'] = explode(',', $server['signature_methods']);
+               return $server;
+       }
+
+
+       /**
+        * Get a list of all server token this user has access to.
+        * 
+        * @param int usr_id
+        * @return array
+        */
+       public function listServerTokens ( $user_id )
+       {
+               $ts = $this->query_all_assoc('
+                                       SELECT  ocr_consumer_key                as consumer_key,
+                                                       ocr_consumer_secret             as consumer_secret,
+                                                       oct_id                                  as token_id,
+                                                       oct_token                               as token,
+                                                       oct_token_secret                as token_secret,
+                                                       oct_usa_id_ref                  as user_id,
+                                                       ocr_signature_methods   as signature_methods,
+                                                       ocr_server_uri                  as server_uri,
+                                                       ocr_server_uri_host             as server_uri_host,
+                                                       ocr_server_uri_path             as server_uri_path,
+                                                       ocr_request_token_uri   as request_token_uri,
+                                                       ocr_authorize_uri               as authorize_uri,
+                                                       ocr_access_token_uri    as access_token_uri,
+                                                       oct_timestamp                   as timestamp
+                                       FROM oauth_consumer_registry
+                                                       JOIN oauth_consumer_token
+                                                       ON oct_ocr_id_ref = ocr_id
+                                       WHERE oct_usa_id_ref = %d
+                                         AND oct_token_type = \'access\'
+                                         AND oct_token_ttl  >= NOW()
+                                       ORDER BY ocr_server_uri_host, ocr_server_uri_path
+                                       ', $user_id);
+               return $ts;
+       }
+
+
+       /**
+        * Count how many tokens we have for the given server
+        * 
+        * @param string consumer_key
+        * @return int
+        */
+       public function countServerTokens ( $consumer_key )
+       {
+               $count = $this->query_one('
+                                       SELECT COUNT(oct_id)
+                                       FROM oauth_consumer_token
+                                                       JOIN oauth_consumer_registry
+                                                       ON oct_ocr_id_ref = ocr_id
+                                       WHERE oct_token_type   = \'access\'
+                                         AND ocr_consumer_key = \'%s\'
+                                         AND oct_token_ttl    >= NOW()
+                                       ', $consumer_key);
+               
+               return $count;
+       }
+
+
+       /**
+        * Get a specific server token for the given user
+        * 
+        * @param string consumer_key
+        * @param string token
+        * @param int user_id
+        * @exception OAuthException when no such token found
+        * @return array
+        */
+       public function getServerToken ( $consumer_key, $token, $user_id )
+       {
+               $ts = $this->query_row_assoc('
+                                       SELECT  ocr_consumer_key                as consumer_key,
+                                                       ocr_consumer_secret             as consumer_secret,
+                                                       oct_token                               as token,
+                                                       oct_token_secret                as token_secret,
+                                                       oct_usa_id_ref                  as usr_id,
+                                                       ocr_signature_methods   as signature_methods,
+                                                       ocr_server_uri                  as server_uri,
+                                                       ocr_server_uri_host             as server_uri_host,
+                                                       ocr_server_uri_path             as server_uri_path,
+                                                       ocr_request_token_uri   as request_token_uri,
+                                                       ocr_authorize_uri               as authorize_uri,
+                                                       ocr_access_token_uri    as access_token_uri,
+                                                       oct_timestamp                   as timestamp
+                                       FROM oauth_consumer_registry
+                                                       JOIN oauth_consumer_token
+                                                       ON oct_ocr_id_ref = ocr_id
+                                       WHERE ocr_consumer_key = \'%s\'
+                                         AND oct_usa_id_ref   = %d
+                                         AND oct_token_type   = \'access\'
+                                         AND oct_token        = \'%s\'
+                                         AND oct_token_ttl    >= NOW()
+                                       ', $consumer_key, $user_id, $token);
+               
+               if (empty($ts))
+               {
+                       throw new OAuthException('No such consumer key ('.$consumer_key.') and token ('.$token.') combination for user "'.$user_id.'"');
+               }
+               return $ts;
+       }
+
+
+       /**
+        * Delete a token we obtained from a server.
+        * 
+        * @param string consumer_key
+        * @param string token
+        * @param int user_id
+        * @param boolean user_is_admin
+        */
+       public function deleteServerToken ( $consumer_key, $token, $user_id, $user_is_admin = false )
+       {
+               if ($user_is_admin)
+               {
+                       $this->query('
+                               DELETE oauth_consumer_token 
+                               FROM oauth_consumer_token
+                                               JOIN oauth_consumer_registry
+                                               ON oct_ocr_id_ref = ocr_id
+                               WHERE ocr_consumer_key  = \'%s\'
+                                 AND oct_token                 = \'%s\'
+                               ', $consumer_key, $token);
+               }
+               else
+               {
+                       $this->query('
+                               DELETE oauth_consumer_token 
+                               FROM oauth_consumer_token
+                                               JOIN oauth_consumer_registry
+                                               ON oct_ocr_id_ref = ocr_id
+                               WHERE ocr_consumer_key  = \'%s\'
+                                 AND oct_token                 = \'%s\'
+                                 AND oct_usa_id_ref    = %d
+                               ', $consumer_key, $token, $user_id);
+               }
+       }
+
+
+       /**
+        * Set the ttl of a server access token.  This is done when the
+        * server receives a valid request with a xoauth_token_ttl parameter in it.
+        * 
+        * @param string consumer_key
+        * @param string token
+        * @param int token_ttl
+        */
+       public function setServerTokenTtl ( $consumer_key, $token, $token_ttl )
+       {
+               if ($token_ttl <= 0)
+               {
+                       // Immediate delete when the token is past its ttl
+                       $this->deleteServerToken($consumer_key, $token, 0, true);
+               }
+               else
+               {
+                       // Set maximum time to live for this token
+                       $this->query('
+                                               UPDATE oauth_consumer_token, oauth_consumer_registry
+                                               SET ost_token_ttl = DATE_ADD(NOW(), INTERVAL %d SECOND)
+                                               WHERE ocr_consumer_key  = \'%s\'
+                                                 AND oct_ocr_id_ref    = ocr_id
+                                                 AND oct_token             = \'%s\'
+                                               ', $token_ttl, $consumer_key, $token);
+               }
+       }
+
+
+       /**
+        * Get a list of all consumers from the consumer registry.
+        * The consumer keys belong to the user or are public (user id is null)
+        * 
+        * @param string q      query term
+        * @param int user_id
+        * @return array
+        */     
+       public function listServers ( $q = '', $user_id )
+       {
+               $q    = trim(str_replace('%', '', $q));
+               $args = array();
+
+               if (!empty($q))
+               {
+                       $where = ' WHERE (      ocr_consumer_key like \'%%%s%%\'
+                                                        OR ocr_server_uri like \'%%%s%%\'
+                                                        OR ocr_server_uri_host like \'%%%s%%\'
+                                                        OR ocr_server_uri_path like \'%%%s%%\')
+                                                AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
+                                       ';
+                       
+                       $args[] = $q;
+                       $args[] = $q;
+                       $args[] = $q;
+                       $args[] = $q;
+                       $args[] = $user_id;
+               }
+               else
+               {
+                       $where  = ' WHERE ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL';
+                       $args[] = $user_id;
+               }
+
+               $servers = $this->query_all_assoc('
+                                       SELECT  ocr_id                                  as id,
+                                                       ocr_usa_id_ref                  as user_id,
+                                                       ocr_consumer_key                as consumer_key,
+                                                       ocr_consumer_secret     as consumer_secret,
+                                                       ocr_signature_methods   as signature_methods,
+                                                       ocr_server_uri                  as server_uri,
+                                                       ocr_server_uri_host             as server_uri_host,
+                                                       ocr_server_uri_path             as server_uri_path,
+                                                       ocr_request_token_uri   as request_token_uri,
+                                                       ocr_authorize_uri               as authorize_uri,
+                                                       ocr_access_token_uri    as access_token_uri
+                                       FROM oauth_consumer_registry
+                                       '.$where.'
+                                       ORDER BY ocr_server_uri_host, ocr_server_uri_path
+                                       ', $args);
+               return $servers;
+       }
+
+
+       /**
+        * Register or update a server for our site (we will be the consumer)
+        * 
+        * (This is the registry at the consumers, registering servers ;-) )
+        * 
+        * @param array server
+        * @param int user_id   user registering this server
+        * @param boolean user_is_admin
+        * @exception OAuthException when fields are missing or on duplicate consumer_key
+        * @return consumer_key
+        */
+       public function updateServer ( $server, $user_id, $user_is_admin = false )
+       {
+               foreach (array('consumer_key', 'server_uri') as $f)
+               {
+                       if (empty($server[$f]))
+                       {
+                               throw new OAuthException('The field "'.$f.'" must be set and non empty');
+                       }
+               }
+               
+               if (!empty($server['id']))
+               {
+                       $exists = $this->query_one('
+                                               SELECT ocr_id
+                                               FROM oauth_consumer_registry
+                                               WHERE ocr_consumer_key = \'%s\'
+                                                 AND ocr_id <> %d
+                                                 AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
+                                               ', $server['consumer_key'], $server['id'], $user_id);
+               }
+               else
+               {
+                       $exists = $this->query_one('
+                                               SELECT ocr_id
+                                               FROM oauth_consumer_registry
+                                               WHERE ocr_consumer_key = \'%s\'
+                                                 AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
+                                               ', $server['consumer_key'], $user_id);
+               }
+
+               if ($exists)
+               {
+                       throw new OAuthException('The server with key "'.$server['consumer_key'].'" has already been registered');
+               }
+
+               $parts = parse_url($server['server_uri']);
+               $host  = (isset($parts['host']) ? $parts['host'] : 'localhost');
+               $path  = (isset($parts['path']) ? $parts['path'] : '/');
+
+               if (isset($server['signature_methods']))
+               {
+                       if (is_array($server['signature_methods']))
+                       {
+                               $server['signature_methods'] = strtoupper(implode(',', $server['signature_methods']));
+                       }
+               }       
+               else
+               {
+                       $server['signature_methods'] = '';
+               }
+
+               // When the user is an admin, then the user can update the user_id of this record
+               if ($user_is_admin && array_key_exists('user_id', $server))
+               {
+                       if (is_null($server['user_id']))
+                       {
+                               $update_user =  ', ocr_usa_id_ref = NULL';
+                       }
+                       else
+                       {
+                               $update_user =  ', ocr_usa_id_ref = '.intval($server['user_id']);
+                       }
+               }
+               else
+               {
+                       $update_user = '';
+               }
+               
+               if (!empty($server['id']))
+               {
+                       // Check if the current user can update this server definition
+                       if (!$user_is_admin)
+                       {
+                               $ocr_usa_id_ref = $this->query_one('
+                                                                       SELECT ocr_usa_id_ref
+                                                                       FROM oauth_consumer_registry
+                                                                       WHERE ocr_id = %d
+                                                                       ', $server['id']);
+                               
+                               if ($ocr_usa_id_ref != $user_id)
+                               {
+                                       throw new OAuthException('The user "'.$user_id.'" is not allowed to update this server');
+                               }
+                       }
+                       
+                       // Update the consumer registration     
+                       $this->query('
+                                       UPDATE oauth_consumer_registry
+                                       SET ocr_consumer_key            = \'%s\',
+                                               ocr_consumer_secret     = \'%s\',
+                                               ocr_server_uri          = \'%s\',
+                                               ocr_server_uri_host     = \'%s\',
+                                               ocr_server_uri_path     = \'%s\',
+                                               ocr_timestamp           = NOW(),
+                                               ocr_request_token_uri   = \'%s\',
+                                               ocr_authorize_uri               = \'%s\',
+                                               ocr_access_token_uri    = \'%s\',
+                                               ocr_signature_methods   = \'%s\'
+                                               '.$update_user.'
+                                       WHERE ocr_id = %d
+                                       ', 
+                                       $server['consumer_key'],
+                                       $server['consumer_secret'],
+                                       $server['server_uri'],
+                                       strtolower($host),
+                                       $path,
+                                       isset($server['request_token_uri']) ? $server['request_token_uri'] : '',
+                                       isset($server['authorize_uri'])     ? $server['authorize_uri']     : '',
+                                       isset($server['access_token_uri'])  ? $server['access_token_uri']  : '',
+                                       $server['signature_methods'],
+                                       $server['id']
+                                       );
+               }
+               else
+               {
+                       if (empty($update_user))
+                       {
+                               // Per default the user owning the key is the user registering the key
+                               $update_user =  ', ocr_usa_id_ref = '.intval($user_id);
+                       }
+
+                       $this->query('
+                                       INSERT INTO oauth_consumer_registry
+                                       SET ocr_consumer_key            = \'%s\',
+                                               ocr_consumer_secret     = \'%s\',
+                                               ocr_server_uri          = \'%s\',
+                                               ocr_server_uri_host     = \'%s\',
+                                               ocr_server_uri_path     = \'%s\',
+                                               ocr_timestamp           = NOW(),
+                                               ocr_request_token_uri   = \'%s\',
+                                               ocr_authorize_uri               = \'%s\',
+                                               ocr_access_token_uri    = \'%s\',
+                                               ocr_signature_methods   = \'%s\'
+                                               '.$update_user, 
+                                       $server['consumer_key'],
+                                       $server['consumer_secret'],
+                                       $server['server_uri'],
+                                       strtolower($host),
+                                       $path,
+                                       isset($server['request_token_uri']) ? $server['request_token_uri'] : '',
+                                       isset($server['authorize_uri'])     ? $server['authorize_uri']     : '',
+                                       isset($server['access_token_uri'])  ? $server['access_token_uri']  : '',
+                                       $server['signature_methods']
+                                       );
+               
+                       $ocr_id = $this->query_insert_id();
+               }
+               return $server['consumer_key'];
+       }
+
+
+       /**
+        * Insert/update a new consumer with this server (we will be the server)
+        * When this is a new consumer, then also generate the consumer key and secret.
+        * Never updates the consumer key and secret.
+        * When the id is set, then the key and secret must correspond to the entry
+        * being updated.
+        * 
+        * (This is the registry at the server, registering consumers ;-) )
+        * 
+        * @param array consumer
+        * @param int user_id   user registering this consumer
+        * @param boolean user_is_admin
+        * @return string consumer key
+        */
+       public function updateConsumer ( $consumer, $user_id, $user_is_admin = false )
+       {
+               if (!$user_is_admin)
+               {
+                       foreach (array('requester_name', 'requester_email') as $f)
+                       {
+                               if (empty($consumer[$f]))
+                               {
+                                       throw new OAuthException('The field "'.$f.'" must be set and non empty');
+                               }
+                       }
+               }
+               
+               if (!empty($consumer['id']))
+               {
+                       if (empty($consumer['consumer_key']))
+                       {
+                               throw new OAuthException('The field "consumer_key" must be set and non empty');
+                       }
+                       if (!$user_is_admin && empty($consumer['consumer_secret']))
+                       {
+                               throw new OAuthException('The field "consumer_secret" must be set and non empty');
+                       }
+
+                       // Check if the current user can update this server definition
+                       if (!$user_is_admin)
+                       {
+                               $osr_usa_id_ref = $this->query_one('
+                                                                       SELECT osr_usa_id_ref
+                                                                       FROM oauth_server_registry
+                                                                       WHERE osr_id = %d
+                                                                       ', $consumer['id']);
+                               
+                               if ($osr_usa_id_ref != $user_id)
+                               {
+                                       throw new OAuthException('The user "'.$user_id.'" is not allowed to update this consumer');
+                               }
+                       }
+                       else
+                       {
+                               // User is an admin, allow a key owner to be changed or key to be shared
+                               if (array_key_exists('user_id',$consumer))
+                               {
+                                       if (is_null($consumer['user_id']))
+                                       {
+                                               $this->query('
+                                                       UPDATE oauth_server_registry
+                                                       SET osr_usa_id_ref = NULL
+                                                       WHERE osr_id = %d
+                                                       ', $consumer['id']);
+                                       }
+                                       else
+                                       {
+                                               $this->query('
+                                                       UPDATE oauth_server_registry
+                                                       SET osr_usa_id_ref = %d
+                                                       WHERE osr_id = %d
+                                                       ', $consumer['user_id'], $consumer['id']);      
+                                       }
+                               }
+                       }
+                       
+                       $this->query('
+                               UPDATE oauth_server_registry
+                               SET osr_requester_name          = \'%s\',
+                                       osr_requester_email             = \'%s\',
+                                       osr_callback_uri                = \'%s\',
+                                       osr_application_uri             = \'%s\',
+                                       osr_application_title   = \'%s\',
+                                       osr_application_descr   = \'%s\',
+                                       osr_application_notes   = \'%s\',
+                                       osr_application_type    = \'%s\',
+                                       osr_application_commercial = IF(%d,1,0),
+                                       osr_timestamp                   = NOW()
+                               WHERE osr_id              = %d
+                                 AND osr_consumer_key    = \'%s\'
+                                 AND osr_consumer_secret = \'%s\'
+                               ',
+                               $consumer['requester_name'],
+                               $consumer['requester_email'],
+                               isset($consumer['callback_uri'])                ? $consumer['callback_uri']                      : '',
+                               isset($consumer['application_uri'])     ? $consumer['application_uri']                   : '',
+                               isset($consumer['application_title'])   ? $consumer['application_title']                 : '',
+                               isset($consumer['application_descr'])   ? $consumer['application_descr']                 : '',
+                               isset($consumer['application_notes'])   ? $consumer['application_notes']                 : '',
+                               isset($consumer['application_type'])    ? $consumer['application_type']                  : '',
+                               isset($consumer['application_commercial']) ? $consumer['application_commercial'] : 0,
+                               $consumer['id'],
+                               $consumer['consumer_key'],
+                               $consumer['consumer_secret']
+                               );
+                               
+
+                       $consumer_key = $consumer['consumer_key'];
+               }
+               else
+               {
+                       $consumer_key   = $this->generateKey(true);
+                       $consumer_secret= $this->generateKey();
+
+                       // When the user is an admin, then the user can be forced to something else that the user
+                       if ($user_is_admin && array_key_exists('user_id',$consumer))
+                       {
+                               if (is_null($consumer['user_id']))
+                               {
+                                       $owner_id = 'NULL';
+                               }
+                               else
+                               {
+                                       $owner_id = intval($consumer['user_id']);
+                               }
+                       }
+                       else
+                       {
+                               // No admin, take the user id as the owner id.
+                               $owner_id = intval($user_id);
+                       }
+
+                       $this->query('
+                               INSERT INTO oauth_server_registry
+                               SET osr_enabled                         = 1,
+                                       osr_status                              = \'active\',
+                                       osr_usa_id_ref                  = %s,
+                                       osr_consumer_key                = \'%s\',
+                                       osr_consumer_secret             = \'%s\',
+                                       osr_requester_name              = \'%s\',
+                                       osr_requester_email             = \'%s\',
+                                       osr_callback_uri                = \'%s\',
+                                       osr_application_uri             = \'%s\',
+                                       osr_application_title   = \'%s\',
+                                       osr_application_descr   = \'%s\',
+                                       osr_application_notes   = \'%s\',
+                                       osr_application_type    = \'%s\',
+                                       osr_application_commercial = IF(%d,1,0),
+                                       osr_timestamp                   = NOW(),
+                                       osr_issue_date                  = NOW()
+                               ',
+                               $owner_id,
+                               $consumer_key,
+                               $consumer_secret,
+                               $consumer['requester_name'],
+                               $consumer['requester_email'],
+                               isset($consumer['callback_uri'])                ? $consumer['callback_uri']                      : '',
+                               isset($consumer['application_uri'])     ? $consumer['application_uri']                   : '',
+                               isset($consumer['application_title'])   ? $consumer['application_title']                 : '',
+                               isset($consumer['application_descr'])   ? $consumer['application_descr']                 : '',
+                               isset($consumer['application_notes'])   ? $consumer['application_notes']                 : '',
+                               isset($consumer['application_type'])    ? $consumer['application_type']                  : '',
+                               isset($consumer['application_commercial']) ? $consumer['application_commercial'] : 0
+                               );
+               }
+               return $consumer_key;
+
+       }
+
+
+
+       /**
+        * Delete a consumer key.  This removes access to our site for all applications using this key.
+        * 
+        * @param string consumer_key
+        * @param int user_id   user registering this server
+        * @param boolean user_is_admin
+        */
+       public function deleteConsumer ( $consumer_key, $user_id, $user_is_admin = false )
+       {
+               if ($user_is_admin)
+               {
+                       $this->query('
+                                       DELETE FROM oauth_server_registry
+                                       WHERE osr_consumer_key = \'%s\'
+                                         AND (osr_usa_id_ref = %d OR osr_usa_id_ref IS NULL)
+                                       ', $consumer_key, $user_id);
+               }
+               else
+               {
+                       $this->query('
+                                       DELETE FROM oauth_server_registry
+                                       WHERE osr_consumer_key = \'%s\'
+                                         AND osr_usa_id_ref   = %d
+                                       ', $consumer_key, $user_id);
+               }
+       }       
+       
+       
+       
+       /**
+        * Fetch a consumer of this server, by consumer_key.
+        * 
+        * @param string consumer_key
+        * @param int user_id
+        * @param boolean user_is_admin (optional)
+        * @exception OAuthException when consumer not found
+        * @return array
+        */
+       public function getConsumer ( $consumer_key, $user_id, $user_is_admin = false )
+       {
+               $consumer = $this->query_row_assoc('
+                                               SELECT  *
+                                               FROM oauth_server_registry
+                                               WHERE osr_consumer_key = \'%s\'
+                                               ', $consumer_key);
+               
+               if (!is_array($consumer))
+               {
+                       throw new OAuthException('No consumer with consumer_key "'.$consumer_key.'"');
+               }
+
+               $c = array();
+               foreach ($consumer as $key => $value)
+               {
+                       $c[substr($key, 4)] = $value;
+               }
+               $c['user_id'] = $c['usa_id_ref'];
+
+               if (!$user_is_admin && !empty($c['user_id']) && $c['user_id'] != $user_id)
+               {
+                       throw new OAuthException('No access to the consumer information for consumer_key "'.$consumer_key.'"');
+               }
+               return $c;
+       }
+
+
+       /**
+        * Fetch the static consumer key for this provider.  The user for the static consumer 
+        * key is NULL (no user, shared key).  If the key did not exist then the key is created.
+        * 
+        * @return string
+        */
+       public function getConsumerStatic ()
+       {
+               $consumer = $this->query_one('
+                                               SELECT osr_consumer_key
+                                               FROM oauth_server_registry
+                                               WHERE osr_consumer_key LIKE \'sc-%%\'
+                                                 AND osr_usa_id_ref IS NULL
+                                               ');
+
+               if (empty($consumer))
+               {
+                       $consumer_key = 'sc-'.$this->generateKey(true);
+                       $this->query('
+                               INSERT INTO oauth_server_registry
+                               SET osr_enabled                         = 1,
+                                       osr_status                              = \'active\',
+                                       osr_usa_id_ref                  = NULL,
+                                       osr_consumer_key                = \'%s\',
+                                       osr_consumer_secret             = \'\',
+                                       osr_requester_name              = \'\',
+                                       osr_requester_email             = \'\',
+                                       osr_callback_uri                = \'\',
+                                       osr_application_uri             = \'\',
+                                       osr_application_title   = \'Static shared consumer key\',
+                                       osr_application_descr   = \'\',
+                                       osr_application_notes   = \'Static shared consumer key\',
+                                       osr_application_type    = \'\',
+                                       osr_application_commercial = 0,
+                                       osr_timestamp                   = NOW(),
+                                       osr_issue_date                  = NOW()
+                               ',
+                               $consumer_key
+                               );
+                       
+                       // Just make sure that if the consumer key is truncated that we get the truncated string
+                       $consumer = $this->getConsumerStatic();
+               }
+               return $consumer;
+       }
+
+
+       /**
+        * Add an unautorized request token to our server.
+        * 
+        * @param string consumer_key
+        * @param array options         (eg. token_ttl)
+        * @return array (token, token_secret)
+        */
+       public function addConsumerRequestToken ( $consumer_key, $options = array() )
+       {
+               $token  = $this->generateKey(true);
+               $secret = $this->generateKey();
+               $osr_id = $this->query_one('
+                                               SELECT osr_id
+                                               FROM oauth_server_registry
+                                               WHERE osr_consumer_key = \'%s\'
+                                                 AND osr_enabled      = 1
+                                               ', $consumer_key);
+
+               if (!$osr_id)
+               {
+                       throw new OAuthException('No server with consumer_key "'.$consumer_key.'" or consumer_key is disabled');
+               }
+
+               if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
+               {
+                       $ttl = intval($options['token_ttl']);
+               }
+               else
+               {
+                       $ttl = $this->max_request_token_ttl;
+               }
+
+               $this->query('
+                               INSERT INTO oauth_server_token
+                               SET ost_osr_id_ref              = %d,
+                                       ost_usa_id_ref          = 1,
+                                       ost_token                       = \'%s\',
+                                       ost_token_secret        = \'%s\',
+                                       ost_token_type          = \'request\',
+                                       ost_token_ttl       = DATE_ADD(NOW(), INTERVAL %d SECOND)
+                               ON DUPLICATE KEY UPDATE
+                                       ost_osr_id_ref          = VALUES(ost_osr_id_ref),
+                                       ost_usa_id_ref          = VALUES(ost_usa_id_ref),
+                                       ost_token                       = VALUES(ost_token),
+                                       ost_token_secret        = VALUES(ost_token_secret),
+                                       ost_token_type          = VALUES(ost_token_type),
+                                       ost_token_ttl       = VALUES(ost_token_ttl),
+                                       ost_timestamp           = NOW()
+                               ', $osr_id, $token, $secret, $ttl);
+               
+               return array('token'=>$token, 'token_secret'=>$secret, 'token_ttl'=>$ttl);
+       }
+       
+       
+       /**
+        * Fetch the consumer request token, by request token.
+        * 
+        * @param string token
+        * @return array  token and consumer details
+        */
+       public function getConsumerRequestToken ( $token )
+       {
+               $rs = $this->query_row_assoc('
+                               SELECT  ost_token                       as token,
+                                               ost_token_secret        as token_secret,
+                                               osr_consumer_key        as consumer_key,
+                                               osr_consumer_secret     as consumer_secret,
+                                               ost_token_type          as token_type
+                               FROM oauth_server_token
+                                               JOIN oauth_server_registry
+                                               ON ost_osr_id_ref = osr_id
+                               WHERE ost_token_type = \'request\'
+                                 AND ost_token      = \'%s\'
+                                 AND ost_token_ttl  >= NOW()
+                               ', $token);
+               
+               return $rs;
+       }
+       
+
+       /**
+        * Delete a consumer token.  The token must be a request or authorized token.
+        * 
+        * @param string token
+        */
+       public function deleteConsumerRequestToken ( $token )
+       {
+               $this->query('
+                                       DELETE FROM oauth_server_token
+                                       WHERE ost_token          = \'%s\'
+                                         AND ost_token_type = \'request\'
+                                       ', $token);
+       }
+       
+
+       /**
+        * Upgrade a request token to be an authorized request token.
+        * 
+        * @param string token
+        * @param int    user_id  user authorizing the token
+        * @param string referrer_host used to set the referrer host for this token, for user feedback
+        */
+       public function authorizeConsumerRequestToken ( $token, $user_id, $referrer_host = '' )
+       {
+               $this->query('
+                                       UPDATE oauth_server_token
+                                       SET ost_authorized    = 1,
+                                               ost_usa_id_ref    = %d,
+                                               ost_timestamp     = NOW(),
+                                               ost_referrer_host = \'%s\'
+                                       WHERE ost_token      = \'%s\'
+                                         AND ost_token_type = \'request\'
+                                       ', $user_id, $referrer_host, $token);
+       }
+
+
+       /**
+        * Count the consumer access tokens for the given consumer.
+        * 
+        * @param string consumer_key
+        * @return int
+        */
+       public function countConsumerAccessTokens ( $consumer_key )
+       {
+               $count = $this->query_one('
+                                       SELECT COUNT(ost_id)
+                                       FROM oauth_server_token
+                                                       JOIN oauth_server_registry
+                                                       ON ost_osr_id_ref = osr_id
+                                       WHERE ost_token_type   = \'access\'
+                                         AND osr_consumer_key = \'%s\'
+                                         AND ost_token_ttl    >= NOW()
+                                       ', $consumer_key);
+               
+               return $count;
+       }
+
+
+       /**
+        * Exchange an authorized request token for new access token.
+        * 
+        * @param string token
+        * @param array options         options for the token, token_ttl
+        * @exception OAuthException when token could not be exchanged
+        * @return array (token, token_secret)
+        */
+       public function exchangeConsumerRequestForAccessToken ( $token, $options = array() )
+       {
+               $new_token  = $this->generateKey(true);
+               $new_secret = $this->generateKey();
+
+               // Maximum time to live for this token
+               if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
+               {
+                       $ttl_sql = 'DATE_ADD(NOW(), INTERVAL '.intval($options['token_ttl']).' SECOND)';
+               }
+               else
+               {
+                       $ttl_sql = "'9999-12-31'";
+               }
+
+               $this->query('
+                                       UPDATE oauth_server_token
+                                       SET ost_token                   = \'%s\',
+                                               ost_token_secret        = \'%s\',
+                                               ost_token_type          = \'access\',
+                                               ost_timestamp           = NOW(),
+                                               ost_token_ttl       = '.$ttl_sql.'
+                                       WHERE ost_token      = \'%s\'
+                                         AND ost_token_type = \'request\'
+                                         AND ost_authorized = 1
+                                         AND ost_token_ttl  >= NOW()
+                                       ', $new_token, $new_secret, $token);
+               
+               if ($this->query_affected_rows() != 1)
+               {
+                       throw new OAuthException('Can\'t exchange request token "'.$token.'" for access token. No such token or not authorized');
+               }
+
+               $ret = array('token' => $new_token, 'token_secret' => $new_secret);
+               $ttl = $this->query_one('
+                                       SELECT  IF(ost_token_ttl >= \'9999-12-31\', NULL, UNIX_TIMESTAMP(ost_token_ttl) - UNIX_TIMESTAMP(NOW())) as token_ttl
+                                       FROM oauth_server_token
+                                       WHERE ost_token = \'%s\'', $new_token);
+
+               if (is_numeric($ttl))
+               {
+                       $ret['token_ttl'] = intval($ttl);
+               }
+               return $ret;
+       }
+
+
+       /**
+        * Fetch the consumer access token, by access token.
+        * 
+        * @param string token
+        * @param int user_id
+        * @exception OAuthException when token is not found
+        * @return array  token and consumer details
+        */
+       public function getConsumerAccessToken ( $token, $user_id )
+       {
+               $rs = $this->query_row_assoc('
+                               SELECT  ost_token                               as token,
+                                               ost_token_secret                as token_secret,
+                                               ost_referrer_host               as token_referrer_host,
+                                               osr_consumer_key                as consumer_key,
+                                               osr_consumer_secret             as consumer_secret,
+                                               osr_application_uri             as application_uri,
+                                               osr_application_title   as application_title,
+                                               osr_application_descr   as application_descr
+                               FROM oauth_server_token
+                                               JOIN oauth_server_registry
+                                               ON ost_osr_id_ref = osr_id
+                               WHERE ost_token_type = \'access\'
+                                 AND ost_token      = \'%s\'
+                                 AND ost_usa_id_ref = %d
+                                 AND ost_token_ttl  >= NOW()
+                               ', $token, $user_id);
+               
+               if (empty($rs))
+               {
+                       throw new OAuthException('No server_token "'.$token.'" for user "'.$user_id.'"');
+               }
+               return $rs;
+       }
+
+
+       /**
+        * Delete a consumer access token.
+        * 
+        * @param string token
+        * @param int user_id
+        * @param boolean user_is_admin
+        */
+       public function deleteConsumerAccessToken ( $token, $user_id, $user_is_admin = false )
+       {
+               if ($user_is_admin)
+               {
+                       $this->query('
+                                               DELETE FROM oauth_server_token
+                                               WHERE ost_token          = \'%s\'
+                                                 AND ost_token_type = \'access\'
+                                               ', $token);
+               }
+               else
+               {
+                       $this->query('
+                                               DELETE FROM oauth_server_token
+                                               WHERE ost_token          = \'%s\'
+                                                 AND ost_token_type = \'access\'
+                                                 AND ost_usa_id_ref = %d
+                                               ', $token, $user_id);
+               }
+       }
+
+
+       /**
+        * Set the ttl of a consumer access token.  This is done when the
+        * server receives a valid request with a xoauth_token_ttl parameter in it.
+        * 
+        * @param string token
+        * @param int ttl
+        */
+       public function setConsumerAccessTokenTtl ( $token, $token_ttl )
+       {
+               if ($token_ttl <= 0)
+               {
+                       // Immediate delete when the token is past its ttl
+                       $this->deleteConsumerAccessToken($token, 0, true);
+               }
+               else
+               {
+                       // Set maximum time to live for this token
+                       $this->query('
+                                               UPDATE oauth_server_token
+                                               SET ost_token_ttl = DATE_ADD(NOW(), INTERVAL %d SECOND)
+                                               WHERE ost_token          = \'%s\'
+                                                 AND ost_token_type = \'access\'
+                                               ', $token_ttl, $token);
+               }
+       }
+
+
+       /**
+        * Fetch a list of all consumer keys, secrets etc.
+        * Returns the public (user_id is null) and the keys owned by the user
+        * 
+        * @param int user_id
+        * @return array
+        */
+       public function listConsumers ( $user_id )
+       {
+               $rs = $this->query_all_assoc('
+                               SELECT  osr_id                                  as id,
+                                               osr_usa_id_ref                  as user_id,
+                                               osr_consumer_key                as consumer_key,
+                                               osr_consumer_secret             as consumer_secret,
+                                               osr_enabled                             as enabled,
+                                               osr_status                              as status,
+                                               osr_issue_date                  as issue_date,
+                                               osr_application_uri             as application_uri,
+                                               osr_application_title   as application_title,
+                                               osr_application_descr   as application_descr,
+                                               osr_requester_name              as requester_name,
+                                               osr_requester_email             as requester_email
+                               FROM oauth_server_registry
+                               WHERE (osr_usa_id_ref = %d OR osr_usa_id_ref IS NULL)
+                               ORDER BY osr_application_title
+                               ', $user_id);
+               return $rs;
+       }
+
+
+       /**
+        * Fetch a list of all consumer tokens accessing the account of the given user.
+        * 
+        * @param int user_id
+        * @return array
+        */
+       public function listConsumerTokens ( $user_id )
+       {
+               $rs = $this->query_all_assoc('
+                               SELECT  osr_consumer_key                as consumer_key,
+                                               osr_consumer_secret             as consumer_secret,
+                                               osr_enabled                             as enabled,
+                                               osr_status                              as status,
+                                               osr_application_uri             as application_uri,
+                                               osr_application_title   as application_title,
+                                               osr_application_descr   as application_descr,
+                                               ost_timestamp                   as timestamp,   
+                                               ost_token                               as token,
+                                               ost_token_secret                as token_secret,
+                                               ost_referrer_host               as token_referrer_host
+                               FROM oauth_server_registry
+                                       JOIN oauth_server_token
+                                       ON ost_osr_id_ref = osr_id
+                               WHERE ost_usa_id_ref = %d
+                                 AND ost_token_type = \'access\'
+                                 AND ost_token_ttl  >= NOW()
+                               ORDER BY osr_application_title
+                               ', $user_id);
+               return $rs;
+       }
+
+
+       /**
+        * Check an nonce/timestamp combination.  Clears any nonce combinations
+        * that are older than the one received.
+        * 
+        * @param string        consumer_key
+        * @param string        token
+        * @param int           timestamp
+        * @param string        nonce
+        * @exception OAuthException    thrown when the timestamp is not in sequence or nonce is not unique
+        */
+       public function checkServerNonce ( $consumer_key, $token, $timestamp, $nonce )
+       {
+               $r = $this->query_row('
+                                                       SELECT MAX(osn_timestamp), MAX(osn_timestamp) > %d + %d
+                                                       FROM oauth_server_nonce
+                                                       WHERE osn_consumer_key = \'%s\'
+                                                         AND osn_token        = \'%s\'
+                                                       ', $timestamp, $this->max_timestamp_skew, $consumer_key, $token);
+
+               if (!empty($r) && $r[1])
+               {
+                       throw new OAuthException('Timestamp is out of sequence. Request rejected. Got '.$timestamp.' last max is '.$r[0].' allowed skew is '.$this->max_timestamp_skew);
+               }
+               
+               // Insert the new combination
+               $this->query('
+                               INSERT IGNORE INTO oauth_server_nonce
+                               SET osn_consumer_key    = \'%s\',
+                                       osn_token                       = \'%s\',
+                                       osn_timestamp           = %d,
+                                       osn_nonce                       = \'%s\'
+                               ', $consumer_key, $token, $timestamp, $nonce);
+               
+               if ($this->query_affected_rows() == 0)
+               {
+                       throw new OAuthException('Duplicate timestamp/nonce combination, possible replay attack.  Request rejected.');
+               }
+
+               // Clean up all timestamps older than the one we just received
+               $this->query('
+                               DELETE FROM oauth_server_nonce
+                               WHERE osn_consumer_key  = \'%s\'
+                                 AND osn_token                 = \'%s\'
+                                 AND osn_timestamp     < %d - %d
+                               ', $consumer_key, $token, $timestamp, $this->max_timestamp_skew);
+       }
+
+
+       /**
+        * Add an entry to the log table
+        * 
+        * @param array keys (osr_consumer_key, ost_token, ocr_consumer_key, oct_token)
+        * @param string received
+        * @param string sent
+        * @param string base_string
+        * @param string notes
+        * @param int (optional) user_id
+        */
+       public function addLog ( $keys, $received, $sent, $base_string, $notes, $user_id = null )
+       {
+               $args = array();
+               $ps   = array();
+               foreach ($keys as $key => $value)
+               {
+                       $args[] = $value;
+                       $ps[]   = "olg_$key = '%s'";
+               }
+
+               if (!empty($_SERVER['REMOTE_ADDR']))
+               {
+                       $remote_ip = $_SERVER['REMOTE_ADDR'];
+               }       
+               else if (!empty($_SERVER['REMOTE_IP']))
+               {
+                       $remote_ip = $_SERVER['REMOTE_IP'];
+               }
+               else
+               {
+                       $remote_ip = '0.0.0.0';
+               }
+
+               // Build the SQL
+               $ps[] = "olg_received   = '%s'";                                                $args[] = $this->makeUTF8($received);
+               $ps[] = "olg_sent       = '%s'";                                                $args[] = $this->makeUTF8($sent);
+               $ps[] = "olg_base_string= '%s'";                                                $args[] = $base_string;
+               $ps[] = "olg_notes      = '%s'";                                                $args[] = $this->makeUTF8($notes);
+               $ps[] = "olg_usa_id_ref = NULLIF(%d,0)";                                $args[] = $user_id;
+               $ps[] = "olg_remote_ip  = IFNULL(INET_ATON('%s'),0)";   $args[] = $remote_ip;
+
+               $this->query('INSERT INTO oauth_log SET '.implode(',', $ps), $args);
+       }
+       
+       
+       /**
+        * Get a page of entries from the log.  Returns the last 100 records
+        * matching the options given.
+        * 
+        * @param array options
+        * @param int user_id   current user
+        * @return array log records
+        */
+       public function listLog ( $options, $user_id )
+       {
+               $where = array();
+               $args  = array();
+               if (empty($options))
+               {
+                       $where[] = 'olg_usa_id_ref = %d';
+                       $args[]  = $user_id;
+               }
+               else
+               {
+                       foreach ($options as $option => $value)
+                       {
+                               if (strlen($value) > 0)
+                               {
+                                       switch ($option)
+                                       {
+                                       case 'osr_consumer_key':
+                                       case 'ocr_consumer_key':
+                                       case 'ost_token':
+                                       case 'oct_token':
+                                               $where[] = 'olg_'.$option.' = \'%s\'';
+                                               $args[]  = $value;      
+                                               break;                          
+                                       }
+                               }
+                       }
+                       
+                       $where[] = '(olg_usa_id_ref IS NULL OR olg_usa_id_ref = %d)';
+                       $args[]  = $user_id;
+               }
+
+               $rs = $this->query_all_assoc('
+                                       SELECT olg_id,
+                                                       olg_osr_consumer_key    AS osr_consumer_key,
+                                                       olg_ost_token                   AS ost_token,
+                                                       olg_ocr_consumer_key    AS ocr_consumer_key,
+                                                       olg_oct_token                   AS oct_token,
+                                                       olg_usa_id_ref                  AS user_id,
+                                                       olg_received                    AS received,
+                                                       olg_sent                                AS sent,
+                                                       olg_base_string                 AS base_string,
+                                                       olg_notes                               AS notes,
+                                                       olg_timestamp                   AS timestamp,
+                                                       INET_NTOA(olg_remote_ip) AS remote_ip
+                                       FROM oauth_log
+                                       WHERE '.implode(' AND ', $where).'
+                                       ORDER BY olg_id DESC
+                                       LIMIT 0,100', $args);
+
+               return $rs;
+       }
+
+
+
+       /**
+        * Initialise the database
+        */
+       public function install ()
+       {
+               require_once dirname(__FILE__) . '/mysql/install.php';
+       }
+       
+       
+       /* ** Some simple helper functions for querying the mysql db ** */
+
+       /**
+        * Perform a query, ignore the results
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        */
+       protected function query ( $sql )
+       {
+               $sql = $this->sql_printf(func_get_args());
+               if (!($res = mysql_query($sql, $this->conn)))
+               {
+                       $this->sql_errcheck($sql);
+               }
+               if (is_resource($res))
+               {
+                       mysql_free_result($res);
+               }
+       }
+       
+
+       /**
+        * Perform a query, ignore the results
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return array
+        */
+       protected function query_all_assoc ( $sql )
+       {
+               $sql = $this->sql_printf(func_get_args());
+               if (!($res = mysql_query($sql, $this->conn)))
+               {
+                       $this->sql_errcheck($sql);
+               }
+               $rs = array();
+               while ($row  = mysql_fetch_assoc($res))
+               {
+                       $rs[] = $row;
+               }
+               mysql_free_result($res);
+               return $rs;
+       }
+       
+       
+       /**
+        * Perform a query, return the first row
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return array
+        */
+       protected function query_row_assoc ( $sql )
+       {
+               $sql = $this->sql_printf(func_get_args());
+               if (!($res = mysql_query($sql, $this->conn)))
+               {
+                       $this->sql_errcheck($sql);
+               }
+               if ($row = mysql_fetch_assoc($res))
+               {
+                       $rs = $row;
+               }
+               else
+               {
+                       $rs = false;
+               }
+               mysql_free_result($res);
+               return $rs;
+       }
+
+       
+       /**
+        * Perform a query, return the first row
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return array
+        */
+       protected function query_row ( $sql )
+       {
+               $sql = $this->sql_printf(func_get_args());
+               if (!($res = mysql_query($sql, $this->conn)))
+               {
+                       $this->sql_errcheck($sql);
+               }
+               if ($row = mysql_fetch_array($res))
+               {
+                       $rs = $row;
+               }
+               else
+               {
+                       $rs = false;
+               }
+               mysql_free_result($res);
+               return $rs;
+       }
+       
+               
+       /**
+        * Perform a query, return the first column of the first row
+        * 
+        * @param string sql
+        * @param vararg arguments (for sprintf)
+        * @return mixed
+        */
+       protected function query_one ( $sql )
+       {
+               $sql = $this->sql_printf(func_get_args());
+               if (!($res = mysql_query($sql, $this->conn)))
+               {
+                       $this->sql_errcheck($sql);
+               }
+               $val = @mysql_result($res, 0, 0);
+               mysql_free_result($res);
+               return $val;
+       }
+       
+       
+       /**
+        * Return the number of rows affected in the last query
+        */
+       protected function query_affected_rows ()
+       {
+               return mysql_affected_rows($this->conn);
+       }
+
+
+       /**
+        * Return the id of the last inserted row
+        * 
+        * @return int
+        */
+       protected function query_insert_id ()
+       {
+               return mysql_insert_id($this->conn);
+       }
+       
+       
+       protected function sql_printf ( $args )
+       {
+               $sql  = array_shift($args);
+               if (count($args) == 1 && is_array($args[0]))
+               {
+                       $args = $args[0];
+               }
+               $args = array_map(array($this, 'sql_escape_string'), $args);
+               return vsprintf($sql, $args);
+       }
+       
+       
+       protected function sql_escape_string ( $s )
+       {
+               if (is_string($s))
+               {
+                       return mysql_real_escape_string($s, $this->conn);
+               }
+               else if (is_null($s))
+               {
+                       return NULL;
+               }
+               else if (is_bool($s))
+               {
+                       return intval($s);
+               }
+               else if (is_int($s) || is_float($s))
+               {
+                       return $s;
+               }
+               else
+               {
+                       return mysql_real_escape_string(strval($s), $this->conn);
+               }
+       }
+       
+       
+       protected function sql_errcheck ( $sql )
+       {
+               if (mysql_errno($this->conn))
+               {
+                       $msg =  "SQL Error in OAuthStoreMySQL: ".mysql_error($this->conn)."\n\n" . $sql;
+                       throw new OAuthException($msg);
+               }
+       }
+}
+
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/store/mysql/install.php b/mod/oauth/vendors/oauth/library/store/mysql/install.php
new file mode 100644 (file)
index 0000000..0015da5
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Installs all tables in the mysql.sql file, using the default mysql connection
+ */
+
+/* Change and uncomment this when you need to: */
+
+/*
+mysql_connect('localhost', 'root');
+if (mysql_errno())
+{
+       die(' Error '.mysql_errno().': '.mysql_error());
+}
+mysql_select_db('test');
+*/
+
+$sql = file_get_contents(dirname(__FILE__) . '/mysql.sql');
+$ps  = explode('#--SPLIT--', $sql);
+
+foreach ($ps as $p)
+{
+       $p = preg_replace('/^\s*#.*$/m', '', $p);
+       
+       mysql_query($p);
+       if (mysql_errno())
+       {
+               die(' Error '.mysql_errno().': '.mysql_error());
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/library/store/mysql/mysql.sql b/mod/oauth/vendors/oauth/library/store/mysql/mysql.sql
new file mode 100644 (file)
index 0000000..d652a1c
--- /dev/null
@@ -0,0 +1,219 @@
+# Datamodel for OAuthStoreMySQL
+#
+# You need to add the foreign key constraints for the user ids your are using.
+# I have commented the constraints out, just look for 'usa_id_ref' to enable them.
+#
+# The --SPLIT-- markers are used by the install.php script
+#   
+# @version $Id: mysql.sql 51 2008-10-15 15:15:47Z marcw@pobox.com $
+# @author Marc Worrell
+#
+
+# Changes:
+#
+# 2008-10-15 (on r48) Added ttl to consumer and server tokens, added named server tokens
+#
+#                      ALTER TABLE oauth_server_token 
+#                      ADD ost_token_ttl datetime not null default '9999-12-31',
+#                      ADD KEY (ost_token_ttl);
+#
+#                      ALTER TABLE oauth_consumer_token 
+#                      ADD oct_name varchar(64) binary not null default '',
+#                      ADD oct_token_ttl datetime not null default '9999-12-31',
+#                      DROP KEY oct_usa_id_ref,
+#                      ADD UNIQUE KEY (oct_usa_id_ref, oct_ocr_id_ref, oct_token_type, oct_name),
+#                      ADD KEY (oct_token_ttl);
+#
+# 2008-09-09 (on r5) Added referrer host to server access token
+#
+#                      ALTER TABLE oauth_server_token ADD ost_referrer_host VARCHAR(128) NOT NULL;
+#
+
+
+#
+# Log table to hold all OAuth request when you enabled logging
+#
+
+CREATE TABLE IF NOT EXISTS oauth_log (
+    olg_id                  int(11) not null auto_increment,
+    olg_osr_consumer_key    varchar(64) binary,
+    olg_ost_token           varchar(64) binary,
+    olg_ocr_consumer_key    varchar(64) binary,
+    olg_oct_token           varchar(64) binary,
+    olg_usa_id_ref          int(11),
+    olg_received            text not null,
+    olg_sent                text not null,
+    olg_base_string         text not null,
+    olg_notes               text not null,
+    olg_timestamp           timestamp not null default current_timestamp,
+    olg_remote_ip           bigint not null,
+
+    primary key (olg_id),
+    key (olg_osr_consumer_key, olg_id),
+    key (olg_ost_token, olg_id),
+    key (olg_ocr_consumer_key, olg_id),
+    key (olg_oct_token, olg_id),
+    key (olg_usa_id_ref, olg_id)
+    
+#   , foreign key (olg_usa_id_ref) references any_user_auth (usa_id_ref)
+#       on update cascade
+#       on delete cascade
+) engine=InnoDB default charset=utf8;
+
+#--SPLIT--
+
+#
+# /////////////////// CONSUMER SIDE ///////////////////
+#
+
+# This is a registry of all consumer codes we got from other servers
+# The consumer_key/secret is obtained from the server
+# We also register the server uri, so that we can find the consumer key and secret
+# for a certain server.  From that server we can check if we have a token for a
+# particular user.
+
+CREATE TABLE IF NOT EXISTS oauth_consumer_registry (
+    ocr_id                  int(11) not null auto_increment,
+    ocr_usa_id_ref          int(11),
+    ocr_consumer_key        varchar(64) binary not null,
+    ocr_consumer_secret     varchar(64) binary not null,
+    ocr_signature_methods   varchar(255) not null default 'HMAC-SHA1,PLAINTEXT',
+    ocr_server_uri          varchar(255) not null,
+    ocr_server_uri_host     varchar(128) not null,
+    ocr_server_uri_path     varchar(128) binary not null,
+
+    ocr_request_token_uri   varchar(255) not null,
+    ocr_authorize_uri       varchar(255) not null,
+    ocr_access_token_uri    varchar(255) not null,
+    ocr_timestamp           timestamp not null default current_timestamp,
+
+    primary key (ocr_id),
+    unique key (ocr_consumer_key, ocr_usa_id_ref),
+    key (ocr_server_uri),
+    key (ocr_server_uri_host, ocr_server_uri_path),
+    key (ocr_usa_id_ref)
+
+#   , foreign key (ocr_usa_id_ref) references any_user_auth(usa_id_ref)
+#       on update cascade
+#       on delete set null
+) engine=InnoDB default charset=utf8;
+
+#--SPLIT--
+
+# Table used to sign requests for sending to a server by the consumer
+# The key is defined for a particular user.  Only one single named
+# key is allowed per user/server combination
+
+CREATE TABLE IF NOT EXISTS oauth_consumer_token (
+    oct_id                  int(11) not null auto_increment,
+    oct_ocr_id_ref          int(11) not null,
+    oct_usa_id_ref          int(11) not null,
+    oct_name                varchar(64) binary not null default '',
+    oct_token               varchar(64) binary not null,
+    oct_token_secret        varchar(64) binary not null,
+    oct_token_type          enum('request','authorized','access'),
+    oct_token_ttl           datetime not null default '9999-12-31',
+    oct_timestamp           timestamp not null default current_timestamp,
+
+    primary key (oct_id),
+    unique key (oct_ocr_id_ref, oct_token),
+    unique key (oct_usa_id_ref, oct_ocr_id_ref, oct_token_type, oct_name),
+       key (oct_token_ttl),
+
+    foreign key (oct_ocr_id_ref) references oauth_consumer_registry (ocr_id)
+        on update cascade
+        on delete cascade
+
+#   , foreign key (oct_usa_id_ref) references any_user_auth (usa_id_ref)
+#       on update cascade
+#       on delete cascade           
+) engine=InnoDB default charset=utf8;
+
+#--SPLIT--
+
+
+#
+# ////////////////// SERVER SIDE /////////////////
+#
+
+# Table holding consumer key/secret combos an user issued to consumers. 
+# Used for verification of incoming requests.
+
+CREATE TABLE IF NOT EXISTS oauth_server_registry (
+    osr_id                      int(11) not null auto_increment,
+    osr_usa_id_ref              int(11),
+    osr_consumer_key            varchar(64) binary not null,
+    osr_consumer_secret         varchar(64) binary not null,
+    osr_enabled                 tinyint(1) not null default '1',
+    osr_status                  varchar(16) not null,
+    osr_requester_name          varchar(64) not null,
+    osr_requester_email         varchar(64) not null,
+    osr_callback_uri            varchar(255) not null,
+    osr_application_uri         varchar(255) not null,
+    osr_application_title       varchar(80) not null,
+    osr_application_descr       text not null,
+    osr_application_notes       text not null,
+    osr_application_type        varchar(20) not null,
+    osr_application_commercial  tinyint(1) not null default '0',
+    osr_issue_date              datetime not null,
+    osr_timestamp               timestamp not null default current_timestamp,
+
+    primary key (osr_id),
+    unique key (osr_consumer_key),
+    key (osr_usa_id_ref)
+
+#   , foreign key (osr_usa_id_ref) references any_user_auth(usa_id_ref)
+#       on update cascade
+#       on delete set null
+) engine=InnoDB default charset=utf8;
+
+#--SPLIT--
+
+# Nonce used by a certain consumer, every used nonce should be unique, this prevents
+# replaying attacks.  We need to store all timestamp/nonce combinations for the
+# maximum timestamp received.
+
+CREATE TABLE IF NOT EXISTS oauth_server_nonce (
+    osn_id                  int(11) not null auto_increment,
+    osn_consumer_key        varchar(64) binary not null,
+    osn_token               varchar(64) binary not null,
+    osn_timestamp           bigint not null,
+    osn_nonce               varchar(80) binary not null,
+
+    primary key (osn_id),
+    unique key (osn_consumer_key, osn_token, osn_timestamp, osn_nonce)
+) engine=InnoDB default charset=utf8;
+
+#--SPLIT--
+
+# Table used to verify signed requests sent to a server by the consumer
+# When the verification is succesful then the associated user id is returned.
+
+CREATE TABLE IF NOT EXISTS oauth_server_token (
+    ost_id                  int(11) not null auto_increment,
+    ost_osr_id_ref          int(11) not null,
+    ost_usa_id_ref          int(11) not null,
+    ost_token               varchar(64) binary not null,
+    ost_token_secret        varchar(64) binary not null,
+    ost_token_type          enum('request','access'),
+    ost_authorized          tinyint(1) not null default '0',
+       ost_referrer_host               varchar(128) not null,
+       ost_token_ttl           datetime not null default '9999-12-31',
+    ost_timestamp           timestamp not null default current_timestamp,
+
+       primary key (ost_id),
+    unique key (ost_token),
+    key (ost_osr_id_ref),
+       key (ost_token_ttl),
+
+       foreign key (ost_osr_id_ref) references oauth_server_registry (osr_id)
+        on update cascade
+        on delete cascade
+
+#   , foreign key (ost_usa_id_ref) references any_user_auth (usa_id_ref)
+#       on update cascade
+#       on delete cascade           
+) engine=InnoDB default charset=utf8;
+
+
+
diff --git a/mod/oauth/vendors/oauth/test/discovery/xrds-fireeagle.xrds b/mod/oauth/vendors/oauth/test/discovery/xrds-fireeagle.xrds
new file mode 100644 (file)
index 0000000..0f5eba2
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XRDS xmlns="xri://$xrds">
+  
+  <!-- FireEagle User-Centric OAuth Configuration -->
+  <XRD xml:id="oauth" xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" version="2.0">
+    
+    <Type>xri://$xrds*simple</Type>
+    <Expires>2008-04-15T00:25:30-07:00</Expires>
+
+    <!-- Request Token -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/request</Type>
+      
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+
+      <URI>https://fireeagle.yahooapis.com/oauth/request_token</URI>
+    </Service>
+
+    <!-- User Authorization -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+
+      <URI>https://fireeagle.yahooapis.com/oauth/access_token</URI>
+    </Service>
+
+    <!-- Access Token -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/access</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+
+      <URI>http://fireeagle.yahoo.net/oauth/authorize</URI>
+    </Service>
+
+    <!-- Protected Resources -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+    </Service>
+
+    <!-- Consumer Identity -->
+    
+      <!-- Manual Consumer Identity Allocation -->
+      <Service>
+        <Type>http://oauth.net/discovery/1.0/consumer-identity/oob</Type>
+        <URI>https://fireeagle.yahoo.net/developer/create</URI>
+      </Service>
+  </XRD>
+  
+  <!-- Global Resource Definition -->
+  
+  <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
+    <Type>xri://$xrds*simple</Type>
+    
+    <!-- OAuth Endpoints Definition -->
+    <Service>
+      <Type>http://oauth.net/discovery/1.0</Type>
+      <URI>#oauth</URI>
+    </Service>
+  </XRD>
+  
+</XRDS>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds b/mod/oauth/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds
new file mode 100644 (file)
index 0000000..ab94b5b
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XRDS xmlns="xri://$xrds">
+  
+  <XRD xml:id="oauth" xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" version="2.0">
+    <Type>xri://$xrds*simple</Type>
+    <Expires>2008-04-30T23:59:59Z</Expires>
+
+    <!-- Request Token -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/request</Type>
+      
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      
+      <URI>http://getsatisfaction.com/api/request_token</URI>
+    </Service>
+
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+
+      <URI>http://getsatisfaction.com/api/authorize</URI>
+    </Service>
+
+    <!-- Access Token -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/access</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+
+      <URI>http://getsatisfaction.com/api/access_token</URI>
+    </Service>
+
+    <!-- Protected Resources -->
+    <!-- 
+      
+      To test successful access token grant, make a request against
+      
+        http://api.getsatisfaction.com/me
+
+      The API should respond with hCard of the user who authorized the token
+      -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>      
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+
+    </Service>
+
+    <!-- Consumer Identity -->
+    
+    <Service>
+      <Type>http://oauth.net/discovery/1.0/consumer-identity/oob</Type>
+      <URI>http://getsatisfaction.com/me/extensions/new</URI>
+    </Service>
+  </XRD>
+  
+  <!-- Global Resource Definition -->
+  
+  <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
+    <Type>xri://$xrds*simple</Type>
+    
+    <!-- OAuth Endpoints Definition -->
+    <Service priority="10">
+      <Type>http://oauth.net/discovery/1.0</Type>
+      <URI>#oauth</URI>
+    </Service>
+  </XRD>
+  
+</XRDS>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/test/discovery/xrds-magnolia.xrds b/mod/oauth/vendors/oauth/test/discovery/xrds-magnolia.xrds
new file mode 100644 (file)
index 0000000..361b5c9
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XRDS xmlns="xri://$xrds">
+  
+  <!-- Ma.gnolia OAuth Configuration -->
+  <XRD xml:id="oauth" xmlns="xri://$XRD*($v*2.0)" version="2.0">
+    
+    <Type>xri://$xrds*simple</Type>
+    <Expires>2008-04-13T07:34:58Z</Expires>
+
+    <!-- Request Token -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/request</Type>
+      
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/RSA-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+
+      <URI>https://ma.gnolia.com/oauth/get_request_token</URI>
+    </Service>
+
+    <!-- User Authorization (HTTPS Prefered) -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+
+      <URI priority="10">https://ma.gnolia.com/oauth/authorize</URI>
+      <URI priority="20">http://ma.gnolia.com/oauth/authorize</URI>
+    </Service>
+
+    <!-- Access Token -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/access</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/RSA-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
+
+      <URI>https://ma.gnolia.com/oauth/get_access_token</URI>
+    </Service>
+
+    <!-- Protected Resources -->
+    <Service>
+      <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
+
+      <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+      <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
+      <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+      <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
+      <Type>http://oauth.net/core/1.0/signature/RSA-SHA1</Type>
+    </Service>
+
+    <!-- Consumer Identity -->
+    
+      <!-- Manual Consumer Identity Allocation -->
+      <Service>
+        <Type>http://oauth.net/discovery/1.0/consumer-identity/oob</Type>
+        <URI>http://ma.gnolia.com/applications/new</URI>
+      </Service>
+  </XRD>
+  
+  <!-- Global Resource Definition -->
+  
+  <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
+    <Type>xri://$xrds*simple</Type>
+    
+    <!-- OAuth Endpoints Definition -->
+    <Service priority="10">
+      <Type>http://oauth.net/discovery/1.0</Type>
+      <URI>#oauth</URI>
+    </Service>
+  </XRD>
+  
+</XRDS>
\ No newline at end of file
diff --git a/mod/oauth/vendors/oauth/test/oauth_test.php b/mod/oauth/vendors/oauth/test/oauth_test.php
new file mode 100644 (file)
index 0000000..0c0504c
--- /dev/null
@@ -0,0 +1,188 @@
+<?php
+
+/**
+ * Tests of OAuth implementation.
+ * 
+ * @version $Id$
+ * @author Marc Worrell <marcw@pobox.com>
+ * @date  Nov 29, 2007 3:46:56 PM
+ * @see http://wiki.oauth.net/TestCases
+ * 
+ * The MIT License
+ * 
+ * Copyright (c) 2007-2008 Mediamatic Lab
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__) . '/../library/OAuthRequest.php';
+require_once dirname(__FILE__) . '/../library/OAuthRequester.php';
+require_once dirname(__FILE__) . '/../library/OAuthRequestSigner.php';
+require_once dirname(__FILE__) . '/../library/OAuthRequestVerifier.php';
+
+if (!function_exists('getallheaders'))
+{
+       function getallheaders()
+       {
+               return array();
+       }
+}
+
+
+oauth_test();
+
+function oauth_test ()
+{
+       error_reporting(E_ALL);
+
+       header('Content-Type: text/plain; charset=utf-8');
+       
+       echo "Performing OAuth module tests.\n\n";
+       echo "See also: http://wiki.oauth.net/TestCases\n\n";
+       
+       assert_options(ASSERT_CALLBACK, 'oauth_assert_handler');
+       assert_options(ASSERT_WARNING,  0);
+       
+       $req = new OAuthRequest('http://www.example.com', 'GET');
+
+       echo "***** Parameter Encoding *****\n\n";
+       
+       assert('$req->urlencode(\'abcABC123\') == \'abcABC123\'');
+       assert('$req->urlencode(\'-._~\') == \'-._~\'');
+       assert('$req->urlencode(\'%\') == \'%25\'');
+       assert('$req->urlencode(\'&=*\') == \'%26%3D%2A\'');
+       assert('$req->urlencode(\'&=*\') == \'%26%3D%2A\'');
+       assert('$req->urlencode("\n") == \'%0A\'');
+       assert('$req->urlencode(" ") == \'%20\'');
+       assert('$req->urlencode("\x7f") == \'%7F\'');
+
+
+       echo "***** Normalize Request Parameters *****\n\n";
+       
+       $req = new OAuthRequest('http://example.com/?name', 'GET');
+       assert('$req->getNormalizedParams() == \'name=\'');
+
+       $req = new OAuthRequest('http://example.com/?a=b', 'GET');
+       assert('$req->getNormalizedParams() == \'a=b\'');
+       
+       $req = new OAuthRequest('http://example.com/?a=b&c=d', 'GET');
+       assert('$req->getNormalizedParams() == \'a=b&c=d\'');
+       
+       // At this moment we don't support two parameters with the same name
+       // so I changed this test case to "a=" and "b=" and not "a=" and "a="
+       $req = new OAuthRequest('http://example.com/?b=x!y&a=x+y', 'GET');
+       assert('$req->getNormalizedParams() == \'a=x%20y&b=x%21y\'');
+       
+       $req = new OAuthRequest('http://example.com/?x!y=a&x=a', 'GET');
+       assert('$req->getNormalizedParams() == \'x=a&x%21y=a\'');
+       
+
+       echo "***** Base String *****\n\n";
+       
+       $req  = new OAuthRequest('http://example.com/?n=v', 'GET');
+       assert('$req->signatureBaseString() == \'GET&http%3A%2F%2Fexample.com%2F&n%3Dv\'');
+       
+       $req = new OAuthRequest(
+                                                       'https://photos.example.net/request_token', 
+                                                       'POST',
+                                                       'oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_timestamp=1191242090&oauth_nonce=hsu94j3884jdopsl&oauth_signature_method=PLAINTEXT&oauth_signature=ignored',
+                                                       array('X-OAuth-Test' => true));
+       assert('$req->signatureBaseString() == \'POST&https%3A%2F%2Fphotos.example.net%2Frequest_token&oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dhsu94j3884jdopsl%26oauth_signature_method%3DPLAINTEXT%26oauth_timestamp%3D1191242090%26oauth_version%3D1.0\'');
+
+       $req = new OAuthRequest(
+                                                       'http://photos.example.net/photos?file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh&oauth_signature=ignored&oauth_signature_method=HMAC-SHA1', 
+                                                       'GET');
+       assert('$req->signatureBaseString() == \'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal\'');
+
+
+       echo "***** HMAC-SHA1 *****\nRequest signing\n";
+
+       OAuthStore::instance('MySQL', array('conn'=>false));
+       $req = new OAuthRequestSigner('http://photos.example.net/photos?file=vacation.jpg&size=original', 'GET');       
+
+       assert('$req->urldecode($req->calculateDataSignature(\'bs\', \'cs\', \'\',   \'HMAC-SHA1\')) == \'egQqG5AJep5sJ7anhXju1unge2I=\'');
+       assert('$req->urldecode($req->calculateDataSignature(\'bs\', \'cs\', \'ts\', \'HMAC-SHA1\')) == \'VZVjXceV7JgPq/dOTnNmEfO0Fv8=\'');
+       
+       $secrets = array(
+                               'consumer_key'          => 'dpf43f3p2l4k3l03',
+                               'consumer_secret'       => 'kd94hf93k423kf44',
+                               'token'                         => 'nnch734d00sl2jdk',
+                               'token_secret'          => 'pfkkdhi9sl3r4s00',
+                               'signature_methods'     => array('HMAC-SHA1'),
+                               'nonce'                         => 'kllo9940pd9333jh',
+                               'timestamp'                     => '1191242096'
+                               );
+       $req->sign(0, $secrets);
+       assert('$req->getParam(\'oauth_signature\', true) == \'tR3+Ty81lMeYAr/Fid0kMTYa/WM=\'');
+
+       echo "***** HMAC-SHA1 *****\nRequest verification\n";
+
+       $req = new OAuthRequestVerifier(
+                               'http://photos.example.net/photos?file=vacation.jpg&size=original'
+                               .'&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=nnch734d00sl2jdk'
+                               .'&oauth_signature_method=HMAC-SHA1&oauth_nonce=kllo9940pd9333jh'
+                               .'&oauth_timestamp=1191242096&oauth_version=1.0'
+                               .'&oauth_signature='.rawurlencode('tR3+Ty81lMeYAr/Fid0kMTYa/WM=')
+                               , 'GET');
+       
+       $req->verifySignature('kd94hf93k423kf44', 'pfkkdhi9sl3r4s00');
+
+       echo "\n";
+       echo "***** Yahoo! test case ******\n\n";
+
+       OAuthStore::instance('MySQL', array('conn'=>false));
+       $req = new OAuthRequestSigner('http://example.com:80/photo', 'GET');
+       
+       $req->setParam('title',   'taken with a 30% orange filter');
+       $req->setParam('file',    'mountain & water view');
+       $req->setParam('format',  'jpeg');
+       $req->setParam('include', array('date','aperture'));
+
+       $secrets = array(
+                               'consumer_key'          => '1234=asdf=4567',
+                               'consumer_secret'       => 'erks823*43=asd&123ls%23',
+                               'token'                         => 'asdf-4354=asew-5698',
+                               'token_secret'          => 'dis9$#$Js009%==',
+                               'signature_methods'     => array('HMAC-SHA1'),
+                               'nonce'                         => '3jd834jd9',
+                               'timestamp'                     => '12303202302'
+                               );
+       $req->sign(0, $secrets);
+
+       // echo "Basestring:\n",$req->signatureBaseString(), "\n\n";
+
+       //echo "queryString:\n",$req->getQueryString(), "\n\n";
+       assert('$req->getQueryString() == \'title=taken%20with%20a%2030%25%20orange%20filter&file=mountain%20%26%20water%20view&format=jpeg&include=date&include=aperture\'');  
+
+       //echo "oauth_signature:\n",$req->getParam('oauth_signature', true),"\n\n";
+       assert('$req->getParam(\'oauth_signature\', true) == \'jMdUSR1vOr3SzNv3gZ5DDDuGirA=\'');
+       
+       echo "\n\nFinished.\n";
+}
+
+
+function oauth_assert_handler ( $file, $line, $code )
+{
+       echo "\nAssertion failed in $file:$line
+   $code\n\n";
+}
+
+/* vi:set ts=4 sts=4 sw=4 binary noeol: */
+
+?>
\ No newline at end of file