<?php
namespace Empire\Core;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\FetchMode;
use Empire\Legacy\db;
use Faker\Provider\DateTime;
use Symfony\Component\HttpFoundation\Request;
class Login {
// public static function initialize(){
// if(Login::isLoggedIn()){
// global $user;
//
// $user = Login::getLoggedIn();
//
// if(!$user){
// Login::logout();
// return;
// }
//
// Login::log($user->id, $_SERVER['REMOTE_ADDR']);
// }
// }
public static function isLoggedIn(){
return null !== Core::session()->get('member_id');
}
// //function for potential future "log in as" use
// public static function isAdminLoggedIn(){
// return Login::isLoggedIn() && isset($_SESSION['ADMIN']);
// }
/**
* @return User|null
*/
public static function getLoggedIn() {
if(!Login::isLoggedIn()) {
return null;
}
if(is_null(Core::user())) {
Core::setUser(User::load(array(Core::session()->get('member_id'))));
}
return Core::user();
}
/**
* @param Request $request
* @return bool
* @throws
*/
public static function processLogin(Request $request) {
$username = str_replace("'", '`', $request->request->get('handle'));
$user = User::getByName($username);
if(!$user){
throw new \Exception("Incorrect username or password!");
}
if(!$user->isActive()) {
throw new \Exception("Your account is currently inactive! Contact ISB or RADE if you feel this is incorrect.");
}
if(!self::verifyPassword($request->request->get('pass'), $user)) {
throw new \Exception("Incorrect username or password!");
}
Core::session()->set('member_id', $user->getID());
Core::setUser($user);
Login::log($user->getID(), $request->server->get('REMOTE_ADDR'));
return true;
}
public static function verifyPassword($password, User $user) {
$verfied = false;
if(password_verify($password, $user->MEMB_PASSWORD)) {
$verfied = true;
} elseif(sha1($password) === $user->MEMB_PASSWORD) {
$verfied = true;
}
if($verfied && password_needs_rehash($user->MEMB_PASSWORD, PASSWORD_DEFAULT)) {
$hash = self::hashPassword($password);
$user->setPassword($hash);
}
return $verfied;
}
public static function hashPassword($password) {
return password_hash($password, PASSWORD_DEFAULT);
}
/**
* @param $token
* @return bool
* @throws \Doctrine\DBAL\DBALException
* @throws \Exception
*/
public static function cookieLogin($token) {
$db = Core::db();
list($token, $signature) = explode(":", $token, 2);
if ($signature != hash_hmac('md5', $token, $_ENV['APP_SECRET'])) {
throw new \Exception('Invalid cookie!');
}
$stmt = $db->executeQuery('SELECT MEMB_ID, COOK_EXPIRE FROM COOKIE WHERE COOK_TOKEN = ? AND COOK_EXPIRE > NOW()', [$token]);
while ($cookie = $stmt->fetch(FetchMode::STANDARD_OBJECT)) {
$user = User::load([$cookie->MEMB_ID]);
Core::session()->set('member_id', $user->getID());
Core::setUser($user);
if ((new \DateTime($cookie->COOK_EXPIRE))->diff(new \DateTime(), true)->m < 1) {
self::setLoginCookie();
}
Login::log($user->getID(), $_SERVER['REMOTE_ADDR']);
return true;
}
throw new \Exception('Cookie expired or not found');
}
/**
* @throws
*/
public static function setLoginCookie() {
if(!Login::isLoggedIn()){
throw new \Exception('Unable to set login cookie, not logged in');
}
$user = Login::getLoggedIn();
//Setting expiration date.
$expires = new \DateTime('+3 months');
//Generating a token.
$token = hash('sha256', random_bytes(32));
//Insert token into DB.
db::insert('COOKIE', ['COOK_TOKEN' => $token, 'COOK_EXPIRE' => $expires->format('Y-m-d H:i:s'), 'MEMB_ID' => $user->getID()]);
//Sign token with server key to protect against tampering
$token .= ":" . hash_hmac('md5', $token, $_ENV["APP_SECRET"]);
//Finally setting the cookie
setcookie('irms_token', $token, $expires->format('U'));
}
public static function unsetLoginCookie() {
setcookie('irms_token', '', [
"expires" => time()-3600,
"path" => '/',
'samesite' => 'None',
]
);
}
public static function logout(){
self::unsetLoginCookie();
$_SESSION = array();
}
public static function log($userID, $ipAddr) {
db::insert('MEMBER_LOGIN', array('MELO_IP' => $ipAddr, 'MELO_STAMP' => time(), 'MEMB_ID' => $userID));
}
public static function expireCookies($id) {
$db = Core::db();
$now = date("Y-m-d H:i:s", strtotime("-1 hours"));
$db->executeQuery("UPDATE COOKIE SET COOK_EXPIRE = $now WHERE MEMB_ID = $id");
}
}