167 lines
6.4 KiB
PHP
167 lines
6.4 KiB
PHP
<?php
|
|
namespace Hanyuu\Users\Db;
|
|
|
|
use RuntimeException;
|
|
use Index\Data\IDbConnection;
|
|
use Index\Data\IDbStatement;
|
|
use Index\Data\IDbResult;
|
|
use Index\Data\DbType;
|
|
use Hanyuu\StatementCache;
|
|
use Hanyuu\Auth\IAuthMethod;
|
|
use Hanyuu\Auth\Auth;
|
|
use Hanyuu\Users\IUsers;
|
|
use Hanyuu\Users\IUserInfo;
|
|
use Hanyuu\Users\IUserPasswordInfo;
|
|
use Hanyuu\Users\IUserTOTPInfo;
|
|
use Hanyuu\Users\UserNotFoundException;
|
|
|
|
class DbUsers implements IUsers {
|
|
private const USERS_TABLE = 'hau_users';
|
|
private const TFA_TABLE = 'hau_users_tfa';
|
|
private const BACKUP_TABLE = 'hau_users_backup';
|
|
private const EMAILS_TABLE = 'hau_users_emails';
|
|
private const PASSWORDS_TABLE = 'hau_users_passwords';
|
|
private const TOTP_TABLE = 'hau_users_totp';
|
|
|
|
private const USERS_FIELDS = [
|
|
'user_id', 'user_name', 'user_country', 'user_colour', 'user_super', 'user_time_zone',
|
|
'UNIX_TIMESTAMP(user_created)', 'UNIX_TIMESTAMP(user_updated)', 'UNIX_TIMESTAMP(user_deleted)',
|
|
];
|
|
private const TFA_FIELDS = [
|
|
'user_id', 'user_tfa_type', 'UNIX_TIMESTAMP(user_tfa_enabled)',
|
|
];
|
|
private const PASSWORDS_FIELDS = [
|
|
'user_id', 'user_password_hash', 'UNIX_TIMESTAMP(user_password_changed)',
|
|
];
|
|
private const TOTP_FIELDS = [
|
|
'user_id', 'user_totp_key', 'UNIX_TIMESTAMP(user_totp_changed)',
|
|
];
|
|
private const EMAILS_FIELDS = [
|
|
'user_id', 'user_email_address', 'UNIX_TIMESTAMP(user_email_created)', 'UNIX_TIMESTAMP(user_email_verified)', 'user_email_recovery',
|
|
];
|
|
private const BACKUP_FIELDS = [
|
|
'user_id', 'user_backup_code', 'UNIX_TIMESTAMP(user_backup_created)', 'UNIX_TIMESTAMP(user_backup_used)',
|
|
];
|
|
|
|
private StatementCache $stmts;
|
|
|
|
public function __construct(
|
|
private IDbConnection $conn
|
|
) {
|
|
$this->stmts = new StatementCache($conn);
|
|
}
|
|
|
|
private function fetchUserInfoSingle(IDbResult $result, string $exceptionText): IUserInfo {
|
|
if(!$result->next())
|
|
throw new UserNotFoundException($exceptionText);
|
|
|
|
return new DbUserInfo($result);
|
|
}
|
|
|
|
public function getUserInfoById(string $userId): IUserInfo {
|
|
$stmt = $this->stmts->getStatement('get info by id', fn() => ('SELECT ' . implode(',', self::USERS_FIELDS) . ' FROM ' . self::USERS_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userId, DbType::STRING);
|
|
$stmt->execute();
|
|
|
|
return $this->fetchUserInfoSingle($stmt->getResult(), 'no user with $userId found');
|
|
}
|
|
|
|
public function getUserInfoByName(string $userName): IUserInfo {
|
|
$stmt = $this->stmts->getStatement('get info by name', fn() => ('SELECT ' . implode(',', self::USERS_FIELDS) . ' FROM ' . self::USERS_TABLE . ' WHERE user_name = ?'));
|
|
$stmt->addParameter(1, $userName, DbType::STRING);
|
|
$stmt->execute();
|
|
|
|
return $this->fetchUserInfoSingle($stmt->getResult(), 'no user with $userName found');
|
|
}
|
|
|
|
|
|
public function countUserTFAMethods(IUserInfo $userInfo): int {
|
|
$stmt = $this->stmts->getStatement('count user tfa methods', fn() => ('SELECT COUNT(*) FROM ' . self::TFA_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
return $result->next() ? $result->getInteger(0) : 0;
|
|
}
|
|
|
|
public function getUserTFAMethods(IUserInfo $userInfo): array {
|
|
$stmt = $this->stmts->getStatement('get user tfa methods', fn() => ('SELECT ' . implode(',', self::TFA_FIELDS) . ' FROM ' . self::TFA_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
$array = [];
|
|
|
|
while($result->next())
|
|
$array[] = new DbUserAuthInfo($result);
|
|
|
|
return $array;
|
|
}
|
|
|
|
public function checkUserTFAMethod(IUserInfo $userInfo, IAuthMethod $method): bool {
|
|
$stmt = $this->stmts->getStatement('check user auth method', fn() => ('SELECT COUNT(*) FROM ' . self::TFA_TABLE . ' WHERE user_id = ? AND user_tfa_type = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->addParameter(2, $method->getName(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
return $result->next() ? $result->getInteger(0) !== 0 : false;
|
|
}
|
|
|
|
|
|
public function getUserPasswordInfo(IUserInfo $userInfo): IUserPasswordInfo {
|
|
$stmt = $this->stmts->getStatement('get pwd', fn() => ('SELECT ' . implode(',', self::PASSWORDS_FIELDS) . ' FROM ' . self::PASSWORDS_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
if(!$result->next())
|
|
throw new RuntimeException('no password info for $userInfo found');
|
|
|
|
return new DbUserPasswordInfo($result);
|
|
}
|
|
|
|
|
|
public function getUserTOTPInfo(IUserInfo $userInfo): IUserTOTPInfo {
|
|
$stmt = $this->stmts->getStatement('get totp', fn() => ('SELECT ' . implode(',', self::TOTP_FIELDS) . ' FROM ' . self::TOTP_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
if(!$result->next())
|
|
throw new RuntimeException('no totp info for $userInfo found');
|
|
|
|
return new DbUserTOTPInfo($result);
|
|
}
|
|
|
|
|
|
public function getUserEMailInfos(IUserInfo $userInfo): array {
|
|
$stmt = $this->stmts->getStatement('get emails', fn() => ('SELECT ' . implode(',', self::EMAILS_FIELDS) . ' FROM ' . self::EMAILS_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
$array = [];
|
|
|
|
while($result->next())
|
|
$array[] = new DbUserEMailInfo($result);
|
|
|
|
return $array;
|
|
}
|
|
|
|
|
|
public function getUserBackupInfos(IUserInfo $userInfo): array {
|
|
$stmt = $this->stmts->getStatement('get backups', fn() => ('SELECT ' . implode(',', self::BACKUP_FIELDS) . ' FROM ' . self::BACKUP_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
$array = [];
|
|
|
|
while($result->next())
|
|
$array[] = new DbUserBackupInfo($result);
|
|
|
|
return $array;
|
|
}
|
|
}
|