Skip to content

Commit

Permalink
Merge branch 'main' into crossterm
Browse files Browse the repository at this point in the history
  • Loading branch information
conradludgate committed Feb 6, 2023
2 parents a40e41c + 5611bc5 commit 0b44eac
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 10 deletions.
74 changes: 74 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -72,6 +72,7 @@ whoami = "1.1.2"
rpassword = "7.0"
semver = "1.0.14"
runtime-format = "0.1.2"
tiny-bip39 = "1"

# from tui
bitflags = "1.3"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -9,7 +9,7 @@
<hr/>

<p align="center">
<a href="https://github.com/ellie/atuin/actions?query=workflow%3ARust"><img src="https://img.shields.io/github/workflow/status/ellie/atuin/Rust?style=flat-square" /></a>
<a href="https://github.com/ellie/atuin/actions?query=workflow%3ARust"><img src="https://img.shields.io/github/actions/workflow/status/ellie/atuin/rust.yml?style=flat-square" /></a>
<a href="https://crates.io/crates/atuin"><img src="https://img.shields.io/crates/v/atuin.svg?style=flat-square" /></a>
<a href="https://crates.io/crates/atuin"><img src="https://img.shields.io/crates/d/atuin.svg?style=flat-square" /></a>
<a href="https://github.com/ellie/atuin/blob/main/LICENSE"><img src="https://img.shields.io/crates/l/atuin.svg?style=flat-square" /></a>
Expand Down
3 changes: 1 addition & 2 deletions atuin-client/src/database.rs
Expand Up @@ -448,8 +448,7 @@ impl Database for Sqlite {
} else if let Some(term) = query_part.strip_prefix('\'') {
format!("{glob}{term}{glob}")
} else if is_inverse {
let term = query_part;
format!("{glob}{term}{glob}")
format!("{glob}{query_part}{glob}")
} else {
query_part.split("").join(glob)
};
Expand Down
1 change: 1 addition & 0 deletions atuin-client/src/encryption.rs
Expand Up @@ -66,6 +66,7 @@ pub fn load_encoded_key(settings: &Settings) -> Result<String> {
}
}

pub type Key = secretbox::Key;
pub fn encode_key(key: secretbox::Key) -> Result<String> {
let buf = rmp_serde::to_vec(&key).wrap_err("could not encode key to message pack")?;
let buf = base64::encode(buf);
Expand Down
2 changes: 1 addition & 1 deletion src/command/client/history.rs
Expand Up @@ -257,7 +257,7 @@ impl Cmd {
}
(Some(session), Some(cwd)) => {
let query = format!(
"select * from history where cwd = '{cwd}' and session = '{session}';"
"select * from history where cwd = '{cwd}' and session = '{session}';",
);
db.query_history(&query).await?
}
Expand Down
19 changes: 15 additions & 4 deletions src/command/client/sync.rs
Expand Up @@ -27,7 +27,11 @@ pub enum Cmd {
Register(register::Cmd),

/// Print the encryption key for transfer to another machine
Key,
Key {
/// Switch to base64 output of the key
#[arg(long)]
base64: bool,
},
}

impl Cmd {
Expand All @@ -37,11 +41,18 @@ impl Cmd {
Self::Login(l) => l.run(&settings).await,
Self::Logout => logout::run(),
Self::Register(r) => r.run(&settings).await,
Self::Key => {
Self::Key { base64 } => {
use atuin_client::encryption::{encode_key, load_key};
let key = load_key(&settings).wrap_err("could not load encryption key")?;
let encode = encode_key(key).wrap_err("could not encode encryption key")?;
println!("{encode}");

if base64 {
let encode = encode_key(key).wrap_err("could not encode encryption key")?;
println!("{encode}");
} else {
let mnemonic = bip39::Mnemonic::from_entropy(&key.0, bip39::Language::English)
.map_err(|_| eyre::eyre!("invalid key"))?;
println!("{mnemonic}");
}
Ok(())
}
}
Expand Down
54 changes: 52 additions & 2 deletions src/command/client/sync/login.rs
@@ -1,10 +1,14 @@
use std::io;

use clap::Parser;
use eyre::Result;
use eyre::{bail, ContextCompat, Result};
use tokio::{fs::File, io::AsyncWriteExt};

use atuin_client::{api_client, settings::Settings};
use atuin_client::{
api_client,
encryption::{encode_key, Key},
settings::Settings,
};
use atuin_common::api::LoginRequest;
use rpassword::prompt_password;

Expand Down Expand Up @@ -54,6 +58,31 @@ impl Cmd {

let key_path = settings.key_path.as_str();
let mut file = File::create(key_path).await?;

// try parse the key as a mnemonic...
let key = match bip39::Mnemonic::from_phrase(&key, bip39::Language::English) {
Ok(mnemonic) => encode_key(
Key::from_slice(mnemonic.entropy()).context("key was not the correct length")?,
)?,
Err(err) => {
if let Some(err) = err.downcast_ref::<bip39::ErrorKind>() {
match err {
// assume they copied in the base64 key
bip39::ErrorKind::InvalidWord => key,
bip39::ErrorKind::InvalidChecksum => bail!("key mnemonic was not valid"),
bip39::ErrorKind::InvalidKeysize(_)
| bip39::ErrorKind::InvalidWordLength(_)
| bip39::ErrorKind::InvalidEntropyLength(_, _) => {
bail!("key was not the correct length")
}
}
} else {
// unknown error. assume they copied the base64 key
key
}
}
};

file.write_all(key.as_bytes()).await?;

println!("Logged in!");
Expand All @@ -75,3 +104,24 @@ fn read_user_input(name: &'static str) -> String {
eprint!("Please enter {name}: ");
get_input().expect("Failed to read from input")
}

#[cfg(test)]
mod tests {
use atuin_client::encryption::Key;

#[test]
fn mnemonic_round_trip() {
let key = Key {
0: [
3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3,
2, 7, 9, 5,
],
};
let phrase = bip39::Mnemonic::from_entropy(&key.0, bip39::Language::English)
.unwrap()
.into_phrase();
let mnemonic = bip39::Mnemonic::from_phrase(&phrase, bip39::Language::English).unwrap();
assert_eq!(mnemonic.entropy(), &key.0);
assert_eq!(phrase, "adapt amused able anxiety mother adapt beef gaze amount else seat alcohol cage lottery avoid scare alcohol cactus school avoid coral adjust catch pink");
}
}

0 comments on commit 0b44eac

Please sign in to comment.