Permalink
Browse files

Modifications to PDO storage handler

  • Loading branch information...
1 parent 87d1756 commit d407b7cf332877491e2c7e108a30102dd61d481b @BenExile committed Oct 2, 2012
Showing with 63 additions and 16 deletions.
  1. +54 −9 Dropbox/OAuth/Storage/PDO.php
  2. +9 −0 Dropbox/OAuth/Storage/TableSchema.sql
  3. +0 −7 examples/oauth_tokens.sql
@@ -36,6 +36,13 @@ class PDO extends Session
private $pdo = null;
/**
+ * Default database table
+ * Override this using setTable()
+ * @var string
+ */
+ private $table = 'dropbox_oauth_tokens';
+
+ /**
* Construct the parent object and
* set the authenticated user ID
* @param \Dropbox\OAuth\Storage\Encrypter $encrypter
@@ -73,6 +80,18 @@ public function connect($host, $db, $user, $pass, $port = 3306)
}
/**
+ * Set the table to store OAuth tokens in
+ * If the table does not exist, the get() method will attempt to create it when it is called.
+ * @todo Check for valid table name and quote it (see below)
+ * @link http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
+ * @return void
+ */
+ public function setTable($table)
+ {
+ $this->table = $table;
+ }
+
+ /**
* Get an OAuth token from the database or session (see below)
* Request tokens are stored in the session, access tokens in the database
* Once a token is retrieved it will be stored in the users session
@@ -89,14 +108,29 @@ public function get($type)
} elseif ($token = parent::get($type)) {
return $token;
} else {
- $query = 'SELECT token FROM oauth_tokens WHERE userID = ? LIMIT 1';
- $stmt = $this->pdo->prepare($query);
- $stmt->execute(array($this->userID));
- if ($result = $stmt->fetch()) {
- $token = $this->decrypt($result['token']);
- $_SESSION[$this->namespace][$type] = $result['token'];
- return $token;
+ try {
+ $query = 'SELECT uid, userID, token FROM ' . $this->table . ' WHERE userID = ? LIMIT 1';
+ $stmt = $this->pdo->prepare($query);
+ $stmt->execute(array($this->userID));
+ if ($result = $stmt->fetch()) {
+ $token = $this->decrypt($result['token']);
+ $_SESSION[$this->namespace][$type] = $result['token'];
+ return $token;
+ }
+ } catch (\PDOException $e) {
+ // Fetch error information from the statement handle
+ $errorInfo = $stmt->errorInfo();
+
+ // Handle the PDOException based on the error code
+ switch ($errorInfo[1]) {
+ case 1146: // Table does not exist
+ $this->createTable();
+ break;
+ default: // Rethrow the PDOException
+ throw $e;
+ }
}
+
return false;
}
}
@@ -111,11 +145,12 @@ public function get($type)
public function set($token, $type)
{
if ($type != 'request_token' && $type != 'access_token') {
- throw new \Dropbox\Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
+ $message = "Expected a type of either 'request_token' or 'access_token', got '$type'";
+ throw new \Dropbox\Exception($message);
} elseif ($type == 'request_token') {
parent::set($token, $type);
} else {
- $query = 'INSERT INTO oauth_tokens (userID, token) VALUES (?, ?) ON DUPLICATE KEY UPDATE token = ?';
+ $query = 'INSERT INTO ' . $this->table . ' (userID, token) VALUES (?, ?) ON DUPLICATE KEY UPDATE token = ?';
$stmt = $this->pdo->prepare($query);
$token = $this->encrypt($token);
$stmt->execute(array($this->userID, $token, $token));
@@ -140,4 +175,14 @@ public function delete()
return false;
}
}
+
+ /**
+ * Attempt to create the OAuth token table
+ * @return void
+ */
+ protected function createTable()
+ {
+ $template = file_get_contents(dirname(__FILE__) . '/TableSchema.sql');
+ $this->pdo->query(sprintf($template, $this->table));
+ }
}
@@ -0,0 +1,9 @@
+CREATE TABLE `%s`
+(
+ `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `userID` int(10) unsigned NOT NULL,
+ `token` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+ PRIMARY KEY (`uid`),
+ UNIQUE KEY `userID` (`userID`)
+)
+ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
@@ -1,7 +0,0 @@
-CREATE TABLE IF NOT EXISTS `oauth_tokens` (
- `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `userID` int(10) unsigned NOT NULL,
- `token` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
- PRIMARY KEY (`uid`),
- UNIQUE KEY `userID` (`userID`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

1 comment on commit d407b7c

@BenExile
Owner

The PDO storage handler will now create the table for OAuth tokens. The default table name has changed which will cause issues for users who are already storing tokens in the old oauth_tokens table and not calling \Dropbox\OAuth\Storage\PDO::setTable(). There are 2 possible fixes that resolve this:

The first is to call \Dropbox\OAuth\Storage\PDO::setTable(), passing 'oauth_tokens' as the table name.

The second is to use the new default table, dropbox_oauth_tokens (or using a table with another name, setting it using the previously mentioned method), and importing the OAuth tokens already stored in oauth_tokens.

Sorry for any inconvenience caused, but this makes the library a lot more flexible going forward.

Please sign in to comment.