aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs119
1 files changed, 97 insertions, 22 deletions
diff --git a/src/config.rs b/src/config.rs
index bbc39f7..efb1b5f 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,51 +1,59 @@
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 {
pub email: Option<String>,
pub base_url: Option<String>,
pub identity_url: Option<String>,
+ pub notifications_url: Option<String>,
#[serde(default = "default_lock_timeout")]
pub lock_timeout: u64,
+ #[serde(default = "default_sync_interval")]
+ pub sync_interval: u64,
#[serde(default = "default_pinentry")]
pub pinentry: String,
- #[serde(default = "stub_device_id")]
- pub device_id: String,
+ pub client_cert_path: Option<std::path::PathBuf>,
+ // backcompat, no longer generated in new configs
+ #[serde(skip_serializing)]
+ pub device_id: Option<String>,
}
impl Default for Config {
fn default() -> Self {
Self {
- email: Default::default(),
- base_url: Default::default(),
- identity_url: Default::default(),
+ email: None,
+ base_url: None,
+ identity_url: None,
+ notifications_url: None,
lock_timeout: default_lock_timeout(),
+ sync_interval: default_sync_interval(),
pinentry: default_pinentry(),
- device_id: default_device_id(),
+ client_cert_path: None,
+ device_id: None,
}
}
}
+#[must_use]
pub fn default_lock_timeout() -> u64 {
3600
}
-pub fn default_pinentry() -> String {
- "pinentry".to_string()
-}
-
-fn default_device_id() -> String {
- uuid::Uuid::new_v4().to_hyphenated().to_string()
+#[must_use]
+pub fn default_sync_interval() -> u64 {
+ 3600
}
-fn stub_device_id() -> String {
- String::from("fix")
+#[must_use]
+pub fn default_pinentry() -> String {
+ "pinentry".to_string()
}
impl Config {
+ #[must_use]
pub fn new() -> Self {
Self::default()
}
@@ -127,36 +135,103 @@ 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(())
}
+ #[must_use]
pub fn base_url(&self) -> String {
self.base_url.clone().map_or_else(
|| "https://api.bitwarden.com".to_string(),
- |url| format!("{}/api", url.trim_end_matches('/')),
+ |url| {
+ let clean_url = url.trim_end_matches('/').to_string();
+ if clean_url == "https://api.bitwarden.eu" {
+ clean_url
+ } else {
+ format!("{clean_url}/api")
+ }
+ },
)
}
+ #[must_use]
pub fn identity_url(&self) -> String {
self.identity_url.clone().unwrap_or_else(|| {
self.base_url.clone().map_or_else(
|| "https://identity.bitwarden.com".to_string(),
- |url| format!("{}/identity", url.trim_end_matches('/')),
+ |url| {
+ let clean_url = url.trim_end_matches('/').to_string();
+ if clean_url == "https://identity.bitwarden.eu" {
+ clean_url
+ } else {
+ format!("{clean_url}/identity")
+ }
+ },
+ )
+ })
+ }
+
+ #[must_use]
+ pub fn notifications_url(&self) -> String {
+ self.notifications_url.clone().unwrap_or_else(|| {
+ self.base_url.clone().map_or_else(
+ || "https://notifications.bitwarden.com".to_string(),
+ |url| {
+ let clean_url = url.trim_end_matches('/').to_string();
+ if clean_url == "https://notifications.bitwarden.eu" {
+ clean_url
+ } else {
+ format!("{clean_url}/notifications")
+ }
+ },
)
})
}
+ #[must_use]
+ pub fn client_cert_path(&self) -> Option<&std::path::Path> {
+ self.client_cert_path.as_deref()
+ }
+
+ #[must_use]
pub fn server_name(&self) -> String {
self.base_url
.clone()
.unwrap_or_else(|| "default".to_string())
}
}
+
+pub async fn device_id(config: &Config) -> Result<String> {
+ 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().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)
+ }
+}