aboutsummaryrefslogtreecommitdiffstats
path: root/crates/turtle/src/atuin_client/login.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/turtle/src/atuin_client/login.rs')
-rw-r--r--crates/turtle/src/atuin_client/login.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/crates/turtle/src/atuin_client/login.rs b/crates/turtle/src/atuin_client/login.rs
new file mode 100644
index 00000000..ca4e16fe
--- /dev/null
+++ b/crates/turtle/src/atuin_client/login.rs
@@ -0,0 +1,68 @@
+use std::path::PathBuf;
+
+use crate::atuin_common::api::LoginRequest;
+use eyre::{Context, Result, bail};
+use tokio::fs::File;
+use tokio::io::AsyncWriteExt;
+
+use crate::atuin_client::{
+ api_client,
+ encryption::{decode_key, load_key},
+ record::{sqlite_store::SqliteStore, store::Store},
+ settings::Settings,
+};
+
+pub async fn login(
+ settings: &Settings,
+ store: &SqliteStore,
+ username: String,
+ password: String,
+ key: String,
+) -> Result<String> {
+ let key_path = settings.key_path.as_str();
+ let key_path = PathBuf::from(key_path);
+
+ if !key_path.exists() {
+ if decode_key(key.clone()).is_err() {
+ bail!("the specified key was invalid");
+ }
+
+ let mut file = File::create(&key_path).await?;
+ file.write_all(key.as_bytes()).await?;
+ } else {
+ // we now know that the user has logged in specifying a key, AND that the key path
+ // exists
+
+ // 1. check if the saved key and the provided key match. if so, nothing to do.
+ // 2. if not, re-encrypt the local history and overwrite the key
+ let current_key: [u8; 32] = load_key(settings)?.into();
+
+ let encoded = key.clone(); // gonna want to save it in a bit
+ let new_key: [u8; 32] = decode_key(key)
+ .context("could not decode provided key - is not valid base64")?
+ .into();
+
+ if new_key != current_key {
+ println!("\nRe-encrypting local store with new key");
+
+ store.re_encrypt(&current_key, &new_key).await?;
+
+ println!("Writing new key");
+ let mut file = File::create(&key_path).await?;
+ file.write_all(encoded.as_bytes()).await?;
+ }
+ }
+
+ let session = api_client::login(
+ settings.sync_address.as_str(),
+ LoginRequest { username, password },
+ )
+ .await?;
+
+ Settings::meta_store()
+ .await?
+ .save_session(&session.session)
+ .await?;
+
+ Ok(session.session)
+}