Auth
[ class tree: Auth ] [ index: Auth ] [ all elements ]

Source for file MDB2.php

Documentation is available at MDB2.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // |                                                                      |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Lorenzo Alberton <l.alberton@quipo.it>                       |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: MDB2.php,v 1.7 2006/02/22 00:14:51 aashley Exp $
  20. //
  21.  
  22. require_once 'Auth/Container.php';
  23. require_once 'MDB2.php';
  24.  
  25. /**
  26.  * Storage driver for fetching login data from a database
  27.  *
  28.  * This storage driver can use all databases which are supported
  29.  * by the PEAR MDB2 abstraction layer to fetch login data.
  30.  *
  31.  * @author   Lorenzo Alberton <l.alberton@quipo.it>
  32.  * @package  Auth
  33.  * @version  $Revision: 1.7 $
  34.  */
  35. {
  36.  
  37.     /**
  38.      * Additional options for the storage container
  39.      * @var array 
  40.      */
  41.     var $options = array();
  42.  
  43.     /**
  44.      * MDB object
  45.      * @var object 
  46.      */
  47.     var $db = null;
  48.     var $dsn = '';
  49.  
  50.     /**
  51.      * User that is currently selected from the DB.
  52.      * @var string 
  53.      */
  54.     var $activeUser = '';
  55.  
  56.     // {{{ Constructor
  57.  
  58.     /**
  59.      * Constructor of the container class
  60.      *
  61.      * Initate connection to the database via PEAR::MDB2
  62.      *
  63.      * @param  string Connection data or MDB2 object
  64.      * @return object Returns an error object if something went wrong
  65.      */
  66.     function Auth_Container_MDB2($dsn)
  67.     {
  68.         $this->_setDefaults();
  69.  
  70.         if (is_array($dsn)) {
  71.             $this->_parseOptions($dsn);
  72.             if (empty($this->options['dsn'])) {
  73.                 PEAR::raiseError('No connection parameters specified!');
  74.             }
  75.         else {
  76.             $this->options['dsn'$dsn;
  77.         }
  78.     }
  79.  
  80.     // }}}
  81.     // {{{ _connect()
  82.  
  83.     /**
  84.      * Connect to database by using the given DSN string
  85.      *
  86.      * @access private
  87.      * @param  mixed DSN string | array | mdb object
  88.      * @return mixed  Object on error, otherwise bool
  89.      */
  90.     function _connect($dsn)
  91.     {
  92.         if (is_string($dsn|| is_array($dsn)) {
  93.             $this->db =MDB2::connect($dsn$this->options['db_options']);
  94.         elseif (is_subclass_of($dsn'MDB2_Driver_Common')) {
  95.             $this->db = $dsn;
  96.         elseif (is_object($dsn&& MDB2::isError($dsn)) {
  97.             return PEAR::raiseError($dsn->getMessage()$dsn->code);
  98.         else {
  99.             return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
  100.                                     41,
  101.                                     PEAR_ERROR_RETURN,
  102.                                     null,
  103.                                     null
  104.                                     );
  105.  
  106.         }
  107.  
  108.         if (MDB2::isError($this->db|| PEAR::isError($this->db)) {
  109.             return PEAR::raiseError($this->db->getMessage()$this->db->code);
  110.         }
  111.         return true;
  112.     }
  113.  
  114.     // }}}
  115.     // {{{ _prepare()
  116.  
  117.     /**
  118.      * Prepare database connection
  119.      *
  120.      * This function checks if we have already opened a connection to
  121.      * the database. If that's not the case, a new connection is opened.
  122.      *
  123.      * @access private
  124.      * @return mixed True or a MDB error object.
  125.      */
  126.     function _prepare()
  127.     {
  128.         if (is_subclass_of($this->db'MDB2_Driver_Common')) {
  129.             return true;
  130.         }
  131.         return $this->_connect($this->options['dsn']);
  132.     }
  133.  
  134.     // }}}
  135.     // {{{ query()
  136.  
  137.     /**
  138.      * Prepare query to the database
  139.      *
  140.      * This function checks if we have already opened a connection to
  141.      * the database. If that's not the case, a new connection is opened.
  142.      * After that the query is passed to the database.
  143.      *
  144.      * @access public
  145.      * @param  string Query string
  146.      * @return mixed  a MDB_result object or MDB_OK on success, a MDB
  147.      *                 or PEAR error on failure
  148.      */
  149.     function query($query)
  150.     {
  151.         $err $this->_prepare();
  152.         if ($err !== true{
  153.             return $err;
  154.         }
  155.         return $this->db->exec($query);
  156.     }
  157.  
  158.     // }}}
  159.     // {{{ _setDefaults()
  160.  
  161.     /**
  162.      * Set some default options
  163.      *
  164.      * @access private
  165.      * @return void 
  166.      */
  167.     function _setDefaults()
  168.     {
  169.         $this->options['table']       'auth';
  170.         $this->options['usernamecol''username';
  171.         $this->options['passwordcol''password';
  172.         $this->options['dsn']         '';
  173.         $this->options['db_fields']   '';
  174.         $this->options['cryptType']   'md5';
  175.         $this->options['db_options']  = array();
  176.     }
  177.  
  178.     // }}}
  179.     // {{{ _parseOptions()
  180.  
  181.     /**
  182.      * Parse options passed to the container class
  183.      *
  184.      * @access private
  185.      * @param  array 
  186.      */
  187.     function _parseOptions($array)
  188.     {
  189.         foreach ($array as $key => $value{
  190.             if (isset($this->options[$key])) {
  191.                 $this->options[$key$value;
  192.             }
  193.         }
  194.  
  195.         // Include additional fields if they exist
  196.         if (!empty($this->options['db_fields'])) {
  197.             if (is_array($this->options['db_fields'])) {
  198.                 $this->options['db_fields'join($this->options['db_fields']', ');
  199.             }
  200.             $this->options['db_fields'', ' $this->options['db_fields'];
  201.         }
  202.     }
  203.  
  204.     // }}}
  205.     // {{{ fetchData()
  206.  
  207.     /**
  208.      * Get user information from database
  209.      *
  210.      * This function uses the given username to fetch
  211.      * the corresponding login data from the database
  212.      * table. If an account that matches the passed username
  213.      * and password is found, the function returns true.
  214.      * Otherwise it returns false.
  215.      *
  216.      * @param   string Username
  217.      * @param   string Password
  218.      * @param   boolean If true password is secured using a md5 hash
  219.      *                   the frontend and auth are responsible for making sure the container supports
  220.      *                   challenge response password authentication
  221.      * @return  mixed  Error object or boolean
  222.      */
  223.     function fetchData($username$password$isChallengeResponse=false)
  224.     {
  225.         // Prepare for a database query
  226.         $err $this->_prepare();
  227.         if ($err !== true{
  228.             return PEAR::raiseError($err->getMessage()$err->getCode());
  229.         }
  230.  
  231.         //Check if db_fields contains a *, if so assume all columns are selected
  232.         if (strstr($this->options['db_fields']'*')) {
  233.             $sql_from '*';
  234.         else {
  235.             $sql_from $this->options['usernamecol'', '$this->options['passwordcol'$this->options['db_fields'];
  236.         }
  237.         $query sprintf("SELECT %s FROM %s WHERE %s = %s",
  238.                          $sql_from,
  239.                          $this->options['table'],
  240.                          $this->options['usernamecol'],
  241.                          $this->db->quote($username'text')
  242.                          );
  243.  
  244.         $res $this->db->queryRow($querynullMDB2_FETCHMODE_ASSOC);
  245.         if (MDB2::isError($res|| PEAR::isError($res)) {
  246.             return PEAR::raiseError($res->getMessage()$res->getCode());
  247.         }
  248.         if (!is_array($res)) {
  249.             $this->activeUser = '';
  250.             return false;
  251.         }
  252.  
  253.         // Perform trimming here before the hashing
  254.         $password trim($password"\r\n");
  255.         $res[$this->options['passwordcol']] trim($res[$this->options['passwordcol']]"\r\n");
  256.         // If using Challenge Response md5 the pass with the secret
  257.         if ($isChallengeResponse{
  258.             $res[$this->options['passwordcol']] =
  259.                 md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']);
  260.             // UGLY cannot avoid without modifying verifyPassword
  261.             if ($this->options['cryptType'== 'md5'{
  262.                 $res[$this->options['passwordcol']] md5($res[$this->options['passwordcol']]);
  263.             }
  264.         }
  265.         if ($this->verifyPassword($password,
  266.                                   $res[$this->options['passwordcol']],
  267.                                   $this->options['cryptType'])) {
  268.             // Store additional field values in the session
  269.             foreach ($res as $key => $value{
  270.                 if ($key == $this->options['passwordcol'||
  271.                     $key == $this->options['usernamecol']{
  272.                     continue;
  273.                 }
  274.                 // Use reference to the auth object if exists
  275.                 // This is because the auth session variable can change so a static call to setAuthData does not make sense
  276.                 $this->_auth_obj->setAuthData($key$value);
  277.             }
  278.             return true;
  279.         }
  280.  
  281.         $this->activeUser = $res[$this->options['usernamecol']];
  282.         return false;
  283.     }
  284.  
  285.     // }}}
  286.     // {{{ listUsers()
  287.  
  288.     /**
  289.      * Returns a list of users from the container
  290.      *
  291.      * @return mixed array|PEAR_Error
  292.      * @access public
  293.      */
  294.     function listUsers()
  295.     {
  296.         $err $this->_prepare();
  297.         if ($err !== true{
  298.             return PEAR::raiseError($err->getMessage()$err->getCode());
  299.         }
  300.  
  301.         $retVal = array();
  302.  
  303.         //Check if db_fields contains a *, if so assume all columns are selected
  304.         if (strstr($this->options['db_fields']'*')) {
  305.             $sql_from '*';
  306.         else {
  307.             $sql_from $this->options['db_fields'];
  308.         }
  309.  
  310.         $query sprintf('SELECT %s FROM %s',
  311.                          $sql_from,
  312.                          $this->options['table']
  313.                          );
  314.  
  315.         $res $this->db->queryAll($querynullMDB2_FETCHMODE_ASSOC);
  316.         if (MDB2::isError($res)) {
  317.             return PEAR::raiseError($res->getMessage()$res->getCode());
  318.         else {
  319.             foreach ($res as $user{
  320.                 $user['username'$user[$this->options['usernamecol']];
  321.                 $retVal[$user;
  322.             }
  323.         }
  324.         return $retVal;
  325.     }
  326.  
  327.     // }}}
  328.     // {{{ addUser()
  329.  
  330.     /**
  331.      * Add user to the storage container
  332.      *
  333.      * @access public
  334.      * @param  string Username
  335.      * @param  string Password
  336.      * @param  mixed  Additional information that are stored in the DB
  337.      *
  338.      * @return mixed True on success, otherwise error object
  339.      */
  340.     function addUser($username$password$additional "")
  341.     {
  342.  
  343.         // Prepare for a database query
  344.         $err $this->_prepare();
  345.         if ($err !== true{
  346.             return PEAR::raiseError($err->getMessage()$err->getCode());
  347.         }
  348.  
  349.         if (isset($this->options['cryptType']&& $this->options['cryptType'== 'none'{
  350.             $cryptFunction 'strval';
  351.         elseif (isset($this->options['cryptType']&& function_exists($this->options['cryptType'])) {
  352.             $cryptFunction $this->options['cryptType'];
  353.         else {
  354.             $cryptFunction 'md5';
  355.         }
  356.  
  357.         $password $cryptFunction($password);
  358.  
  359.         $additional_key   '';
  360.         $additional_value '';
  361.  
  362.         if (is_array($additional)) {
  363.             foreach ($additional as $key => $value{
  364.                 $additional_key   .= ', ' $key;
  365.                 $additional_value .= ', ' $this->db->quote($value'text');
  366.             }
  367.         }
  368.  
  369.         $query sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
  370.                          $this->options['table'],
  371.                          $this->options['usernamecol'],
  372.                          $this->options['passwordcol'],
  373.                          $additional_key,
  374.                          $this->db->quote($username'text'),
  375.                          $this->db->quote($password'text'),
  376.                          $additional_value
  377.                          );
  378.  
  379.         $res $this->query($query);
  380.  
  381.         if (MDB2::isError($res)) {
  382.             return PEAR::raiseError($res->getMessage()$res->code);
  383.         }
  384.         return true;
  385.     }
  386.  
  387.     // }}}
  388.     // {{{ removeUser()
  389.  
  390.     /**
  391.      * Remove user from the storage container
  392.      *
  393.      * @access public
  394.      * @param  string Username
  395.      *
  396.      * @return mixed True on success, otherwise error object
  397.      */
  398.     function removeUser($username)
  399.     {
  400.         // Prepare for a database query
  401.         $err $this->_prepare();
  402.         if ($err !== true{
  403.             return PEAR::raiseError($err->getMessage()$err->getCode());
  404.         }
  405.  
  406.         $query sprintf("DELETE FROM %s WHERE %s = %s",
  407.                          $this->options['table'],
  408.                          $this->options['usernamecol'],
  409.                          $this->db->quote($username'text')
  410.                          );
  411.  
  412.         $res $this->query($query);
  413.  
  414.         if (MDB2::isError($res)) {
  415.             return PEAR::raiseError($res->getMessage()$res->code);
  416.         }
  417.         return true;
  418.     }
  419.  
  420.     // }}}
  421.     // {{{ changePassword()
  422.  
  423.     /**
  424.      * Change password for user in the storage container
  425.      *
  426.      * @param string Username
  427.      * @param string The new password (plain text)
  428.      */
  429.     function changePassword($username$password)
  430.     {
  431.         // Prepare for a database query
  432.         $err $this->_prepare();
  433.         if ($err !== true{
  434.             return PEAR::raiseError($err->getMessage()$err->getCode());
  435.         }
  436.  
  437.         if (isset($this->options['cryptType']&& $this->options['cryptType'== 'none'{
  438.             $cryptFunction 'strval';
  439.         elseif (isset($this->options['cryptType']&& function_exists($this->options['cryptType'])) {
  440.             $cryptFunction $this->options['cryptType'];
  441.         else {
  442.             $cryptFunction 'md5';
  443.         }
  444.  
  445.         $password $cryptFunction($password);
  446.  
  447.         $query sprintf("UPDATE %s SET %s = %s WHERE %s = %s",
  448.                          $this->options['table'],
  449.                          $this->options['passwordcol'],
  450.                          $this->db->quote($password'text'),
  451.                          $this->options['usernamecol'],
  452.                          $this->db->quote($username'text')
  453.                          );
  454.  
  455.         $res $this->query($query);
  456.  
  457.         if (MDB2::isError($res)) {
  458.             return PEAR::raiseError($res->getMessage()$res->code);
  459.         }
  460.         return true;
  461.     }
  462.  
  463.     // }}}
  464.     // {{{ supportsChallengeResponse()
  465.  
  466.     /**
  467.      * Determine if this container supports
  468.      * password authentication with challenge response
  469.      *
  470.      * @return bool 
  471.      * @access public
  472.      */
  473.     function supportsChallengeResponse()
  474.     {
  475.         return in_array($this->options['cryptType']array('md5''none'''));
  476.     }
  477.  
  478.     // }}}
  479.     // {{{ getCryptType()
  480.  
  481.     /**
  482.      * Returns the selected crypt type for this container
  483.      *
  484.      * @return string Function used to crypt the password
  485.      */
  486.     function getCryptType()
  487.     {
  488.         return $this->options['cryptType'];
  489.     }
  490.  
  491.     // }}}
  492.  
  493. }
  494. ?>

Documentation generated on Mon, 11 Mar 2019 14:36:56 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.