2023-01-09 21:44:34 +00:00
< ? php
2023-10-20 22:11:43 +00:00
namespace Hanyuu\Users ;
2023-01-09 21:44:34 +00:00
use RuntimeException ;
use Index\Data\IDbConnection ;
use Index\Data\IDbStatement ;
use Index\Data\IDbResult ;
2023-10-18 10:34:30 +00:00
use Hanyuu\StatementCache ;
use Hanyuu\Auth\IAuthMethod ;
use Hanyuu\Auth\Auth ;
2023-10-20 22:11:43 +00:00
use Hanyuu\Users\UserInfo ;
use Hanyuu\Users\UserPasswordInfo ;
use Hanyuu\Users\UserTOTPInfo ;
2023-01-09 21:44:34 +00:00
2023-10-20 22:11:43 +00:00
class Users {
2023-01-09 21:44:34 +00:00
private const USERS_TABLE = 'hau_users' ;
2023-10-18 10:34:30 +00:00
private const TFA_TABLE = 'hau_users_tfa' ;
2023-01-09 21:44:34 +00:00
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)' ,
];
2023-10-18 10:34:30 +00:00
private const TFA_FIELDS = [
'user_id' , 'user_tfa_type' , 'UNIX_TIMESTAMP(user_tfa_enabled)' ,
2023-01-09 21:44:34 +00:00
];
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)' ,
];
2023-10-18 10:34:30 +00:00
private StatementCache $stmts ;
2023-01-09 21:44:34 +00:00
public function __construct (
private IDbConnection $conn
2023-10-18 10:34:30 +00:00
) {
$this -> stmts = new StatementCache ( $conn );
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
private function fetchUserInfoSingle ( IDbResult $result , string $exceptionText ) : UserInfo {
2023-01-09 21:44:34 +00:00
if ( ! $result -> next ())
2023-10-20 22:11:43 +00:00
throw new RuntimeException ( $exceptionText );
2023-01-09 21:44:34 +00:00
2023-10-20 22:11:43 +00:00
return new UserInfo ( $result );
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
public function getUserInfoById ( string $userId ) : UserInfo {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get info by id' , fn () => ( 'SELECT ' . implode ( ',' , self :: USERS_FIELDS ) . ' FROM ' . self :: USERS_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userId );
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
return $this -> fetchUserInfoSingle ( $stmt -> getResult (), 'no user with $userId found' );
}
2023-10-20 22:11:43 +00:00
public function getUserInfoByName ( string $userName ) : UserInfo {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get info by name' , fn () => ( 'SELECT ' . implode ( ',' , self :: USERS_FIELDS ) . ' FROM ' . self :: USERS_TABLE . ' WHERE user_name = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userName );
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
return $this -> fetchUserInfoSingle ( $stmt -> getResult (), 'no user with $userName found' );
}
2023-10-20 22:11:43 +00:00
public function countUserTFAMethods ( UserInfo $userInfo ) : int {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'count user tfa methods' , fn () => ( 'SELECT COUNT(*) FROM ' . self :: TFA_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
2023-10-18 10:34:30 +00:00
$stmt -> execute ();
$result = $stmt -> getResult ();
2023-01-09 21:44:34 +00:00
2023-10-18 10:34:30 +00:00
return $result -> next () ? $result -> getInteger ( 0 ) : 0 ;
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
public function getUserTFAMethods ( UserInfo $userInfo ) : array {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get user tfa methods' , fn () => ( 'SELECT ' . implode ( ',' , self :: TFA_FIELDS ) . ' FROM ' . self :: TFA_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
2023-10-18 10:34:30 +00:00
$result = $stmt -> getResult ();
$array = [];
while ( $result -> next ())
2023-10-20 22:11:43 +00:00
$array [] = new UserAuthInfo ( $result );
2023-10-18 10:34:30 +00:00
return $array ;
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
public function checkUserTFAMethod ( UserInfo $userInfo , IAuthMethod $method ) : bool {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'check user auth method' , fn () => ( 'SELECT COUNT(*) FROM ' . self :: TFA_TABLE . ' WHERE user_id = ? AND user_tfa_type = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
$stmt -> addParameter ( 2 , $method -> getName ());
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
2023-10-18 10:34:30 +00:00
$result = $stmt -> getResult ();
2023-01-09 21:44:34 +00:00
2023-10-18 10:34:30 +00:00
return $result -> next () ? $result -> getInteger ( 0 ) !== 0 : false ;
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
public function getUserPasswordInfo ( UserInfo $userInfo ) : UserPasswordInfo {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get pwd' , fn () => ( 'SELECT ' . implode ( ',' , self :: PASSWORDS_FIELDS ) . ' FROM ' . self :: PASSWORDS_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
$result = $stmt -> getResult ();
if ( ! $result -> next ())
throw new RuntimeException ( 'no password info for $userInfo found' );
2023-10-20 22:11:43 +00:00
return new UserPasswordInfo ( $result );
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
public function getUserTOTPInfo ( UserInfo $userInfo ) : UserTOTPInfo {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get totp' , fn () => ( 'SELECT ' . implode ( ',' , self :: TOTP_FIELDS ) . ' FROM ' . self :: TOTP_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
$result = $stmt -> getResult ();
if ( ! $result -> next ())
throw new RuntimeException ( 'no totp info for $userInfo found' );
2023-10-20 22:11:43 +00:00
return new UserTOTPInfo ( $result );
2023-01-09 21:44:34 +00:00
}
2023-10-20 22:11:43 +00:00
public function getUserEMailInfos ( UserInfo $userInfo ) : array {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get emails' , fn () => ( 'SELECT ' . implode ( ',' , self :: EMAILS_FIELDS ) . ' FROM ' . self :: EMAILS_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
$result = $stmt -> getResult ();
$array = [];
while ( $result -> next ())
2023-10-20 22:11:43 +00:00
$array [] = new UserEMailInfo ( $result );
2023-01-09 21:44:34 +00:00
return $array ;
}
2023-10-20 22:11:43 +00:00
public function getUserBackupInfos ( UserInfo $userInfo ) : array {
2023-10-18 10:34:30 +00:00
$stmt = $this -> stmts -> getStatement ( 'get backups' , fn () => ( 'SELECT ' . implode ( ',' , self :: BACKUP_FIELDS ) . ' FROM ' . self :: BACKUP_TABLE . ' WHERE user_id = ?' ));
2023-10-20 22:11:43 +00:00
$stmt -> addParameter ( 1 , $userInfo -> getId ());
2023-01-09 21:44:34 +00:00
$stmt -> execute ();
$result = $stmt -> getResult ();
$array = [];
while ( $result -> next ())
2023-10-20 22:11:43 +00:00
$array [] = new UserBackupInfo ( $result );
2023-01-09 21:44:34 +00:00
return $array ;
}
}