summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls Piņķis <emils@mullvad.net>2019-10-02 18:41:28 +0100
committerEmīls Piņķis <emils@mullvad.net>2019-10-04 13:11:28 +0100
commitbc9797e5e5f08cb023d746a69077c171b16cec98 (patch)
tree544e12870379f52103b521f857578166fcc9fb57
parent57077610a857dc14b0192e49e35ec096d9698f06 (diff)
downloadmullvadvpn-bc9797e5e5f08cb023d746a69077c171b16cec98.tar.xz
mullvadvpn-bc9797e5e5f08cb023d746a69077c171b16cec98.zip
Add RPC to create accounts to daemon
-rw-r--r--mullvad-daemon/src/lib.rs88
-rw-r--r--mullvad-daemon/src/management_interface.rs18
-rw-r--r--mullvad-rpc/src/lib.rs1
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>;
});