87 lines
3 KiB
PHP
87 lines
3 KiB
PHP
<?php
|
|
namespace Hanyuu\Auth\Db;
|
|
|
|
use Index\XString;
|
|
use Index\Data\IDbConnection;
|
|
use Index\Data\IDbResult;
|
|
use Index\Data\DbType;
|
|
use Hanyuu\StatementCache;
|
|
use Hanyuu\Auth\IAuthLogin;
|
|
use Hanyuu\Auth\IAuthMethod;
|
|
use Hanyuu\Auth\Auth;
|
|
use Hanyuu\Users\IUserInfo;
|
|
|
|
class DbAuth extends Auth {
|
|
private const LOGINS_TABLE = 'hau_auth_logins';
|
|
|
|
private const LOGINS_FIELDS = [
|
|
'auth_login_id', 'user_id', 'auth_login_ip', 'auth_login_country',
|
|
'auth_login_factors_required', 'auth_login_factors_done',
|
|
'UNIX_TIMESTAMP(auth_login_started)', 'UNIX_TIMESTAMP(auth_login_valid)', 'UNIX_TIMESTAMP(auth_login_completed)',
|
|
];
|
|
|
|
private StatementCache $stmts;
|
|
|
|
public function __construct(
|
|
private IDbConnection $conn
|
|
) {
|
|
$this->stmts = new StatementCache($conn);
|
|
}
|
|
|
|
|
|
public function createLoginSession(
|
|
IUserInfo $userInfo,
|
|
string $remoteAddr,
|
|
string $countryCode,
|
|
int $factors
|
|
): string {
|
|
$loginId = XString::random(48);
|
|
|
|
$stmt = $this->stmts->getStatement('create login', function() {
|
|
return 'INSERT INTO ' . self::LOGINS_TABLE
|
|
. ' (auth_login_id, user_id, auth_login_ip, auth_login_country, auth_login_factors_required)'
|
|
. ' VALUES (?, ?, INET6_ATON(?), ?, ?)';
|
|
});
|
|
|
|
$stmt->addParameter(1, $loginId, DbType::STRING);
|
|
$stmt->addParameter(2, $userInfo->getId(), DbType::STRING);
|
|
$stmt->addParameter(3, $remoteAddr, DbType::STRING);
|
|
$stmt->addParameter(4, $countryCode, DbType::STRING);
|
|
$stmt->addParameter(5, $factors, DbType::INTEGER);
|
|
$stmt->execute();
|
|
|
|
return $loginId;
|
|
}
|
|
|
|
public function destroyLoginSession(IAuthLogin $loginInfo): void {
|
|
$stmt = $this->stmts->getStatement('destroy login', fn() => ('DELETE FROM ' . self::LOGINS_TABLE . ' WHERE auth_login_id = ?'));
|
|
$stmt->addParameter(1, $loginInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
}
|
|
|
|
private function fetchLoginSingle(IDbResult $result, string $exceptionText): IUserInfo {
|
|
if(!$result->next())
|
|
throw new AuthLoginNotFoundException($exceptionText);
|
|
|
|
return new DbUserInfo($result);
|
|
}
|
|
|
|
public function getLoginSessionById(string $loginId): ?IAuthLogin {
|
|
$stmt = $this->stmts->getStatement('get login by id', fn() => ('SELECT ' . implode(',', self::LOGINS_FIELDS) . ' FROM ' . self::LOGINS_TABLE . ' WHERE auth_login_id = ?'));
|
|
$stmt->addParameter(1, $loginId, DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
if(!$result->next())
|
|
return null;
|
|
|
|
return new DbAuthLogin($result);
|
|
}
|
|
|
|
public function incrementLoginSessionDone(IAuthLogin $login): void {
|
|
$stmt = $this->stmts->getStatement('increment login done', fn() => ('UPDATE ' . self::LOGINS_TABLE . ' SET auth_login_factors_done = auth_login_factors_done + 1 WHERE auth_login_id = ?'));
|
|
$stmt->addParameter(1, $login->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
}
|
|
}
|