441 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			441 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /**
 | |
|  * Licensed to Jasig under one or more contributor license
 | |
|  * agreements. See the NOTICE file distributed with this work for
 | |
|  * additional information regarding copyright ownership.
 | |
|  *
 | |
|  * Jasig licenses this file to you under the Apache License,
 | |
|  * Version 2.0 (the "License"); you may not use this file except in
 | |
|  * compliance with the License. You may obtain a copy of the License at:
 | |
|  *
 | |
|  * http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  *
 | |
|  * PHP Version 5
 | |
|  *
 | |
|  * @file     CAS/PGTStorage/Db.php
 | |
|  * @category Authentication
 | |
|  * @package  PhpCAS
 | |
|  * @author   Daniel Frett <daniel.frett@gmail.com>
 | |
|  * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 | |
|  * @link     https://wiki.jasig.org/display/CASC/phpCAS
 | |
|  */
 | |
| 
 | |
| define('CAS_PGT_STORAGE_DB_DEFAULT_TABLE', 'cas_pgts');
 | |
| 
 | |
| /**
 | |
|  * Basic class for PGT database storage
 | |
|  * The CAS_PGTStorage_Db class is a class for PGT database storage.
 | |
|  *
 | |
|  * @class    CAS_PGTStorage_Db
 | |
|  * @category Authentication
 | |
|  * @package  PhpCAS
 | |
|  * @author   Daniel Frett <daniel.frett@gmail.com>
 | |
|  * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 | |
|  * @link     https://wiki.jasig.org/display/CASC/phpCAS
 | |
|  *
 | |
|  * @ingroup internalPGTStorageDb
 | |
|  */
 | |
| 
 | |
| class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage
 | |
