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.         if (self::$driver === null{
  125.             $config self::loadConfig();
  126.             $db strtolower($config['driver']);
  127.             $driver jApp::loadPlugin($db'auth''.auth.php'$config['driver'].'AuthDriver'$config[$config['driver']]);
  128.             if(is_null($driver))
  129.                 throw new jException('jelix~auth.error.driver.notfound',$db);
  130.             self::$driver $driver;
  131.         }
  132.         return self::$driver;
  133.     }
  134.  
  135.     /**
  136.      * return the value of a parameter of the configuration of the current driver
  137.      * @param string $paramName 
  138.      * @return string the value. null if it doesn't exist
  139.      */
  140.     public static function getDriverParam($paramName{
  141.         $config self::loadConfig();
  142.         $config $config[$config['driver']];
  143.         if(isset($config[$paramName]))
  144.             return $config[$paramName];
  145.         else
  146.             return null;
  147.     }
  148.  
  149.     /**
  150.      * load user data
  151.      *
  152.      * This method returns an object, generated by the driver, and which contains
  153.      * data corresponding to the given login. This method should be called if you want
  154.      * to update data of a user. see updateUser method.
  155.      *
  156.      * @param string $login 
  157.      * @return object the user
  158.      */
  159.     public static function getUser($login){
  160.         $dr self::getDriver();
  161.         return $dr->getUser($login);
  162.     }
  163.  
  164.     /**
  165.      * Create a new user object
  166.      *
  167.      * You should call this method if you want to create a new user. It returns an object,
  168.      * representing a user. Then you should fill its properties and give it to the saveNewUser
  169.      * method.
  170.      *
  171.      * @param string $login the user login
  172.      * @param string $password the user password (not encrypted)
  173.      * @return object the returned object depends on the driver
  174.      * @since 1.0b2
  175.      */
  176.     public static function createUserObject($login,$password){
  177.         $dr self::getDriver();
  178.         return $dr->createUserObject($login,$password);
  179.     }
  180.  
  181.     /**
  182.      * Save a new user
  183.      *
  184.      * if the saving has succeed, a AuthNewUser event is sent
  185.      * The given object should have been created by calling createUserObject method :
  186.      *
  187.      * example :
  188.      *  <pre>
  189.      *   $user = jAuth::createUserObject('login','password');
  190.      *   $user->email ='bla@foo.com';
  191.      *   jAuth::saveNewUser($user);
  192.      *  </pre>
  193.      *  the type of $user depends of the driver, so it can have other properties.
  194.      *
  195.      * @param  object $user the user data
  196.      * @return object the user (eventually, with additional data)
  197.      */
  198.     public static function saveNewUser($user){
  199.         $dr self::getDriver();
  200.         if($dr->saveNewUser($user))
  201.             jEvent::notify ('AuthNewUser'array('user'=>$user));
  202.         return $user;
  203.     }
  204.  
  205.     /**
  206.      * update user data
  207.      *
  208.      * It send a AuthUpdateUser event if the saving has succeed. If you want
  209.      * to change the user password, you must use jAuth::changePassword method
  210.      * instead of jAuth::updateUser method.
  211.      *
  212.      * The given object should have been created by calling getUser method.
  213.      * Example :
  214.      *  <pre>
  215.      *   $user = jAuth::getUser('login');
  216.      *   $user->email ='bla@foo.com';
  217.      *   jAuth::updateUser($user);
  218.      *  </pre>
  219.      *  the type of $user depends of the driver, so it can have other properties.
  220.      *
  221.      * @param object $user  user data
  222.      */
  223.     public static function updateUser($user){
  224.         $dr self::getDriver();
  225.         if($dr->updateUser($user=== false)
  226.             return false;
  227.  
  228.         if(self::isConnected(&& self::getUserSession()->login === $user->login){
  229.             $config self::loadConfig();
  230.             $_SESSION[$config['session_name']] $user;
  231.         }
  232.         jEvent::notify ('AuthUpdateUser'array('user'=>$user));
  233.         return true;
  234.     }
  235.  
  236.     /**
  237.      * remove a user
  238.      * send first AuthCanRemoveUser event, then if ok, send AuthRemoveUser
  239.      * and then remove the user.
  240.      * @param string $login the user login
  241.      * @return boolean true if ok
  242.      */
  243.     public static function removeUser($login){
  244.         $dr self::getDriver();
  245.         $eventresp jEvent::notify ('AuthCanRemoveUser'array('login'=>$login));
  246.         foreach($eventresp->getResponse(as $rep){
  247.             if(!isset($rep['canremove']|| $rep['canremove'=== false)
  248.                 return false;
  249.         }
  250.         $user $dr->getUser($login);
  251.         if($dr->removeUser($login)===false)
  252.             return false;
  253.         jEvent::notify ('AuthRemoveUser'array('login'=>$login'user'=>$user));
  254.         if(self::isConnected(&& self::getUserSession()->login === $login)
  255.             self::logout();
  256.         return true;
  257.     }
  258.  
  259.     /**
  260.      * construct the user list
  261.      * @param string $pattern '' for all users
  262.      * @return array array of object
  263.      */
  264.     public static function getUserList($pattern '%'){
  265.         $dr self::getDriver();
  266.         return $dr->getUserlist($pattern);
  267.     }
  268.  
  269.     /**
  270.      * change a user password
  271.      *
  272.      * @param string $login the login of the user
  273.      * @param string $newpassword the new password (not encrypted)
  274.      * @return boolean true if the change succeed
  275.      */
  276.     public static function changePassword($login$newpassword){
  277.         $dr self::getDriver();
  278.         if($dr->changePassword($login$newpassword)===false)
  279.             return false;
  280.         if(self::isConnected(&& self::getUserSession()->login === $login){
  281.             $config self::loadConfig();
  282.             $_SESSION[$config['session_name']] self::getUser($login);
  283.         }
  284.         return true;
  285.     }
  286.  
  287.     /**
  288.      * verify that the password correspond to the login
  289.      * @param string $login the login of the user
  290.      * @param string $password the password to test (not encrypted)
  291.      * @return object|false if ok, returns the user as object
  292.      */
  293.     public static function verifyPassword($login$password){
  294.         $dr self::getDriver();
  295.         return $dr->verifyPassword($login$password);
  296.     }
  297.  
  298.     /**
  299.      * authentificate a user, and create a user in the php session
  300.      * @param string $login the login of the user
  301.      * @param string $password the password to test (not encrypted)
  302.      * @param boolean $persistant (optional) the session must be persistant
  303.      * @return boolean true if authentification is ok
  304.      */
  305.     public static function login($login$password$persistant=false){
  306.  
  307.         $dr self::getDriver();
  308.         $config self::loadConfig();
  309.  
  310.         $eventresp jEvent::notify ('AuthBeforeLogin'array('login'=>$login));
  311.         foreach($eventresp->getResponse(as $rep){
  312.             if(isset($rep['processlogin']&& $rep['processlogin'=== false)
  313.                 return false;
  314.         }
  315.  
  316.         if($user $dr->verifyPassword($login$password)){
  317.  
  318.             $eventresp jEvent::notify ('AuthCanLogin'array('login'=>$login'user'=>$user));
  319.             foreach($eventresp->getResponse(as $rep){
  320.                 if(!isset($rep['canlogin']|| $rep['canlogin'=== false)
  321.                     return false;
  322.             }
  323.  
  324.             $_SESSION[$config['session_name']] $user;
  325.  
  326.             if ($persistant{
  327.                 $persistence self::generateCookieToken($login$password);
  328.             }
  329.             else {
  330.                 $persistence 0;
  331.             }
  332.  
  333.             jEvent::notify ('AuthLogin'array('login'=>$login'persistence'=>$persistence));
  334.             return true;
  335.         }else{
  336.             jEvent::notify ('AuthErrorLogin'array('login'=>$login));
  337.             return false;
  338.         }
  339.     }
  340.  
  341.     /**
  342.      * Check if persistant session is enabled in config
  343.      * @return boolean true if persistant session in enabled
  344.      */
  345.     public static function isPersistant(){
  346.         $config self::loadConfig();
  347.         if(!isset($config['persistant_enable']))
  348.             return false;
  349.         else
  350.             return $config['persistant_enable'];
  351.     }
  352.  
  353.     /**
  354.      * logout a user and delete the user in the php session
  355.      */
  356.     public static function logout(){
  357.  
  358.         $config self::loadConfig();
  359.         jEvent::notify ('AuthLogout'array('login'=>$_SESSION[$config['session_name']]->login));
  360.         $_SESSION[$config['session_name']] new jAuthDummyUser();
  361.  
  362.         if (isset($config['session_destroy']&& $config['session_destroy']{
  363.             $params session_get_cookie_params();
  364.             setcookie(session_name()''time(42000$params["path"]$params["domain"]$params["secure"]$params["httponly"]);
  365.             session_destroy();
  366.         }
  367.  
  368.         if(isset($config['persistant_enable']&& $config['persistant_enable']){
  369.             if(!isset($config['persistant_cookie_name']))
  370.                 throw new jException('jelix~auth.error.persistant.incorrectconfig','persistant_cookie_name, persistant_crypt_key');
  371.             setcookie($config['persistant_cookie_name'].'[auth]'''time(3600$config['persistant_cookie_path']);
  372.         }
  373.     }
  374.  
  375.     /**
  376.      * Says if the user is connected
  377.      * @return boolean 
  378.      */
  379.     public static function isConnected(){
  380.         $config self::loadConfig();
  381.         return (isset($_SESSION[$config['session_name']]&& $_SESSION[$config['session_name']]->login != '');
  382.     }
  383.  
  384.    /**
  385.     * return the user stored in the php session
  386.     * @return object the user data
  387.     */
  388.     public static function getUserSession (){
  389.         $config self::loadConfig();
  390.         if (isset ($_SESSION[$config['session_name']]))
  391.             $_SESSION[$config['session_name']] new jAuthDummyUser();
  392.         return $_SESSION[$config['session_name']];
  393.     }
  394.  
  395.     /**
  396.      * generate a password with random letters, numbers and special characters
  397.      * @param int $length the length of the generated password
  398.      * @param boolean $withoutSpecialChars (optional, default false) the generated password may be use this characters : !@#$%^&*?_,~
  399.      * @return string the generated password
  400.      */
  401.     public static function getRandomPassword($length 10$withoutSpecialChars false){
  402.         if ($length 10)
  403.             $length 10;
  404.         $nbNumber floor($length/4);
  405.         if ($nbNumber 2)
  406.             $nbNumber 2;
  407.         if ($withoutSpecialChars)
  408.             $nbSpec 0;
  409.         else {
  410.             $nbSpec floor($length/5);
  411.             if ($nbSpec 1)
  412.                 $nbSpec 1;
  413.         }
  414.  
  415.         $nbLower floor(($length-$nbNumber-$nbSpec)/2);
  416.         $nbUpper $length-$nbNumber-$nbLower-$nbSpec;
  417.  
  418.         $pass '';
  419.  
  420.         $letter "1234567890";
  421.         for($i=0;$i<$nbNumber;$i++)
  422.             $pass .= $letter[rand(0,9)];
  423.  
  424.         $letter '!@#$%^&*?_,~';
  425.         for($i=0;$i<$nbSpec;$i++)
  426.             $pass .= $letter[rand(0,11)];
  427.  
  428.         $letter "abcdefghijklmnopqrstuvwxyz";
  429.         for($i=0;$i<$nbLower;$i++)
  430.             $pass .= $letter[rand(0,25)];
  431.  
  432.         $letter "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  433.         for($i=0;$i<$nbUpper;$i++)
  434.             $pass .= $letter[rand(0,25)];
  435.  
  436.         return str_shuffle($pass);
  437.     }
  438.  
  439.     /**
  440.      *
  441.      */
  442.     public static function checkCookieToken({
  443.         $config self::loadConfig();
  444.         if (isset($config['persistant_enable']&& $config['persistant_enable'&& !self::isConnected()) {
  445.             if (isset($config['persistant_cookie_name']&& isset($config['persistant_crypt_key'])) {
  446.                 $cookieName $config['persistant_cookie_name'];
  447.                 if (isset($_COOKIE[$cookieName]['auth']&& strlen($_COOKIE[$cookieName]['auth'])>0{
  448.                     $decrypted jCrypt::decrypt($_COOKIE[$cookieName]['auth'],$config['persistant_crypt_key']);
  449.                     $decrypted @unserialize($decrypted);
  450.                     if ($decrypted && is_array($decrypted)) {
  451.                         list($login$password$decrypted;
  452.                         self::login($login$passwordtrue);
  453.                     }
  454.                 }
  455.                 if (isset($_COOKIE[$cookieName]['login'])) {
  456.                     // destroy deprecated cookies
  457.                     setcookie($cookieName.'[login]'''time(3600$config['persistant_cookie_path']);
  458.                     setcookie($cookieName.'[passwd]'''time(3600$config['persistant_cookie_path']);
  459.                 }
  460.             }
  461.             else {
  462.                 throw new jException('jelix~auth.error.persistant.incorrectconfig','persistant_cookie_name, persistant_crypt_key');
  463.             }
  464.         }
  465.     }
  466.  
  467.     public static function generateCookieToken($login$password{
  468.         $persistence 0;
  469.         $config self::loadConfig();
  470.  
  471.         // Add a cookie for session persistance, if enabled
  472.         if (isset($config['persistant_enable']&& $config['persistant_enable']{
  473.             if (!isset($config['persistant_crypt_key']|| !isset($config['persistant_cookie_name'])) {
  474.                 throw new jException('jelix~auth.error.persistant.incorrectconfig','persistant_cookie_name, persistant_crypt_key');
  475.             }
  476.  
  477.             if (isset($config['persistant_duration']))
  478.                 $persistence $config['persistant_duration']*86400;
  479.             else
  480.                 $persistence 86400// 24h
  481.             $persistence += time();
  482.             //$login = $_SESSION[$config['session_name']]->login;
  483.             $encrypted jCrypt::encrypt(serialize(array($login$password)),$config['persistant_crypt_key']);
  484.             setcookie($config['persistant_cookie_name'].'[auth]'$encrypted$persistence$config['persistant_cookie_path']);
  485.         }
  486.         return $persistence;
  487.     }
  488.  
  489.  
  490. }

Documentation generated on Wed, 24 Sep 2014 21:56:20 +0200 by phpDocumentor 1.4.3