aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/rbw-agent/actions.rs12
-rw-r--r--src/bin/rbw-agent/agent.rs32
-rw-r--r--src/bin/rbw/commands.rs6
-rw-r--r--src/config.rs8
4 files changed, 49 insertions, 9 deletions
diff --git a/src/bin/rbw-agent/actions.rs b/src/bin/rbw-agent/actions.rs
index e857a1e..7b5dc58 100644
--- a/src/bin/rbw-agent/actions.rs
+++ b/src/bin/rbw-agent/actions.rs
@@ -130,7 +130,6 @@ pub async fn login(
protected_key,
)) => {
login_success(
- sock,
state,
access_token,
refresh_token,
@@ -166,11 +165,10 @@ pub async fn login(
tty,
&email,
password.clone(),
- provider
+ provider,
)
.await?;
login_success(
- sock,
state,
access_token,
refresh_token,
@@ -307,7 +305,6 @@ async fn two_factor(
}
async fn login_success(
- sock: &mut crate::sock::Sock,
state: std::sync::Arc<tokio::sync::RwLock<crate::agent::State>>,
access_token: String,
refresh_token: String,
@@ -329,7 +326,7 @@ async fn login_success(
db.protected_key = Some(protected_key.to_string());
save_db(&db).await?;
- sync(sock, false).await?;
+ sync(None).await?;
let db = load_db().await?;
let Some(protected_private_key) = db.protected_private_key
@@ -497,8 +494,7 @@ pub async fn check_lock(
}
pub async fn sync(
- sock: &mut crate::sock::Sock,
- ack: bool,
+ sock: Option<&mut crate::sock::Sock>,
) -> anyhow::Result<()> {
let mut db = load_db().await?;
@@ -527,7 +523,7 @@ pub async fn sync(
db.entries = entries;
save_db(&db).await?;
- if ack {
+ if let Some(sock) = sock {
respond_ack(sock).await?;
}
diff --git a/src/bin/rbw-agent/agent.rs b/src/bin/rbw-agent/agent.rs
index 8fa6768..7dcab16 100644
--- a/src/bin/rbw-agent/agent.rs
+++ b/src/bin/rbw-agent/agent.rs
@@ -7,6 +7,8 @@ pub struct State {
Option<std::collections::HashMap<String, rbw::locked::Keys>>,
pub timeout: crate::timeout::Timeout,
pub timeout_duration: std::time::Duration,
+ pub sync_timeout: crate::timeout::Timeout,
+ pub sync_timeout_duration: std::time::Duration,
}
impl State {
@@ -29,10 +31,15 @@ impl State {
self.org_keys = None;
self.timeout.clear();
}
+
+ pub fn set_sync_timeout(&mut self) {
+ self.sync_timeout.set(self.sync_timeout_duration);
+ }
}
pub struct Agent {
timer_r: tokio::sync::mpsc::UnboundedReceiver<()>,
+ sync_timer_r: tokio::sync::mpsc::UnboundedReceiver<()>,
state: std::sync::Arc<tokio::sync::RwLock<State>>,
}
@@ -41,14 +48,23 @@ impl Agent {
let config = rbw::config::Config::load()?;
let timeout_duration =
std::time::Duration::from_secs(config.lock_timeout);
+ let sync_timeout_duration =
+ std::time::Duration::from_secs(config.sync_interval);
let (timeout, timer_r) = crate::timeout::Timeout::new();
+ let (sync_timeout, sync_timer_r) = crate::timeout::Timeout::new();
+ if sync_timeout_duration > std::time::Duration::ZERO {
+ sync_timeout.set(sync_timeout_duration);
+ }
Ok(Self {
timer_r,
+ sync_timer_r,
state: std::sync::Arc::new(tokio::sync::RwLock::new(State {
priv_key: None,
org_keys: None,
timeout,
timeout_duration,
+ sync_timeout,
+ sync_timeout_duration,
})),
})
}
@@ -60,6 +76,7 @@ impl Agent {
enum Event {
Request(std::io::Result<tokio::net::UnixStream>),
Timeout(()),
+ Sync(()),
}
let mut stream = futures_util::stream::select_all([
tokio_stream::wrappers::UnixListenerStream::new(listener)
@@ -70,6 +87,11 @@ impl Agent {
)
.map(Event::Timeout)
.boxed(),
+ tokio_stream::wrappers::UnboundedReceiverStream::new(
+ self.sync_timer_r,
+ )
+ .map(Event::Sync)
+ .boxed(),
]);
while let Some(event) = stream.next().await {
match event {
@@ -94,6 +116,14 @@ impl Agent {
Event::Timeout(()) => {
self.state.write().await.clear();
}
+ Event::Sync(()) => {
+ // this could fail if we aren't logged in, but we don't
+ // care about that
+ tokio::spawn(async move {
+ let _ = crate::actions::sync(None).await;
+ });
+ self.state.write().await.set_sync_timeout();
+ }
}
}
Ok(())
@@ -141,7 +171,7 @@ async fn handle_request(
false
}
rbw::protocol::Action::Sync => {
- crate::actions::sync(sock, true).await?;
+ crate::actions::sync(Some(sock)).await?;
false
}
rbw::protocol::Action::Decrypt {
diff --git a/src/bin/rbw/commands.rs b/src/bin/rbw/commands.rs
index 668cb89..5d51f70 100644
--- a/src/bin/rbw/commands.rs
+++ b/src/bin/rbw/commands.rs
@@ -639,6 +639,12 @@ pub fn config_set(key: &str, value: &str) -> anyhow::Result<()> {
config.lock_timeout = timeout;
}
}
+ "sync_interval" => {
+ let interval = value
+ .parse()
+ .context("failed to parse value for sync_interval")?;
+ config.sync_interval = interval;
+ }
"pinentry" => config.pinentry = value.to_string(),
_ => return Err(anyhow::anyhow!("invalid config key: {}", key)),
}
diff --git a/src/config.rs b/src/config.rs
index 91aa449..d70a21b 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -10,6 +10,8 @@ pub struct Config {
pub identity_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,
pub client_cert_path: Option<std::path::PathBuf>,
@@ -25,6 +27,7 @@ impl Default for Config {
base_url: None,
identity_url: None,
lock_timeout: default_lock_timeout(),
+ sync_interval: default_sync_interval(),
pinentry: default_pinentry(),
client_cert_path: None,
device_id: None,
@@ -38,6 +41,11 @@ pub fn default_lock_timeout() -> u64 {
}
#[must_use]
+pub fn default_sync_interval() -> u64 {
+ 3600
+}
+
+#[must_use]
pub fn default_pinentry() -> String {
"pinentry".to_string()
}