self::$user['organization'])); } return self::$organization; } public static function getShibId() { if (empty(self::$user['shibid'])) return false; return self::$user['shibid']; } public static function load() { if (self::isLoggedIn()) return true; $hasSession = Session::load(); if (empty($_SERVER['persistent-id'])) { if (Session::getUid() === false) { if (!empty($_SERVER['Shib-Session-ID'])) { Message::addError('Sie haben sich erfolgreich mittels bwIDM authentifiziert,' . ' aber der IdP Ihrer Einrichtung scheint die benötigten Metadaten nicht' . ' an den bwLehrpool-SP zu übermitteln. Bitte wenden Sie sich an den Support.'); } Session::delete(); return false; } // Try user from local DB self::$user = Database::queryFirst('SELECT userid, shibid, organizationid AS organization, firstname, lastname, email FROM user WHERE userid = :uid LIMIT 1', array('uid' => Session::getUid())); self::$isInDb = self::$user !== false; if (!self::$isInDb) { Session::delete(); } return self::$isInDb; } // Try bwIDM etc. if (!$hasSession) { // Make sure cookies are enabled if (!empty($_SERVER['Shib-Session-ID'])) { if (isset($_GET['force-cookie'])) die('Bitte aktivieren Sie Cookies und Javascript!'); } Session::create(); Session::set('token', md5(mt_rand() . $_SERVER['REMOTE_ADDR'] . microtime(true) . $_SERVER['persistent-id'] . mt_rand())); Session::save(); if (!empty($_SERVER['Shib-Session-ID'])) Util::redirect('?do=Main&force-cookie=true.dat'); } 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' => NULL, 'shibid' => $shibId, 'firstname' => $_SERVER['givenName'], 'lastname' => $_SERVER['sn'], 'email' => $_SERVER['mail'], ); // Figure out whether the user should be considered a tutor if (isset($_SERVER['affiliation']) && (strpos(";{$_SERVER['affiliation']}", ';employee@') !== false || strpos(";{$_SERVER['affiliation']}", ';staff@') !== false)) self::$user['role'] = 'TUTOR'; elseif (isset($_SERVER['entitlement']) && strpos(";{$_SERVER['entitlement']};", ';http://bwidm.de/entitlement/bwLehrpool;') !== false) self::$user['role'] = 'TUTOR'; else self::$user['role'] = 'STUDENT'; // 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, 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; } self::$user['userid'] = $user['userid']; if (Session::getUid() === false) { Session::setUid($user['userid']); Session::save(); } // Already signed up, see if we can fetch missing fields from DB 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, $existingLogin = false) { if (empty(self::$user['shibid'])) Util::traceError('NO SHIBID'); // Merging with test-account: if (!empty($existingLogin)) { if ($anonymous) { $ret = Database::exec("UPDATE user SET shibid = :shibid, firstname = '', lastname = '', email = '', password = '' " . " WHERE userid = :userid LIMIT 1", array( 'shibid' => self::$user['shibid'], 'userid' => $existingLogin )); } else { $ret = Database::exec("UPDATE user SET shibid = :shibid, password = '', firstname = :firstname, lastname = :lastname, email = :email " . " WHERE userid = :userid LIMIT 1", array( 'shibid' => self::$user['shibid'], 'userid' => $existingLogin, 'firstname' => self::$user['firstname'], 'lastname' => self::$user['lastname'], 'email' => self::$user['email'] )); } return $ret > 0; } // New account if ($anonymous) { Database::exec("INSERT INTO user (shibid, userid, organizationid, firstname, lastname, email) " . " VALUES (:shibid, :shibid, :org, '', '', '') " . " ON DUPLICATE KEY UPDATE firstname = '', lastname = '', email = '', password = ''", array( 'shibid' => self::$user['shibid'], 'org' => self::getOrganizationId() )); } else { Database::exec("INSERT INTO user (shibid, userid, organizationid, firstname, lastname, email) " . " VALUES (:shibid, :shibid, :org, :firstname, :lastname, :email) " . " ON DUPLICATE KEY UPDATE firstname = VALUES(firstname), lastname = VALUES(lastname), email = VALUES(email), password = ''", array( 'shibid' => self::$user['shibid'], 'firstname' => self::$user['firstname'], 'lastname' => self::$user['lastname'], 'email' => self::$user['email'], 'org' => self::getOrganizationId() )); } return true; } 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 userid = :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() - CONFIG_SESSION_TIMEOUT, null, null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true); } Session::delete(); if (self::$isShib) { Header('Location: /Shibboleth.sso/Logout'); } else { Header('Location: ?do=Main'); } exit(0); } public static function delete() { if (!User::isLoggedIn() || !User::isInDatabase()) return true; return Database::exec("DELETE FROM user WHERE userid = :userid LIMIT 1", array('userid' => User::getId()), true) > 0; } }