summaryrefslogblamecommitdiffstats
path: root/inc/user.inc.php
blob: dd94ab7131493e32b9bc7ecb7daa8f2648ab62c4 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

     

                        

                                



                                    
 
                                     
 
                                                 



                                             






                                             

                                        

                                        
                                               

         






                                                  
                                                                                               
         

                                        
                                                               
                                                     

                                                                     








                                                                                                  
                         

                                                                                                                  


                                                                                        

         


                                                                                               
          



                                                                                                                   
                                                                                                                            


                                                                  



                                              

                                                                
                                                  
                                                                     
                                                     








                                                                                                                 


                 
                                                                             
         

                                        
                                                               
                                                     




                                                                                                                   

                                                                                                       
                                                                                 





                                                                               

                                  
                          

         
                                           
         
                                       
                                    
                                      


                                                           

                                                    
                                               
                                                                                                                                    

                                                  
                                                              




                                    
                                                                                   






                                                                                                                         
                                                                     

                                        
                                     




                                                                                                                                          
                                                                                     
         
                                                                                                                                    



                                                           
                                                                               
                                                    
                            

         

                                             
         
                                  
                                                        


                        
                                                                   








                                                                                                              
 






                                                  
                                                               











                                                               
 
<?php

declare(strict_types=1);

use JetBrains\PhpStorm\NoReturn;

require_once('inc/session.inc.php');

class User
{

	private static $user = false;

	public static function isLoggedIn(): bool
	{
		return self::$user !== false;
	}

	public static function getId()
	{
		if (!self::isLoggedIn())
			return false;
		return self::$user['userid'];
	}

	public static function getName()
	{
		if (!self::isLoggedIn())
			return false;
		return self::$user['fullname'];
	}

	public static function getLogin(): ?string
	{
		if (!self::isLoggedIn())
			return null;
		return self::$user['login'];
	}

	public static function hasPermission(string $permission, ?int $locationid = NULL): bool
	{
		if (!self::isLoggedIn())
			return false;
		if (Module::isAvailable("permissionmanager")) {
			if ($permission[0] === '.') {
				$permission = substr($permission, 1);
			} else {
				if (class_exists('Page')) {
					$module = Page::getModule();
					if ($module !== false) {
						$module = $module->getIdentifier();
					}
				} else {
					$module = strtolower(Request::any('do'));
				}
				$permission = $module ? $module . "." . $permission : $permission;
			}
			return PermissionUtil::userHasPermission(self::$user['userid'], $permission, $locationid);
		}
		if (self::$user['permissions'] & Permission::get('superadmin'))
			return true;
		return (self::$user['permissions'] & Permission::get($permission)) != 0;
	}

	/**
	 * Confirm current user has the given permission, stop execution and show error message
	 * otherwise.
	 *
	 * @param string $permission Permission to check for
	 * @param null|int $locationid location this permission has to apply to, NULL if any location is sufficient
	 * @param null|string $redirect page to redirect to if permission is not given, NULL defaults to main page
	 */
	public static function assertPermission(string $permission, ?int $locationid = NULL, ?string $redirect = NULL): void
	{
		if (User::hasPermission($permission, $locationid))
			return;
		if (AJAX) {
			Message::renderList();
			exit;
		}
		if (!is_null($redirect)) {
			Message::addError('main.no-permission');
			Util::redirect($redirect);
		} elseif (Module::isAvailable('permissionmanager')) {
			if ($permission[0] !== '.') {
				$module = Page::getModule();
				if ($module !== false) {
					$permission = '.' . $module->getIdentifier() . '.' . $permission;
				}
			}
			Util::redirect('?do=permissionmanager&show=denied&permission=' . urlencode($permission));
		} else {
			Message::addError('main.no-permission');
			Util::redirect('?do=main');
		}
	}

	public static function getAllowedLocations(string $permission): array
	{
		if (!self::isLoggedIn())
			return [];
		if (Module::isAvailable("permissionmanager")) {
			if ($permission[0] === '.') {
				$permission = substr($permission, 1);
			} else {
				$module = Page::getModule();
				$permission = $module ? $module->getIdentifier() . "." . $permission : $permission;
			}
			return PermissionUtil::getAllowedLocations(self::$user['userid'], $permission);
		}
		if (self::$user['permissions'] & Permission::get('superadmin')) {
			if (Module::isAvailable('locations')) {
				$a = array_keys(Location::getLocationsAssoc());
				$a[] = 0;
			} else {
				$a = [0];
			}
			return $a;
		}
		return [];
	}

	public static function load(): bool
	{
		if (self::isLoggedIn())
			return true;
		if (Session::load()) {
			if (empty(Session::get('token'))) {
				self::generateToken();
			}
			$uid = Session::getUserId();
			if ($uid < 1)
				self::logout();
			self::$user = Database::queryFirst('SELECT * FROM user WHERE userid = :uid LIMIT 1', array(':uid' => $uid));
			if (self::$user === false)
				self::logout();
			settype(self::$user['userid'], 'int');
			return true;
		}
		return false;
	}

	public static function testPassword(string $userid, string $password): bool
	{
		$ret = Database::queryFirst('SELECT passwd FROM user WHERE userid = :userid LIMIT 1', compact('userid'));
		if ($ret === false)
			return false;
		return Crypto::verify($password, $ret['passwd']);
	}

	public static function updatePassword(string $password): bool
	{
		if (!self::isLoggedIn())
			return false;
		$passwd = Crypto::hash6($password);
		$userid = self::getId();
		return Database::exec('UPDATE user SET passwd = :passwd WHERE userid = :userid LIMIT 1', compact('userid', 'passwd')) > 0;
	}

	public static function login(string $user, string $pass, bool $fixedIp): bool
	{
		$ret = Database::queryFirst('SELECT userid, passwd FROM user WHERE login = :user LIMIT 1', array(':user' => $user));
		if ($ret === false)
			return false;
		if (!Crypto::verify($pass, $ret['passwd']))
			return false;
		Session::create($ret['passwd'], (int)$ret['userid'], $fixedIp);
		self::generateToken($ret['passwd']);
		return true;
	}

	#[NoReturn]
	public static function logout(): void
	{
		Session::delete();
		Header('Location: ?do=Main&fromlogout');
		exit(0);
	}

	public static function setLastSeenEvent(int $eventid): void
	{
		if (!self::isLoggedIn())
			return;
		Database::exec("UPDATE user SET lasteventid = :eventid WHERE userid = :userid LIMIT 1", array(
			'eventid' => $eventid,
			'userid' => self::$user['userid']
		));
		self::$user['lasteventid'] = $eventid;
	}

	public static function getLastSeenEvent()
	{
		if (!self::isLoggedIn())
			return false;
		return self::$user['lasteventid'];
	}

	private static function generateToken($salt = ''): void
	{
		Session::set('token', md5($salt . ','
			. rand() . ','
			. time() . ','
			. rand() . ','
			. $_SERVER['REMOTE_ADDR'] . ','
			. rand() . ','
			. $_SERVER['REMOTE_PORT'] . ','
			. rand() . ','
			. $_SERVER['HTTP_USER_AGENT']), false);
	}

}