PageRenderTime 124ms CodeModel.GetById 60ms app.highlight 12ms RepoModel.GetById 48ms app.codeStats 0ms

/library/Zend/Auth/Adapter/DbTable.php

https://bitbucket.org/baruffaldi/webapp-urltube
PHP | 461 lines | 201 code | 56 blank | 204 comment | 24 complexity | df58d1592188f916067fad84daf6c7d0 MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Auth
 17 * @subpackage Zend_Auth_Adapter
 18 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: DbTable.php 8862 2008-03-16 15:36:00Z thomas $
 21 */
 22
 23
 24/**
 25 * @see Zend_Auth_Adapter_Interface
 26 */
 27require_once 'Zend/Auth/Adapter/Interface.php';
 28
 29/**
 30 * @see Zend_Db_Adapter_Abstract
 31 */
 32require_once 'Zend/Db/Adapter/Abstract.php';
 33
 34/**
 35 * @see Zend_Auth_Result
 36 */
 37require_once 'Zend/Auth/Result.php';
 38
 39
 40/**
 41 * @category   Zend
 42 * @package    Zend_Auth
 43 * @subpackage Zend_Auth_Adapter
 44 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 45 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 46 */
 47class Zend_Auth_Adapter_DbTable implements Zend_Auth_Adapter_Interface
 48{
 49    /**
 50     * Database Connection
 51     *
 52     * @var Zend_Db_Adapter_Abstract
 53     */
 54    protected $_zendDb = null;
 55
 56    /**
 57     * $_tableName - the table name to check
 58     *
 59     * @var string
 60     */
 61    protected $_tableName = null;
 62
 63    /**
 64     * $_identityColumn - the column to use as the identity
 65     *
 66     * @var string
 67     */
 68    protected $_identityColumn = null;
 69
 70    /**
 71     * $_credentialColumns - columns to be used as the credentials
 72     *
 73     * @var string
 74     */
 75    protected $_credentialColumn = null;
 76
 77    /**
 78     * $_identity - Identity value
 79     *
 80     * @var string
 81     */
 82    protected $_identity = null;
 83
 84    /**
 85     * $_credential - Credential values
 86     *
 87     * @var string
 88     */
 89    protected $_credential = null;
 90
 91    /**
 92     * $_credentialTreatment - Treatment applied to the credential, such as MD5() or PASSWORD()
 93     *
 94     * @var string
 95     */
 96    protected $_credentialTreatment = null;
 97
 98    /**
 99     * $_authenticateResultInfo
100     *
101     * @var array
102     */
103    protected $_authenticateResultInfo = null;
104    
105    /**
106     * $_resultRow - Results of database authentication query
107     *
108     * @var array
109     */
110    protected $_resultRow = null;
111
112    /**
113     * __construct() - Sets configuration options
114     *
115     * @param  Zend_Db_Adapter_Abstract $zendDb
116     * @param  string                   $tableName
117     * @param  string                   $identityColumn
118     * @param  string                   $credentialColumn
119     * @param  string                   $credentialTreatment
120     * @return void
121     */
122    public function __construct(Zend_Db_Adapter_Abstract $zendDb, $tableName = null, $identityColumn = null,
123                                $credentialColumn = null, $credentialTreatment = null)
124    {
125        $this->_zendDb = $zendDb;
126
127        if (null !== $tableName) {
128            $this->setTableName($tableName);
129        }
130
131        if (null !== $identityColumn) {
132            $this->setIdentityColumn($identityColumn);
133        }
134
135        if (null !== $credentialColumn) {
136            $this->setCredentialColumn($credentialColumn);
137        }
138
139        if (null !== $credentialTreatment) {
140            $this->setCredentialTreatment($credentialTreatment);
141        }
142    }
143
144    /**
145     * setTableName() - set the table name to be used in the select query
146     *
147     * @param  string $tableName
148     * @return Zend_Auth_Adapter_DbTable Provides a fluent interface
149     */
150    public function setTableName($tableName)
151    {
152        $this->_tableName = $tableName;
153        return $this;
154    }
155
156    /**
157     * setIdentityColumn() - set the column name to be used as the identity column
158     *
159     * @param  string $identityColumn
160     * @return Zend_Auth_Adapter_DbTable Provides a fluent interface
161     */
162    public function setIdentityColumn($identityColumn)
163    {
164        $this->_identityColumn = $identityColumn;
165        return $this;
166    }
167
168    /**
169     * setCredentialColumn() - set the column name to be used as the credential column
170     *
171     * @param  string $credentialColumn
172     * @return Zend_Auth_Adapter_DbTable Provides a fluent interface
173     */
174    public function setCredentialColumn($credentialColumn)
175    {
176        $this->_credentialColumn = $credentialColumn;
177        return $this;
178    }
179
180    /**
181     * setCredentialTreatment() - allows the developer to pass a parameterized string that is
182     * used to transform or treat the input credential data
183     *
184     * In many cases, passwords and other sensitive data are encrypted, hashed, encoded,
185     * obscured, or otherwise treated through some function or algorithm. By specifying a
186     * parameterized treatment string with this method, a developer may apply arbitrary SQL
187     * upon input credential data.
188     *
189     * Examples:
190     *
191     *  'PASSWORD(?)'
192     *  'MD5(?)'
193     *
194     * @param  string $treatment
195     * @return Zend_Auth_Adapter_DbTable Provides a fluent interface
196     */
197    public function setCredentialTreatment($treatment)
198    {
199        $this->_credentialTreatment = $treatment;
200        return $this;
201    }
202
203    /**
204     * setIdentity() - set the value to be used as the identity
205     *
206     * @param  string $value
207     * @return Zend_Auth_Adapter_DbTable Provides a fluent interface
208     */
209    public function setIdentity($value)
210    {
211        $this->_identity = $value;
212        return $this;
213    }
214
215    /**
216     * setCredential() - set the credential value to be used, optionally can specify a treatment
217     * to be used, should be supplied in parameterized form, such as 'MD5(?)' or 'PASSWORD(?)'
218     *
219     * @param  string $credential
220     * @return Zend_Auth_Adapter_DbTable Provides a fluent interface
221     */
222    public function setCredential($credential)
223    {
224        $this->_credential = $credential;
225        return $this;
226    }
227
228    /**
229     * getResultRowObject() - Returns the result row as a stdClass object
230     *
231     * @param  string|array $returnColumns
232     * @param  string|array $omitColumns
233     * @return stdClass|boolean
234     */
235    public function getResultRowObject($returnColumns = null, $omitColumns = null)
236    {
237        if (!$this->_resultRow) {
238            return false;
239        }
240        
241        $returnObject = new stdClass();
242
243        if (null !== $returnColumns) {
244
245            $availableColumns = array_keys($this->_resultRow);
246            foreach ( (array) $returnColumns as $returnColumn) {
247                if (in_array($returnColumn, $availableColumns)) {
248                    $returnObject->{$returnColumn} = $this->_resultRow[$returnColumn];
249                }
250            }
251            return $returnObject;
252
253        } elseif (null !== $omitColumns) {
254
255            $omitColumns = (array) $omitColumns;
256            foreach ($this->_resultRow as $resultColumn => $resultValue) {
257                if (!in_array($resultColumn, $omitColumns)) {
258                    $returnObject->{$resultColumn} = $resultValue;
259                }
260            }
261            return $returnObject;
262
263        } else {
264
265            foreach ($this->_resultRow as $resultColumn => $resultValue) {
266                $returnObject->{$resultColumn} = $resultValue;
267            }
268            return $returnObject;
269
270        }
271    }
272
273    /**
274     * authenticate() - defined by Zend_Auth_Adapter_Interface.  This method is called to 
275     * attempt an authenication.  Previous to this call, this adapter would have already
276     * been configured with all nessissary information to successfully connect to a database
277     * table and attempt to find a record matching the provided identity.
278     *
279     * @throws Zend_Auth_Adapter_Exception if answering the authentication query is impossible
280     * @return Zend_Auth_Result
281     */
282    public function authenticate()
283    {
284        $this->_authenticateSetup();
285        $dbSelect = $this->_authenticateCreateSelect();
286        $resultIdentities = $this->_authenticateQuerySelect($dbSelect);
287        
288        if ( ($authResult = $this->_authenticateValidateResultset($resultIdentities)) instanceof Zend_Auth_Result) {
289            return $authResult;
290        }
291        
292        $authResult = $this->_authenticateValidateResult(array_shift($resultIdentities));
293        return $authResult;
294    }
295
296    /**
297     * _authenticateSetup() - This method abstracts the steps involved with making sure
298     * that this adapter was indeed setup properly with all required peices of information.
299     *
300     * @throws Zend_Auth_Adapter_Exception - in the event that setup was not done properly
301     * @return true
302     */
303    protected function _authenticateSetup()
304    {
305        $exception = null;
306
307        if ($this->_tableName == '') {
308            $exception = 'A table must be supplied for the Zend_Auth_Adapter_DbTable authentication adapter.';
309        } elseif ($this->_identityColumn == '') {
310            $exception = 'An identity column must be supplied for the Zend_Auth_Adapter_DbTable authentication adapter.';
311        } elseif ($this->_credentialColumn == '') {
312            $exception = 'A credential column must be supplied for the Zend_Auth_Adapter_DbTable authentication adapter.';
313        } elseif ($this->_identity == '') {
314            $exception = 'A value for the identity was not provided prior to authentication with Zend_Auth_Adapter_DbTable.';
315        } elseif ($this->_credential === null) {
316            $exception = 'A credential value was not provided prior to authentication with Zend_Auth_Adapter_DbTable.';
317        }
318
319        if (null !== $exception) {
320            /**
321             * @see Zend_Auth_Adapter_Exception
322             */
323            require_once 'Zend/Auth/Adapter/Exception.php';
324            throw new Zend_Auth_Adapter_Exception($exception);
325        }
326        
327        $this->_authenticateResultInfo = array(
328            'code'     => Zend_Auth_Result::FAILURE,
329            'identity' => $this->_identity,
330            'messages' => array()
331            );
332            
333        return true;
334    }
335
336    /**
337     * _authenticateCreateSelect() - This method creates a Zend_Db_Select object that
338     * is completely configured to be queried against the database.
339     *
340     * @return Zend_Db_Select
341     */
342    protected function _authenticateCreateSelect()
343    {
344        // build credential expression
345        if (empty($this->_credentialTreatment) || (strpos($this->_credentialTreatment, "?") === false)) {
346            $this->_credentialTreatment = '?';
347        }
348
349        $credentialExpression = new Zend_Db_Expr(
350            '(CASE WHEN ' . 
351            $this->_zendDb->quoteInto(
352                $this->_zendDb->quoteIdentifier($this->_credentialColumn, true)
353                . ' = ' . $this->_credentialTreatment, $this->_credential
354                )
355            . ' THEN 1 ELSE 0 END) AS '
356            . $this->_zendDb->quoteIdentifier('zend_auth_credential_match')
357            );
358
359        // get select
360        $dbSelect = $this->_zendDb->select();
361        $dbSelect->from($this->_tableName, array('*', $credentialExpression))
362                 ->where($this->_zendDb->quoteIdentifier($this->_identityColumn, true) . ' = ?', $this->_identity);
363
364        return $dbSelect;
365    }
366
367    /**
368     * _authenticateQuerySelect() - This method accepts a Zend_Db_Select object and
369     * performs a query against the database with that object.
370     *
371     * @param Zend_Db_Select $dbSelect
372     * @throws Zend_Auth_Adapter_Exception - when a invalid select object is encoutered
373     * @return array
374     */
375    protected function _authenticateQuerySelect(Zend_Db_Select $dbSelect)
376    {
377        try {
378            if ($this->_zendDb->getFetchMode() != Zend_DB::FETCH_ASSOC) {
379                $origDbFetchMode = $this->_zendDb->getFetchMode();
380                $this->_zendDb->setFetchMode(Zend_DB::FETCH_ASSOC);
381            }
382            $resultIdentities = $this->_zendDb->fetchAll($dbSelect->__toString());
383            if (isset($origDbFetchMode)) {
384                $this->_zendDb->setFetchMode($origDbFetchMode);
385                unset($origDbFetchMode);
386            }
387        } catch (Exception $e) {
388            /**
389             * @see Zend_Auth_Adapter_Exception
390             */
391            require_once 'Zend/Auth/Adapter/Exception.php';
392            throw new Zend_Auth_Adapter_Exception('The supplied parameters to Zend_Auth_Adapter_DbTable failed to '
393                                                . 'produce a valid sql statement, please check table and column names '
394                                                . 'for validity.');
395        }
396        return $resultIdentities;
397    }
398
399    /**
400     * _authenticateValidateResultSet() - This method attempts to make certian that only one
401     * record was returned in the result set
402     *
403     * @param array $resultIdentities
404     * @return true|Zend_Auth_Result
405     */
406    protected function _authenticateValidateResultSet(array $resultIdentities)
407    {
408
409
410        if (count($resultIdentities) < 1) {
411            $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND;
412            $this->_authenticateResultInfo['messages'][] = 'A record with the supplied identity could not be found.';
413            return $this->_authenticateCreateAuthResult();
414        } elseif (count($resultIdentities) > 1) {
415            $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS;
416            $this->_authenticateResultInfo['messages'][] = 'More than one record matches the supplied identity.';
417            return $this->_authenticateCreateAuthResult();
418        }
419
420        return true;
421    }
422
423    /**
424     * _authenticateValidateResult() - This method attempts to validate that the record in the 
425     * result set is indeed a record that matched the identity provided to this adapter.
426     *
427     * @param array $resultIdentity
428     * @return Zend_Auth_Result
429     */
430    protected function _authenticateValidateResult($resultIdentity)
431    {
432        if ($resultIdentity['zend_auth_credential_match'] != '1') {
433            $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
434            $this->_authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
435            return $this->_authenticateCreateAuthResult();
436        }
437
438        unset($resultIdentity['zend_auth_credential_match']);
439        $this->_resultRow = $resultIdentity;
440
441        $this->_authenticateResultInfo['code'] = Zend_Auth_Result::SUCCESS;
442        $this->_authenticateResultInfo['messages'][] = 'Authentication successful.';
443        return $this->_authenticateCreateAuthResult();
444    }
445    
446    /**
447     * _authenticateCreateAuthResult() - This method creates a Zend_Auth_Result object
448     * from the information that has been collected during the authenticate() attempt.
449     *
450     * @return Zend_Auth_Result
451     */
452    protected function _authenticateCreateAuthResult()
453    {
454        return new Zend_Auth_Result(
455            $this->_authenticateResultInfo['code'],
456            $this->_authenticateResultInfo['identity'],
457            $this->_authenticateResultInfo['messages']
458            );
459    }
460
461}