Skip to content

Commit

Permalink
Init device keys as part of starting account controller (#1449)
Browse files Browse the repository at this point in the history
* Init device keys as part of starting account controller

* Remove two unwraps

* Add reset device id to uniffi

* Update uniffi files
  • Loading branch information
octol authored Nov 4, 2024
1 parent a53141a commit 3907183
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 26 deletions.
18 changes: 12 additions & 6 deletions nym-vpn-core/crates/nym-vpn-account-controller/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,24 @@ where
data_dir: PathBuf,
user_agent: UserAgent,
cancel_token: CancellationToken,
) -> Self {
) -> Result<Self, Error> {
let account_storage = AccountStorage::from(storage);

// TODO: remove unwraps.
let storage_paths = nym_sdk::mixnet::StoragePaths::new_from_dir(data_dir).unwrap();
// Generate the device keys if we don't already have them
account_storage.init_keys().await?;

let storage_paths =
nym_sdk::mixnet::StoragePaths::new_from_dir(data_dir).map_err(Error::StoragePaths)?;
let credential_storage = VpnCredentialStorage {
storage: storage_paths.persistent_credential_storage().await.unwrap(),
storage: storage_paths
.persistent_credential_storage()
.await
.map_err(Error::SetupCredentialStorage)?,
};

let (command_tx, command_rx) = tokio::sync::mpsc::unbounded_channel();

AccountController {
Ok(AccountController {
account_storage,
credential_storage,
vpn_api_client: create_api_client(user_agent),
Expand All @@ -140,7 +146,7 @@ where
command_rx,
command_tx,
cancel_token,
}
})
}

