123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- <?php
- /**
- * SQL-backed OpenID stores for use with PEAR::MDB2.
- *
- * PHP versions 4 and 5
- *
- * LICENSE: See the COPYING file included in this distribution.
- *
- * @package OpenID
- * @author JanRain, Inc. <openid@janrain.com>
- * @copyright 2005 Janrain, Inc.
- * @license http://www.gnu.org/copyleft/lesser.html LGPL
- */
- require_once 'MDB2.php';
- /**
- * @access private
- */
- require_once 'Auth/OpenID/Interface.php';
- /**
- * @access private
- */
- require_once 'Auth/OpenID.php';
- /**
- * @access private
- */
- require_once 'Auth/OpenID/Nonce.php';
- /**
- * This store uses a PEAR::MDB2 connection to store persistence
- * information.
- *
- * The table names used are determined by the class variables
- * associations_table_name and nonces_table_name. To change the name
- * of the tables used, pass new table names into the constructor.
- *
- * To create the tables with the proper schema, see the createTables
- * method.
- *
- * @package OpenID
- */
- class Auth_OpenID_MDB2Store extends Auth_OpenID_OpenIDStore {
- /**
- * This creates a new MDB2Store instance. It requires an
- * established database connection be given to it, and it allows
- * overriding the default table names.
- *
- * @param connection $connection This must be an established
- * connection to a database of the correct type for the SQLStore
- * subclass you're using. This must be a PEAR::MDB2 connection
- * handle.
- *
- * @param associations_table: This is an optional parameter to
- * specify the name of the table used for storing associations.
- * The default value is 'oid_associations'.
- *
- * @param nonces_table: This is an optional parameter to specify
- * the name of the table used for storing nonces. The default
- * value is 'oid_nonces'.
- */
- function Auth_OpenID_MDB2Store($connection,
- $associations_table = null,
- $nonces_table = null)
- {
- $this->associations_table_name = "oid_associations";
- $this->nonces_table_name = "oid_nonces";
- // Check the connection object type to be sure it's a PEAR
- // database connection.
- if (!is_object($connection) ||
- !is_subclass_of($connection, 'mdb2_driver_common')) {
- trigger_error("Auth_OpenID_MDB2Store expected PEAR connection " .
- "object (got ".get_class($connection).")",
- E_USER_ERROR);
- return;
- }
- $this->connection = $connection;
- // Be sure to set the fetch mode so the results are keyed on
- // column name instead of column index.
- $this->connection->setFetchMode(MDB2_FETCHMODE_ASSOC);
-
- if (@PEAR::isError($this->connection->loadModule('Extended'))) {
- trigger_error("Unable to load MDB2_Extended module", E_USER_ERROR);
- return;
- }
- if ($associations_table) {
- $this->associations_table_name = $associations_table;
- }
- if ($nonces_table) {
- $this->nonces_table_name = $nonces_table;
- }
- $this->max_nonce_age = 6 * 60 * 60;
- }
- function tableExists($table_name)
- {
- return !@PEAR::isError($this->connection->query(
- sprintf("SELECT * FROM %s LIMIT 0",
- $table_name)));
- }
- function createTables()
- {
- $n = $this->create_nonce_table();
- $a = $this->create_assoc_table();
- if (!$n || !$a) {
- return false;
- }
- return true;
- }
- function create_nonce_table()
- {
- if (!$this->tableExists($this->nonces_table_name)) {
- switch ($this->connection->phptype) {
- case "mysql":
- case "mysqli":
- // Custom SQL for MySQL to use InnoDB and variable-
- // length keys
- $r = $this->connection->exec(
- sprintf("CREATE TABLE %s (\n".
- " server_url VARCHAR(2047) NOT NULL DEFAULT '',\n".
- " timestamp INTEGER NOT NULL,\n".
- " salt CHAR(40) NOT NULL,\n".
- " UNIQUE (server_url(255), timestamp, salt)\n".
- ") TYPE=InnoDB",
- $this->nonces_table_name));
- if (@PEAR::isError($r)) {
- return false;
- }
- break;
- default:
- if (@PEAR::isError(
- $this->connection->loadModule('Manager'))) {
- return false;
- }
- $fields = array(
- "server_url" => array(
- "type" => "text",
- "length" => 2047,
- "notnull" => true
- ),
- "timestamp" => array(
- "type" => "integer",
- "notnull" => true
- ),
- "salt" => array(
- "type" => "text",
- "length" => 40,
- "fixed" => true,
- "notnull" => true
- )
- );
- $constraint = array(
- "unique" => 1,
- "fields" => array(
- "server_url" => true,
- "timestamp" => true,
- "salt" => true
- )
- );
-
- $r = $this->connection->createTable($this->nonces_table_name,
- $fields);
- if (@PEAR::isError($r)) {
- return false;
- }
-
- $r = $this->connection->createConstraint(
- $this->nonces_table_name,
- $this->nonces_table_name . "_constraint",
- $constraint);
- if (@PEAR::isError($r)) {
- return false;
- }
- break;
- }
- }
- return true;
- }
- function create_assoc_table()
- {
- if (!$this->tableExists($this->associations_table_name)) {
- switch ($this->connection->phptype) {
- case "mysql":
- case "mysqli":
- // Custom SQL for MySQL to use InnoDB and variable-
- // length keys
- $r = $this->connection->exec(
- sprintf("CREATE TABLE %s(\n".
- " server_url VARCHAR(2047) NOT NULL DEFAULT '',\n".
- " handle VARCHAR(255) NOT NULL,\n".
- " secret BLOB NOT NULL,\n".
- " issued INTEGER NOT NULL,\n".
- " lifetime INTEGER NOT NULL,\n".
- " assoc_type VARCHAR(64) NOT NULL,\n".
- " PRIMARY KEY (server_url(255), handle)\n".
- ") TYPE=InnoDB",
- $this->associations_table_name));
- if (@PEAR::isError($r)) {
- return false;
- }
- break;
- default:
- if (@PEAR::isError(
- $this->connection->loadModule('Manager'))) {
- return false;
- }
- $fields = array(
- "server_url" => array(
- "type" => "text",
- "length" => 2047,
- "notnull" => true
- ),
- "handle" => array(
- "type" => "text",
- "length" => 255,
- "notnull" => true
- ),
- "secret" => array(
- "type" => "blob",
- "length" => "255",
- "notnull" => true
- ),
- "issued" => array(
- "type" => "integer",
- "notnull" => true
- ),
- "lifetime" => array(
- "type" => "integer",
- "notnull" => true
- ),
- "assoc_type" => array(
- "type" => "text",
- "length" => 64,
- "notnull" => true
- )
- );
- $options = array(
- "primary" => array(
- "server_url" => true,
- "handle" => true
- )
- );
-
- $r = $this->connection->createTable(
- $this->associations_table_name,
- $fields,
- $options);
- if (@PEAR::isError($r)) {
- return false;
- }
- break;
- }
- }
- return true;
- }
- function storeAssociation($server_url, $association)
- {
- $fields = array(
- "server_url" => array(
- "value" => $server_url,
- "key" => true
- ),
- "handle" => array(
- "value" => $association->handle,
- "key" => true
- ),
- "secret" => array(
- "value" => $association->secret,
- "type" => "blob"
- ),
- "issued" => array(
- "value" => $association->issued
- ),
- "lifetime" => array(
- "value" => $association->lifetime
- ),
- "assoc_type" => array(
- "value" => $association->assoc_type
- )
- );
-
- return !@PEAR::isError($this->connection->replace(
- $this->associations_table_name,
- $fields));
- }
- function cleanupNonces()
- {
- global $Auth_OpenID_SKEW;
- $v = time() - $Auth_OpenID_SKEW;
- return $this->connection->exec(
- sprintf("DELETE FROM %s WHERE timestamp < %d",
- $this->nonces_table_name, $v));
- }
- function cleanupAssociations()
- {
- return $this->connection->exec(
- sprintf("DELETE FROM %s WHERE issued + lifetime < %d",
- $this->associations_table_name, time()));
- }
- function getAssociation($server_url, $handle = null)
- {
- $sql = "";
- $params = null;
- $types = array(
- "text",
- "blob",
- "integer",
- "integer",
- "text"
- );
- if ($handle !== null) {
- $sql = sprintf("SELECT handle, secret, issued, lifetime, assoc_type " .
- "FROM %s WHERE server_url = ? AND handle = ?",
- $this->associations_table_name);
- $params = array($server_url, $handle);
- } else {
- $sql = sprintf("SELECT handle, secret, issued, lifetime, assoc_type " .
- "FROM %s WHERE server_url = ? ORDER BY issued DESC",
- $this->associations_table_name);
- $params = array($server_url);
- }
-
- $assoc = $this->connection->getRow($sql, $types, $params);
- if (!$assoc || @PEAR::isError($assoc)) {
- return null;
- } else {
- $association = new Auth_OpenID_Association($assoc['handle'],
- stream_get_contents(
- $assoc['secret']),
- $assoc['issued'],
- $assoc['lifetime'],
- $assoc['assoc_type']);
- fclose($assoc['secret']);
- return $association;
- }
- }
- function removeAssociation($server_url, $handle)
- {
- $r = $this->connection->execParam(
- sprintf("DELETE FROM %s WHERE server_url = ? AND handle = ?",
- $this->associations_table_name),
- array($server_url, $handle));
-
- if (@PEAR::isError($r) || $r == 0) {
- return false;
- }
- return true;
- }
- function useNonce($server_url, $timestamp, $salt)
- {
- global $Auth_OpenID_SKEW;
- if (abs($timestamp - time()) > $Auth_OpenID_SKEW ) {
- return false;
- }
-
- $fields = array(
- "timestamp" => $timestamp,
- "salt" => $salt
- );
-
- if (!empty($server_url)) {
- $fields["server_url"] = $server_url;
- }
-
- $r = $this->connection->autoExecute(
- $this->nonces_table_name,
- $fields,
- MDB2_AUTOQUERY_INSERT);
-
- if (@PEAR::isError($r)) {
- return false;
- }
- return true;
- }
- /**
- * Resets the store by removing all records from the store's
- * tables.
- */
- function reset()
- {
- $this->connection->query(sprintf("DELETE FROM %s",
- $this->associations_table_name));
- $this->connection->query(sprintf("DELETE FROM %s",
- $this->nonces_table_name));
- }
- }
- ?>
|