Add logout, only login if not already logged in (#91)

Also:
- Ensures that a key is generated as soon as a user registers!
- Ensures that "atuin key" will generate a key if needed, and doesn't
  double base64 encode data

And a few other little fixes :)

Resolves #85
Resolves #86
This commit is contained in:
Ellie Huxtable 2021-05-09 20:11:17 +01:00 committed by GitHub
parent af707ac5a4
commit e43e5ce74a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 14 deletions

View file

@ -24,23 +24,30 @@ pub struct EncryptedHistory {
pub nonce: secretbox::Nonce, pub nonce: secretbox::Nonce,
} }
pub fn new_key(settings: &Settings) -> Result<secretbox::Key> {
let path = settings.key_path.as_str();
let key = secretbox::gen_key();
let encoded = encode_key(key.clone())?;
let mut file = File::create(path)?;
file.write_all(encoded.as_bytes())?;
Ok(key)
}
// Loads the secret key, will create + save if it doesn't exist // Loads the secret key, will create + save if it doesn't exist
pub fn load_key(settings: &Settings) -> Result<secretbox::Key> { pub fn load_key(settings: &Settings) -> Result<secretbox::Key> {
let path = settings.key_path.as_str(); let path = settings.key_path.as_str();
if PathBuf::from(path).exists() { let key = if PathBuf::from(path).exists() {
let key = std::fs::read_to_string(path)?; let key = std::fs::read_to_string(path)?;
let key = decode_key(key)?; decode_key(key)?
Ok(key)
} else { } else {
let key = secretbox::gen_key(); new_key(settings)?
let encoded = encode_key(key.clone())?; };
let mut file = File::create(path)?; Ok(key)
file.write_all(encoded.as_bytes())?;
Ok(key)
}
} }
pub fn load_encoded_key(settings: &Settings) -> Result<String> { pub fn load_encoded_key(settings: &Settings) -> Result<String> {

View file

@ -83,7 +83,9 @@ impl Settings {
} }
pub fn should_sync(&self) -> Result<bool> { pub fn should_sync(&self) -> Result<bool> {
if !self.auto_sync { let session_path = atuin_common::utils::data_dir().join("session");
if !self.auto_sync || !session_path.exists() {
return Ok(false); return Ok(false);
} }

View file

@ -53,3 +53,9 @@ If you want to login to a new machine, you will require your encryption key
``` ```
atuin login -u <USERNAME> -p <PASSWORD> -k <KEY> atuin login -u <USERNAME> -p <PASSWORD> -k <KEY>
``` ```
## Logout
```
atuin logout
```

View file

@ -22,6 +22,16 @@ pub struct Cmd {
impl Cmd { impl Cmd {
pub fn run(&self, settings: &Settings) -> Result<()> { pub fn run(&self, settings: &Settings) -> Result<()> {
let session_path = atuin_common::utils::data_dir().join("session");
if session_path.exists() {
println!(
"You are already logged in! Please run 'atuin logout' if you wish to login again"
);
return Ok(());
}
let session = api_client::login( let session = api_client::login(
settings.sync_address.as_str(), settings.sync_address.as_str(),
self.username.as_str(), self.username.as_str(),
@ -34,7 +44,7 @@ impl Cmd {
let key_path = settings.key_path.as_str(); let key_path = settings.key_path.as_str();
let mut file = File::create(key_path)?; let mut file = File::create(key_path)?;
file.write_all(&base64::decode(self.key.clone())?)?; file.write_all(self.key.as_bytes())?;
println!("Logged in!"); println!("Logged in!");

12
src/command/logout.rs Normal file
View file

@ -0,0 +1,12 @@
use std::fs::remove_file;
pub fn run() {
let session_path = atuin_common::utils::data_dir().join("session");
if session_path.exists() {
remove_file(session_path.as_path()).expect("Failed to remove session file");
println!("You have logged out!");
} else {
println!("You are not logged in");
}
}

View file

@ -13,6 +13,7 @@ mod history;
mod import; mod import;
mod init; mod init;
mod login; mod login;
mod logout;
mod register; mod register;
mod search; mod search;
mod server; mod server;
@ -83,6 +84,9 @@ pub enum AtuinCmd {
#[structopt(about = "login to the configured server")] #[structopt(about = "login to the configured server")]
Login(login::Cmd), Login(login::Cmd),
#[structopt(about = "log out")]
Logout,
#[structopt(about = "register with the configured server")] #[structopt(about = "register with the configured server")]
Register(register::Cmd), Register(register::Cmd),
@ -136,6 +140,10 @@ impl AtuinCmd {
Self::Sync { force } => sync::run(&client_settings, force, &mut db).await, Self::Sync { force } => sync::run(&client_settings, force, &mut db).await,
Self::Login(l) => l.run(&client_settings), Self::Login(l) => l.run(&client_settings),
Self::Logout => {
logout::run();
Ok(())
}
Self::Register(r) => register::run( Self::Register(r) => register::run(
&client_settings, &client_settings,
r.username.as_str(), r.username.as_str(),
@ -143,8 +151,8 @@ impl AtuinCmd {
r.password.as_str(), r.password.as_str(),
), ),
Self::Key => { Self::Key => {
let key = std::fs::read(client_settings.key_path.as_str())?; let key = atuin_client::encryption::load_key(&client_settings)?;
println!("{}", base64::encode(key)); println!("{}", atuin_client::encryption::encode_key(key)?);
Ok(()) Ok(())
} }

View file

@ -27,5 +27,8 @@ pub fn run(settings: &Settings, username: &str, email: &str, password: &str) ->
let mut file = File::create(path)?; let mut file = File::create(path)?;
file.write_all(session.session.as_bytes())?; file.write_all(session.session.as_bytes())?;
// Create a new key, and save it to disk
let _key = atuin_client::encryption::new_key(settings)?;
Ok(()) Ok(())
} }