Orion PHP  0.11.12
The PHP5.3 framework
auth.php
Go to the documentation of this file.
00001 <?php
00002 
00003 namespace Orion\Core;
00004 
00005 use \Orion\Models;
00006 
00007 
00008 /**
00009  * \Orion\Core\Auth
00010  * 
00011  * Orion authentification class.
00012  *
00013  * <p><b>For performance matters, roles and levels are stored into an arrayMap
00014  * in configuration file</b></p>
00015  *
00016  * @author Thibaut Despoulain
00017  * @license BSD 4-clauses
00018  * @version 0.11.12
00019  *
00020  * @static
00021  */
00022 class Auth
00023 {
00024     /**
00025      * Core\Auth error : Login field mismatch
00026      */
00027     const E_LOGIN_MISMATCH = 50;
00028     /**
00029      * Core\Auth error : Password field mismatch
00030      */
00031     const E_PASSWORD_MISMATCH = 51;
00032     /**
00033      * Core\Auth error : Permission level too low
00034      */
00035     const E_LEVEL_RESTRICT = 52;
00036     /**
00037      * Core\Auth error : Missing login data
00038      */
00039     const E_NO_DATA = 53;
00040     /**
00041      * Core\Auth error Unknown error
00042      */
00043     const E_UNKNOWN = 54;
00044     /**
00045      * Core\Auth error : User is not verified
00046      */
00047     const E_NOT_VERIFIED = 55;
00048 
00049     /**
00050      * User data (once logged in)
00051      * @var Core\AuthUser $user
00052      */
00053     private static $user = null;
00054 
00055     /**
00056      * Try loging the user in.
00057      * <ul>
00058      * <li>Checks if already logged in session var</li>
00059      * <li>If not, check for post data from login module</li>
00060      * <li>Otherwise, redirect to login module</li>
00061      * </ul>
00062      * <p>If user if found and password/login match, user data is stored into
00063      * $this->user attributes, that you can access using Core\Auth->user()->name;
00064      * for example.</p>
00065      * <p>If login fails, a redirection occurs toward login module
00066      * , using /error/err_code routing.</p>
00067      */
00068     public static function login( $noredirect=false )
00069     {
00070         if ( isset( $_SESSION[ 'orionauth' ] ) )
00071         {
00072             $session = new Models\Auth\User();
00073             $session->fromArray( $_SESSION[ 'orionauth' ] );
00074             if ( \Orion::isDebug() )
00075                 var_dump( $session );
00076             self::$user = $session;
00077             return true;
00078         }
00079         else
00080         {
00081             if ( isset( $_POST[ 'auth' ] ) && isset( $_POST[ 'login' ] ) && isset( $_POST[ 'password' ] ) )
00082             {
00083                 $data = Models\Auth\User::get()
00084                         ->where( 'login', Query::EQUAL, $_POST[ 'login' ] )
00085                         ->limit( 1 )
00086                         ->fetch();
00087                 if ( $data != false )
00088                 {
00089                     if ( Models\Auth\User::hasField( 'verified' ) && $data->verified == 0 )
00090                     {
00091                         if ( $noredirect )
00092                             return false;
00093                         else
00094                             Context::redirect( Context::genModuleURL( \Orion::config()->get( 'AUTH_MODULE' ), 'error-' . self::E_NOT_VERIFIED ), 'default' );
00095                     }
00096                     $hash = Security::saltedHash( $_POST[ 'password' ], $_POST[ 'login' ] );
00097                     if ( $hash == $data->password )
00098                     {
00099                         $session = new Models\Auth\User();
00100                         $session->login = $data->login;
00101                         $session->level = $data->level;
00102                         $session->name = $data->name;
00103                         $session->surname = $data->surname;
00104                         $session->id = $data->id;
00105 
00106                         self::$user = $session;
00107                         $_SESSION[ 'orionauth' ] = $session->toArray();
00108                         return true;
00109                     }
00110                     else
00111                     {
00112                         if ( $noredirect )
00113                             return false;
00114                         else
00115                             Context::redirect( Context::genModuleURL( \Orion::config()->get( 'AUTH_MODULE' ), 'error-' . self::E_PASSWORD_MISMATCH ), 'default' );
00116                     }
00117                 }
00118                 else
00119                 {
00120                     if ( $noredirect )
00121                         return false;
00122                     else
00123                         Context::redirect( Context::genModuleURL( \Orion::config()->get( 'AUTH_MODULE' ), 'error-' . self::E_LOGIN_MISMATCH ), 'default' );
00124                 }
00125             }
00126             else
00127             {
00128                 $_SESSION[ 'orion_auth_target' ] = Context::getFullURL();
00129                 if ( $noredirect )
00130                     return false;
00131                 else
00132                     Context::redirect( Context::genModuleURL( \Orion::config()->get( 'AUTH_MODULE' ), 'do/login', 'default' ) );
00133             }
00134         }
00135     }
00136 
00137     /**
00138      * Manual login method
00139      * @param type $user
00140      * @param type $password
00141      * @return int Returns 0 if success, else returns a specific error code that is > 0
00142      */
00143     public static function manualLogin( $user, $password )
00144     {
00145         try
00146         {
00147             if ( empty( $user ) || empty( $password ) )
00148                 return self::E_NO_DATA;
00149 
00150             $data = Models\Auth\User::get()
00151                     ->where( 'login', Query::EQUAL, $user )
00152                     ->limit( 1 )
00153                     ->fetch();
00154 
00155             if ( $data != false )
00156             {
00157                 if ( Models\Auth\User::hasField( 'verified' ) && $data->verified == 0 )
00158                 {
00159                     return self::E_NOT_VERIFIED;
00160                 }
00161                 $hash = Security::saltedHash( $password, $user );
00162                 if ( $hash == $data->password )
00163                 {
00164                     $session = new Models\Auth\User();
00165                     $session->login = $data->login;
00166                     $session->level = $data->level;
00167                     $session->name = $data->name;
00168                     $session->surname = $data->surname;
00169                     $session->id = $data->id;
00170 
00171                     self::$user = $session;
00172                     $_SESSION[ 'orionauth' ] = $session->toArray();
00173                     return 0;
00174                 }
00175                 else
00176                 {
00177                     return self::E_PASSWORD_MISMATCH;
00178                 }
00179             }
00180             else
00181             {
00182                 return self::E_LOGIN_MISMATCH;
00183             }
00184         }
00185         catch ( Exception $e )
00186         {
00187             throw $e;
00188         }
00189     }
00190 
00191     /**
00192      * <p><b>Must be called AFTER Core\Auth::login()</b></p>
00193      * Allows access only to logged users that have a level equal to or less than provided role. If permission is nsot granted, it will automatically redirect the user to the login module.
00194      * <p><b>Note that while it's doing all login/auth/redirection work automatically, you still have to create the corresponding user table in your database in addition to provide the login module into orion's module directory.</b></p>
00195      * @see Core\Auth
00196      *      MainConfig
00197      *      LoginModule
00198      * @param string $slug the role identifier (ie: 'administrator', 'member', etc.). See your configuration file for a liste of roles and their permission level.
00199      * @return bool TRUE if user has the permission, FALSE otherwise (even if redirected)
00200      */
00201     public static function allow( $slug, $noredirect=false )
00202     {
00203         if ( !self::logged() )
00204             self::login();
00205 
00206         $roles = \Orion::config()->get( 'AUTH_ROLES' );
00207 
00208         if ( !array_key_exists( $slug, $roles ) )
00209             throw new Exception( 'Unable to restrict access, role [' . $slug . '] does not exist.', E_USER_ERROR, __CLASS__ );
00210 
00211         if ( self::$user == null || empty( self::$user->level ) || self::$user->level <= 0 )
00212             throw new Exception( 'Missing user information. See Core\Auth for more info.', E_USER_ERROR, __CLASS__ );
00213 
00214         if ( self::$user->level > $roles[ $slug ] )
00215         {
00216             Context::setHeaderCode( 403 );
00217             if ( !$noredirect )
00218                 Context::redirect( Context::genModuleURL( 'users', 'error-' . self::E_LEVEL_RESTRICT, 'admin' ) );
00219             return false;
00220         }
00221         else
00222         {
00223             return true;
00224         }
00225     }
00226 
00227     /**
00228      * Logs the user out.
00229      * Unsets the session data.
00230      */
00231     public static function logout()
00232     {
00233         // Unset all of the session variables.
00234         $_SESSION = array( );
00235 
00236         // Delete the session cookie.
00237         if ( isset( $_COOKIE[ session_name() ] ) )
00238             setcookie( session_name(), '', time() - 42000, '/' );
00239 
00240         // Finally, destroy the session itself.
00241         session_destroy();
00242 
00243         self::$user = null;
00244     }
00245 
00246     /**
00247      * Is a user logged in ?
00248      * <p><b>Not for security testing !!! Use allow($slug) instead</b></p>
00249      * @return bool
00250      */
00251     public static function logged()
00252     {
00253         if ( isset( $_SESSION[ 'orionauth' ] ) )
00254         {
00255             if ( empty( self::$user ) )
00256                 return self::login( true );
00257             else
00258                 return true;
00259         }
00260 
00261         return false;
00262     }
00263 
00264     /**
00265      * Refresh user data from database.
00266      * 
00267      * @return \Orion\Models\Auth\User or false if refresh failed.
00268      */
00269     public static function refreshData()
00270     {
00271         if ( !self::logged() )
00272             return false;
00273 
00274         $data = Models\Auth\User::get()
00275                 ->where( 'id', Query::EQUAL, self::$user->id )
00276                 ->limit( 1 )
00277                 ->fetch();
00278 
00279         if ( $data == false )
00280             return false;
00281 
00282         $session = new Models\Auth\User();
00283         $session->login = $data->login;
00284         $session->level = $data->level;
00285         $session->name = $data->name;
00286         $session->surname = $data->surname;
00287         $session->id = $data->id;
00288 
00289         self::$user = $session;
00290         $_SESSION[ 'orionauth' ] = $session->toArray();
00291 
00292         return self::$user;
00293     }
00294 
00295     /**
00296      * Gets user data
00297      * @return Core\AuthUser $user
00298      */
00299     public static function user()
00300     {
00301         return self::$user;
00302     }
00303 
00304 }
00305 
00306 ?>