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

Source for file Common.php

Documentation is available at Common.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * A framework for authentication and authorization in PHP applications
  6.  *
  7.  * LiveUser is an authentication/permission framework designed
  8.  * to be flexible and easily extendable.
  9.  *
  10.  * Since it is impossible to have a
  11.  * "one size fits all" it takes a container
  12.  * approach which should enable it to
  13.  * be versatile enough to meet most needs.
  14.  *
  15.  * PHP version 4 and 5
  16.  *
  17.  * LICENSE: This library is free software; you can redistribute it and/or
  18.  * modify it under the terms of the GNU Lesser General Public
  19.  * License as published by the Free Software Foundation; either
  20.  * version 2.1 of the License, or (at your option) any later version.
  21.  *
  22.  * This library is distributed in the hope that it will be useful,
  23.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  25.  * Lesser General Public License for more details.
  26.  *
  27.  * You should have received a copy of the GNU Lesser General Public
  28.  * License along with this library; if not, write to the Free Software
  29.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30.  * MA  02111-1307  USA
  31.  *
  32.  *
  33.  * @category authentication
  34.  * @package LiveUser
  35.  * @author  Markus Wolff <wolff@21st.de>
  36.  * @author  Helgi Þormar Þorbjörnsson <dufuz@php.net>
  37.  * @author  Lukas Smith <smith@pooteeweet.org>
  38.  * @author  Arnaud Limbourg <arnaud@php.net>
  39.  * @author  Pierre-Alain Joye <pajoye@php.net>
  40.  * @author  Bjoern Kraus <krausbn@php.net>
  41.  * @copyright 2002-2006 Markus Wolff
  42.  * @license http://www.gnu.org/licenses/lgpl.txt
  43.  * @version CVS: $Id: Common.php,v 1.59 2006/08/15 06:43:20 mahono Exp $
  44.  * @link http://pear.php.net/LiveUser
  45.  */
  46.  
  47. /**
  48.  * This class provides a set of functions for implementing a user
  49.  * authorisation system on live websites. All authorisation
  50.  * backends/containers must be inherited from this base class.
  51.  *
  52.  * @category authentication
  53.  * @package LiveUser
  54.  * @author   Markus Wolff <wolff@21st.de>
  55.  * @copyright 2002-2006 Markus Wolff
  56.  * @license http://www.gnu.org/licenses/lgpl.txt
  57.  * @version Release: @package_version@
  58.  * @link http://pear.php.net/LiveUser
  59.  */
  60. {
  61.     /**
  62.      * Has the current user successfully logged in?
  63.      *
  64.      * @var    bool 
  65.      * @access public
  66.      * @see    LiveUser_Auth_Common::isActive
  67.      */
  68.     var $loggedIn = null;
  69.  
  70.     /**
  71.      * Timestamp of current login (last to be written)
  72.      *
  73.      * @var    int 
  74.      * @access public
  75.      */
  76.     var $currentLogin = 0;
  77.  
  78.     /**
  79.      * Auth maximum lifetime in seconds
  80.      *
  81.      * If this variable is set to 0, auth never expires
  82.      *
  83.      * @var    int 
  84.      * @access public
  85.      */
  86.     var $expireTime = 0;
  87.  
  88.     /**
  89.      * Maximum time of idleness in seconds
  90.      *
  91.      * Idletime gets refreshed each time, init() is called. If this
  92.      * variable is set to 0, idle time is never checked.
  93.      *
  94.      * @var    int 
  95.      * @access public
  96.      */
  97.     var $idleTime = 0;
  98.  
  99.     /**
  100.      * Possible encryption modes.
  101.      *
  102.      * @var    array 
  103.      * @access public
  104.      */
  105.     var $encryptionModes = array(
  106.         'MD5'   => 'MD5',
  107.         'PLAIN' => 'PLAIN',
  108.         'RC4'   => 'RC4',
  109.         'SHA1'  => 'SHA1'
  110.     );
  111.  
  112.     /**
  113.      * Defines the algorithm used for encrypting/decrypting passwords.
  114.      *
  115.      * @var    string 
  116.      */
  117.     var $passwordEncryptionMode = 'MD5';
  118.  
  119.     /**
  120.      * Defines the secret to use for encryption if needed
  121.      *
  122.      * @var    string 
  123.      * @access public
  124.      */
  125.     var $secret = '';
  126.  
  127.     /**
  128.      * Error stack
  129.      *
  130.      * @var    PEAR_ErrorStack 
  131.      * @access public
  132.      */
  133.     var $stack = null;
  134.  
  135.     /**
  136.     * Array of all the user data read from the backend database
  137.     *
  138.     * @var array 
  139.     * @access public
  140.     */
  141.     var $propertyValues = array();
  142.  
  143.     /**
  144.      * The name associated with this auth container. The name is used
  145.      * when adding users from this container to the reference table
  146.      * in the permission container. This way it is possible to see
  147.      * from which auth container the user data is coming from.
  148.      *
  149.      * @var    string 
  150.      * @access public
  151.      */
  152.     var $containerName = null;
  153.  
  154.     /**
  155.      * External values to check (config settings)
  156.      *
  157.      * @var    array 
  158.      * @access public
  159.      */
  160.     var $externalValues = array();
  161.  
  162.     /**
  163.      * A list of handle fields that are used to find a user.
  164.      *
  165.      * @var    array 
  166.      * @access public
  167.      */
  168.     var $handles = array('handle');
  169.  
  170.     /**
  171.      * Table configuration
  172.      *
  173.      * @var    array 
  174.      * @access public
  175.      */
  176.     var $tables = array();
  177.  
  178.     /**
  179.      * All fields with their types
  180.      *
  181.      * @var    array 
  182.      * @access public
  183.      */
  184.     var $fields = array();
  185.  
  186.     /**
  187.      * All fields with their alias
  188.      *
  189.      * @var    array 
  190.      * @access public
  191.      */
  192.     var $alias = array();
  193.  
  194.     /**
  195.      * Class constructor. Feel free to override in backend subclasses.
  196.      *
  197.      * @var    array configuration options
  198.      * @return void 
  199.      *
  200.      * @access protected
  201.      */
  202.     function LiveUser_Auth_Common()
  203.     {
  204.         $this->stack = &PEAR_ErrorStack::singleton('LiveUser');
  205.     }
  206.  
  207.     /**
  208.      * Load the storage container
  209.      *
  210.      * @param   array  array containing the configuration.
  211.      * @param   string name of the container that should be used
  212.      * @return  bool true on success or false on failure
  213.      *
  214.      * @access public
  215.      */
  216.     function init($conf$containerName)
  217.     {
  218.         $this->containerName = $containerName;
  219.         if (is_array($conf)) {
  220.             $keys array_keys($conf);
  221.             foreach ($keys as $key{
  222.                 if (isset($this->$key)) {
  223.                     $this->$key =$conf[$key];
  224.                 }
  225.             }
  226.         }
  227.  
  228.         if (array_key_exists('storage'$conf&& is_array($conf['storage'])) {
  229.             $keys array_keys($conf['storage']);
  230.             foreach ($keys as $key{
  231.                 if (isset($this->$key)) {
  232.                     $this->$key =$conf['storage'][$key];
  233.                 }
  234.             }
  235.         }
  236.  
  237.         require_once 'LiveUser/Auth/Storage/Globals.php';
  238.         if (empty($this->tables)) {
  239.             $this->tables = $GLOBALS['_LiveUser']['auth']['tables'];
  240.         else {
  241.             $this->tables = LiveUser::arrayMergeClobber($GLOBALS['_LiveUser']['auth']['tables']$this->tables);
  242.         }
  243.         if (empty($this->fields)) {
  244.             $this->fields = $GLOBALS['_LiveUser']['auth']['fields'];
  245.         else {
  246.             $this->fields = LiveUser::arrayMergeClobber($GLOBALS['_LiveUser']['auth']['fields']$this->fields);
  247.         }
  248.         if (empty($this->alias)) {
  249.             $this->alias = $GLOBALS['_LiveUser']['auth']['alias'];
  250.         else {
  251.             $this->alias = LiveUser::arrayMergeClobber($GLOBALS['_LiveUser']['auth']['alias']$this->alias);
  252.         }
  253.     }
  254.  
  255.     /**
  256.      * store all properties in an array
  257.      *
  258.      * @return  array 
  259.      *
  260.      * @access public
  261.      */
  262.     function freeze()
  263.     {
  264.         // get values from $this->externalValues['values'] and
  265.         // store them into $this->propertyValues['storedExternalValues']
  266.         $this->setExternalValues();
  267.  
  268.         $propertyValues = array(
  269.             'propertyValues'    => $this->propertyValues,
  270.             'loggedIn'          => $this->loggedIn,
  271.             'currentLogin'      => $this->currentLogin,
  272.         );
  273.  
  274.         return $propertyValues;
  275.     }
  276.  
  277.     /**
  278.      * Reinitializes properties
  279.      *
  280.      * @param   array  $propertyValues 
  281.      * @return  bool 
  282.      *
  283.      * @access public
  284.      */
  285.     function unfreeze($propertyValues)
  286.     {
  287.          foreach ($propertyValues as $key => $value{
  288.              $this->{$key$value;
  289.          }
  290.  
  291.         return $this->externalValuesMatch();
  292.     }
  293.  
  294.     /**
  295.      * Decrypts a password so that it can be compared with the user input.
  296.      * Uses the algorithm defined in the passwordEncryptionMode property.
  297.      *
  298.      * @param  string the encrypted password
  299.      * @return string the decrypted password
  300.      *
  301.      * @access public
  302.      */
  303.     function decryptPW($encryptedPW)
  304.     {
  305.         return LiveUser::decryptPW($encryptedPW$this->passwordEncryptionMode$this->secret);
  306.     }
  307.  
  308.     /**
  309.      * Encrypts a password for storage in a backend container.
  310.      * Uses the algorithm defined in the passwordEncryptionMode property.
  311.      *
  312.      * @param string  encryption type
  313.      * @return string the encrypted password
  314.      *
  315.      * @access public
  316.      */
  317.     function encryptPW($plainPW)
  318.     {
  319.         return LiveUser::encryptPW($plainPW$this->passwordEncryptionMode$this->secret);
  320.     }
  321.  
  322.     /**
  323.      * Tries to make a login with the given handle and password.
  324.      * A user can't login if he's not active.
  325.      *
  326.      * @param  string   user handle
  327.      * @param  string   user password
  328.      * @param  bool|intif the user data should be read using the auth user id
  329.      * @return bool null when user is inactive, true on success or false on failure
  330.      *
  331.      * @access public
  332.      */
  333.     function login($handle$passwd$auth_user_id = false)
  334.     {
  335.         // Init value: Is user logged in?
  336.         $this->loggedIn = false;
  337.  
  338.         // Read user data from database
  339.         $result $this->readUserData($handle$passwd$auth_user_id);
  340.         if (!$result{
  341.             return $result;
  342.         }
  343.  
  344.         // If login is successful (user data has been read)
  345.         // ...we still need to check if this user is declared active
  346.         if (!array_key_exists('is_active'$this->propertyValues)
  347.             || $this->propertyValues['is_active']
  348.         {
  349.             // ...and if so, we have a successful login (hooray)!
  350.             $this->loggedIn = true;
  351.             $this->currentLogin = time();
  352.         }
  353.  
  354.         // In case Login was successful update user data
  355.         if ($this->loggedIn{
  356.             $this->_updateUserData();
  357.         }
  358.  
  359.         return true;
  360.     }
  361.  
  362.     /**
  363.      * Writes current values for user back to the database.
  364.      * This method does nothing in the base class and is supposed to
  365.      * be overridden in subclasses according to the supported backend.
  366.      *
  367.      * @return bool true on success or false on failure
  368.      *
  369.      * @access private
  370.      */
  371.     function _updateUserData()
  372.     {
  373.         $this->stack->push(LIVEUSER_ERROR_NOT_SUPPORTED'exception',
  374.             array('feature' => '_updateUserData')
  375.         );
  376.         return false;
  377.     }
  378.  
  379.     /**
  380.      * Reads user data from the given data source
  381.      * If only $handle is given, it will read the data
  382.      * from the first user with that handle and return
  383.      * true on success.
  384.      * If $handle and $passwd are given, it will try to
  385.      * find the first user with both handle and password
  386.      * matching and return true on success (this allows
  387.      * multiple users having the same handle but different
  388.      * passwords - yep, some people want this).
  389.      * if only an auth_user_id is passed it will try to read the data based on the id
  390.      * If no match is found, false is being returned.
  391.      *
  392.      * Again, this does nothing in the base class. The
  393.      * described functionality must be implemented in a
  394.      * subclass overriding this method.
  395.      *
  396.      * @param  string user handle
  397.      * @param  string user password
  398.      * @param  bool|intif the user data should be read using the auth user id
  399.      * @return bool true on success or false on failure
  400.      *
  401.      * @access public
  402.      */
  403.     function readUserData($handle ''$passwd ''$auth_user_id = false)
  404.     {
  405.         $this->stack->push(LIVEUSER_ERROR_NOT_SUPPORTED'exception',
  406.             array('feature' => 'readUserData')
  407.         );
  408.         return false;
  409.     }
  410.  
  411.     /**
  412.      * Function returns the inquired value if it exists in the class.
  413.      *
  414.      * @param  string  name of the property to be returned.
  415.      * @return mixed   null, a scalar or an array.
  416.      *
  417.      * @access public
  418.      */
  419.     function getProperty($what)
  420.     {
  421.         $that = null;
  422.         if (array_key_exists($what$this->propertyValues)) {
  423.             $that $this->propertyValues[$what];
  424.         elseif (isset($this->$what)) {
  425.             $that $this->$what;
  426.         }
  427.         return $that;
  428.     }
  429.  
  430.     /**
  431.      * Creates associative array of values from $externalValues['values'] with $keysToCheck
  432.      *
  433.      * @return void 
  434.      *
  435.      * @access public
  436.      */
  437.     function setExternalValues()
  438.     {
  439.         if (array_key_exists('keysToCheck'$this->externalValues)
  440.             && is_array($this->externalValues['keysToCheck'])
  441.         {
  442.             foreach ($this->externalValues['keysToCheck'as $keyToCheck{
  443.                 if (array_key_exists($keyToCheck$this->externalValues['values'])) {
  444.                     $this->propertyValues['storedExternalValues'][$keyToCheck=
  445.                         md5($this->externalValues['values'][$keyToCheck]);
  446.                 }
  447.             }
  448.         }
  449.     }
  450.  
  451.     /**
  452.      * Check if the stored external values match the current external values
  453.      *
  454.      * @return bool true on success or false on failure
  455.      *
  456.      * @access public
  457.      */
  458.     function externalValuesMatch()
  459.     {
  460.         if (array_key_exists('storedExternalValues'$this->propertyValues)
  461.             && is_array($this->propertyValues['storedExternalValues'])
  462.         {
  463.             foreach ($this->propertyValues['storedExternalValues'as $keyToCheck => $storedValue{
  464.                 // return false if any one of the stored values does not match the current value
  465.                 if (!array_key_exists($keyToCheck$this->externalValues['values'])
  466.                     || md5($this->externalValues['values'][$keyToCheck]!= $storedValue
  467.                 {
  468.                     return false;
  469.                 }
  470.             }
  471.         }
  472.         return true;
  473.     }
  474.  
  475.     /**
  476.      * properly disconnect from resources
  477.      *
  478.      * @return bool true on success or false on failure
  479.      *
  480.      * @access public
  481.      */
  482.     function disconnect()
  483.     {
  484.         return true;
  485.     }
  486.  
  487. }
  488. ?>

Documentation generated on Mon, 28 Jan 2008 03:30:08 -0500 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.