async fn register_device(&self) -> Result<(), Error> {
Expand Down
6 changes: 6 additions & 0 deletions nym-vpn-core/crates/nym-vpn-account-controller/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@ pub enum Error {
source: Box<dyn std::error::Error + Send + Sync>,
},

#[error("failed to setup account storage paths")]
StoragePaths(#[source] nym_sdk::Error),

#[error(transparent)]
CredentialStorage(#[from] nym_credential_storage::error::StorageError),

#[error("failed to setup credential storage")]
SetupCredentialStorage(#[source] nym_sdk::Error),

#[error("failed to register device")]
RegisterDevice(#[source] nym_vpn_api_client::VpnApiClientError),

Expand Down
1 change: 1 addition & 0 deletions nym-vpn-core/crates/nym-vpn-account-controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ mod error;
mod storage;

pub use controller::{AccountCommand, AccountController};
pub use error::Error;
pub use shared_state::{AccountStateSummary, ReadyToConnect, SharedAccountState};
11 changes: 11 additions & 0 deletions nym-vpn-core/crates/nym-vpn-account-controller/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ where
Self { storage }
}

pub(crate) async fn init_keys(&self) -> Result<(), Error> {
self.storage
.lock()
.await
.init_keys(None)
.await
.map_err(|err| Error::KeyStore {
source: Box::new(err),
})
}

// Load account and keep the error type
pub(crate) async fn load_account_from_storage(
&self,
Expand Down
1 change: 0 additions & 1 deletion nym-vpn-core/crates/nym-vpn-api-client/src/jwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ pub(crate) struct Jwt {
jwt: String,
}

#[allow(unused)]
impl Jwt {
pub fn new_secp256k1(wallet: &DirectSecp256k1HdWallet) -> Jwt {
let timestamp = std::time::UNIX_EPOCH.elapsed().unwrap().as_secs() as u128;
Expand Down
17 changes: 15 additions & 2 deletions nym-vpn-core/crates/nym-vpn-lib/src/platform/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::{path::PathBuf, str::FromStr, sync::Arc};

use nym_vpn_account_controller::{AccountCommand, ReadyToConnect, SharedAccountState};
use nym_vpn_store::mnemonic::MnemonicStorage;
use nym_vpn_store::{keys::KeyStore, mnemonic::MnemonicStorage};
use tokio::{sync::mpsc::UnboundedSender, task::JoinHandle};
use tokio_util::sync::CancellationToken;

Expand Down Expand Up @@ -53,7 +53,10 @@ async fn start_account_controller(data_dir: PathBuf) -> Result<AccountController
user_agent,
shutdown_token.child_token(),
)
.await;
.await
.map_err(|err| VpnError::InternalError {
details: err.to_string(),
})?;

let shared_account_state = account_controller.shared_state();
let account_command_tx = account_controller.command_tx();
Expand Down Expand Up @@ -198,6 +201,16 @@ pub(super) async fn remove_account_mnemonic(path: &str) -> Result<bool, VpnError
Ok(is_account_removed_success)
}

pub(super) async fn reset_device_identity(path: &str) -> Result<(), VpnError> {
let storage = setup_account_storage(path)?;
storage
.reset_keys(None)
.await
.map_err(|err| VpnError::InternalError {
details: err.to_string(),
})
}

pub(super) async fn get_account_summary() -> Result<AccountStateSummary, VpnError> {
let shared_account_state = get_shared_account_state().await?;
let account_state_summary = shared_account_state.lock().await.clone();
Expand Down
6 changes: 6 additions & 0 deletions nym-vpn-core/crates/nym-vpn-lib/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ pub fn removeAccountMnemonic(path: String) -> Result<bool, VpnError> {
RUNTIME.block_on(account::remove_account_mnemonic(&path))
}

#[allow(non_snake_case)]
#[uniffi::export]
pub fn resetDeviceIdentity(path: String) -> Result<(), VpnError> {
RUNTIME.block_on(account::reset_device_identity(&path))
}

#[allow(non_snake_case)]
#[uniffi::export]
pub fn getAccountSummary() -> Result<AccountStateSummary, VpnError> {
Expand Down
18 changes: 18 additions & 0 deletions nym-vpn-core/crates/nym-vpn-lib/uniffi/nym_vpn_lib.kt
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,8 @@ internal open class UniffiVTableCallbackInterfaceTunnelStatusListener(








Expand Down Expand Up @@ -826,6 +828,8 @@ internal interface UniffiLib : Library {
): Byte
fun uniffi_nym_vpn_lib_fn_func_removeaccountmnemonic(`path`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
): Byte
fun uniffi_nym_vpn_lib_fn_func_resetdeviceidentity(`path`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
): Unit
fun uniffi_nym_vpn_lib_fn_func_startaccountcontroller(`dataDir`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
): Unit
fun uniffi_nym_vpn_lib_fn_func_startvpn(`config`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus,
Expand Down Expand Up @@ -962,6 +966,8 @@ internal interface UniffiLib : Library {
): Short
fun uniffi_nym_vpn_lib_checksum_func_removeaccountmnemonic(
): Short
fun uniffi_nym_vpn_lib_checksum_func_resetdeviceidentity(
): Short
fun uniffi_nym_vpn_lib_checksum_func_startaccountcontroller(
): Short
fun uniffi_nym_vpn_lib_checksum_func_startvpn(
Expand Down Expand Up @@ -1016,6 +1022,9 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) {
if (lib.uniffi_nym_vpn_lib_checksum_func_removeaccountmnemonic() != 51019.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_nym_vpn_lib_checksum_func_resetdeviceidentity() != 48847.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_nym_vpn_lib_checksum_func_startaccountcontroller() != 34257.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
Expand Down Expand Up @@ -5365,6 +5374,15 @@ public object FfiConverterTypeUrl: FfiConverter<Url, RustBuffer.ByValue> {
}


@Throws(VpnException::class) fun `resetDeviceIdentity`(`path`: kotlin.String)
=
uniffiRustCallWithError(VpnException) { _status ->
UniffiLib.INSTANCE.uniffi_nym_vpn_lib_fn_func_resetdeviceidentity(
FfiConverterString.lower(`path`),_status)
}



@Throws(VpnException::class) fun `startAccountController`(`dataDir`: kotlin.String)
=
uniffiRustCallWithError(VpnException) { _status ->
Expand Down
9 changes: 9 additions & 0 deletions nym-vpn-core/crates/nym-vpn-lib/uniffi/nym_vpn_lib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5903,6 +5903,12 @@ public func removeAccountMnemonic(path: String)throws -> Bool {
)
})
}
public func resetDeviceIdentity(path: String)throws {try rustCallWithError(FfiConverterTypeVpnError.lift) {
uniffi_nym_vpn_lib_fn_func_resetdeviceidentity(
FfiConverterString.lower(path),$0
)
}
}
public func startAccountController(dataDir: String)throws {try rustCallWithError(FfiConverterTypeVpnError.lift) {
uniffi_nym_vpn_lib_fn_func_startaccountcontroller(
FfiConverterString.lower(dataDir),$0
Expand Down Expand Up @@ -5969,6 +5975,9 @@ private var initializationResult: InitializationResult {
if (uniffi_nym_vpn_lib_checksum_func_removeaccountmnemonic() != 51019) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_nym_vpn_lib_checksum_func_resetdeviceidentity() != 48847) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_nym_vpn_lib_checksum_func_startaccountcontroller() != 34257) {
return InitializationResult.apiChecksumMismatch
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ impl From<AccountError> for nym_vpn_proto::AccountError {
message: err.to_string(),
details: hashmap! {},
},
AccountError::AccountControllerError { .. } => nym_vpn_proto::AccountError {
kind: AccountErrorType::Storage as i32,
message: err.to_string(),
details: hashmap! {},
},
}
}
}
5 changes: 0 additions & 5 deletions nym-vpn-core/crates/nym-vpnd/src/service/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,6 @@ pub enum ConfigSetupError {
#[error("failed to set permissions for directory {dir}: {error}")]
SetPermissions { dir: PathBuf, error: std::io::Error },

#[error("failed to init keys")]
FailedToInitKeys {
source: nym_vpn_store::keys::persistence::OnDiskKeysError,
},

#[error("global network details not set")]
GlobalNetworkNotSet,
}
Expand Down
7 changes: 5 additions & 2 deletions nym-vpn-core/crates/nym-vpnd/src/service/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@ pub enum AccountError {
FailedToResetKeys {
source: Box<dyn std::error::Error + Send + Sync>,
},

#[error(transparent)]
AccountControllerError {
source: nym_vpn_account_controller::Error,
},
}

#[derive(Debug, thiserror::Error)]
Expand All @@ -376,8 +381,6 @@ pub enum SetNetworkError {

#[derive(thiserror::Error, Debug)]
pub enum Error {
// FIXME: this variant should be constructed
#[allow(unused)]
#[error("account error: {0}")]
Account(#[source] AccountError),

Expand Down
12 changes: 2 additions & 10 deletions nym-vpn-core/crates/nym-vpnd/src/service/vpn_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ use nym_vpn_lib::{
},
MixnetClientConfig, NodeIdentity, Recipient,
};
use nym_vpn_store::keys::KeyStore as _;

use crate::{config::GlobalConfigFile, GLOBAL_NETWORK_DETAILS};

Expand Down Expand Up @@ -427,14 +426,6 @@ impl NymVpnService<nym_vpn_lib::storage::VpnClientOnDiskStorage> {
// Make sure the data dir exists
super::config::create_data_dir(&data_dir).map_err(Error::ConfigSetup)?;

// Generate the device keys if we don't already have them
storage
.lock()
.await
.init_keys(None)
.await
.map_err(|source| Error::ConfigSetup(ConfigSetupError::FailedToInitKeys { source }))?;

// We need to create the user agent here and not in the controller so that we correctly
// pick up build time constants.
let user_agent = crate::util::construct_user_agent();
Expand All @@ -444,7 +435,8 @@ impl NymVpnService<nym_vpn_lib::storage::VpnClientOnDiskStorage> {
user_agent.clone(),
shutdown_token.child_token(),
)
.await;
.await
.map_err(|source| Error::Account(AccountError::AccountControllerError { source }))?;

let shared_account_state = account_controller.shared_state();
let account_command_tx = account_controller.command_tx();
Expand Down

0 comments on commit 3907183

Please sign in to comment.