Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Vaults RPCs #4366

Merged
merged 5 commits into from
Feb 5, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 48 additions & 14 deletions ethcore/src/account_provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl AccountProvider {

/// Returns each account along with name and meta.
pub fn account_meta(&self, address: Address) -> Result<AccountMeta, Error> {
let account = StoreAccountRef::root(address);
let account = self.sstore.account_ref(&address)?;
Ok(AccountMeta {
name: self.sstore.name(&account)?,
meta: self.sstore.meta(&account)?,
Expand All @@ -276,38 +276,38 @@ impl AccountProvider {

/// Returns each account along with name and meta.
pub fn set_account_name(&self, address: Address, name: String) -> Result<(), Error> {
self.sstore.set_name(&StoreAccountRef::root(address), name)?;
self.sstore.set_name(&self.sstore.account_ref(&address)?, name)?;
Ok(())
}

/// Returns each account along with name and meta.
pub fn set_account_meta(&self, address: Address, meta: String) -> Result<(), Error> {
self.sstore.set_meta(&StoreAccountRef::root(address), meta)?;
self.sstore.set_meta(&self.sstore.account_ref(&address)?, meta)?;
Ok(())
}

/// Returns `true` if the password for `account` is `password`. `false` if not.
pub fn test_password(&self, address: &Address, password: &str) -> Result<bool, Error> {
self.sstore.test_password(&StoreAccountRef::root(address.clone()), password)
self.sstore.test_password(&self.sstore.account_ref(&address)?, password)
.map_err(Into::into)
}

/// Permanently removes an account.
pub fn kill_account(&self, address: &Address, password: &str) -> Result<(), Error> {
self.sstore.remove_account(&StoreAccountRef::root(address.clone()), &password)?;
self.sstore.remove_account(&self.sstore.account_ref(&address)?, &password)?;
Ok(())
}

/// Changes the password of `account` from `password` to `new_password`. Fails if incorrect `password` given.
pub fn change_password(&self, account: &Address, password: String, new_password: String) -> Result<(), Error> {
self.sstore.change_password(&StoreAccountRef::root(account.clone()), &password, &new_password)
pub fn change_password(&self, address: &Address, password: String, new_password: String) -> Result<(), Error> {
self.sstore.change_password(&self.sstore.account_ref(address)?, &password, &new_password)
}

/// Helper method used for unlocking accounts.
fn unlock_account(&self, address: Address, password: String, unlock: Unlock) -> Result<(), Error> {
// verify password by signing dump message
// result may be discarded
let account = StoreAccountRef::root(address);
let account = self.sstore.account_ref(&address)?;
let _ = self.sstore.sign(&account, &password, &Default::default())?;

// check if account is already unlocked pernamently, if it is, do nothing
Expand Down Expand Up @@ -360,20 +360,21 @@ impl AccountProvider {
/// Checks if given account is unlocked
pub fn is_unlocked(&self, address: Address) -> bool {
let unlocked = self.unlocked.read();
let account = StoreAccountRef::root(address);
unlocked.get(&account).is_some()
self.sstore.account_ref(&address)
.map(|r| unlocked.get(&r).is_some())
.unwrap_or(false)
}

/// Signs the message. If password is not provided the account must be unlocked.
pub fn sign(&self, address: Address, password: Option<String>, message: Message) -> Result<Signature, SignError> {
let account = StoreAccountRef::root(address);
let account = self.sstore.account_ref(&address)?;
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
Ok(self.sstore.sign(&account, &password, &message)?)
}

/// Signs given message with supplied token. Returns a token to use in next signing within this session.
pub fn sign_with_token(&self, address: Address, token: AccountToken, message: Message) -> Result<(Signature, AccountToken), SignError> {
let account = StoreAccountRef::root(address);
let account = self.sstore.account_ref(&address)?;
let is_std_password = self.sstore.test_password(&account, &token)?;

let new_token = random_string(16);
Expand All @@ -396,7 +397,7 @@ impl AccountProvider {
pub fn decrypt_with_token(&self, address: Address, token: AccountToken, shared_mac: &[u8], message: &[u8])
-> Result<(Vec<u8>, AccountToken), SignError>
{
let account = StoreAccountRef::root(address);
let account = self.sstore.account_ref(&address)?;
let is_std_password = self.sstore.test_password(&account, &token)?;

let new_token = random_string(16);
Expand All @@ -417,7 +418,7 @@ impl AccountProvider {

/// Decrypts a message. If password is not provided the account must be unlocked.
pub fn decrypt(&self, address: Address, password: Option<String>, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, SignError> {
let account = StoreAccountRef::root(address);
let account = self.sstore.account_ref(&address)?;
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?)
}
Expand All @@ -433,6 +434,39 @@ impl AccountProvider {
.map(|a| a.into_iter().map(|a| a.address).collect())
.map_err(Into::into)
}

/// Create new vault.
pub fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> {
self.sstore.create_vault(name, password)
.map_err(Into::into)
}

/// Open existing vault.
pub fn open_vault(&self, name: &str, password: &str) -> Result<(), Error> {
self.sstore.open_vault(name, password)
.map_err(Into::into)
}

/// Close previously opened vault.
pub fn close_vault(&self, name: &str) -> Result<(), Error> {
self.sstore.close_vault(name)
.map_err(Into::into)
}

/// Change vault password.
pub fn change_vault_password(&self, name: &str, new_password: &str) -> Result<(), Error> {
self.sstore.change_vault_password(name, new_password)
.map_err(Into::into)
}

/// Change vault of the given address.
pub fn change_vault(&self, address: Address, new_vault: &str) -> Result<(), Error> {
let new_vault_ref = if new_vault.is_empty() { SecretVaultRef::Root } else { SecretVaultRef::Vault(new_vault.to_owned()) };
let old_account_ref = self.sstore.account_ref(&address)?;
self.sstore.change_account_vault(new_vault_ref, old_account_ref)
.map_err(Into::into)
.map(|_| ())
}
}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions ethstore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ parking_lot = "0.3"
ethcrypto = { path = "../ethcrypto" }
ethcore-util = { path = "../util" }
smallvec = "0.3.1"
ethcore-devtools = { path = "../devtools" }

[build-dependencies]
serde_codegen = { version = "0.8", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion ethstore/src/dir/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
// and find entry with given address
let to_remove = self.files()?
.into_iter()
.find(|&(_, ref acc)| acc == account);
.find(|&(_, ref acc)| acc.id == account.id && acc.address == account.address);

// remove it
match to_remove {
Expand Down
4 changes: 3 additions & 1 deletion ethstore/src/dir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ pub trait VaultKeyDirectory: KeyDirectory {
fn as_key_directory(&self) -> &KeyDirectory;
/// Vault name
fn name(&self) -> &str;
/// Get vault key
fn key(&self) -> VaultKey;
/// Set new key for vault
fn set_key(&self, old_key: VaultKey, key: VaultKey) -> Result<(), SetKeyError>;
fn set_key(&self, key: VaultKey) -> Result<(), SetKeyError>;
}

pub use self::disk::RootDiskDirectory;
Expand Down
Loading