diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-10-02 18:41:28 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-10-04 13:11:28 +0100 |
| commit | bc9797e5e5f08cb023d746a69077c171b16cec98 (patch) | |
| tree | 544e12870379f52103b521f857578166fcc9fb57 | |
| parent | 57077610a857dc14b0192e49e35ec096d9698f06 (diff) | |
| download | mullvadvpn-bc9797e5e5f08cb023d746a69077c171b16cec98.tar.xz mullvadvpn-bc9797e5e5f08cb023d746a69077c171b16cec98.zip | |
Add RPC to create accounts to daemon
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 88 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 18 | ||||
| -rw-r--r-- | mullvad-rpc/src/lib.rs | 1 |
3 files changed, 95 insertions, 12 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 7508bd9216..783239f5ea 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -150,6 +150,11 @@ pub(crate) enum InternalDaemonEvent { std::result::Result<mullvad_types::wireguard::WireguardData, wireguard::Error>, ), ), + /// New Account created + NewAccountEvent( + AccountToken, + oneshot::Sender<std::result::Result<String, mullvad_rpc::Error>>, + ), } impl From<TunnelStateTransition> for InternalDaemonEvent { @@ -499,6 +504,7 @@ where } TriggerShutdown => self.trigger_shutdown_event(), WgKeyEvent(key_event) => self.handle_wireguard_key_event(key_event), + NewAccountEvent(account_token, tx) => self.handle_new_account_event(account_token, tx), } Ok(()) } @@ -741,6 +747,7 @@ where SetTargetState(tx, state) => self.on_set_target_state(tx, state), GetState(tx) => self.on_get_state(tx), GetCurrentLocation(tx) => self.on_get_current_location(tx), + CreateNewAccount(tx) => self.on_create_new_account(tx), GetAccountData(tx, account_token) => self.on_get_account_data(tx, account_token), GetWwwAuthToken(tx) => self.on_get_www_auth_token(tx), GetRelayLocations(tx) => self.on_get_relay_locations(tx), @@ -839,6 +846,22 @@ where } } + fn handle_new_account_event( + &mut self, + new_token: AccountToken, + tx: oneshot::Sender<std::result::Result<String, mullvad_rpc::Error>>, + ) { + match self.set_account(Some(new_token.clone())) { + Ok(_) => { + self.set_target_state(TargetState::Unsecured); + let _ = tx.send(Ok(new_token)); + } + Err(err) => { + log::error!("Failed to save new account - {}", err); + } + }; + } + fn on_set_target_state( &mut self, tx: oneshot::Sender<std::result::Result<(), ()>>, @@ -916,6 +939,31 @@ where }) } + fn on_create_new_account( + &mut self, + tx: oneshot::Sender<std::result::Result<String, mullvad_rpc::Error>>, + ) { + let daemon_tx = self.tx.clone(); + let future = self.accounts_proxy.create_account().then( + move |result| -> std::result::Result<(), ()> { + match result { + Ok(account_token) => { + let _ = + daemon_tx.send(InternalDaemonEvent::NewAccountEvent(account_token, tx)); + } + Err(err) => { + let _ = tx.send(Err(err)); + } + }; + Ok(()) + }, + ); + + if self.tokio_remote.execute(future).is_err() { + log::error!("Failed to spawn future for creating a new account"); + } + } + fn on_get_account_data( &mut self, tx: oneshot::Sender<BoxFuture<AccountData, mullvad_rpc::Error>>, @@ -948,19 +996,11 @@ where } fn on_set_account(&mut self, tx: oneshot::Sender<()>, account_token: Option<String>) { - let save_result = self.settings.set_account_token(account_token.clone()); - - match save_result { + match self.set_account(account_token.clone()) { Ok(account_changed) => { - Self::oneshot_send(tx, (), "set_account response"); if account_changed { - self.ensure_wireguard_keys_for_current_account(); - self.event_listener.notify_settings(self.settings.clone()); match account_token { - Some(token) => { - if let Err(e) = self.account_history.bump_history(&token) { - log::error!("Failed to bump account history: {}", e); - } + Some(_) => { info!("Initiating tunnel restart because the account token changed"); self.reconnect_tunnel(); } @@ -968,12 +1008,36 @@ where info!("Disconnecting because account token was cleared"); self.set_target_state(TargetState::Unsecured); } - } + }; } + Self::oneshot_send(tx, (), "set_account response"); + } + Err(e) => { + log::error!("Failed to set account - {}", e); } - Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } + + fn set_account( + &mut self, + account_token: Option<String>, + ) -> std::result::Result<bool, settings::Error> { + let account_changed = self.settings.set_account_token(account_token.clone())?; + if account_changed { + self.event_listener.notify_settings(self.settings.clone()); + + // Bump account history if a token was set + if let Some(token) = account_token { + if let Err(e) = self.account_history.bump_history(&token) { + log::error!("Failed to bump account history: {}", e); + } + } + + self.ensure_wireguard_keys_for_current_account(); + } + Ok(account_changed) + } + fn on_get_account_history(&mut self, tx: oneshot::Sender<Vec<AccountToken>>) { Self::oneshot_send( tx, diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 61a95fc3c5..aa0ae1bb37 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -40,6 +40,10 @@ build_rpc_trait! { pub trait ManagementInterfaceApi { type Metadata; + /// Creates and sets a new account + #[rpc(meta, name = "create_new_account")] + fn create_new_account(&self, Self::Metadata) -> BoxFuture<String, Error>; + /// Fetches and returns metadata about an account. Returns an error on non-existing /// accounts. #[rpc(meta, name = "get_account_data")] @@ -183,6 +187,7 @@ pub enum ManagementCommand { GetState(OneshotSender<TunnelState>), /// Get the current geographical location. GetCurrentLocation(OneshotSender<Option<GeoIpLocation>>), + CreateNewAccount(OneshotSender<std::result::Result<String, mullvad_rpc::Error>>), /// Request the metadata for an account. GetAccountData( OneshotSender<BoxFuture<AccountData, mullvad_rpc::Error>>, @@ -378,6 +383,19 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi { type Metadata = Meta; + fn create_new_account(&self, _: Self::Metadata) -> BoxFuture<String, Error> { + let (tx, rx) = sync::oneshot::channel(); + let future = self + .send_command_to_daemon(ManagementCommand::CreateNewAccount(tx)) + .and_then(|_| rx.map_err(|_| Error::internal_error())) + .and_then(|result| match result { + Ok(account_token) => Ok(account_token), + Err(e) => Err(Self::map_rpc_error(&e)), + }); + + Box::new(future) + } + fn get_account_data( &self, _: Self::Metadata, diff --git a/mullvad-rpc/src/lib.rs b/mullvad-rpc/src/lib.rs index b1554c1a5d..ced3bfc729 100644 --- a/mullvad-rpc/src/lib.rs +++ b/mullvad-rpc/src/lib.rs @@ -104,6 +104,7 @@ impl MullvadRpcFactory { } jsonrpc_client!(pub struct AccountsProxy { + pub fn create_account(&mut self) -> RpcRequest<AccountToken>; pub fn get_expiry(&mut self, account_token: AccountToken) -> RpcRequest<DateTime<Utc>>; pub fn get_www_auth_token(&mut self, account_token: AccountToken) -> RpcRequest<String>; }); |
