171 lines
6.4 KiB
PHP
171 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\Users\IUsers;
|
|
use Hanyuu\Users\IUserInfo;
|
|
use Hanyuu\Users\IUserPasswordInfo;
|
|
use Hanyuu\Users\IUserTOTPInfo;
|
|
|
|
class DbUsers implements IUsers {
|
|
private const USERS_TABLE = 'hau_users';
|
|
private const AUTH_TABLE = 'hau_users_auth';
|
|
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 AUTH_FIELDS = [
|
|
'user_id', 'user_auth_type', 'UNIX_TIMESTAMP(user_auth_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 const FIRST_FACTOR_AUTH = ['pwd'];
|
|
private const SECOND_FACTOR_AUTH = ['totp'];
|
|
|
|
public function __construct(
|
|
private IDbConnection $conn
|
|
) {}
|
|
|
|
private array $statements = [];
|
|
|
|
private function getStatement(string $name, callable $query): IDbStatement {
|
|
if(array_key_exists($name, $this->statements))
|
|
return $this->statements[$name];
|
|
return $this->statements[$name] = $this->conn->prepare($query());
|
|
}
|
|
|
|
|
|
private function fetchUserInfoSingle(IDbResult $result, string $exceptionText): IUserInfo {
|
|
if(!$result->next())
|
|
throw new RuntimeException($exceptionText);
|
|
|
|
return new DbUserInfo($result);
|
|
}
|
|
|
|
public function getUserInfoById(string $userId): IUserInfo {
|
|
$stmt = $this->getStatement('get info by id', fn() => ('SELECT ' . implode(',', self::USERS_FIELDS) . ' FROM ' . self::USERS_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->reset();
|
|
$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->getStatement('get info by name', fn() => ('SELECT ' . implode(',', self::USERS_FIELDS) . ' FROM ' . self::USERS_TABLE . ' WHERE user_name = ?'));
|
|
$stmt->reset();
|
|
$stmt->addParameter(1, $userName, DbType::STRING);
|
|
$stmt->execute();
|
|
|
|
return $this->fetchUserInfoSingle($stmt->getResult(), 'no user with $userName found');
|
|
}
|
|
|
|
|
|
private function fetchAuthInfoMultiple(IDbResult $result): array {
|
|
$array = [];
|
|
|
|
while($result->next())
|
|
$array[] = new DbUserAuthInfo($result);
|
|
|
|
return $array;
|
|
}
|
|
|
|
public function getUserFirstFactorAuthInfos(IUserInfo $userInfo): array {
|
|
$stmt = $this->getStatement('get auth first', fn() => ('SELECT ' . implode(',', self::AUTH_FIELDS) . ' FROM ' . self::AUTH_TABLE . ' WHERE user_id = ? AND user_auth_type IN ("' . implode('", "', self::FIRST_FACTOR_AUTH) . '")'));
|
|
$stmt->reset();
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
|
|
return $this->fetchAuthInfoMultiple($stmt->getResult());
|
|
}
|
|
|
|
public function getUserSecondFactorAuthInfos(IUserInfo $userInfo): array {
|
|
$stmt = $this->getStatement('get auth second', fn() => ('SELECT ' . implode(',', self::AUTH_FIELDS) . ' FROM ' . self::AUTH_TABLE . ' WHERE user_id = ? AND user_auth_type IN ("' . implode('", "', self::SECOND_FACTOR_AUTH) . '")'));
|
|
$stmt->reset();
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
|
|
return $this->fetchAuthInfoMultiple($stmt->getResult());
|
|
}
|
|
|
|
|
|
public function getUserPasswordInfo(IUserInfo $userInfo): IUserPasswordInfo {
|
|
$stmt = $this->getStatement('get pwd', fn() => ('SELECT ' . implode(',', self::PASSWORDS_FIELDS) . ' FROM ' . self::PASSWORDS_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->reset();
|
|
$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->getStatement('get totp', fn() => ('SELECT ' . implode(',', self::TOTP_FIELDS) . ' FROM ' . self::TOTP_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->reset();
|
|
$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->getStatement('get emails', fn() => ('SELECT ' . implode(',', self::EMAILS_FIELDS) . ' FROM ' . self::EMAILS_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->reset();
|
|
$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->getStatement('get backups', fn() => ('SELECT ' . implode(',', self::BACKUP_FIELDS) . ' FROM ' . self::BACKUP_TABLE . ' WHERE user_id = ?'));
|
|
$stmt->reset();
|
|
$stmt->addParameter(1, $userInfo->getId(), DbType::STRING);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
$array = [];
|
|
|
|
while($result->next())
|
|
$array[] = new DbUserBackupInfo($result);
|
|
|
|
return $array;
|
|
}
|
|
}
|