View file veppa_wallpaper/sys/app/models/AuthUser.php

File size: 7.06Kb
<?php 
/**
 * Free Wallpaper Script
 *
 * Free Wallpaper Script by Vepa Halliyev is licensed under a Creative Commons Attribution-Share Alike 3.0 License.
 *
 * @package		Free Wallpaper Script
 * @author		Vepa Halliyev
 * @copyright	Copyright (c) 2009, Vepa Halliyev, veppa.com.
 * @license		http://www.veppa.com/free-wallpaper-script/
 * @link		http://www.veppa.com/free-wallpaper-script/
 * @since		Version 1.0
 * @filesource
 */
/**
 * Class AuthUser
 *
 * All informations of the logged in user, plug all method for login, login
 * and permissions
 */
class AuthUser
{
    const SESSION_KEY               = 'veppa_wallpaper_auth_user';
    const COOKIE_KEY                = 'veppa_wallpaper_auth_user';
    const ALLOW_LOGIN_WITH_USERNAME = true;
    const COOKIE_LIFE               = 1209600; // 2 weeks
    const DELAY_ON_INVALID_LOGIN    = true;
    
    
    static protected $is_logged_in  = false;
    static protected $loaded  		= false;
    static public $user        		= false;
    
    static public function load()
    {
    	if(!self::$loaded)
    	{
	        if (isset($_SESSION[self::SESSION_KEY]) && isset($_SESSION[self::SESSION_KEY]['username']))
	            $user = new User($_SESSION[self::SESSION_KEY]);
	        else if (isset($_COOKIE[self::COOKIE_KEY]))
	            $user = self::challengeCookie($_COOKIE[self::COOKIE_KEY]);
	        else
	            return false;
	        
	        if ( ! $user)
	            return self::logout();
	        
	        self::setInfos($user);
	        
	        self::$loaded = true;
	        
    	}
    }
    
    static public function setInfos(Record $user)
    {
    	// store only nessesary fields in session 
    	$arr_user_info_filds = array('id','username','email','level');
    	foreach($arr_user_info_filds as $field)
    	{
    		$arr_user[$field] = $user->{$field};
    	}
    	
        $_SESSION[self::SESSION_KEY] = $arr_user;
        
        self::$user = $user;
        self::$is_logged_in = true;
    }
    
    static public function isLoggedIn($redirect = true)
    {
    	self::load();
    	
    	if($redirect && !self::$is_logged_in)
    	{
    		//exit('self::$is_logged_in:'.self::$is_logged_in);
    		$rd = self::getRdUrl();
			redirect(get_url('login/'.$rd));
    	}
        return self::$is_logged_in;
    }
    
	static function getRdUrl()
	{
			
		$rd = '?rd='.urlencode('http://'.$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]);
		/*
		 if($_SERVER['SERVER_PORT']!='80')
		 {
		 $port = ':'.$_SERVER['SERVER_PORT'];
		 }

		 $rd = ($_SERVER['QUERY_STRING']==NULL) ?
		 '?rd='.urlencode('http://'.$_SERVER['SERVER_NAME'].$port.$_SERVER['SCRIPT_NAME']) :
		 '?rd='.urlencode('http://'.$_SERVER['SERVER_NAME'].$port.$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING']);
		 */
		return $rd;
	}
    
    
    /**
     * Checks if user has (one of) the required permissions.
     *
     * @param string $permission Can contain a single permission or comma seperated list of permissions.
     * @return boolean
     */
    static public function hasPermission($permission,$user_id=0,$redirect = false)
    {
    	// 
    	$return = false;
        switch($permission)
        {
        	case User::PERMISSION_ADMIN:
        	case 'admin':
        		$return = (self::$user->level == User::PERMISSION_ADMIN);
        		break;
        	case User::PERMISSION_MODERATOR:
        	case 'moderator':
        		// admin or moderator
        		$return = (self::$user->level == User::PERMISSION_MODERATOR);
        		if(!$return)
        		{
        			return self::hasPermission(User::PERMISSION_ADMIN,$user_id,$redirect);
        		}
        		break;
        	case User::PERMISSION_USER:
        	case 'user':
        		// moderator and admin can be a user
        		$return = (self::$user->level == User::PERMISSION_USER);
        		
        		if($return)
        		{
		       		if($user_id)
		        	{
		        		// check if current user is correct if user_id is passed
		        		$return = (self::$user->id == $user_id);
	        		}
        		}
        		
        		if(!$return)
        		{
        			$return = self::hasPermission(User::PERMISSION_MODERATOR,$user_id,$redirect);
        		}
        		break;
        }
        
        if(!$return && $redirect)
        {
        	redirect(get_rul('login/noPermission'));
        }
        
        return $return;
    }
    
    static public function login($username, $password, $set_cookie=false)
    {
        self::logout();
          
        $user = User::findBy('email', $username);
        
        if ( ! $user instanceof User && self::ALLOW_LOGIN_WITH_USERNAME)
            $user = User::findBy('username', $username);

        if ($user instanceof User && $user->password == md5($password))
        {
            $user->logged_at = REQUEST_TIME;
            $input = Input::getInstance();
            $user->ip = $input->ip_address();
            $user->save();
            
            if ($set_cookie)
            {
                $time = REQUEST_TIME + self::COOKIE_LIFE;
                Flash::setCookie(self::COOKIE_KEY, self::bakeUserCookie($time, $user), $time);
            }
            
            self::setInfos($user);
            return true;
        }
        else
        {
            if (self::DELAY_ON_INVALID_LOGIN)
            {
                if ( ! isset($_SESSION[self::SESSION_KEY.'_invalid_logins']))
                    $_SESSION[self::SESSION_KEY.'_invalid_logins'] = 1;
                else
                    ++$_SESSION[self::SESSION_KEY.'_invalid_logins'];
                
                sleep(max(0, min($_SESSION[self::SESSION_KEY.'_invalid_logins'], (ini_get('max_execution_time') - 1))));
            }
            return false;   
        }
    }
    
    static public function logout()
    {
        unset($_SESSION[self::SESSION_KEY]);
        
        self::eatCookie();
        self::$user = false;
    }
    
    static protected function challengeCookie($cookie)
    {
        $params = self::explodeCookie($cookie);
        if (isset($params['exp'], $params['id'], $params['digest']))
        {
            if ( ! $user = Record::findByIdFrom('User', $params['id']))
                return false;
            
            if (self::bakeUserCookie($params['exp'], $user) == $cookie && $params['exp'] > REQUEST_TIME)
                return $user;
            
        }
        return false;
    }
    
    static protected function explodeCookie($cookie)
    {
        $pieces = explode('&', $cookie);
        
        if (count($pieces) < 2)
            return array();
        
        foreach ($pieces as $piece)
        {
            list($key, $value) = explode('=', $piece);
            $params[$key] = $value;
        }
        return $params;
    }
    
    static protected function eatCookie()
    {
    	Flash::clearCookie(self::COOKIE_KEY);
    }
    
    static protected function bakeUserCookie($time, $user)
    {
    	$user_ip = REMOTE_ADDR;
		$salt = crc32($time.$user->id.$user_ip.$_SERVER['HTTP_USER_AGENT']) % 1234 ;
		$digest = md5($user->id.$time.$salt.$user->email.$user_ip.$_SERVER['HTTP_USER_AGENT']);
        return 'exp='.$time.'&id='.$user->id.'&digest='.$digest;
    }
    
} // end AuthUser class