Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * Licensed to Jasig under one or more contributor license
5
 * agreements. See the NOTICE file distributed with this work for
6
 * additional information regarding copyright ownership.
7
 *
8
 * Jasig licenses this file to you under the Apache License,
9
 * Version 2.0 (the "License"); you may not use this file except in
10
 * compliance with the License. You may obtain a copy of the License at:
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 *
20
 * PHP Version 7
21
 *
22
 * @file     CAS/PGTStorage/Db.php
23
 * @category Authentication
24
 * @package  PhpCAS
25
 * @author   Daniel Frett <daniel.frett@gmail.com>
26
 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
27
 * @link     https://wiki.jasig.org/display/CASC/phpCAS
28
 */
29
 
30
define('CAS_PGT_STORAGE_DB_DEFAULT_TABLE', 'cas_pgts');
31
 
32
/**
33
 * Basic class for PGT database storage
34
 * The CAS_PGTStorage_Db class is a class for PGT database storage.
35
 *
36
 * @class    CAS_PGTStorage_Db
37
 * @category Authentication
38
 * @package  PhpCAS
39
 * @author   Daniel Frett <daniel.frett@gmail.com>
40
 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
41
 * @link     https://wiki.jasig.org/display/CASC/phpCAS
42
 *
43
 * @ingroup internalPGTStorageDb
44
 */
45
 
