This repository has been archived by the owner on Apr 18, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 134
/
PDO.php
188 lines (172 loc) · 6.11 KB
/
PDO.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<?php
/**
* OAuth storage handler built on PDO
* @todo Add table creation script
* @todo Database fallback?
* @author Ben Tadiar <ben@handcraftedbyben.co.uk>
* @link https://github.com/benthedesigner/dropbox
* @package Dropbox\Oauth
* @subpackage Storage
*/
namespace Dropbox\OAuth\Storage;
class PDO extends Session
{
/**
* Authenticated user ID
* @var int
*/
private $userID = null;
/**
* Associative array of PDO connection options
* @var array
*/
private $options = array(
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
);
/**
* Forward-declare PDO object
* @var null|PDO
*/
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
* @param int $userID
* @throws \Dropbox\Exception
*/
public function __construct(Encrypter $encrypter = null, $userID)
{
// Throw an Exception if PDO is not loaded
if (!extension_loaded('PDO')) {
throw new \Dropbox\Exception('This storage handler requires the PDO extension');
}
// Construct the parent object so we can access the SESSION
// instead of querying the database on every request
parent::__construct($encrypter);
// Set the authenticated user ID
$this->userID = $userID;
}
/**
* Connect to the database
* @param string $host Database server hostname
* @param string $db Database to connect to
* @param string $user Database username
* @param string $pass Database user password
* @param int $port Database server port (Default: 3306)
* @return void
*/
public function connect($host, $db, $user, $pass, $port = 3306)
{
$dsn = 'mysql:host=' . $host . ';port=' . $port . ';dbname=' . $db;
$this->pdo = new \PDO($dsn, $user, $pass, $this->options);
}
/**
* 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
* for subsequent requests to reduce overheads
* @param string $type Token type to retrieve
* @return array|bool
*/
public function get($type)
{
if ($type != 'request_token' && $type != 'access_token') {
throw new \Dropbox\Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
} elseif ($type == 'request_token') {
return parent::get($type);
} elseif ($token = parent::get($type)) {
return $token;
} else {
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;
}
}
/**
* Set an OAuth token in the database or session (see below)
* Request tokens are stored in the session, access tokens in the database
* @param \stdClass Token object to set
* @param string $type Token type
* @return void
*/
public function set($token, $type)
{
if ($type != 'request_token' && $type != 'access_token') {
$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 ' . $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));
$_SESSION[$this->namespace][$type] = $token;
}
}
/**
* Delete access token for the current user ID from the database
* @todo Add error checking
* @return bool
*/
public function delete()
{
try {
parent::delete();
$query = 'DELETE FROM oauth_tokens WHERE userID = ?';
$stmt = $this->pdo->prepare($query);
$stmt->execute(array($this->userID));
return $stmt->rowCount() > 0;
} catch(\PDOException $e) {
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));
}
}