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








                                            
                                            




















                                                                        




                                            




                                        






                                                  






                                                 































                                                                                                                    







                                                    























                                                                                                                       
                                              



                                                        


                                                                                                                                                                                                                                

                                 




                                                                                                                                                  


























                                                                                                                                                                                 



                                                         


                                                                                
                                                                                             












                                                                                                                      

                                                                                                              




                                                                                                                      

                                                                                                                                                      








                                                                                






















                                                                                                             




                                                                                                                                      
                                                             









                                                                                                                                                                                              




                                                                                                                                           
                                  




                                                                      



                        
<?php

class User
{

	private static $user = false;
	private static $organization = NULL;
	private static $isShib = false;
	private static $isInDb = false;
	private static $isAnonymous = false;

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

	public static function isShibbolethAuth()
	{
		return self::$isShib;
	}

	public static function isInDatabase()
	{
		return self::$isInDb;
	}

	public static function isLocalOnly()
	{
		return self::$user !== false && self::$isShib === false;
	}

	public static function isAnonymous()
	{
		return self::$isAnonymous;
	}

	public static function getData()
	{
		return self::$user;
	}

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

	public static function getMail()
	{
		if (!isset(self::$user['email']))
			return false;
		return self::$user['email'];
	}

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

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

	public static function hasFullName()
	{
		return self::$user !== false && !empty(self::$user['firstname']) && !empty(self::$user['lastname']);
	}

	public static function isTutor()
	{
		return isset(self::$user['role']) && self::$user['role'] === 'tutor';
	}

	public static function getOrganizationId()
	{
		$org = self::getOrganization();
		if (!isset($org['organizationid']))
			return false;
		return $org['organizationid'];
	}

	public static function getOrganizationName()
	{
		$org = self::getOrganization();
		if (!isset($org['name']))
			return false;
		return $org['name'];
	}

	public static function getRemoteOrganizationId()
	{
		if (empty(self::$user['organization']))
			return false;
		return self::$user['organization'];
	}

	public static function getOrganization()
	{
		if (!self::isLoggedIn())
			return false;
		if (is_null(self::$organization)) {
			self::$organization = Database::queryFirst('SELECT organizationid, name FROM satellite_suffix '
				. ' INNER JOIN satellite USING (organizationid) '
				. ' WHERE suffix = :org LIMIT 1',
				array('org' => self::$user['organization']));
		}
		return self::$organization;
	}

	public static function load()
	{
		if (self::isLoggedIn())
			return true;
		$hasSession = Session::load();
		if (empty($_SERVER['persistent-id'])) {
			if (Session::getUid() === false)
				return false;
			// Try user from local DB
			self::$user = Database::queryFirst('SELECT userid, shibid, login, organizationid AS organization, firstname, lastname, email FROM user WHERE userid = :uid LIMIT 1', array('uid' => Session::getUid()));
			self::$isInDb = self::$user !== false;
			return self::$isInDb;
		}
		// Try bwIDM etc.
		if (!$hasSession) {
			Session::create();
			Session::set('token', md5(mt_rand() . $_SERVER['REMOTE_ADDR'] . microtime(true) . $_SERVER['persistent-id'] . mt_rand()));
			Session::save();
		}
		self::$isShib = true;
		if (!isset($_SERVER['sn'])) $_SERVER['sn'] = '';
		if (!isset($_SERVER['givenName'])) $_SERVER['givenName'] = '';
		if (!isset($_SERVER['mail'])) $_SERVER['mail'] = '';
		$shibId = md5($_SERVER['persistent-id']);
		self::$user = array(
			'userid' => 0,
			'shibid' => $shibId,
			'login' => NULL,
			'firstname' => $_SERVER['givenName'],
			'lastname' => $_SERVER['sn'],
			'email' => $_SERVER['mail'],
		);
		// Figure out whether the user should be considered a tutor
		if (isset($_SERVER['affiliation']) && preg_match('/(^|;)employee@/', $_SERVER['affiliation']))
			self::$user['role'] = 'tutor';
		elseif (isset($_SERVER['entitlement']) && strpos(";{$_SERVER['entitlement']};", ';http://bwidm.de/entitlement/bwLehrpool;') !== false)
			self::$user['role'] = 'tutor';
		// Try to figure out organization
		if (isset($_SERVER['affiliation']) && preg_match('/@([a-zA-Z\-\._]+)(;|$)/', $_SERVER['affiliation'], $out))
			self::$user['organization'] = $out[1];
		// Get matching db entry if any
		$user = Database::queryFirst('SELECT userid, login, firstname, lastname, email, fixedname FROM user WHERE shibid = :shibid LIMIT 1', array('shibid' => $shibId));
		if ($user === false) {
			// No match in database, user is not signed up
			return true;
		}
		if (Session::getUid() === false) {
			Session::setUid($user['userid']);
			Session::save();
		}
		// Already signed up, see if we can fetch missing fields from DB
		self::$user['login'] = $user['login'];
		self::$isInDb = true;
		self::$isAnonymous = (empty($user['firstname']) && empty($user['lastname']));
		foreach (array('firstname', 'lastname', 'email') as $key) {
			if (empty(self::$user[$key]))
				self::$user[$key] = $user[$key];
		}
		return true;
	}

