X-Git-Url: https://git.mdrn.pl/piwik-CASLogin.git/blobdiff_plain/237569a1cfdd478618b0ecda78a7ac13548c515f..dc6aefd9f59af623481149a8b6c71b973efd1196:/CAS/CAS/PGTStorage/Db.php diff --git a/CAS/CAS/PGTStorage/Db.php b/CAS/CAS/PGTStorage/Db.php new file mode 100644 index 0000000..1f635f8 --- /dev/null +++ b/CAS/CAS/PGTStorage/Db.php @@ -0,0 +1,429 @@ + + * @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 + * @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 the 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 $_table_options; + + /** + * the table to use for storing/retrieving pgt's + */ + private $_table; + + /** + * This method returns the table to use when storing/retrieving PGT's + * + * @return 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 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 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 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 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 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 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 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; + } + + /** @} */ + +} + +?>