From 42badc1f3281961bbfadffffb64de913f5b6084f Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 10 Feb 2022 01:07:05 -0500 Subject: move device_id to a separate data file --- CHANGELOG.md | 5 +++++ src/actions.rs | 6 ++++-- src/config.rs | 57 ++++++++++++++++++++++++++++++++++++++------------------- src/dirs.rs | 5 +++++ src/error.rs | 6 ++++++ 5 files changed, 58 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79b5e70..3c514d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## [1.4.2] - Unreleased +### Changed + +* Device id is now stored in a separate file in the local data directory + instead of as part of the config (#74) + ### Fixed * Fix api renaming in official bitwarden server (#80) diff --git a/src/actions.rs b/src/actions.rs index b16e6f2..f6cef56 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -8,7 +8,9 @@ pub async fn register( let client = crate::api::Client::new(&config.base_url(), &config.identity_url()); - client.register(email, &config.device_id, &apikey).await?; + client + .register(email, &crate::config::device_id(&config).await?, &apikey) + .await?; Ok(()) } @@ -29,7 +31,7 @@ pub async fn login( let (access_token, refresh_token, protected_key) = client .login( email, - &config.device_id, + &crate::config::device_id(&config).await?, &identity.master_password_hash, two_factor_token, two_factor_provider, diff --git a/src/config.rs b/src/config.rs index 9b47590..23ef765 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use std::io::{Read as _, Write as _}; -use tokio::io::AsyncReadExt as _; +use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _}; #[derive(serde::Serialize, serde::Deserialize, Debug)] pub struct Config { @@ -12,8 +12,9 @@ pub struct Config { pub lock_timeout: u64, #[serde(default = "default_pinentry")] pub pinentry: String, - #[serde(default = "stub_device_id")] - pub device_id: String, + // backcompat, no longer generated in new configs + #[serde(skip_serializing)] + pub device_id: Option, } impl Default for Config { @@ -24,7 +25,7 @@ impl Default for Config { identity_url: None, lock_timeout: default_lock_timeout(), pinentry: default_pinentry(), - device_id: default_device_id(), + device_id: None, } } } @@ -39,16 +40,6 @@ pub fn default_pinentry() -> String { "pinentry".to_string() } -#[must_use] -fn default_device_id() -> String { - uuid::Uuid::new_v4().to_hyphenated().to_string() -} - -#[must_use] -fn stub_device_id() -> String { - String::from("fix") -} - impl Config { #[must_use] pub fn new() -> Self { @@ -132,14 +123,10 @@ impl Config { } pub fn validate() -> Result<()> { - let mut config = Self::load()?; + let config = Self::load()?; if config.email.is_none() { return Err(Error::ConfigMissingEmail); } - if config.device_id == stub_device_id() { - config.device_id = default_device_id(); - config.save()?; - } Ok(()) } @@ -168,3 +155,35 @@ impl Config { .unwrap_or_else(|| "default".to_string()) } } + +pub async fn device_id(config: &Config) -> Result { + let file = crate::dirs::device_id_file(); + if let Ok(mut fh) = tokio::fs::File::open(&file).await { + let mut s = String::new(); + fh.read_to_string(&mut s) + .await + .map_err(|e| Error::LoadDeviceId { + source: e, + file: file.clone(), + })?; + Ok(s.trim().to_string()) + } else { + let id = config.device_id.as_ref().map_or_else( + || uuid::Uuid::new_v4().to_hyphenated().to_string(), + String::to_string, + ); + let mut fh = tokio::fs::File::create(&file).await.map_err(|e| { + Error::LoadDeviceId { + source: e, + file: file.clone(), + } + })?; + fh.write_all(id.as_bytes()).await.map_err(|e| { + Error::LoadDeviceId { + source: e, + file: file.clone(), + } + })?; + Ok(id) + } +} diff --git a/src/dirs.rs b/src/dirs.rs index bc97ed5..5ebeaa2 100644 --- a/src/dirs.rs +++ b/src/dirs.rs @@ -67,6 +67,11 @@ pub fn agent_stderr_file() -> std::path::PathBuf { data_dir().join("agent.err") } +#[must_use] +pub fn device_id_file() -> std::path::PathBuf { + data_dir().join("device_id") +} + #[must_use] pub fn socket_file() -> std::path::PathBuf { runtime_dir().join("socket") diff --git a/src/error.rs b/src/error.rs index 8116de2..46b242b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -116,6 +116,12 @@ pub enum Error { file: std::path::PathBuf, }, + #[error("failed to load device id from {}", .file.display())] + LoadDeviceId { + source: tokio::io::Error, + file: std::path::PathBuf, + }, + #[error("invalid padding")] Padding, -- cgit v1.2.3-54-g00ecf