Source for file jAuth.class.php

Documentation is available at jAuth.class.php

  1. <?php
  2. /**
  3. @package    jelix
  4. @subpackage auth
  5. @author     Laurent Jouanneau
  6. @contributor Frédéric Guillot, Antoine Detante, Julien Issler, Dominique Papin, Tahina Ramaroson, Sylvain de Vathaire, Vincent Viaud
  7. @copyright  2001-2005 CopixTeam, 2005-2012 Laurent Jouanneau, 2007 Frédéric Guillot, 2007 Antoine Detante
  8. @copyright  2007-2008 Julien Issler, 2008 Dominique Papin, 2010 NEOV, 2010 BP2I
  9. *
  10. *  This classes were get originally from an experimental branch of the Copix project (Copix 2.3dev, http://www.copix.org)
  11. *  Few lines of code are still copyrighted 2001-2005 CopixTeam (LGPL licence).
  12. *  Initial author of this Copix classes is Laurent Jouanneau, and this classes were adapted for Jelix by him
  13. @licence  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  14. */
  15.  
  16. require(JELIX_LIB_PATH.'auth/jIAuthDriver.iface.php');
  17.  
  18. require(JELIX_LIB_PATH.'auth/jAuthDriverBase.class.php');
  19.  
  20.  
  21.  
  22. /**
  23.  * This is the main class for authentification process
  24.  * @package    jelix
  25.  * @subpackage auth
  26.  */
  27. class jAuth {
  28.  
  29.     /**
  30.      * @deprecated
  31.      * @see jAuth::getConfig()
  32.      */
  33.     protected static function _getConfig({
  34.         return self::loadConfig();
  35.     }
  36.  
  37.     protected static $config null;
  38.     protected static $driver null;
  39.     /**
  40.      * Load the configuration of authentification, stored in the auth plugin config
  41.      * @return array 
  42.      * @since 1.2.10
  43.      */
  44.     public static function loadConfig($newconfig null){
  45.  
  46.         if (self::$config === null || $newconfig{
  47.             if (!$newconfig{
  48.                 global $gJCoord;
  49.                 $plugin $gJCoord->getPlugin('auth');
  50.                 if($plugin === null)
  51.                     throw new jException('jelix~auth.error.plugin.missing');
  52.                 $config $plugin->config;
  53.             }
  54.             else {
  55.                 $config $newconfig;
  56.             }
  57.  
  58.             if (!isset($config['session_name'])
  59.                 || $config['session_name'== '')
  60.                 $config['session_name''JELIX_USER';
  61.  
  62.             if (!isset$config['persistant_cookie_path'])
  63.                 ||  $config['persistant_cookie_path'== ''{
  64.                 if (isset($GLOBALS['gJConfig']))
  65.                     $config['persistant_cookie_path'$GLOBALS['gJConfig']->urlengine['basePath'];
  66.                 else
  67.                     $config['persistant_cookie_path''/';
  68.             }
  69.  
  70.             // Read hash method configuration. If not empty, cryptPassword will use
  71.             // the new API of PHP 5.5 (password_verify and so on...)
  72.             $password_hash_method (isset($config['password_hash_method'])$config['password_hash_method']:0);
  73.  
  74.             if ($password_hash_method === '' || (is_numeric($password_hash_method))) {
  75.                 $password_hash_method 0;
  76.             }
  77.             else {
  78.                 $password_hash_methodintval($password_hash_method);
  79.             }
  80.  
  81.             if ($password_hash_method 0{
  82.                 require_once(dirname(__FILE__).'/password.php');
  83.                 if (!can_use_password_API()) {
  84.                     $password_hash_method 0;
  85.                 }
  86.             }
  87.  
  88.             $password_hash_options (isset($config['password_hash_options'])?$config['password_hash_options']:'');
  89.             if ($password_hash_options != ''{
  90.                 $list '{"'.str_replace(array('=',';')array('":"''","')$config['password_hash_options']).'"}';
  91.                 $json new jJson(SERVICES_JSON_LOOSE_TYPE);
  92.                 $password_hash_options @$json->decode($list);
  93.                 if (!$password_hash_options)
  94.                     $password_hash_options array();
  95.             }
  96.             else {
  97.                 $password_hash_options array();
  98.             }
  99.  
  100.             $config['password_hash_method'$password_hash_method;
  101.             $config['password_hash_options'$password_hash_options;
  102.  
  103.             $config[$config['driver']]['password_hash_method'$password_hash_method;
  104.             $config[$config['driver']]['password_hash_options'$password_hash_options;
  105.             self::$config $config;
  106.         }
  107.         return self::$config;
  108.     }
  109.  
  110.     /**
  111.      * @deprecated
  112.      * @see jAuth::getDriver()
  113.      */
  114.     protected static function _getDriver({
  115.         return self::getDriver();
  116.     }
  117.  
  118.     /**
  119.      * return the auth driver
  120.      * @return jIAuthDriver 
  121.      * @since 1.2.10
  122.      */
  123.     public static function getDriver(){
  124.  
  125.         if (self::$driver === null{
  126.             $config self::loadConfig();
  127.             global $gJConfig;
  128.             $db strtolower($config['driver']);
  129.             if(!isset($gJConfig->_pluginsPathList_auth)
  130.                 || !isset($gJConfig->_pluginsPathList_auth[$db])
  131.                 || !file_exists($gJConfig->_pluginsPathList_auth[$db]) )
  132.                 throw new jException('jelix~auth.error.driver.notfound',$db);
  133.  
  134.             require_once($gJConfig->_pluginsPathList_auth[$db].$db.'.auth.php');
  135.             $dname $config['driver'].'AuthDriver';
  136.             $driver new $dname($config[$config['driver']]);
  137.             self::$driver $driver;
  138.         }
  139.         return self::$driver;
  140.     }
  141.  
  142.     /**
  143.      * return the value of a parameter of the configuration of the current driver
  144.      * @param string $paramName 
  145.      * @return string the value. null if it doesn't exist
  146.      */
  147.     public static function getDriverParam($paramName{
  148.         $config self::loadConfig();
  149.         $config $config[$config['driver']];
  150.         if(isset($config[$paramName]))
  151.             return $config[$paramName];
  152.         else
  153.             return null;
  154.     }
  155.  
  156.     /**
  157.      * load user data
  158.      *
  159.      * This method returns an object, generated by the driver, and which contains
  160.      * data corresponding to the given login. This method should be called if you want
  161.      * to update data of a user. see updateUser method.
  162.      *
  163.      * @param string $login 
  164.      * @return object the user
  165.      */
  166.     public static function getUser($login){
  167.         $dr self::getDriver();
  168.         return $dr->getUser($login);
  169.     }
  170.  
  171.     /**
  172.      * Create a new user object
  173.      *
  174.      * You should call this method if you want to create a new user. It returns an object,
  175.      * representing a user. Then you should fill its properties and give it to the saveNewUser
  176.      * method.
  177.      *
  178.      * @param string $login the user login
  179.      * @param string $password the user password (not encrypted)
  180.      * @return object the returned object depends on the driver
  181.      * @since 1.0b2
  182.      */
  183.     public static function createUserObject($login,$password){
  184.         $dr self::getDriver();
  185.         return $dr->createUserObject($login,$password);
  186.     }
  187.  
  188.     /**
  189.      * Save a new user
  190.      *
  191.      * if the saving has succeed, a AuthNewUser event is sent
  192.      * The given object should have been created by calling createUserObject method :
  193.      *
  194.      * example :
  195.      *  <pre>
  196.      *   $user = jAuth::createUserObject('login','password');
  197.      *   $user->email ='bla@foo.com';
  198.      *   jAuth::saveNewUser($user);
  199.      *  </pre>
  200.      *  the type of $user depends of the driver, so it can have other properties.
  201.      *
  202.      * @param  object $user the user data
  203.      * @return object the user (eventually, with additional data)
  204.      */
  205.     public static function saveNewUser($user){
  206.         $dr self::getDriver();
  207.         if($dr->saveNewUser($user))
  208.             jEvent::notify ('AuthNewUser'array('user'=>$user));
  209.         return $user;
  210.     }
  211.  
  212.     /**
  213.      * update user data
  214.      *
  215.      * It send a AuthUpdateUser event if the saving has succeed. If you want
  216.      * to change the user password, you must use jAuth::changePassword method
  217.      * instead of jAuth::updateUser method.
  218.      *
  219.      * The given object should have been created by calling getUser method.
  220.      * Example :
  221.      *  <pre>
  222.      *   $user = jAuth::getUser('login');
  223.      *   $user->email ='bla@foo.com';
  224.      *   jAuth::updateUser($user);
  225.      *  </pre>
  226.      *  the type of $user depends of the driver, so it can have other properties.
  227.      *
  228.      * @param object $user  user data
  229.      */
  230.     public static function updateUser($user){
  231.         $dr self::getDriver();
  232.         if($dr->updateUser($user=== false)
  233.             return false;
  234.  
  235.         if(self::isConnected(&& self::getUserSession()->login === $user->login){
  236.             $config self::loadConfig();
  237.             $_SESSION[$config['session_name']] $user;
  238.         }
  239.         jEvent::notify ('AuthUpdateUser'array('user'=>$user));
  240.         return true;
  241.     }
  242.  
  243.     /**
  244.      * remove a user
  245.      * send first AuthCanRemoveUser event, then if ok, send AuthRemoveUser
  246.      * and then remove the user.
  247.      * @param string $login the user login
  248.      * @return boolean true if ok
  249.      */
  250.     public static function removeUser($login){
  251.         $dr self::getDriver();
  252.         $eventresp jEvent::notify ('AuthCanRemoveUser'array('login'=>$login));
  253.         foreach($eventresp->getResponse(as $rep){
  254.             if(!isset($rep['canremove']|| $rep['canremove'=== false)
  255.                 return false;
  256.         }
  257.         $user $dr->getUser($login);
  258.         if($dr->removeUser($login)===false)
  259.             return false;
  260.         jEvent::notify ('AuthRemoveUser'array('login'=>$login'user'=>$user));
  261.         if(self::isConnected(&& self::getUserSession()->login === $login)
  262.             self::logout();
  263.         return true;
  264.     }
  265.  
  266.     /**
  267.      * construct the user list
  268.      * @param string $pattern '' for all users
  269.      * @return array array of object
  270.      */
  271.     public static function getUserList($pattern '%'){
  272.         $dr self::getDriver();
  273.         return $dr->getUserlist($pattern);
  274.     }
  275.  
  276.     /**
  277.      * change a user password
  278.      *
  279.      * @param string $login the login of the user
  280.      * @param string $newpassword the new password (not encrypted)
  281.      * @return boolean true if the change succeed
  282.      */
  283.     public static function changePassword($login$newpassword){
  284.         $dr self::getDriver();
  285.         if($dr->changePassword($login$newpassword)===false)
  286.             return false;
  287.         if(self::isConnected(&& self::getUserSession()->login === $login){
  288.             $config self::loadConfig();
  289.             $_SESSION[$config['session_name']] self::getUser($login);
  290.         }
  291.         return true;
  292.     }
  293.  
  294.     /**
  295.      * verify that the password correspond to the login
  296.      * @param string $login the login of the user
  297.      * @param string $password the password to test (not encrypted)
  298.      * @return object|false if ok, returns the user as object
  299.      */
  300.     public static function verifyPassword($login$password){
  301.         $dr self::getDriver();
  302.         return $dr->verifyPassword($login$password);
  303.     }
  304.  
  305.     /**
  306.      * authentificate a user, and create a user in the php session
  307.      * @param string $login the login of the user
  308.      * @param string $password the password to test (not encrypted)
  309.      * @param boolean $persistant (optional) the session must be persistant
  310.      * @return boolean true if authentification is ok
  311.      */
  312.     public static function login($login$password$persistant=false){
  313.  
  314.         $dr self::getDriver();
  315.         $config self::loadConfig();
  316.  
  317.         $eventresp jEvent::notify ('AuthBeforeLogin'array('login'=>$login));
  318.         foreach($eventresp->getResponse(as $rep){
  319.             if(isset($rep['processlogin']&& $rep['processlogin'=== false)
  320.                 return false;
  321.         }
  322.  
  323.         if($user $dr->verifyPassword($login$password)){
  324.  
  325.             $eventresp jEvent::notify ('AuthCanLogin'array('login'=>$login'user'=>$user));
  326.             foreach($eventresp->getResponse(as $rep){
  327.                 if(!isset($rep['canlogin']|| $rep['canlogin'=== false)
  328.                     return false;
  329.             }
  330.  
  331.             $_SESSION[$config['session_name']] $user;
  332.  
  333.             if ($persistant{
  334.                 $persistence self::generateCookieToken($login$password);
  335.             }
  336.             else {
  337.                 $persistence 0;
  338.             }
  339.  
  340.             jEvent::notify ('AuthLogin'array('login'=>$login'persistence'=>$persistence));
  341.             return true;
  342.         }else{
  343.             jEvent::notify ('AuthErrorLogin'array('login'=>$login));
  344.             return false;
  345.         }
  346.     }
  347.  
  348.     /**
  349.      * Check if persistant session is enabled in config
  350.      * @return boolean true if persistant session in enabled
  351.      */
  352.     public static function isPersistant(){
  353.         $config self::loadConfig();
  354.         if(!isset($config['persistant_enable']))
  355.             return false;
  356.         else
  357.             return $config['persistant_enable'];
  358.     }
  359.  
  360.     /**
  361.      * logout a user and delete the user in the php session
  362.      */
  363.     public static function logout(){
  364.  
  365.         $config self::loadConfig();
  366.         jEvent::notify ('AuthLogout'array('login'=>$_SESSION[$config['session_name']]->login));
  367.         $_SESSION[$config['session_name']] new jAuthDummyUser();
  368.  
  369.         if (isset($config['session_destroy']&& $config['session_destroy']{
  370.             $params session_get_cookie_params();
  371.             setcookie(session_name()''time(42000$params["path"]$params["domain"]$params["secure"]$params["httponly"]);
  372.             session_destroy();
  373.         }
  374.  
  375.         if(isset($config['persistant_enable']&& $config['persistant_enable']){
  376.             if(!isset($config['persistant_cookie_name']))
  377.                 throw new jException('jelix~auth.error.persistant.incorrectconfig','persistant_cookie_name, persistant_crypt_key');
  378.             setcookie($config['persistant_cookie_name'].'[auth]'''time(3600$config['persistant_cookie_path']);
  379.         }
  380.     }
  381.  
  382.     /**
  383.      * Says if the user is connected
  384.      * @return boolean 
  385.      */
  386.     public static function isConnected(){
  387.         $config self::loadConfig();
  388.         return (isset($_SESSION[$config['session_name']]&& $_SESSION[$config['session_name']]->login != '');
  389.     }
  390.  
  391.    /**
  392.     * return the user stored in the php session
  393.     * @return object the user data
  394.     */
  395.     public static function getUserSession (){
  396.         $config self::loadConfig();
  397.         if (isset ($_SESSION[$config['session_name']]))
  398.             $_SESSION[$config['session_name']] new jAuthDummyUser();
  399.         return $_SESSION[$config['session_name']];
  400.     }
  401.  
  402.     /**
  403.      * generate a password with random letter or number
  404.      * @param int $length the length of the generated password
  405.      * @return string the generated password
  406.      */
  407.     public static function getRandomPassword($length 10){
  408.         $letter "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  409.         $pass '';
  410.         for($i=0;$i<$length;$i++)
  411.             $pass .= $letter[rand(0,61)];
  412.         return $pass;
  413.     }
  414.  
  415.     /**
  416.      *
  417.      */
  418.     public static function checkCookieToken({
  419.         $config self::loadConfig();
  420.         if (isset($config['persistant_enable']&& $config['persistant_enable'&& !self::isConnected()) {
  421.             if (isset($config['persistant_cookie_name']&& isset($config['persistant_crypt_key'])) {
  422.                 $cookieName $config['persistant_cookie_name'];
  423.                 if (isset($_COOKIE[$cookieName]['auth']&& strlen($_COOKIE[$cookieName]['auth'])>0{
  424.                     $decrypted jCrypt::decrypt($_COOKIE[$cookieName]['auth'],$config['persistant_crypt_key']);
  425.                     $decrypted @unserialize($decrypted);
  426.                     if ($decrypted && is_array($decrypted)) {
  427.                         list($login$password$decrypted;
  428.                         self::login($login$passwordtrue);
  429.                     }
  430.                 }
  431.                 if (isset($_COOKIE[$cookieName]['login'])) {
  432.                     // destroy deprecated cookies
  433.                     setcookie($cookieName.'[login]'''time(3600$config['persistant_cookie_path']);
  434.                     setcookie($cookieName.'[passwd]'''time(3600$config['persistant_cookie_path']);
  435.                 }
  436.             }
  437.             else {
  438.                 throw new jException('jelix~auth.error.persistant.incorrectconfig','persistant_cookie_name, persistant_crypt_key');
  439.             }
  440.         }
  441.     }
  442.  
  443.     public static function generateCookieToken($login$password{
  444.         $persistence 0;
  445.         $config self::loadConfig();
  446.  
  447.         // Add a cookie for session persistance, if enabled
  448.         if (isset($config['persistant_enable']&& $config['persistant_enable']{
  449.             if (!isset($config['persistant_crypt_key']|| !isset($config['persistant_cookie_name'])) {
  450.                 throw new jException('jelix~auth.error.persistant.incorrectconfig','persistant_cookie_name, persistant_crypt_key');
  451.             }
  452.  
  453.             if (isset($config['persistant_duration']))
  454.                 $persistence $config['persistant_duration']*86400;
  455.             else
  456.                 $persistence 86400// 24h
  457.             $persistence += time();
  458.             //$login = $_SESSION[$config['session_name']]->login;
  459.             $encrypted jCrypt::encrypt(serialize(array($login$password)),$config['persistant_crypt_key']);
  460.             setcookie($config['persistant_cookie_name'].'[auth]'$encrypted$persistence$config['persistant_cookie_path']);
  461.         }
  462.         return $persistence;
  463.     }
  464.  
  465.  
  466. }

Documentation generated on Thu, 19 Sep 2013 00:02:21 +0200 by phpDocumentor 1.4.3