	public static function deploy($anonymous)
	{
		if (empty(self::$user['shibid']))
			Util::traceError('NO SHIBID');
		if ($anonymous) {
			Database::exec("INSERT INTO user (shibid, login, organizationid, firstname, lastname, email) "
				. " VALUES (:shibid, :shibid, :org, '', '', '') "
				. " ON DUPLICATE KEY UPDATE firstname = '', lastname = '', email = ''", array(
					'shibid' => self::$user['shibid'],
					'org'    => self::getOrganizationId()
			));
		} else {
			Database::exec("INSERT INTO user (shibid, login, organizationid, firstname, lastname, email) "
				. " VALUES (:shibid, :shibid, :org, :firstname, :lastname, :email) "
				. " ON DUPLICATE KEY UPDATE firstname = VALUES(firstname), lastname = VALUES(lastname), email = VALUES(email)", array(
					'shibid' => self::$user['shibid'],
					'firstname' => self::$user['firstname'],
					'lastname' => self::$user['lastname'],
					'email' => self::$user['email'],
					'org'    => self::getOrganizationId()
			));
		}
	}

	public static function updatePassword($pass)
	{
		if (!self::isLoggedIn() || self::$isShib || !self::$isInDb)
			return false;
		$pw = Crypto::hash6($pass);
		$ret = Database::exec('UPDATE user SET password = :pass WHERE userid = :user LIMIT 1', array(
			'pass' => $pw,
			'user' => self::getId()
		));
		return $ret == 1;
	}


	public static function updateMail($mail)
	{
		if (!self::isLoggedIn() || self::$isShib || !self::$isInDb)
			return false;
		$ret = Database::exec('UPDATE user SET email = :mail WHERE userid = :user LIMIT 1', array(
			'mail' => $mail,
			'user' => self::getId()
		));
		return $ret == 1 || $mail === self::get('email');
	}
	public static function login($user, $pass)
	{
		$ret = Database::queryFirst('SELECT userid, password FROM user WHERE login = :user LIMIT 1', array(':user' => $user));
		if ($ret === false)
			return false;
		if (!Crypto::verify($pass, $ret['password']))
			return false;
		Session::create();
		Session::setUid($ret['userid']);
		Session::set('token', md5(rand() . time() . mt_rand() . $_SERVER['REMOTE_ADDR'] . rand() . $_SERVER['REMOTE_PORT'] . rand() . $_SERVER['HTTP_USER_AGENT'] . microtime(true)));
		Session::save();
		return true;
	}

	public static function logout()
	{
		foreach ($_COOKIE as $name => $value) {
			if (substr($name, 0, 5) !== '_shib')
				continue;
			@setcookie($name, '', time() - 8640000, null, null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true);
		}
		Session::delete();
		if (self::$isShib) {
			Header('Location: ?do=Logout&noredirect=yes');
		} else {
			Header('Location: ?do=Main');
		}
		exit(0);
	}

}