Files
telegram-tui/src/tdlib/auth.rs
Mikhail Kilin 3b7ef41cae
Some checks failed
ci/woodpecker/pr/check Pipeline was successful
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
fix: resolve all 40 clippy warnings (dead_code, unused_imports, lints)
- Add #[allow(unused_imports)] on pub re-exports used only by lib/tests
- Add #[allow(dead_code)] on public API items unused in binary target
- Fix collapsible_if, redundant_closure, unnecessary_map_or in main.rs
- Prefix unused test variables with underscore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 17:50:18 +03:00

216 lines
8.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use tdlib_rs::enums::{AuthorizationState, Update};
use tdlib_rs::functions;
/// Состояние процесса авторизации в Telegram.
///
/// Отслеживает текущий этап аутентификации пользователя,
/// от инициализации TDLib до полной авторизации.
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub enum AuthState {
/// Ожидание параметров TDLib (начальное состояние).
WaitTdlibParameters,
/// Ожидание ввода номера телефона.
WaitPhoneNumber,
/// Ожидание ввода кода подтверждения из SMS/Telegram.
WaitCode,
/// Ожидание ввода пароля двухфакторной аутентификации (2FA).
WaitPassword,
/// Авторизация завершена, клиент готов к работе.
Ready,
/// Соединение закрыто.
Closed,
/// Произошла ошибка авторизации.
Error(String),
}
/// Менеджер авторизации TDLib.
///
/// Управляет процессом авторизации пользователя в Telegram,
/// отслеживает текущее состояние и предоставляет методы
/// для отправки учетных данных (номер телефона, код, пароль).
///
/// # Процесс авторизации
///
/// 1. `WaitTdlibParameters` → автоматически
/// 2. `WaitPhoneNumber` → [`send_phone_number()`](Self::send_phone_number)
/// 3. `WaitCode` → [`send_code()`](Self::send_code)
/// 4. `WaitPassword` (опционально) → [`send_password()`](Self::send_password)
/// 5. `Ready` → авторизация завершена
///
/// # Examples
///
/// ```ignore
/// let mut auth_manager = AuthManager::new(client_id);
///
/// // Отправляем номер телефона
/// auth_manager.send_phone_number("+1234567890".to_string()).await?;
///
/// // После получения кода из SMS
/// auth_manager.send_code("12345".to_string()).await?;
///
/// // Если включена 2FA
/// if auth_manager.state == AuthState::WaitPassword {
/// auth_manager.send_password("my_password".to_string()).await?;
/// }
///
/// // Проверяем авторизацию
/// if auth_manager.is_authenticated() {
/// println!("Successfully authenticated!");
/// }
/// ```
pub struct AuthManager {
/// Текущее состояние авторизации.
pub state: AuthState,
/// ID клиента TDLib для API вызовов.
client_id: i32,
}
#[allow(dead_code)]
impl AuthManager {
/// Создает новый менеджер авторизации.
///
/// # Arguments
///
/// * `client_id` - ID клиента TDLib для API вызовов
///
/// # Returns
///
/// Новый экземпляр `AuthManager` в состоянии `WaitTdlibParameters`.
pub fn new(client_id: i32) -> Self {
Self { state: AuthState::WaitTdlibParameters, client_id }
}
/// Проверяет, завершена ли авторизация.
///
/// # Returns
///
/// `true` если состояние равно `AuthState::Ready`, иначе `false`.
///
/// # Examples
///
/// ```ignore
/// if auth_manager.is_authenticated() {
/// println!("User is authenticated");
/// }
/// ```
pub fn is_authenticated(&self) -> bool {
self.state == AuthState::Ready
}
/// Обрабатывает обновление состояния авторизации от TDLib.
///
/// Автоматически обновляет внутреннее состояние [`AuthState`] на основе
/// полученного update от TDLib.
///
/// # Arguments
///
/// * `update` - Обновление от TDLib (проверяется на `Update::AuthorizationState`)
///
/// # Note
///
/// Этот метод должен вызываться для каждого update от TDLib,
/// чтобы состояние авторизации оставалось актуальным.
pub fn handle_auth_update(&mut self, update: &Update) {
if let Update::AuthorizationState(auth_update) = update {
self.state = match &auth_update.authorization_state {
AuthorizationState::WaitTdlibParameters => AuthState::WaitTdlibParameters,
AuthorizationState::WaitPhoneNumber => AuthState::WaitPhoneNumber,
AuthorizationState::WaitCode(_) => AuthState::WaitCode,
AuthorizationState::WaitPassword(_) => AuthState::WaitPassword,
AuthorizationState::Ready => AuthState::Ready,
AuthorizationState::Closed => AuthState::Closed,
_ => return,
};
}
}
/// Отправляет номер телефона для авторизации.
///
/// Используется на этапе [`AuthState::WaitPhoneNumber`].
/// После успешной отправки состояние изменится на `WaitCode`.
///
/// # Arguments
///
/// * `phone` - Номер телефона в международном формате (например, "+1234567890")
///
/// # Returns
///
/// * `Ok(())` - Номер телефона принят, ожидайте SMS с кодом
/// * `Err(String)` - Ошибка (неверный формат, проблемы с сетью и т.д.)
///
/// # Examples
///
/// ```ignore
/// auth_manager.send_phone_number("+1234567890".to_string()).await?;
/// ```
pub async fn send_phone_number(&self, phone: String) -> Result<(), String> {
functions::set_authentication_phone_number(phone, None, self.client_id)
.await
.map(|_| ())
.map_err(|e| format!("Ошибка отправки номера: {:?}", e))
}
/// Отправляет код подтверждения из SMS или Telegram.
///
/// Используется на этапе [`AuthState::WaitCode`].
/// После успешной проверки состояние изменится на `Ready` или `WaitPassword`
/// (если включена двухфакторная аутентификация).
///
/// # Arguments
///
/// * `code` - Код подтверждения (обычно 5 цифр)
///
/// # Returns
///
/// * `Ok(())` - Код верный
/// * `Err(String)` - Неверный код или истек срок действия
///
/// # Examples
///
/// ```ignore
/// auth_manager.send_code("12345".to_string()).await?;
/// ```
pub async fn send_code(&self, code: String) -> Result<(), String> {
functions::check_authentication_code(code, self.client_id)
.await
.map(|_| ())
.map_err(|e| format!("Ошибка проверки кода: {:?}", e))
}
/// Отправляет пароль двухфакторной аутентификации (2FA).
///
/// Используется на этапе [`AuthState::WaitPassword`] (только если 2FA включена).
/// После успешной проверки состояние изменится на `Ready`.
///
/// # Arguments
///
/// * `password` - Пароль двухфакторной аутентификации
///
/// # Returns
///
/// * `Ok(())` - Пароль верный, авторизация завершена
/// * `Err(String)` - Неверный пароль
///
/// # Examples
///
/// ```ignore
/// if auth_manager.state == AuthState::WaitPassword {
/// auth_manager.send_password("my_2fa_password".to_string()).await?;
/// }
/// ```
pub async fn send_password(&self, password: String) -> Result<(), String> {
functions::check_authentication_password(password, self.client_id)
.await
.map(|_| ())
.map_err(|e| format!("Ошибка проверки пароля: {:?}", e))
}
}