diff options
| -rw-r--r-- | mullvad-daemon/src/device/mod.rs | 63 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 27 |
2 files changed, 47 insertions, 43 deletions
diff --git a/mullvad-daemon/src/device/mod.rs b/mullvad-daemon/src/device/mod.rs index 92199de406..b2b9976501 100644 --- a/mullvad-daemon/src/device/mod.rs +++ b/mullvad-daemon/src/device/mod.rs @@ -225,6 +225,14 @@ impl From<PrivateDevice> for Device { } #[derive(Clone)] +pub(crate) enum AccountEvent { + /// Emitted when the device state changes. + Device(PrivateDeviceEvent), + /// Emitted when the account expiry is fetched. + Expiry(DateTime<Utc>), +} + +#[derive(Clone)] pub(crate) enum PrivateDeviceEvent { /// Logged in on a new device. Login(PrivateAccountAndDevice), @@ -236,40 +244,30 @@ pub(crate) enum PrivateDeviceEvent { Updated(PrivateAccountAndDevice), /// The key was rotated. RotatedKey(PrivateAccountAndDevice), - /// Emitted when the account expiry is fetched. - AccountExpiry(DateTime<Utc>), } -#[derive(err_derive::Error, Debug)] -#[error(display = "Device event type has no public equivalent")] -pub(crate) struct PrivateOnlyEvent; - -impl TryFrom<PrivateDeviceEvent> for DeviceEvent { - type Error = PrivateOnlyEvent; - - fn try_from(event: PrivateDeviceEvent) -> Result<DeviceEvent, PrivateOnlyEvent> { +impl From<PrivateDeviceEvent> for DeviceEvent { + fn from(event: PrivateDeviceEvent) -> DeviceEvent { let cause = match event { PrivateDeviceEvent::Login(_) => DeviceEventCause::LoggedIn, PrivateDeviceEvent::Logout => DeviceEventCause::LoggedOut, PrivateDeviceEvent::Revoked => DeviceEventCause::Revoked, PrivateDeviceEvent::Updated(_) => DeviceEventCause::Updated, PrivateDeviceEvent::RotatedKey(_) => DeviceEventCause::RotatedKey, - PrivateDeviceEvent::AccountExpiry(_) => return Err(PrivateOnlyEvent), }; - let new_state = DeviceState::from(event.state().ok_or(PrivateOnlyEvent)?); - Ok(DeviceEvent { cause, new_state }) + let new_state = DeviceState::from(event.state()); + DeviceEvent { cause, new_state } } } impl PrivateDeviceEvent { - pub fn state(self) -> Option<PrivateDeviceState> { + pub fn state(self) -> PrivateDeviceState { match self { - PrivateDeviceEvent::Login(config) => Some(PrivateDeviceState::LoggedIn(config)), - PrivateDeviceEvent::Updated(config) => Some(PrivateDeviceState::LoggedIn(config)), - PrivateDeviceEvent::RotatedKey(config) => Some(PrivateDeviceState::LoggedIn(config)), - PrivateDeviceEvent::Logout => Some(PrivateDeviceState::LoggedOut), - PrivateDeviceEvent::Revoked => Some(PrivateDeviceState::Revoked), - PrivateDeviceEvent::AccountExpiry(_) => None, + PrivateDeviceEvent::Login(config) => PrivateDeviceState::LoggedIn(config), + PrivateDeviceEvent::Updated(config) => PrivateDeviceState::LoggedIn(config), + PrivateDeviceEvent::RotatedKey(config) => PrivateDeviceState::LoggedIn(config), + PrivateDeviceEvent::Logout => PrivateDeviceState::LoggedOut, + PrivateDeviceEvent::Revoked => PrivateDeviceState::Revoked, } } } @@ -396,7 +394,7 @@ pub(crate) struct AccountManager { device_service: DeviceService, data: PrivateDeviceState, rotation_interval: RotationInterval, - listeners: Vec<Box<dyn Sender<PrivateDeviceEvent> + Send>>, + listeners: Vec<Box<dyn Sender<AccountEvent> + Send>>, last_validation: Option<SystemTime>, validation_requests: Vec<ResponseTx<()>>, expiry_requests: Vec<ResponseTx<DateTime<Utc>>>, @@ -411,7 +409,7 @@ impl AccountManager { rest_handle: rest::MullvadRestHandle, settings_dir: &Path, initial_rotation_interval: RotationInterval, - listener_tx: impl Sender<PrivateDeviceEvent> + Send + 'static, + listener_tx: impl Sender<AccountEvent> + Send + 'static, ) -> Result<(AccountManagerHandle, PrivateDeviceState), Error> { let (cacher, data) = DeviceCacher::new(settings_dir).await?; let token = data.device().map(|state| state.account_token.clone()); @@ -657,7 +655,7 @@ impl AccountManager { match &response { Ok(submission) => { // Send expiry update event - let event = PrivateDeviceEvent::AccountExpiry(submission.new_expiry); + let event = AccountEvent::Expiry(submission.new_expiry); self.listeners .retain(|listener| listener.send(event.clone()).is_ok()); } @@ -682,7 +680,7 @@ impl AccountManager { } // Send expiry update event - let event = PrivateDeviceEvent::AccountExpiry(expiry); + let event = AccountEvent::Expiry(expiry); self.listeners .retain(|listener| listener.send(event.clone()).is_ok()); @@ -855,8 +853,11 @@ impl AccountManager { Self::drain_requests(&mut self.rotation_requests, || Err(err_constructor())); Self::drain_requests(&mut self.expiry_requests, || Err(err_constructor())); - self.listeners - .retain(|listener| listener.send(PrivateDeviceEvent::Revoked).is_ok()); + self.listeners.retain(|listener| { + listener + .send(AccountEvent::Device(PrivateDeviceEvent::Revoked)) + .is_ok() + }); } async fn logout(&mut self, tx: ResponseTx<()>) { @@ -872,8 +873,11 @@ impl AccountManager { let old_config = self.data.logout(); - self.listeners - .retain(|listener| listener.send(PrivateDeviceEvent::Logout).is_ok()); + self.listeners.retain(|listener| { + listener + .send(AccountEvent::Device(PrivateDeviceEvent::Logout)) + .is_ok() + }); if let Some(old_config) = old_config { let logout_call = tokio::spawn(Box::pin(self.logout_api_call(old_config))); @@ -905,7 +909,7 @@ impl AccountManager { } async fn set(&mut self, event: PrivateDeviceEvent) -> Result<(), Error> { - let device_state = event.clone().state().expect("event type must imply state"); + let device_state = event.clone().state(); if device_state == self.data { return Ok(()); } @@ -921,6 +925,7 @@ impl AccountManager { self.data = device_state; + let event = AccountEvent::Device(event); self.listeners .retain(|listener| listener.send(event.clone()).is_ok()); diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index b4797d7f28..49f27751cc 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -28,7 +28,7 @@ pub mod version; mod version_check; use crate::target_state::PersistentTargetState; -use device::{PrivateAccountAndDevice, PrivateDeviceEvent}; +use device::{AccountEvent, PrivateAccountAndDevice, PrivateDeviceEvent}; use futures::{ channel::{mpsc, oneshot}, future::{abortable, AbortHandle, Future, LocalBoxFuture}, @@ -304,7 +304,7 @@ pub(crate) enum InternalDaemonEvent { /// The background job fetching new `AppVersionInfo`s got a new info object. NewAppVersionInfo(AppVersionInfo), /// Sent when a device is updated in any way (key rotation, login, logout, etc.). - DeviceEvent(PrivateDeviceEvent), + DeviceEvent(AccountEvent), /// Handles updates from versions without devices. DeviceMigrationEvent(Result<PrivateAccountAndDevice, device::Error>), /// The split tunnel paths or state were updated. @@ -336,8 +336,8 @@ impl From<AppVersionInfo> for InternalDaemonEvent { } } -impl From<PrivateDeviceEvent> for InternalDaemonEvent { - fn from(event: PrivateDeviceEvent) -> Self { +impl From<AccountEvent> for InternalDaemonEvent { + fn from(event: AccountEvent) -> Self { InternalDaemonEvent::DeviceEvent(event) } } @@ -1044,9 +1044,9 @@ where self.event_listener.notify_app_version(app_version_info); } - async fn handle_device_event(&mut self, event: PrivateDeviceEvent) { + async fn handle_device_event(&mut self, event: AccountEvent) { match &event { - PrivateDeviceEvent::Login(device) => { + AccountEvent::Device(PrivateDeviceEvent::Login(device)) => { if let Err(error) = self.account_history.set(device.account_token.clone()).await { log::error!( "{}", @@ -1058,25 +1058,23 @@ where self.reconnect_tunnel(); } } - PrivateDeviceEvent::Logout => { + AccountEvent::Device(PrivateDeviceEvent::Logout) => { log::info!("Disconnecting because account token was cleared"); self.set_target_state(TargetState::Unsecured).await; } - PrivateDeviceEvent::Revoked => { + AccountEvent::Device(PrivateDeviceEvent::Revoked) => { // If we're currently in a secured state, reconnect to make sure we immediately // enter the error state. if *self.target_state == TargetState::Secured { self.connect_tunnel(); } } - PrivateDeviceEvent::RotatedKey(_) => { + AccountEvent::Device(PrivateDeviceEvent::RotatedKey(_)) => { if self.get_target_tunnel_type() == Some(TunnelType::Wireguard) { self.schedule_reconnect(WG_RECONNECT_DELAY); } } - PrivateDeviceEvent::AccountExpiry(expiry) - if *self.target_state == TargetState::Secured => - { + AccountEvent::Expiry(expiry) if *self.target_state == TargetState::Secured => { if expiry >= &chrono::Utc::now() { if let TunnelState::Error(ref state) = self.tunnel_state { if matches!(state.cause(), ErrorStateCause::AuthFailed(_)) { @@ -1093,8 +1091,9 @@ where } _ => (), } - if let Ok(event) = DeviceEvent::try_from(event) { - self.event_listener.notify_device_event(event); + if let AccountEvent::Device(event) = event { + self.event_listener + .notify_device_event(DeviceEvent::from(event)); } } |