46
class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage
47
{
48
    /**
49
     * @addtogroup internalCAS_PGTStorageDb
50
     * @{
51
     */
52
 
53
    /**
54
     * the PDO object to use for database interactions
55
     */
56
    private $_pdo;
57
 
58
    /**
59
     * This method returns the PDO object to use for database interactions.
60
     *
61
     * @return PDO object
62
     */
63
    private function _getPdo()
64
    {
65
        return $this->_pdo;
66
    }
67
 
68
    /**
69
     * database connection options to use when creating a new PDO object
70
     */
71
    private $_dsn;
72
    private $_username;
73
    private $_password;
74
    private $_driver_options;
75
 
76
    /**
77
     * @var string the table to use for storing/retrieving pgt's
78
     */
79
    private $_table;
80
 
81
    /**
82
     * This method returns the table to use when storing/retrieving PGT's
83
     *
84
     * @return string the name of the pgt storage table.
85
     */
86
    private function _getTable()
87
    {
88
        return $this->_table;
89
    }
90
 
91
    // ########################################################################
92
    //  DEBUGGING
93
    // ########################################################################
94
 
95
    /**
96
     * This method returns an informational string giving the type of storage
97
     * used by the object (used for debugging purposes).
98
     *
99
     * @return string an informational string.
100
     */
101
    public function getStorageType()
102
    {
103
        return "db";
104
    }
105
 
106
    /**
107
     * This method returns an informational string giving informations on the
108
     * parameters of the storage.(used for debugging purposes).
109
     *
110
     * @return string an informational string.
111
     * @public
112
     */
113
    public function getStorageInfo()
114
    {
115
        return 'table=`'.$this->_getTable().'\'';
116
    }
117
 
118
    // ########################################################################
119
    //  CONSTRUCTOR
120
    // ########################################################################
121
 
122
    /**
123
     * The class constructor.
124
     *
125
     * @param CAS_Client $cas_parent     the CAS_Client instance that creates
126
     * the object.
127
     * @param string     $dsn_or_pdo     a dsn string to use for creating a PDO
128
     * object or a PDO object
129
     * @param string     $username       the username to use when connecting to
130
     * the database
131
     * @param string     $password       the password to use when connecting to
132
     * the database
133
     * @param string     $table          the table to use for storing and
134
     * retrieving PGT's
135
     * @param string     $driver_options any driver options to use when
136
     * connecting to the database
137
     */
138
    public function __construct(
139
        $cas_parent, $dsn_or_pdo, $username='', $password='', $table='',
140
        $driver_options=null
141
    ) {
142
        phpCAS::traceBegin();
143
        // call the ancestor's constructor
144
        parent::__construct($cas_parent);
145
 
146
        // set default values
147
        if ( empty($table) ) {
148
            $table = CAS_PGT_STORAGE_DB_DEFAULT_TABLE;
149
        }
150
        if ( !is_array($driver_options) ) {
151
            $driver_options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
152
        }
153
 
154
        // store the specified parameters
155
        if ($dsn_or_pdo instanceof PDO) {
156
            $this->_pdo = $dsn_or_pdo;
157
        } else {
158
            $this->_dsn = $dsn_or_pdo;
159
            $this->_username = $username;
160
            $this->_password = $password;
161
            $this->_driver_options = $driver_options;
162
        }
163
 
164
        // store the table name
165
        $this->_table = $table;
166
 
167
        phpCAS::traceEnd();
168
    }
169
 
170
    // ########################################################################
171
    //  INITIALIZATION
172
    // ########################################################################
173
 
174
    /**
175
     * This method is used to initialize the storage. Halts on error.
176
     *
177
     * @return void
178
     */
179
    public function init()
180
    {
181
        phpCAS::traceBegin();
182
        // if the storage has already been initialized, return immediatly
183
        if ($this->isInitialized()) {
184
            return;
185
        }
186
 
187
        // initialize the base object
188
        parent::init();
189
 
190
        // create the PDO object if it doesn't exist already
191
        if (!($this->_pdo instanceof PDO)) {
192
            try {
193
                $this->_pdo = new PDO(
194
                    $this->_dsn, $this->_username, $this->_password,
195
                    $this->_driver_options
196
                );
197
            }
198
            catch(PDOException $e) {
199
                phpCAS::error('Database connection error: ' . $e->getMessage());
200
            }
201
        }
202
 
203
        phpCAS::traceEnd();
204
    }
205
 
206
    // ########################################################################
207
    //  PDO database interaction
208
    // ########################################################################
209
 
210
    /**
211
     * attribute that stores the previous error mode for the PDO handle while
212
     * processing a transaction
213
     */
214
    private $_errMode;
215
 
216
    /**
217
     * This method will enable the Exception error mode on the PDO object
218
     *
219
     * @return void
220
     */
221
    private function _setErrorMode()
222
    {
223
        // get PDO object and enable exception error mode
224
        $pdo = $this->_getPdo();
225
        $this->_errMode = $pdo->getAttribute(PDO::ATTR_ERRMODE);
226
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
227
    }
228
 
229
    /**
230
     * this method will reset the error mode on the PDO object
231
     *
232
     * @return void
233
     */
234
    private function _resetErrorMode()
235
    {
236
        // get PDO object and reset the error mode to what it was originally
237
        $pdo = $this->_getPdo();
238
        $pdo->setAttribute(PDO::ATTR_ERRMODE, $this->_errMode);
239
    }
240
 
241
    // ########################################################################
242
    //  database queries
243
    // ########################################################################
244
    // these queries are potentially unsafe because the person using this library
245
    // can set the table to use, but there is no reliable way to escape SQL
246
    // fieldnames in PDO yet
247
 
248
    /**
249
     * This method returns the query used to create a pgt storage table
250
     *
251
     * @return string the create table SQL, no bind params in query
252
     */
253
    protected function createTableSql()
254
    {
255
        return 'CREATE TABLE ' . $this->_getTable()
256
            . ' (pgt_iou VARCHAR(255) NOT NULL PRIMARY KEY, pgt VARCHAR(255) NOT NULL)';
257
    }
258
 
259
    /**
260
     * This method returns the query used to store a pgt
261
     *
262
     * @return string the store PGT SQL, :pgt and :pgt_iou are the bind params contained
263
     *         in the query
264
     */
265
    protected function storePgtSql()
266
    {
267
        return 'INSERT INTO ' . $this->_getTable()
268
            . ' (pgt_iou, pgt) VALUES (:pgt_iou, :pgt)';
269
    }
270
 
271
    /**
272
     * This method returns the query used to retrieve a pgt. the first column
273
     * of the first row should contain the pgt
274
     *
275
     * @return string the retrieve PGT SQL, :pgt_iou is the only bind param contained
276
     *         in the query
277
     */
278
    protected function retrievePgtSql()
279
    {
280
        return 'SELECT pgt FROM ' . $this->_getTable() . ' WHERE pgt_iou = :pgt_iou';
281
    }
282
 
283
    /**
284
     * This method returns the query used to delete a pgt.
285
     *
286
     * @return string the delete PGT SQL, :pgt_iou is the only bind param contained in
287
     *         the query
288
     */
289
    protected function deletePgtSql()
290
    {
291
        return 'DELETE FROM ' . $this->_getTable() . ' WHERE pgt_iou = :pgt_iou';
292
    }
293
 
294
    // ########################################################################
295
    //  PGT I/O
296
    // ########################################################################
297
 
298
    /**
299
     * This method creates the database table used to store pgt's and pgtiou's
300
     *
301
     * @return void
302
     */
303
    public function createTable()
304
    {
305
        phpCAS::traceBegin();
306
 
307
        // initialize this PGTStorage object if it hasn't been initialized yet
308
        if ( !$this->isInitialized() ) {
309
            $this->init();
310
        }
311
 
312
        // initialize the PDO object for this method
313
        $pdo = $this->_getPdo();
314
        $this->_setErrorMode();
315
 
316
        try {
317
            $pdo->beginTransaction();
318
 
319
            $query = $pdo->query($this->createTableSQL());
320
            $query->closeCursor();
321
 
322
            $pdo->commit();
323
        }
324
        catch(PDOException $e) {
325
            // attempt rolling back the transaction before throwing a phpCAS error
326
            try {
327
                $pdo->rollBack();
328
            }
329
            catch(PDOException $e) {
330
            }
331
            phpCAS::error('error creating PGT storage table: ' . $e->getMessage());
332
        }
333
 
334
        // reset the PDO object
335
        $this->_resetErrorMode();
336
 
337
        phpCAS::traceEnd();
338
    }
339
 
340
    /**
341
     * This method stores a PGT and its corresponding PGT Iou in the database.
342
     * Echoes a warning on error.
343
     *
344
     * @param string $pgt     the PGT
345
     * @param string $pgt_iou the PGT iou
346
     *
347
     * @return void
348
     */
349
    public function write($pgt, $pgt_iou)
350
    {
351
        phpCAS::traceBegin();
352
 
353
        // initialize the PDO object for this method
354
        $pdo = $this->_getPdo();
355
        $this->_setErrorMode();
356
 
357
        try {
358
            $pdo->beginTransaction();
359
 
360
            $query = $pdo->prepare($this->storePgtSql());
361
            $query->bindValue(':pgt', $pgt, PDO::PARAM_STR);
362
            $query->bindValue(':pgt_iou', $pgt_iou, PDO::PARAM_STR);
363
            $query->execute();
364
            $query->closeCursor();
365
 
366
            $pdo->commit();
367
        }
368
        catch(PDOException $e) {
369
            // attempt rolling back the transaction before throwing a phpCAS error
370
            try {
371
                $pdo->rollBack();
372
            }
373
            catch(PDOException $e) {
374
            }
375
            phpCAS::error('error writing PGT to database: ' . $e->getMessage());
376
        }
377
 
378
        // reset the PDO object
379
        $this->_resetErrorMode();
380
 
381
        phpCAS::traceEnd();
382
    }
383
 
384
    /**
385
     * This method reads a PGT corresponding to a PGT Iou and deletes the
386
     * corresponding db entry.
387
     *
388
     * @param string $pgt_iou the PGT iou
389
     *
390
     * @return string|false the corresponding PGT, or FALSE on error
391
     */
392
    public function read($pgt_iou)
393
    {
394
        phpCAS::traceBegin();
395
        $pgt = false;
396
 
397
        // initialize the PDO object for this method
398
        $pdo = $this->_getPdo();
399
        $this->_setErrorMode();
400
 
401
        try {
402
            $pdo->beginTransaction();
403
 
404
            // fetch the pgt for the specified pgt_iou
405
            $query = $pdo->prepare($this->retrievePgtSql());
406
            $query->bindValue(':pgt_iou', $pgt_iou, PDO::PARAM_STR);
407
            $query->execute();
408
            $pgt = $query->fetchColumn(0);
409
            $query->closeCursor();
410
 
411
            // delete the specified pgt_iou from the database
412
            $query = $pdo->prepare($this->deletePgtSql());
413
            $query->bindValue(':pgt_iou', $pgt_iou, PDO::PARAM_STR);
414
            $query->execute();
415
            $query->closeCursor();
416
 
417
            $pdo->commit();
418
        }
419
        catch(PDOException $e) {
420
            // attempt rolling back the transaction before throwing a phpCAS error
421
            try {
422
                $pdo->rollBack();
423
            }
424
            catch(PDOException $e) {
425
            }
426
            phpCAS::trace('error reading PGT from database: ' . $e->getMessage());
427
        }
428
 
429
        // reset the PDO object
430
        $this->_resetErrorMode();
431
 
432
        phpCAS::traceEnd();
433
        return $pgt;
434
    }
435
 
436
    /** @} */
437
 
438
}
439
 
440
?>