134 lines
3.6 KiB
PHP
134 lines
3.6 KiB
PHP
<?php
|
||
/**
|
||
* @package Bicycle
|
||
* @author Egor Isaev
|
||
* @description FileAuthDriver.php
|
||
* @copyright (c) 06/08/2026
|
||
*/
|
||
|
||
namespace Services\Auth;
|
||
|
||
use System\Classes\Config;
|
||
use System\Classes\Session;
|
||
|
||
/**
|
||
* Авторизация по списку пользователей из PHP-файла:
|
||
* return ['login' => ['password' => '<password_hash>', ...доп. поля], ...];
|
||
*
|
||
* Путь к файлу — Config::get('auth', 'users_file').
|
||
* Состояние авторизации хранится в сессии (логин текущего пользователя),
|
||
* ключ сессии — Config::get('auth', 'session_key') (по умолчанию 'auth_user').
|
||
*/
|
||
class FileAuthDriver implements AuthDriver
|
||
{
|
||
/** @var string|null Путь к файлу пользователей (если не передан — берётся из конфига) */
|
||
protected ?string $_users_file;
|
||
|
||
/** @var string Ключ сессии, под которым хранится логин авторизованного пользователя */
|
||
protected string $_session_key;
|
||
|
||
/**
|
||
* @param string|null $users_file Путь к файлу пользователей (для тестов/переопределения)
|
||
* @param string|null $session_key Ключ сессии (для тестов/переопределения)
|
||
*/
|
||
public function __construct(?string $users_file = null, ?string $session_key = null)
|
||
{
|
||
$this->_users_file = $users_file ?? Config::get('auth', 'users_file') ?? null;
|
||
$this->_session_key = $session_key ?? Config::get('auth', 'session_key') ?? 'auth_user';
|
||
}
|
||
|
||
/**
|
||
* Загружает список пользователей из файла (с полем 'password').
|
||
*
|
||
* @return array<string,array>
|
||
*/
|
||
protected function users(): array
|
||
{
|
||
if ($this->_users_file === null || !file_exists($this->_users_file)) {
|
||
return [];
|
||
}
|
||
|
||
return (array)(include $this->_users_file);
|
||
}
|
||
|
||
/**
|
||
* Логин текущего авторизованного пользователя из сессии.
|
||
*
|
||
* @return string|null
|
||
*/
|
||
protected function currentLogin(): ?string
|
||
{
|
||
return Session::instance()->get($this->_session_key);
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function login(string $login, string $password): bool
|
||
{
|
||
$user = $this->users()[$login] ?? null;
|
||
|
||
if ($user === null || !password_verify($password, $user['password'] ?? '')) {
|
||
return false;
|
||
}
|
||
|
||
Session::instance()->set($this->_session_key, $login);
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function logout(): void
|
||
{
|
||
Session::instance()->delete($this->_session_key);
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function loggedIn(): bool
|
||
{
|
||
return $this->getUser() !== null;
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function getUser(): ?array
|
||
{
|
||
$login = $this->currentLogin();
|
||
|
||
if ($login === null) {
|
||
return null;
|
||
}
|
||
|
||
$user = $this->users()[$login] ?? null;
|
||
|
||
if ($user === null) {
|
||
return null;
|
||
}
|
||
|
||
unset($user['password']);
|
||
|
||
return ['login' => $login] + $user;
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function checkPassword(string $password): bool
|
||
{
|
||
$login = $this->currentLogin();
|
||
|
||
if ($login === null) {
|
||
return false;
|
||
}
|
||
|
||
$hash = $this->users()[$login]['password'] ?? null;
|
||
|
||
return $hash !== null && password_verify($password, $hash);
|
||
}
|
||
}
|