From 5a4c4b9fa0df891fcdd9beee18be0db4a45da701 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Thu, 11 Jun 2026 16:27:35 +0200 Subject: chore(server): Remove the last remnants of the "hub" sync-server thingy --- crates/turtle/src/atuin_client/auth.rs | 94 ++++++++++------------------------ 1 file changed, 26 insertions(+), 68 deletions(-) (limited to 'crates/turtle/src/atuin_client') diff --git a/crates/turtle/src/atuin_client/auth.rs b/crates/turtle/src/atuin_client/auth.rs index b260d433..620e127e 100644 --- a/crates/turtle/src/atuin_client/auth.rs +++ b/crates/turtle/src/atuin_client/auth.rs @@ -1,4 +1,3 @@ -use async_trait::async_trait; use eyre::{Context, Result, bail}; use reqwest::{Url, header::USER_AGENT}; @@ -14,66 +13,19 @@ use crate::atuin_client::settings::Settings; static APP_USER_AGENT: &str = concat!("atuin/", env!("CARGO_PKG_VERSION")); -/// Result of an auth operation that may require 2FA. -pub(crate) enum AuthResponse { - /// Operation succeeded; for login/register, contains the session token. - /// `auth_type` indicates the kind of token: `Some("hub")` for Hub API - /// tokens (prefixed `atapi_`), `Some("cli")` for legacy CLI session - /// tokens. `None` when the server didn't include the field (old servers). - Success { - session: String, - auth_type: Option, - }, - /// Two-factor authentication is required; the caller should prompt for a - /// TOTP code and retry with it. - TwoFactorRequired, -} - -/// Result of a mutating account operation that may require 2FA. -pub(crate) enum MutateResponse { - /// Operation completed successfully. - Success, - /// Two-factor authentication is required; the caller should prompt for a - /// TOTP code and retry. - TwoFactorRequired, -} - -/// Abstraction over the legacy (Rust sync server) and Hub auth APIs. -/// -/// CLI commands use this trait so they don't need to know which backend is -/// active — they just prompt for input and call these methods. -#[async_trait] -pub(crate) trait AuthClient: Send + Sync { - /// Log in with username + password, optionally providing a TOTP code. - async fn login(&self, username: &str, password: &str) -> Result; - - /// Register a new account. - async fn register(&self, username: &str, email: &str, password: &str) -> Result; - - /// Change the account password, optionally providing a TOTP code. - async fn change_password( - &self, - current_password: &str, - new_password: &str, - totp_code: Option<&str>, - ) -> Result; - - /// Delete the account, requiring the current password and optionally a TOTP code. - async fn delete_account( - &self, - password: &str, - totp_code: Option<&str>, - ) -> Result; +/// Result of an auth operation +pub(crate) struct AuthResponse { + pub(crate) session: String, } /// Resolve the appropriate [`AuthClient`] for the current settings. -pub(crate) async fn auth_client(settings: &Settings) -> Box { - Box::new(LegacyAuthClient::new( +pub(crate) async fn auth_client(settings: &Settings) -> LegacyAuthClient { + LegacyAuthClient::new( &settings.sync_address, settings.session_token().await.ok(), settings.network_connect_timeout, settings.network_timeout, - )) as Box + ) } // --------------------------------------------------------------------------- @@ -125,9 +77,9 @@ impl LegacyAuthClient { } } -#[async_trait] -impl AuthClient for LegacyAuthClient { - async fn login(&self, username: &str, password: &str) -> Result { +impl LegacyAuthClient { + /// Log in with username + password, optionally providing a TOTP code. + pub(crate) async fn login(&self, username: &str, password: &str) -> Result { // The legacy server has no 2FA support; totp_code is ignored. let resp = api_client::login( &self.address, @@ -138,26 +90,31 @@ impl AuthClient for LegacyAuthClient { ) .await?; - Ok(AuthResponse::Success { + Ok(AuthResponse { session: resp.session, - auth_type: resp.auth.or(Some("cli".into())), }) } - async fn register(&self, username: &str, email: &str, password: &str) -> Result { + /// Register a new account. + pub(crate) async fn register( + &self, + username: &str, + email: &str, + password: &str, + ) -> Result { let resp = api_client::register(&self.address, username, email, password).await?; - Ok(AuthResponse::Success { + Ok(AuthResponse { session: resp.session, - auth_type: resp.auth.or(Some("cli".into())), }) } - async fn change_password( + /// Change the account password, optionally providing a TOTP code. + pub(crate) async fn change_password( &self, current_password: &str, new_password: &str, _totp_code: Option<&str>, - ) -> Result { + ) -> Result<()> { let client = self.authenticated_client()?; let url = make_url(&self.address, "/account/password")?; @@ -171,18 +128,19 @@ impl AuthClient for LegacyAuthClient { .await?; match resp.status().as_u16() { - 200 => Ok(MutateResponse::Success), + 200 => Ok(()), 401 => bail!("current password is incorrect"), 403 => bail!("invalid login details"), _ => bail!("unknown error"), } } - async fn delete_account( + /// Delete the account, requiring the current password and optionally a TOTP code. + pub(crate) async fn delete_account( &self, password: &str, _totp_code: Option<&str>, - ) -> Result { + ) -> Result<()> { let client = self.authenticated_client()?; let url = make_url(&self.address, "/account")?; @@ -193,7 +151,7 @@ impl AuthClient for LegacyAuthClient { .await?; match resp.status().as_u16() { - 200 => Ok(MutateResponse::Success), + 200 => Ok(()), 401 => bail!("password is incorrect"), 403 => bail!("invalid login details"), _ => bail!("unknown error"), -- cgit v1.3.1