Files
thetool/lib/mvcfronk/mfLogin/mfLoginController.php
2025-03-17 08:56:54 +00:00

240 lines
7.7 KiB
PHP

<?php
class mfLoginController extends mfBaseController
{
protected function init($request)
{
$this->layout()->setTemplate("mfLogin/Index");
if ($request['mfLoginTemplate']) {
$this->layout()->setTemplate($request['mfLoginTemplate']);
}
/*if($request['mfLoginGet']) {
$_SESSION['mfLoginGet']=$request['mfLoginGet'];
}*/
if ($request['mfLoginUrl']) {
$_SESSION['mfLoginUrl'] = $request['mfLoginUrl'];
}
$this->logout();
}
protected function indexAction()
{
if ($_SESSION[MFAPPNAME . "_loginfailed"]) {
$this->layout()->set("LayoutError", "Login fehlgeschlagen.");
}
unset($_SESSION[MFAPPNAME . "_loginfailed"]);
}
protected function loginAction($request)
{
#Check if 2FA Code existiert
if (!$request['TwofactorCode'] || !is_int((int)$request['TwofactorCode'])) {
$code2fa = "unset";
} else {
$code2fa = $request['TwofactorCode'];
}
#Check ob Angemeldet bleiben aktiv ist
if (isset($request['Remember']) && $request['Remember'] === "true") {
$remember = true;
} else {
$remember = false;
}
#performLogin um 2FA Code und Remember erweitert
$performLogin = $this->performLogin($request['Username'], $request['Password'], $code2fa, $remember);
#performLogin um mehrere Stati erweitert
if ($performLogin === true) {
} elseif ($performLogin == "2fa") {
$this->layout()->setTemplate("mfLogin/Index");
$this->layout()->set("request", $request);
$this->layout()->set("requesttype", $performLogin);
return;
} elseif ($performLogin == "false2fa") {
$this->layout()->setTemplate("mfLogin/Index");
$this->layout()->setFlash("Verifizierungscode falsch oder abgelaufen", "error");
$this->layout()->set("request", $request);
$this->layout()->set("requesttype", $performLogin);
return;
} else {
$_SESSION[MFAPPNAME . "_loginfailed"] = true;
$this->layout()->setTemplate("mfLogin/Index");
$this->layout()->set("requesttype", "falselogin");
return;
}
//$get=$_SESSION['mfLoginGet'];
$url = $_SESSION['mfLoginUrl'];
//unset($_SESSION['mfLoginGet']);
unset($_SESSION['mfLoginUrl']);
/*
$mod=$get['action'];
if(preg_match('/([^_]+)_(.+)/',$action,$m)) {
$mod=$m[1];
$action=$m[2];
}
unset($get['action']);
self::redirect($mod,$action,$get);
*/
#Header wird nur neu geladen wenn Login true ist
header("Location: $url");
}
/*
* Internal functions
*/
public function logout()
{
if (!defined("MFAPPNAME")) define("MFAPPNAME", "mvcfronk");
if (!defined("MFUSERTABLE")) define("MFUSERTABLE", "mfWorker");
//session_name(MFAPPNAME."_session");
//session_start();
#Delete Token (DB und Cookie)
UserToken::deleteToken();
unset($_SESSION[MFAPPNAME . '_username']);
unset($_SESSION[MFAPPNAME . '_ip']);
}
public static function staticLogout()
{
if (!defined("MFAPPNAME")) define("MFAPPNAME", "mvcfronk");
if (!defined("MFUSERTABLE")) define("MFUSERTABLE", "mfWorker");
//session_name(MFAPPNAME."_session");
//session_start();
#Delete Token (DB und Cookie)
UserToken::deleteToken();
unset($_SESSION[MFAPPNAME . '_username']);
unset($_SESSION[MFAPPNAME . '_ip']);
}
public static function isLoggedIn()
{
$db = FronkDB::singleton();
if (!defined("MFAPPNAME")) define("MFAPPNAME", "mvcfronk");
if (!defined("MFUSERTABLE")) define("MFUSERTABLE", "mfWorker");
//session_name(MFAPPNAME."_session");
//session_start();
#Check if Token Cookie und DB Eintrag existiert
UserToken::checkToken();
if ($_SESSION[MFAPPNAME . '_username'] && $_SESSION[MFAPPNAME . '_ip']) {
$username = $_SESSION[MFAPPNAME . '_username'];
$ip = $_SERVER['REMOTE_ADDR'];
$sid = session_id();
if ($_SESSION[MFAPPNAME . '_ip'] == $ip) {
// session seems legit, check if user exists and additionally check IP saved in database
$res = $db->select(MFUSERTABLE, "*", "username='$username' AND ip='$ip' AND sessionid='$sid'");
if ($db->num_rows($res)) {
$user = $db->fetch_object($res);
self::initSession($user);
return true;
}
return false;
}
} else {
return false;
}
}
protected static function initSession($user)
{
$_SESSION[MFAPPNAME . '_username'] = $user->username;
$_SESSION[MFAPPNAME . '_ip'] = $_SERVER['REMOTE_ADDR'];
unset($_SESSION[MFAPPNAME . "_loginfailed"]);
$user = mfUser::singleton($user);
return true;
}
protected function performLogin($username, $password, $code2fa, $remember)
{
if (!defined("MFAPPNAME")) define("MFAPPNAME", "mvcfronk");
if (!defined("MFUSERTABLE")) define("MFUSERTABLE", "mfWorker");
//session_set_cookie_params(0);
//session_name(MFAPPNAME."_session");
//session_start();
if (!is_scalar($username) || !is_scalar($password)) {
return false;
}
$username = $this->db()->escape($username);
$res = $this->db()->select(MFUSERTABLE, "*", "username='$username'");
if (!$this->db()->num_rows($res)) {
sleep(1);
return false;
}
$user = $this->db()->fetch_object($res);
if ($user->active == 0) return false;
$hash = $user->password;
#2FA Variablen
$twofactor = $user->twofactor;
$twofactorcode = $user->twofactorcode;
$twofactortimestamp = $user->twofactortimestamp;
#Zeitdifferenz des 2FA Codes
$timeSecond = time() - $twofactortimestamp;
$userid = $user->id;
$salt = substr($hash, 0, 16);
$passhash = $this->generatePasswordHash($password, $salt);
if ($passhash === $hash) {
if ($twofactor !== "0") {
if ($code2fa == "unset") {
#2FA Code wird generiert
$twoFactor = new UserTwofactor($userid);
$twoFactor->sendCode();
return "2fa"; #Return für das Einblenden der Verifizierungsmaske
} elseif ($twofactorcode != $code2fa || $timeSecond > 300) {
return "false2fa"; #Return für falscher/abgelaufener 2FA Code
} elseif ($remember) {
#Token generieren in DB und Cookie schreiben
UserToken::generateToken($userid);
}
$twoFactor = new UserTwofactor($userid);
$twoFactor->removeCode();
}
//session_name(MFAPPNAME."_session");
//session_start();
$this->db()->update(MFUSERTABLE, array('ip' => $_SERVER['REMOTE_ADDR'], 'sessionid' => session_id()), "username='$username'");
$this->log->debug("$username logged in");
self::initSession($user);
return true;
}
sleep(1);
return false;
}
public static function generatePasswordHash($pass, $salt = NULL)
{
if (!$salt) {
$salt = substr(md5(uniqid(rand(), true)), 0, 16);
} else {
$salt = substr($salt, 0, 16);
}
return $salt . sha1($salt . $pass);
}
}