| {
 | |
|     /**
 | |
|      * @addtogroup internalCAS_PGTStorageDb
 | |
|      * @{
 | |
|      */
 | |
| 
 | |
|     /**
 | |
|      * the PDO object to use for database interactions
 | |
|      */
 | |
|     private $_pdo;
 | |
| 
 | |
|     /**
 | |
|      * This method returns the PDO object to use for database interactions.
 | |
|      *
 | |
|      * @return PDO object
 | |
|      */
 | |
|     private function _getPdo()
 | |
|     {
 | |
|         return $this->_pdo;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * database connection options to use when creating a new PDO object
 | |
|      */
 | |
|     private $_dsn;
 | |
|     private $_username;
 | |
|     private $_password;
 | |
|     private $_driver_options;
 | |
| 
 | |
|     /**
 | |
|      * @var string the table to use for storing/retrieving pgt's
 | |
|      */
 | |
|     private $_table;
 | |
| 
 | |
|     /**
 | |
|      * This method returns the table to use when storing/retrieving PGT's
 | |
|      *
 | |
|      * @return string the name of the pgt storage table.
 | |
|      */
 | |
|     private function _getTable()
 | |
|     {
 | |
|         return $this->_table;
 | |
|     }
 | |
| 
 | |
|     // ########################################################################
 | |
|     //  DEBUGGING
 | |
|     // ########################################################################
 | |
| 
 | |
|     /**
 | |
|      * This method returns an informational string giving the type of storage
 | |
|      * used by the object (used for debugging purposes).
 | |
|      *
 | |
|      * @return string an informational string.
 | |
|      */
 | |
|     public function getStorageType()
 | |
|     {
 | |
|         return "db";
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * This method returns an informational string giving informations on the
 | |
|      * parameters of the storage.(used for debugging purposes).
 | |
|      *
 | |
|      * @return string an informational string.
 | |
|      * @public
 | |
|      */
 | |
|     public function getStorageInfo()
 | |
|     {
 | |
|         return 'table=`'.$this->_getTable().'\'';
 | |
|     }
 | |
| 
 | |
|     // ########################################################################
 | |
|     //  CONSTRUCTOR
 | |
|     // ########################################################################
 | |
| 
 | |
|     /**
 | |
|      * The class constructor.
 | |
|      *
 | |
|      * @param CAS_Client $cas_parent     the CAS_Client instance that creates
 | |
|      * the object.
 | |
|      * @param string     $dsn_or_pdo     a dsn string to use for creating a PDO
 | |
|      * object or a PDO object
 | |
|      * @param string     $username       the username to use when connecting to
 | |
|      * the database
 | |
|      * @param string     $password       the password to use when connecting to
 | |
|      * the database
 | |
|      * @param string     $table          the table to use for storing and
 | |
|      * retrieving PGT's
 | |
|      * @param string     $driver_options any driver options to use when
 | |
|      * connecting to the database
 | |
|      */
 | |
|     public function __construct(
 | |
|         $cas_parent, $dsn_or_pdo, $username='', $password='', $table='',
 | |
|         $driver_options=null
 | |
|     ) {
 | |
|         phpCAS::traceBegin();
 | |
|         // call the ancestor's constructor
 | |
|         parent::__construct($cas_parent);
 | |
| 
 | |
|         // set default values
 | |
|         if ( empty($table) ) {
 | |
|             $table = CAS_PGT_STORAGE_DB_DEFAULT_TABLE;
 | |
|         }
 | |
|         if ( !is_array($driver_options) ) {
 | |
|             $driver_options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
 | |
|         }
 | |
| 
 | |
|         // store the specified parameters
 | |
|         if ($dsn_or_pdo instanceof PDO) {
 | |
|             $this->_pdo = $dsn_or_pdo;
 | |
|         } else {
 | |
|             $this->_dsn = $dsn_or_pdo;
 | |
|             $this->_username = $username;
 | |
|             $this->_password = $password;
 | |
|             $this->_driver_options = $driver_options;
 | |
|         }
 | |
| 
 | |
|         // store the table name
 | |
|         $this->_table = $table;
 | |
| 
 | |
|         phpCAS::traceEnd();
 | |
|     }
 | |
| 
 | |
|     // ########################################################################
 | |
|     //  INITIALIZATION
 | |
|     // ########################################################################
 | |
| 
 | |
|     /**
 | |
|      * This method is used to initialize the storage. Halts on error.
 | |
|      *
 | |
|      * @return void
 | |
|      */
 | |
|     public function init()
 | |
|     {
 | |
|         phpCAS::traceBegin();
 | |
|         // if the storage has already been initialized, return immediatly
 | |
|         if ($this->isInitialized()) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         // initialize the base object
 | |
|         parent::init();
 | |
| 
 | |
|         // create the PDO object if it doesn't exist already
 | |
|         if (!($this->_pdo instanceof PDO)) {
 | |
|             try {
 | |
|                 $this->_pdo = new PDO(
 | |
|                     $this->_dsn, $this->_username, $this->_password,
 | |
|                     $this->_driver_options
 | |
|                 );
 | |
|             }
 | |
|             catch(PDOException $e) {
 | |
|                 phpCAS::error('Database connection error: ' . $e->getMessage());
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         phpCAS::traceEnd();
 | |
|     }
 | |
| 
 | |
|     // ########################################################################
 | |
|     //  PDO database interaction
 | |
|     // ########################################################################
 | |
| 
 | |
|     /**
 | |
|      * attribute that stores the previous error mode for the PDO handle while
 | |
|      * processing a transaction
 | |
|      */
 | |
|     private $_errMode;
 | |
| 
 | |
|     /**
 | |
|      * This method will enable the Exception error mode on the PDO object
 | |
|      *
 | |
|      * @return void
 | |
|      */
 | |
|     private function _setErrorMode()
 | |
|     {
 | |
|         // get PDO object and enable exception error mode
 | |
|         $pdo = $this->_getPdo();
 | |
|         $this->_errMode = $pdo->getAttribute(PDO::ATTR_ERRMODE);
 | |
|         $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * this method will reset the error mode on the PDO object
 | |
|      *
 | |
|      * @return void
 | |
|      */
 | |
|     private function _resetErrorMode()
 | |
|     {
 | |
|         // get PDO object and reset the error mode to what it was originally
 | |
|         $pdo = $this->_getPdo();
 | |
|         $pdo->setAttribute(PDO::ATTR_ERRMODE, $this->_errMode);
 | |
|     }
 | |
| 
 | |
|     // ########################################################################
 | |
|     //  database queries
 | |
|     // ########################################################################
 | |
|     // these queries are potentially unsafe because the person using this library
 | |
|     // can set the table to use, but there is no reliable way to escape SQL
 | |
|     // fieldnames in PDO yet
 | |
| 
 | |
|     /**
 | |
|      * This method returns the query used to create a pgt storage table
 | |
|      *
 | |
|      * @return string the create table SQL, no bind params in query
 | |
|      */
 | |
|     protected function createTableSql()
 | |
|     {
 | |
|         return 'CREATE TABLE ' . $this->_getTable()
 | |
|             . ' (pgt_iou VARCHAR(255) NOT NULL PRIMARY KEY, pgt VARCHAR(255) NOT NULL)';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * This method returns the query used to store a pgt
 | |
|      *
 | |
|      * @return string the store PGT SQL, :pgt and :pgt_iou are the bind params contained
 | |
|      *         in the query
 | |
|      */
 | |
|     protected function storePgtSql()
 | |
|     {
 | |
|         return 'INSERT INTO ' . $this->_getTable()
 | |
|             . ' (pgt_iou, pgt) VALUES (:pgt_iou, :pgt)';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * This method returns the query used to retrieve a pgt. the first column
 | |
|      * of the first row should contain the pgt
 | |
|      *
 | |
|      * @return string the retrieve PGT SQL, :pgt_iou is the only bind param contained
 | |
|      *         in the query
 | |
|      */
 | |
|     protected function retrievePgtSql()
 | |
|     {
 | |
|         return 'SELECT pgt FROM ' . $this->_getTable() . ' WHERE pgt_iou = :pgt_iou';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * This method returns the query used to delete a pgt.
 | |
|      *
 | |
|      * @return string the delete PGT SQL, :pgt_iou is the only bind param contained in
 | |
|      *         the query
 | |
|      */
 | |
|     protected function deletePgtSql()
 | |
|     {
 | |
|         return 'DELETE FROM ' . $this->_getTable() . ' WHERE pgt_iou = :pgt_iou';
 | |
|     }
 | |
| 
 | |
|     // ########################################################################
 | |
|     //  PGT I/O
 | |
|     // ########################################################################
 | |
| 
 | |
|     /**
 | |
|      * This method creates the database table used to store pgt's and pgtiou's
 | |
|      *
 | |
|      * @return void
 | |
|      */
 | |
|     public function createTable()
 | |
|     {
 | |
|         phpCAS::traceBegin();
 | |
| 
 | |
|         // initialize this PGTStorage object if it hasn't been initialized yet
 | |
|         if ( !$this->isInitialized() ) {
 | |
|             $this->init();
 | |
|         }
 | |
| 
 | |
|         // initialize the PDO object for this method
 | |
|         $pdo = $this->_getPdo();
 | |
|         $this->_setErrorMode();
 | |
| 
 | |
|         try {
 | |
|             $pdo->beginTransaction();
 | |
| 
 | |
|             $query = $pdo->query($this->createTableSQL());
 | |
|             $query->closeCursor();
 | |
| 
 | |
|             $pdo->commit();
 | |
|         }
 | |
|         catch(PDOException $e) {
 | |
|             // attempt rolling back the transaction before throwing a phpCAS error
 | |
|             try {
 | |
|                 $pdo->rollBack();
 | |
|             }
 | |
|             catch(PDOException $e) {
 | |
|             }
 | |
|             phpCAS::error('error creating PGT storage table: ' . $e->getMessage());
 | |
|         }
 | |
| 
 | |
|         // reset the PDO object
 | |
|         $this->_resetErrorMode();
 | |
| 
 | |
|         phpCAS::traceEnd();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * This method stores a PGT and its corresponding PGT Iou in the database.
 | |
|      * Echoes a warning on error.
 | |
|      *
 | |
|      * @param string $pgt     the PGT
 | |
|      * @param string $pgt_iou the PGT iou
 | |
|      *
 | |
|      * @return void
 | |
|      */
 | |
|     public function write($pgt, $pgt_iou)
 | |
|     {
 | |
|         phpCAS::traceBegin();
 | |
| 
 | |
|         // initialize the PDO object for this method
 | |
|         $pdo = $this->_getPdo();
 | |
|         $this->_setErrorMode();
 | |
| 
 | |
|         try {
 | |
|             $pdo->beginTransaction();
 | |
| 
 | |
|             $query = $pdo->prepare($this->storePgtSql());
 | |
|             $query->bindValue(':pgt', $pgt, PDO::PARAM_STR);
 | |
|             $query->bindValue(':pgt_iou', $pgt_iou, PDO::PARAM_STR);
 | |
|             $query->execute();
 | |
|             $query->closeCursor();
 | |
| 
 | |
|             $pdo->commit();
 | |
|         }
 | |
|         catch(PDOException $e) {
 | |
|             // attempt rolling back the transaction before throwing a phpCAS error
 | |
|             try {
 | |
|                 $pdo->rollBack();
 | |
|             }
 | |
|             catch(PDOException $e) {
 | |
|             }
 | |
|             phpCAS::error('error writing PGT to database: ' . $e->getMessage());
 | |
|         }
 | |
| 
 | |
|         // reset the PDO object
 | |
|         $this->_resetErrorMode();
 | |
| 
 | |
|         phpCAS::traceEnd();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * This method reads a PGT corresponding to a PGT Iou and deletes the
 | |
|      * corresponding db entry.
 | |
|      *
 | |
|      * @param string $pgt_iou the PGT iou
 | |
|      *
 | |
|      * @return string|false the corresponding PGT, or FALSE on error
 | |
|      */
 | |
|     public function read($pgt_iou)
 | |
|     {
 | |
|         phpCAS::traceBegin();
 | |
|         $pgt = false;
 | |
| 
 | |
|         // initialize the PDO object for this method
 | |
|         $pdo = $this->_getPdo();
 | |
|         $this->_setErrorMode();
 | |
| 
 | |
|         try {
 | |
|             $pdo->beginTransaction();
 | |
| 
 | |
|             // fetch the pgt for the specified pgt_iou
 | |
|             $query = $pdo->prepare($this->retrievePgtSql());
 | |
|             $query->bindValue(':pgt_iou', $pgt_iou, PDO::PARAM_STR);
 | |
|             $query->execute();
 | |
|             $pgt = $query->fetchColumn(0);
 | |
|             $query->closeCursor();
 | |
| 
 | |
|             // delete the specified pgt_iou from the database
 | |
|             $query = $pdo->prepare($this->deletePgtSql());
 | |
|             $query->bindValue(':pgt_iou', $pgt_iou, PDO::PARAM_STR);
 | |
|             $query->execute();
 | |
|             $query->closeCursor();
 | |
| 
 | |
|             $pdo->commit();
 | |
|         }
 | |
|         catch(PDOException $e) {
 | |
|             // attempt rolling back the transaction before throwing a phpCAS error
 | |
|             try {
 | |
|                 $pdo->rollBack();
 | |
|             }
 | |
|             catch(PDOException $e) {
 | |
|             }
 | |
|             phpCAS::trace('error reading PGT from database: ' . $e->getMessage());
 | |
|         }
 | |
| 
 | |
|         // reset the PDO object
 | |
|         $this->_resetErrorMode();
 | |
| 
 | |
|         phpCAS::traceEnd();
 | |
|         return $pgt;
 | |
|     }
 | |
| 
 | |
|     /** @} */
 | |
| 
 | |
| }
 | |
| 
 | |
| ?>
 |