diff --git a/registration-system/frameworks/Environment.php b/registration-system/frameworks/Environment.php index 4aa09ce5780bbaa235cbac59f0209a7fda257f34..683d63338522fa4cbba2e34c5251b0c24ec8f2de 100644 --- a/registration-system/frameworks/Environment.php +++ b/registration-system/frameworks/Environment.php @@ -1,112 +1,150 @@ <?php -require_once __DIR__.'/../config.inc.php'; -require_once __DIR__.'/../lang.php'; +require_once __DIR__ . '/../config.inc.php'; +require_once __DIR__ . '/../lang.php'; require_once 'medoo.php'; require_once 'commons.php'; require_once 'soft_protect.php'; class Environment { + const LOGIN_RIGHTS_NONE = 0; + const LOGIN_RIGHTS_ADMIN = 1; + const LOGIN_RIGHTS_SUDO = 2; + private static $__instance; public $database; public $config; + private $dangling_form_data; + private $permission_level = Environment::LOGIN_RIGHTS_NONE; - public static function getEnv() { - if(self::$__instance == NULL) self::$__instance = new Environment(); + public static function getEnv($admin = false) { + if (self::$__instance == NULL) self::$__instance = new Environment($admin); return self::$__instance; } - protected function __construct() { + protected function __construct($admin = false) { global $config_db, $config_studitypen, $config_essen, $config_reisearten, $invalidCharsRegEx, $config_reisearten_o, $config_essen_o, $config_studitypen_o; $this->database = new medoo(array( 'database_type' => $config_db["type"], 'database_name' => $config_db["name"], - 'server' => $config_db["host"], - 'username' => $config_db["user"], - 'password' => $config_db["pass"] + 'server' => $config_db["host"], + 'username' => $config_db["user"], + 'password' => $config_db["pass"] )); $this->config = [ 'studitypen' => $config_studitypen, - 'essen' => $config_essen, + 'essen' => $config_essen, 'reisearten' => $config_reisearten, 'invalidChars' => $invalidCharsRegEx ]; $this->oconfig = [ 'studitypen' => $config_studitypen_o, - 'essen' => $config_essen_o, + 'essen' => $config_essen_o, 'reisearten' => $config_reisearten_o ]; - } - - // signup method + if ($admin) { + self::adminCheckIfLogin(); + if (self::adminIsLoggedIn()) + $this->permission_level = self::adminGetLevel(); + } + } - // only waitlist - - /** - * @returns TRUE iff regular registration is allowed - */ - public function isRegistrationOpen($fid) { - $ret = $this->getRegistrationState($fid); - return $ret === 0; + // ======================================================================================================== + // ADMIN STUFF + + private static function adminCheckIfLogin() { + if (isset($_GET['logout'])) { + Environment::adminLogOut(); + } else if (isset($_POST['user']) and isset($_POST['password'])) { + $user = $_POST['user']; + $password = $_POST['password']; + if (Environment::adminIsValidUser($user, $password)) + $_SESSION['loggedIn'] = $user; + } } - /** - * @returns TRUE iff regular registration is allowed - * @param $fid - fahrt id to check - * @param $mail - email address to check - * @param $list - list to check (bachelor or waitlist) - */ - public function isRegistered($fid, $mail, $list = 'bachelor') { - return $this->database->has($list, ['AND' => ['fahrt_id'=>$fid, 'mehl' => $mail]]); + private static function adminIsValidUser($user, $password) { + $config_admins = Environment::adminReadUsersFile(); + foreach ($config_admins as $cfg_user => $cfg_password) { + if ($cfg_user != $user) + continue; + $cfg_password = $cfg_password["pw"]; + if ($cfg_password[0] == '{') { + if (strpos($cfg_password, "{SHA254}") >= 0) { + $beginOfSalt = strpos($cfg_password, "$"); + $salt = substr($cfg_password, 9, strpos($cfg_password, "$") - 9); + $hash = substr($cfg_password, $beginOfSalt + 1); + + if (hash('sha256', $password . $salt) == $hash) + return true; + } + } else { + // ONLY sha256 yet, others not implemented + } + } + return false; } - /** - * returns value depending on registration status - * 0 = registration open (slots available) - * 1 = all slots taken -> waitlist open - * 2 = registration closed! - * - * @param $fid (optional) to pass this parameter - * @returns int the state of the trip (see above) - */ - public function getRegistrationState($fid = NULL) { - if(is_null($fid)) $fid = $this->getSelectedTripId(); + private static function adminReadUsersFile() { + global $config_userfile; + $ret = []; + $handle = fopen($config_userfile, "r"); + if ($handle) { + while (($line = fgets($handle)) !== false) { + $tmp = explode(" ", $line); + if (count($tmp) >= 3) { + $ret[$tmp[1]] = ["pw" => $tmp[2], "sa" => $tmp[0]]; + } + } + } + fclose($handle); + return $ret; + } - comm_verbose(3,"checking if fid ". $fid . " is open"); - $open = $this->database->has('fahrten', ['AND' => ['fahrt_id'=>$fid, 'regopen'=>1]]); - if(!$open) - return 2; + private static function adminIsLoggedIn() { + return isset($_SESSION['loggedIn']) and $_SESSION['loggedIn'] != ''; + } - $cnt = $this->database->count("bachelor", ["AND"=> - ["backstepped" => NULL, - "fahrt_id" => $fid]]); - $max = $this->database->get("fahrten", "max_bachelor", ["fahrt_id" => $fid]); - $wl = $this->database->count('waitlist', ['AND' => - ["transferred" => NULL, - "fahrt_id" => $fid]]); + private static function adminGetLevel() { + $config_admins = Environment::adminReadUsersFile(); + if (isset($_SESSION['loggedIn']) && isset($config_admins[$_SESSION['loggedIn']])) { + if ($config_admins[$_SESSION['loggedIn']]['sa'] === 'S') + return Environment::LOGIN_RIGHTS_SUDO; + elseif ($config_admins[$_SESSION['loggedIn']]['sa'] === 'N') + return Environment::LOGIN_RIGHTS_ADMIN; + } + return Environment::LOGIN_RIGHTS_NONE; + } - comm_verbose(3,"cnt: ".$cnt.", max: ".$max.", open: ".($open ? "yes" : "no")); + public function isAdmin() { + return $this->permission_level == Environment::LOGIN_RIGHTS_ADMIN or + $this->permission_level == Environment::LOGIN_RIGHTS_SUDO; + } - if ( $cnt < $max && $wl == 0 ) - return 0; + public function isSuperAdmin() { + return $this->permission_level == Environment::LOGIN_RIGHTS_SUDO; + } - return 1; + public static function adminLogOut() { + session_destroy(); + header("location: .."); } + /** - * @return trip selected via $_REQUEST (or null) + * @return int|null trip selected via $_REQUEST (or null) */ public function getSelectedTripId() { - if(isset($_REQUEST['fid'])) - return (int) $_REQUEST['fid']; + if (isset($_REQUEST['fid'])) + return (int)$_REQUEST['fid']; else return null; } @@ -115,11 +153,11 @@ class Environment { * @return bool true iff selected trip id is in the DB */ public function isSelectedTripIdValid() { - $fid = $this->getSelectedTripId(); - if ($fid == null) return false; + $fid = $this->getSelectedTripId(); + if ($fid == null) return false; $valid = $this->database->has('fahrten', - ['fahrt_id'=> $fid]); - if(!$valid) comm_verbose(1,"FID nicht vorhanden!"); + ['fahrt_id' => $fid]); + if (!$valid) comm_verbose(1, "FID nicht vorhanden!"); return $valid; } @@ -147,114 +185,12 @@ class Environment { } public function getBachelor($bid = NULL) { - if(!is_null($this->dangling_form_data)) + if (!is_null($this->dangling_form_data)) return $this->dangling_form_data; - if(is_null($bid)) + if (is_null($bid)) return $this->getEmptyBachelor(); else return $this->getBachelorFromDB($bid); } - /** - * Given a registration id, return all parameters from the db - * - * @param $bid - * @return null or registration details - */ - public function getBachelorFromDB($bid) { - if(!is_null($bid) && - $this->database->has('bachelor', ['bachelor_id' => $bid])){ - - $bachelor = $this->database->select('bachelor', - ['forname','sirname','anday','abday','antyp','abtyp','pseudo', - 'mehl','essen','public','virgin','studityp','comment'], - ['bachelor_id'=>$bid]); - $bachelor['id'] = $bid; - return $bachelor[0]; - } - return $this->getEmptyBachelor(); - } - - /** - * Will return an empty registration field - * - * @return array - */ - public function getEmptyBachelor() { - $possible_dates = comm_get_possible_dates($this->database, $this->getSelectedTripId()); - - return [ - 'forname' => "", 'sirname' => "", - 'anday' => $possible_dates[0], 'abday' => $possible_dates[count($possible_dates)-1], - 'antyp' => "", 'abtyp' => "", - 'pseudo' => "", 'mehl' => "", 'essen' => "", 'public' => "", - 'studityp' => "", 'comment'=>"" - ]; - } - - /** - * @param $data - * @return bool - */ - public function sendBachelorToDB($data) { - - // === prepare data to insert === - $data['anm_time'] = time(); - $data['anday'] = date('Y-m-d', DateTime::createFromFormat('d.m.Y',$data['anday'])->getTimestamp()); - $data['abday'] = date('Y-m-d', DateTime::createFromFormat('d.m.Y',$data['abday'])->getTimestamp()); - - if($this->isInWaitlistMode()){ - if($this->getRegistrationState($data['fahrt_id'])==1){ - $this->database->exec("LOCK TABLES fahrten, waitlist WRITE"); // count should not be calculated in two scripts at once - - // === prepare data to insert === - $data['waitlist_id'] = comm_generate_key($this->database, - ["bachelor" => "bachelor_id", "waitlist" => "waitlist_id"], - ['fahrt_id'=>$data['fahrt_id']]); - - // === insert data === - $insertOk = !$this->isRegistered($data['fahrt_id'], $data['mehl'], 'waitlist'); - - if($insertOk) $this->database->insert("waitlist", $data); - $this->database->exec("UNLOCK TABLES"); // insert is done now, count may be recalculated in other threads - if(!$insertOk) return false; - - // === notify success === - $this->feedbackHelper("lang_waitmail", $data['mehl'], $data['waitlist_id'], $data['fahrt_id']); - } - else return false; - } else { - $this->database->exec("LOCK TABLES fahrten, bachelor WRITE"); // count should not be calculated in two scripts at once - - // === prepare data to insert === - $data['version'] = 1; - $data['bachelor_id'] = comm_generate_key($this->database, - ["bachelor" => "bachelor_id"], - ['fahrt_id'=>$data['fahrt_id']]); - - // === check regstration full === - $res = $this->database->get("fahrten", - ["regopen", "max_bachelor"], - ["fahrt_id" => $data['fahrt_id']]); - if (!$res || $res['regopen'] != "1") { - $this->database->exec("UNLOCK TABLES"); - return false; - } - - $insertOk = $this->isRegistrationOpen($data['fahrt_id']) && !$this->isRegistered($data['fahrt_id'], $data['mehl']); - - if ($insertOk) - $this->database->insert("bachelor", $data); - $this->database->exec("UNLOCK TABLES"); // insert is done now, count may be recalculated in other threads - if (!$insertOk) - return false; // full - - // === notify success === - $this->feedbackHelper(["lang_regmail", "lang_payinfomail"], $data['mehl'], $data['bachelor_id'], $data['fahrt_id']); - } - - return true; - } - - }