-
-
Notifications
You must be signed in to change notification settings - Fork 637
/
Copy pathlogin.rs
86 lines (72 loc) · 2.74 KB
/
login.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::path::PathBuf;
use atuin_common::api::LoginRequest;
use eyre::{Context, Result, bail};
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
use crate::{
api_client,
encryption::{Key, decode_key, encode_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> {
// 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()))?,
Err(err) => {
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")
}
}
}
};
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(¤t_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?;
let session_path = settings.session_path.as_str();
let mut file = File::create(session_path).await?;
file.write_all(session.session.as_bytes()).await?;
Ok(session.session)
}