Proper default accounts RPCs (#4580)
* Default accounts setting - account provider * RPC support for default accounts * Updating JS code * Rename whitelist to addresses
This commit is contained in:
parent
1949d44d0c
commit
72998d3ce3
@ -23,7 +23,7 @@ use self::stores::{AddressBook, DappsSettingsStore, NewDappsPolicy};
|
||||
use std::fmt;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::time::{Instant, Duration};
|
||||
use util::RwLock;
|
||||
use util::{FixedHash, RwLock};
|
||||
use ethstore::{SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore,
|
||||
random_string, SecretVaultRef, StoreAccountRef};
|
||||
use ethstore::dir::MemoryDirectory;
|
||||
@ -241,25 +241,88 @@ impl AccountProvider {
|
||||
Ok(accounts.into_iter().map(|a| a.address).collect())
|
||||
}
|
||||
|
||||
/// Sets a whitelist of accounts exposed for unknown dapps.
|
||||
/// Sets addresses of accounts exposed for unknown dapps.
|
||||
/// `None` means that all accounts will be visible.
|
||||
pub fn set_new_dapps_whitelist(&self, accounts: Option<Vec<Address>>) -> Result<(), Error> {
|
||||
/// If not `None` or empty it will also override default account.
|
||||
pub fn set_new_dapps_addresses(&self, accounts: Option<Vec<Address>>) -> Result<(), Error> {
|
||||
let current_default = self.new_dapps_default_address()?;
|
||||
|
||||
self.dapps_settings.write().set_policy(match accounts {
|
||||
None => NewDappsPolicy::AllAccounts,
|
||||
None => NewDappsPolicy::AllAccounts {
|
||||
default: current_default,
|
||||
},
|
||||
Some(accounts) => NewDappsPolicy::Whitelist(accounts),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets a whitelist of accounts exposed for unknown dapps.
|
||||
/// Gets addresses of accounts exposed for unknown dapps.
|
||||
/// `None` means that all accounts will be visible.
|
||||
pub fn new_dapps_whitelist(&self) -> Result<Option<Vec<Address>>, Error> {
|
||||
pub fn new_dapps_addresses(&self) -> Result<Option<Vec<Address>>, Error> {
|
||||
Ok(match self.dapps_settings.read().policy() {
|
||||
NewDappsPolicy::AllAccounts => None,
|
||||
NewDappsPolicy::AllAccounts { .. } => None,
|
||||
NewDappsPolicy::Whitelist(accounts) => Some(accounts),
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets a default account for unknown dapps.
|
||||
/// This account will always be returned as the first one.
|
||||
pub fn set_new_dapps_default_address(&self, address: Address) -> Result<(), Error> {
|
||||
if !self.valid_addresses()?.contains(&address) {
|
||||
return Err(SSError::InvalidAccount.into());
|
||||
}
|
||||
|
||||
let mut settings = self.dapps_settings.write();
|
||||
let new_policy = match settings.policy() {
|
||||
NewDappsPolicy::AllAccounts { .. } => NewDappsPolicy::AllAccounts { default: address },
|
||||
NewDappsPolicy::Whitelist(list) => NewDappsPolicy::Whitelist(Self::insert_default(list, address)),
|
||||
};
|
||||
settings.set_policy(new_policy);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Inserts given address as first in the vector, preventing duplicates.
|
||||
fn insert_default(mut addresses: Vec<Address>, default: Address) -> Vec<Address> {
|
||||
if let Some(position) = addresses.iter().position(|address| address == &default) {
|
||||
addresses.swap(0, position);
|
||||
} else {
|
||||
addresses.insert(0, default);
|
||||
}
|
||||
|
||||
addresses
|
||||
}
|
||||
|
||||
/// Returns a list of accounts that new dapp should see.
|
||||
/// First account is always the default account.
|
||||
fn new_dapps_addresses_list(&self) -> Result<Vec<Address>, Error> {
|
||||
match self.dapps_settings.read().policy() {
|
||||
NewDappsPolicy::AllAccounts { default } => if default.is_zero() {
|
||||
self.accounts()
|
||||
} else {
|
||||
Ok(Self::insert_default(self.accounts()?, default))
|
||||
},
|
||||
NewDappsPolicy::Whitelist(accounts) => {
|
||||
let addresses = self.filter_addresses(accounts)?;
|
||||
if addresses.is_empty() {
|
||||
Ok(vec![self.accounts()?.get(0).cloned().unwrap_or(0.into())])
|
||||
} else {
|
||||
Ok(addresses)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a default account for new dapps
|
||||
/// Will return zero address in case the default is not set and there are no accounts configured.
|
||||
pub fn new_dapps_default_address(&self) -> Result<Address, Error> {
|
||||
Ok(self.new_dapps_addresses_list()?
|
||||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(0.into())
|
||||
)
|
||||
}
|
||||
|
||||
/// Gets a list of dapps recently requesting accounts.
|
||||
pub fn recent_dapps(&self) -> Result<HashMap<DappId, u64>, Error> {
|
||||
Ok(self.dapps_settings.read().recent_dapps())
|
||||
@ -272,41 +335,74 @@ impl AccountProvider {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets addresses visile for dapp.
|
||||
pub fn dapps_addresses(&self, dapp: DappId) -> Result<Vec<Address>, Error> {
|
||||
let dapps = self.dapps_settings.read();
|
||||
/// Gets addresses visible for given dapp.
|
||||
pub fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<Address>, Error> {
|
||||
let accounts = self.dapps_settings.read().settings().get(&dapp).map(|settings| {
|
||||
(settings.accounts.clone(), settings.default.clone())
|
||||
});
|
||||
|
||||
let accounts = dapps.settings().get(&dapp).map(|settings| settings.accounts.clone());
|
||||
match accounts {
|
||||
Some(accounts) => Ok(accounts),
|
||||
None => match dapps.policy() {
|
||||
NewDappsPolicy::AllAccounts => self.accounts(),
|
||||
NewDappsPolicy::Whitelist(accounts) => self.filter_addresses(accounts),
|
||||
}
|
||||
Some((Some(accounts), Some(default))) => self.filter_addresses(Self::insert_default(accounts, default)),
|
||||
Some((Some(accounts), None)) => self.filter_addresses(accounts),
|
||||
Some((None, Some(default))) => self.filter_addresses(Self::insert_default(self.new_dapps_addresses_list()?, default)),
|
||||
_ => self.new_dapps_addresses_list(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns default account for particular dapp falling back to other allowed accounts if necessary.
|
||||
pub fn default_address(&self, dapp: DappId) -> Result<Address, Error> {
|
||||
self.dapps_addresses(dapp)?
|
||||
pub fn dapp_default_address(&self, dapp: DappId) -> Result<Address, Error> {
|
||||
let dapp_default = self.dapp_addresses(dapp)?
|
||||
.get(0)
|
||||
.cloned()
|
||||
.ok_or(SSError::InvalidAccount)
|
||||
.cloned();
|
||||
|
||||
match dapp_default {
|
||||
Some(default) => Ok(default),
|
||||
None => self.new_dapps_default_address(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets addresses visile for dapp.
|
||||
pub fn set_dapps_addresses(&self, dapp: DappId, addresses: Vec<Address>) -> Result<(), Error> {
|
||||
let addresses = self.filter_addresses(addresses)?;
|
||||
self.dapps_settings.write().set_accounts(dapp, addresses);
|
||||
/// Sets default address for given dapp.
|
||||
/// Does not alter dapp addresses, but this account will always be returned as the first one.
|
||||
pub fn set_dapp_default_address(&self, dapp: DappId, address: Address) -> Result<(), Error> {
|
||||
if !self.valid_addresses()?.contains(&address) {
|
||||
return Err(SSError::InvalidAccount.into());
|
||||
}
|
||||
|
||||
self.dapps_settings.write().set_default(dapp, address);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sets addresses visible for given dapp.
|
||||
/// If `None` - falls back to dapps addresses
|
||||
/// If not `None` and not empty it will also override default account.
|
||||
pub fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<Address>>) -> Result<(), Error> {
|
||||
let (addresses, default) = match addresses {
|
||||
Some(addresses) => {
|
||||
let addresses = self.filter_addresses(addresses)?;
|
||||
let default = addresses.get(0).cloned();
|
||||
(Some(addresses), default)
|
||||
},
|
||||
None => (None, None),
|
||||
};
|
||||
|
||||
let mut settings = self.dapps_settings.write();
|
||||
if let Some(default) = default {
|
||||
settings.set_default(dapp.clone(), default);
|
||||
}
|
||||
settings.set_accounts(dapp, addresses);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn valid_addresses(&self) -> Result<HashSet<Address>, Error> {
|
||||
Ok(self.addresses_info().into_iter()
|
||||
.map(|(address, _)| address)
|
||||
.chain(self.accounts()?)
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Removes addresses that are neither accounts nor in address book.
|
||||
fn filter_addresses(&self, addresses: Vec<Address>) -> Result<Vec<Address>, Error> {
|
||||
let valid = self.addresses_info().into_iter()
|
||||
.map(|(address, _)| address)
|
||||
.chain(self.accounts()?)
|
||||
.collect::<HashSet<_>>();
|
||||
let valid = self.valid_addresses()?;
|
||||
|
||||
Ok(addresses.into_iter()
|
||||
.filter(|a| valid.contains(&a))
|
||||
@ -743,44 +839,92 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_set_dapps_addresses() {
|
||||
fn should_reset_dapp_addresses_to_default() {
|
||||
// given
|
||||
let ap = AccountProvider::transient_provider();
|
||||
let app = DappId("app1".into());
|
||||
// add accounts to address book
|
||||
ap.set_address_name(1.into(), "1".into());
|
||||
ap.set_address_name(2.into(), "2".into());
|
||||
// set `AllAccounts` policy
|
||||
ap.set_new_dapps_addresses(Some(vec![1.into(), 2.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
|
||||
// Alter and check
|
||||
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 3.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
|
||||
|
||||
// Reset back to default
|
||||
ap.set_dapp_addresses(app.clone(), None).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_set_dapps_default_address() {
|
||||
// given
|
||||
let ap = AccountProvider::transient_provider();
|
||||
let app = DappId("app1".into());
|
||||
// set `AllAccounts` policy
|
||||
ap.set_new_dapps_whitelist(None).unwrap();
|
||||
ap.set_new_dapps_addresses(None).unwrap();
|
||||
// add accounts to address book
|
||||
ap.set_address_name(1.into(), "1".into());
|
||||
ap.set_address_name(2.into(), "2".into());
|
||||
|
||||
// when
|
||||
ap.set_dapps_addresses(app.clone(), vec![1.into(), 2.into(), 3.into()]).unwrap();
|
||||
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 2.into(), 3.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||
|
||||
// then
|
||||
assert_eq!(ap.dapps_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
// when setting empty list
|
||||
ap.set_dapp_addresses(app.clone(), Some(vec![])).unwrap();
|
||||
|
||||
// then default account is intact
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||
|
||||
// alter default account
|
||||
ap.set_dapp_default_address("app1".into(), 2.into()).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![2.into()]);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 2.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_set_dapps_policy() {
|
||||
fn should_set_dapps_policy_and_default_account() {
|
||||
// given
|
||||
let ap = AccountProvider::transient_provider();
|
||||
|
||||
// default_account should be always available
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), 0.into());
|
||||
|
||||
let address = ap.new_account("test").unwrap();
|
||||
ap.set_address_name(1.into(), "1".into());
|
||||
|
||||
// When returning nothing
|
||||
ap.set_new_dapps_whitelist(Some(vec![])).unwrap();
|
||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![]);
|
||||
// Default account set to first account by default
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
|
||||
|
||||
// Even when returning nothing
|
||||
ap.set_new_dapps_addresses(Some(vec![])).unwrap();
|
||||
// Default account is still returned
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||
|
||||
// change to all
|
||||
ap.set_new_dapps_whitelist(None).unwrap();
|
||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![address]);
|
||||
ap.set_new_dapps_addresses(None).unwrap();
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||
|
||||
// change to non-existent account
|
||||
ap.set_new_dapps_whitelist(Some(vec![2.into()])).unwrap();
|
||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![]);
|
||||
ap.set_new_dapps_addresses(Some(vec![2.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||
|
||||
// change to a whitelist
|
||||
ap.set_new_dapps_whitelist(Some(vec![1.into()])).unwrap();
|
||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![1.into()]);
|
||||
// change to a addresses
|
||||
ap.set_new_dapps_addresses(Some(vec![1.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![1.into()]);
|
||||
|
||||
// it overrides default account
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), 1.into());
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||
|
||||
ap.set_new_dapps_default_address(address).unwrap();
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
|
||||
}
|
||||
}
|
||||
|
@ -92,13 +92,16 @@ impl AddressBook {
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub struct DappsSettings {
|
||||
/// A list of visible accounts
|
||||
pub accounts: Vec<Address>,
|
||||
pub accounts: Option<Vec<Address>>,
|
||||
/// Default account
|
||||
pub default: Option<Address>,
|
||||
}
|
||||
|
||||
impl From<JsonSettings> for DappsSettings {
|
||||
fn from(s: JsonSettings) -> Self {
|
||||
DappsSettings {
|
||||
accounts: s.accounts.into_iter().map(Into::into).collect(),
|
||||
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
|
||||
default: s.default.map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,7 +109,8 @@ impl From<JsonSettings> for DappsSettings {
|
||||
impl From<DappsSettings> for JsonSettings {
|
||||
fn from(s: DappsSettings) -> Self {
|
||||
JsonSettings {
|
||||
accounts: s.accounts.into_iter().map(Into::into).collect(),
|
||||
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
|
||||
default: s.default.map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,14 +118,18 @@ impl From<DappsSettings> for JsonSettings {
|
||||
/// Dapps user settings
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum NewDappsPolicy {
|
||||
AllAccounts,
|
||||
AllAccounts {
|
||||
default: Address,
|
||||
},
|
||||
Whitelist(Vec<Address>),
|
||||
}
|
||||
|
||||
impl From<JsonNewDappsPolicy> for NewDappsPolicy {
|
||||
fn from(s: JsonNewDappsPolicy) -> Self {
|
||||
match s {
|
||||
JsonNewDappsPolicy::AllAccounts => NewDappsPolicy::AllAccounts,
|
||||
JsonNewDappsPolicy::AllAccounts { default } => NewDappsPolicy::AllAccounts {
|
||||
default: default.into(),
|
||||
},
|
||||
JsonNewDappsPolicy::Whitelist(accounts) => NewDappsPolicy::Whitelist(
|
||||
accounts.into_iter().map(Into::into).collect()
|
||||
),
|
||||
@ -132,7 +140,9 @@ impl From<JsonNewDappsPolicy> for NewDappsPolicy {
|
||||
impl From<NewDappsPolicy> for JsonNewDappsPolicy {
|
||||
fn from(s: NewDappsPolicy) -> Self {
|
||||
match s {
|
||||
NewDappsPolicy::AllAccounts => JsonNewDappsPolicy::AllAccounts,
|
||||
NewDappsPolicy::AllAccounts { default } => JsonNewDappsPolicy::AllAccounts {
|
||||
default: default.into(),
|
||||
},
|
||||
NewDappsPolicy::Whitelist(accounts) => JsonNewDappsPolicy::Whitelist(
|
||||
accounts.into_iter().map(Into::into).collect()
|
||||
),
|
||||
@ -230,7 +240,9 @@ impl DappsSettingsStore {
|
||||
|
||||
/// Returns current new dapps policy
|
||||
pub fn policy(&self) -> NewDappsPolicy {
|
||||
self.policy.get("default").cloned().unwrap_or(NewDappsPolicy::AllAccounts)
|
||||
self.policy.get("default").cloned().unwrap_or(NewDappsPolicy::AllAccounts {
|
||||
default: 0.into(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns recent dapps with last accessed timestamp
|
||||
@ -266,13 +278,22 @@ impl DappsSettingsStore {
|
||||
}
|
||||
|
||||
/// Sets accounts for specific dapp.
|
||||
pub fn set_accounts(&mut self, id: DappId, accounts: Vec<Address>) {
|
||||
pub fn set_accounts(&mut self, id: DappId, accounts: Option<Vec<Address>>) {
|
||||
{
|
||||
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
settings.accounts = accounts;
|
||||
}
|
||||
self.settings.save(JsonSettings::write);
|
||||
}
|
||||
|
||||
/// Sets a default account for specific dapp.
|
||||
pub fn set_default(&mut self, id: DappId, default: Address) {
|
||||
{
|
||||
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
settings.default = Some(default);
|
||||
}
|
||||
self.settings.save(JsonSettings::write);
|
||||
}
|
||||
}
|
||||
|
||||
/// Disk-serializable HashMap
|
||||
@ -385,13 +406,14 @@ mod tests {
|
||||
let mut b = DappsSettingsStore::new(&path);
|
||||
|
||||
// when
|
||||
b.set_accounts("dappOne".into(), vec![1.into(), 2.into()]);
|
||||
b.set_accounts("dappOne".into(), Some(vec![1.into(), 2.into()]));
|
||||
|
||||
// then
|
||||
let b = DappsSettingsStore::new(&path);
|
||||
assert_eq!(b.settings(), hash_map![
|
||||
"dappOne".into() => DappsSettings {
|
||||
accounts: vec![1.into(), 2.into()],
|
||||
accounts: Some(vec![1.into(), 2.into()]),
|
||||
default: None,
|
||||
}
|
||||
]);
|
||||
}
|
||||
@ -422,7 +444,9 @@ mod tests {
|
||||
let mut store = DappsSettingsStore::new(&path);
|
||||
|
||||
// Test default policy
|
||||
assert_eq!(store.policy(), NewDappsPolicy::AllAccounts);
|
||||
assert_eq!(store.policy(), NewDappsPolicy::AllAccounts {
|
||||
default: 0.into(),
|
||||
});
|
||||
|
||||
// when
|
||||
store.set_policy(NewDappsPolicy::Whitelist(vec![1.into(), 2.into()]));
|
||||
|
@ -170,18 +170,30 @@ export default class Parity {
|
||||
.execute('parity_generateSecretPhrase');
|
||||
}
|
||||
|
||||
getDappsAddresses (dappId) {
|
||||
getDappAddresses (dappId) {
|
||||
return this._transport
|
||||
.execute('parity_getDappsAddresses', dappId)
|
||||
.execute('parity_getDappAddresses', dappId)
|
||||
.then(outAddresses);
|
||||
}
|
||||
|
||||
getNewDappsWhitelist () {
|
||||
getDappDefaultAddress (dappId) {
|
||||
return this._transport
|
||||
.execute('parity_getNewDappsWhitelist')
|
||||
.execute('parity_getDappDefaultAddress', dappId)
|
||||
.then(outAddress);
|
||||
}
|
||||
|
||||
getNewDappsAddresses () {
|
||||
return this._transport
|
||||
.execute('parity_getNewDappsAddresses')
|
||||
.then((addresses) => addresses ? addresses.map(outAddress) : null);
|
||||
}
|
||||
|
||||
getNewDappsDefaultAddress () {
|
||||
return this._transport
|
||||
.execute('parity_getNewDappsDefaultAddress')
|
||||
.then(outAddress);
|
||||
}
|
||||
|
||||
getVaultMeta (vaultName) {
|
||||
return this._transport
|
||||
.execute('parity_getVaultMeta', vaultName)
|
||||
@ -391,9 +403,14 @@ export default class Parity {
|
||||
.execute('parity_setAuthor', inAddress(address));
|
||||
}
|
||||
|
||||
setDappsAddresses (dappId, addresses) {
|
||||
setDappAddresses (dappId, addresses) {
|
||||
return this._transport
|
||||
.execute('parity_setDappsAddresses', dappId, inAddresses(addresses));
|
||||
.execute('parity_setDappAddresses', dappId, inAddresses(addresses));
|
||||
}
|
||||
|
||||
setDappDefaultAddress (dappId, address) {
|
||||
return this._transport
|
||||
.execute('parity_setDappDefaultAddress', dappId, address ? inAddress(address) : null);
|
||||
}
|
||||
|
||||
setEngineSigner (address, password) {
|
||||
@ -431,9 +448,14 @@ export default class Parity {
|
||||
.execute('parity_setMode', mode);
|
||||
}
|
||||
|
||||
setNewDappsWhitelist (addresses) {
|
||||
setNewDappsAddresses (addresses) {
|
||||
return this._transport
|
||||
.execute('parity_setNewDappsWhitelist', addresses ? inAddresses(addresses) : null);
|
||||
.execute('parity_setNewDappsAddresses', addresses ? inAddresses(addresses) : null);
|
||||
}
|
||||
|
||||
setNewDappsDefaultAddress (address) {
|
||||
return this._transport
|
||||
.execute('parity_setNewDappsDefaultAddress', inAddress(address));
|
||||
}
|
||||
|
||||
setTransactionsLimit (quantity) {
|
||||
|
@ -123,8 +123,10 @@ export default class Personal {
|
||||
this._accountsInfo();
|
||||
return;
|
||||
|
||||
case 'parity_setDappsAddresses':
|
||||
case 'parity_setNewDappsWhitelist':
|
||||
case 'parity_setDappAddresses':
|
||||
case 'parity_setDappDefaultAddress':
|
||||
case 'parity_setNewDappsAddresses':
|
||||
case 'parity_setNewDappsDefaultAddress':
|
||||
this._defaultAccount(true);
|
||||
this._listAccounts();
|
||||
return;
|
||||
|
@ -1186,9 +1186,9 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
setDappsAddresses: {
|
||||
setDappAddresses: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Sets the available addresses for a dapp.',
|
||||
desc: 'Sets the available addresses for a dapp. When provided with non-empty list changes the default account as well.',
|
||||
params: [
|
||||
{
|
||||
type: String,
|
||||
@ -1197,7 +1197,7 @@ export default {
|
||||
},
|
||||
{
|
||||
type: Array,
|
||||
desc: 'Array of available accounts available to the dapp.',
|
||||
desc: 'Array of available accounts available to the dapp or `null` for default list.',
|
||||
example: ['0x407d73d8a49eeb85d32cf465507dd71d507100c1']
|
||||
}
|
||||
],
|
||||
@ -1208,7 +1208,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
getDappsAddresses: {
|
||||
getDappAddresses: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Returns the list of accounts available to a specific dapp.',
|
||||
params: [
|
||||
@ -1225,13 +1225,52 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
setNewDappsWhitelist: {
|
||||
setDappDefaultAddress: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Changes dapp default address. Does not affect other accounts exposed for this dapp, but default account will always be retured as the first one.',
|
||||
params: [
|
||||
{
|
||||
type: String,
|
||||
desc: 'Dapp Id.',
|
||||
example: 'web'
|
||||
},
|
||||
{
|
||||
type: Address,
|
||||
desc: 'Default Address.',
|
||||
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: Boolean,
|
||||
desc: '`true` if the call was successful',
|
||||
example: true
|
||||
}
|
||||
},
|
||||
|
||||
getDappDefaultAddress: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Returns a default account available to a specific dapp.',
|
||||
params: [
|
||||
{
|
||||
type: String,
|
||||
desc: 'Dapp Id.',
|
||||
example: 'web'
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: Address,
|
||||
desc: 'Default Address',
|
||||
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||
}
|
||||
},
|
||||
|
||||
setNewDappsAddresses: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Sets the list of accounts available to new dapps.',
|
||||
params: [
|
||||
{
|
||||
type: Array,
|
||||
desc: 'List of accounts available by default.',
|
||||
desc: 'List of accounts available by default or `null` for all accounts.',
|
||||
example: ['0x407d73d8a49eeb85d32cf465507dd71d507100c1']
|
||||
}
|
||||
],
|
||||
@ -1242,7 +1281,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
getNewDappsWhitelist: {
|
||||
getNewDappsAddresses: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Returns the list of accounts available to a new dapps.',
|
||||
params: [],
|
||||
@ -1253,6 +1292,34 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
setNewDappsDefaultAddress: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Changes global default address. This setting may be overriden for a specific dapp.',
|
||||
params: [
|
||||
{
|
||||
type: Address,
|
||||
desc: 'Default Address.',
|
||||
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: Boolean,
|
||||
desc: '`true` if the call was successful',
|
||||
example: true
|
||||
}
|
||||
},
|
||||
|
||||
getNewDappsDefaultAddress: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Returns a default account available to dapps.',
|
||||
params: [],
|
||||
returns: {
|
||||
type: Address,
|
||||
desc: 'Default Address',
|
||||
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||
}
|
||||
},
|
||||
|
||||
listRecentDapps: {
|
||||
subdoc: SUBDOC_ACCOUNTS,
|
||||
desc: 'Returns a list of the most recent active dapps.',
|
||||
|
@ -102,7 +102,7 @@ export default class Store {
|
||||
|
||||
loadWhitelist () {
|
||||
return this._api.parity
|
||||
.getNewDappsWhitelist()
|
||||
.getNewDappsAddresses()
|
||||
.then((whitelist) => {
|
||||
this.setWhitelist(whitelist);
|
||||
})
|
||||
@ -113,7 +113,7 @@ export default class Store {
|
||||
|
||||
updateWhitelist (whitelist) {
|
||||
return this._api.parity
|
||||
.setNewDappsWhitelist(whitelist)
|
||||
.setNewDappsAddresses(whitelist)
|
||||
.then(() => {
|
||||
this.setWhitelist(whitelist);
|
||||
})
|
||||
|
@ -31,8 +31,8 @@ let store;
|
||||
function create () {
|
||||
api = {
|
||||
parity: {
|
||||
getNewDappsWhitelist: sinon.stub().resolves(WHITELIST),
|
||||
setNewDappsWhitelist: sinon.stub().resolves(true)
|
||||
getNewDappsAddresses: sinon.stub().resolves(WHITELIST),
|
||||
setNewDappsAddresses: sinon.stub().resolves(true)
|
||||
}
|
||||
};
|
||||
|
||||
@ -46,7 +46,7 @@ describe('modals/DappPermissions/store', () => {
|
||||
|
||||
describe('constructor', () => {
|
||||
it('retrieves the whitelist via api', () => {
|
||||
expect(api.parity.getNewDappsWhitelist).to.be.calledOnce;
|
||||
expect(api.parity.getNewDappsAddresses).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('sets the retrieved whitelist', () => {
|
||||
@ -79,12 +79,12 @@ describe('modals/DappPermissions/store', () => {
|
||||
store.closeModal();
|
||||
});
|
||||
|
||||
it('calls setNewDappsWhitelist', () => {
|
||||
expect(api.parity.setNewDappsWhitelist).to.have.been.calledOnce;
|
||||
it('calls setNewDappsAddresses', () => {
|
||||
expect(api.parity.setNewDappsAddresses).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('has the default account in first position', () => {
|
||||
expect(api.parity.setNewDappsWhitelist).to.have.been.calledWith(['789', '456']);
|
||||
expect(api.parity.setNewDappsAddresses).to.have.been.calledWith(['789', '456']);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -61,7 +61,7 @@ export default class AccountStore {
|
||||
this.setDefaultAccount(address);
|
||||
|
||||
return this._api.parity
|
||||
.setNewDappsWhitelist(accounts)
|
||||
.setNewDappsAddresses(accounts)
|
||||
.catch((error) => {
|
||||
console.warn('makeDefaultAccount', error);
|
||||
});
|
||||
@ -78,7 +78,7 @@ export default class AccountStore {
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
this._api.parity.getNewDappsWhitelist(),
|
||||
this._api.parity.getNewDappsAddresses(),
|
||||
this._api.parity.allAccountsInfo()
|
||||
])
|
||||
.then(([whitelist, accounts]) => {
|
||||
|
@ -76,8 +76,8 @@ describe('views/ParityBar/AccountStore', () => {
|
||||
store.setAccounts.restore();
|
||||
});
|
||||
|
||||
it('calls into parity_getNewDappsWhitelist', () => {
|
||||
expect(api.parity.getNewDappsWhitelist).to.have.been.called;
|
||||
it('calls into parity_getNewDappsAddresses', () => {
|
||||
expect(api.parity.getNewDappsAddresses).to.have.been.called;
|
||||
});
|
||||
|
||||
it('calls into parity_allAccountsInfo', () => {
|
||||
@ -104,8 +104,8 @@ describe('views/ParityBar/AccountStore', () => {
|
||||
return store.makeDefaultAccount(ACCOUNT_NEW);
|
||||
});
|
||||
|
||||
it('calls into parity_setNewDappsWhitelist (with ordering)', () => {
|
||||
expect(api.parity.setNewDappsWhitelist).to.have.been.calledWith([
|
||||
it('calls into parity_setNewDappsAddresses (with ordering)', () => {
|
||||
expect(api.parity.setNewDappsAddresses).to.have.been.calledWith([
|
||||
ACCOUNT_NEW, ACCOUNT_FIRST, ACCOUNT_DEFAULT
|
||||
]);
|
||||
});
|
||||
|
@ -36,8 +36,8 @@ function createApi () {
|
||||
parity: {
|
||||
defaultAccount: sinon.stub().resolves(ACCOUNT_DEFAULT),
|
||||
allAccountsInfo: sinon.stub().resolves(ACCOUNTS),
|
||||
getNewDappsWhitelist: sinon.stub().resolves(null),
|
||||
setNewDappsWhitelist: sinon.stub().resolves(true)
|
||||
getNewDappsAddresses: sinon.stub().resolves(null),
|
||||
setNewDappsAddresses: sinon.stub().resolves(true)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,9 @@ use hash;
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct DappsSettings {
|
||||
/// A list of accounts this Dapp can see.
|
||||
pub accounts: Vec<hash::Address>,
|
||||
pub accounts: Option<Vec<hash::Address>>,
|
||||
/// Default account
|
||||
pub default: Option<hash::Address>,
|
||||
}
|
||||
|
||||
impl_serialization!(String => DappsSettings);
|
||||
@ -40,7 +42,10 @@ impl_serialization!(String => DappsHistory);
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum NewDappsPolicy {
|
||||
/// All accounts are exposed by default.
|
||||
AllAccounts,
|
||||
AllAccounts {
|
||||
/// Default account, which should be returned as the first one.
|
||||
default: hash::Address,
|
||||
},
|
||||
/// Only accounts listed here are exposed by default for new dapps.
|
||||
Whitelist(Vec<hash::Address>),
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
||||
let store = take_weak!(self.accounts);
|
||||
store
|
||||
.note_dapp_used(dapp.clone())
|
||||
.and_then(|_| store.dapps_addresses(dapp))
|
||||
.and_then(|_| store.dapp_addresses(dapp))
|
||||
.map_err(|e| errors::internal("Could not fetch accounts.", e))
|
||||
}
|
||||
}
|
||||
@ -308,10 +308,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
let author = move || {
|
||||
let mut miner = take_weak!(self.miner).author();
|
||||
if miner == 0.into() {
|
||||
let accounts = self.dapp_accounts(dapp.into())?;
|
||||
if let Some(address) = accounts.get(0) {
|
||||
miner = *address;
|
||||
}
|
||||
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
|
||||
}
|
||||
|
||||
Ok(RpcH160::from(miner))
|
||||
|
@ -187,7 +187,7 @@ impl Eth for EthClient {
|
||||
|
||||
let accounts = self.accounts
|
||||
.note_dapp_used(dapp.clone())
|
||||
.and_then(|_| self.accounts.dapps_addresses(dapp))
|
||||
.and_then(|_| self.accounts.dapp_addresses(dapp))
|
||||
.map_err(|e| errors::internal("Could not fetch accounts.", e))
|
||||
.map(|accs| accs.into_iter().map(Into::<RpcH160>::into).collect());
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::str::FromStr;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use futures::{self, Future, BoxFuture};
|
||||
use futures::{future, Future, BoxFuture};
|
||||
|
||||
use util::{RotatingLogger, Address};
|
||||
use util::misc::version_data;
|
||||
@ -118,7 +118,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
||||
let store = take_weak!(self.accounts);
|
||||
let dapp_accounts = store
|
||||
.note_dapp_used(dapp.clone().into())
|
||||
.and_then(|_| store.dapps_addresses(dapp.into()))
|
||||
.and_then(|_| store.dapp_addresses(dapp.into()))
|
||||
.map_err(|e| errors::internal("Could not fetch accounts.", e))?
|
||||
.into_iter().collect::<HashSet<_>>();
|
||||
|
||||
@ -146,16 +146,13 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
||||
|
||||
fn default_account(&self, meta: Self::Metadata) -> BoxFuture<H160, Error> {
|
||||
let dapp_id = meta.dapp_id();
|
||||
let default_account = move || {
|
||||
Ok(take_weak!(self.accounts)
|
||||
.dapps_addresses(dapp_id.into())
|
||||
future::ok(
|
||||
take_weakf!(self.accounts)
|
||||
.dapp_default_address(dapp_id.into())
|
||||
.map(Into::into)
|
||||
.ok()
|
||||
.and_then(|accounts| accounts.get(0).cloned())
|
||||
.map(|acc| acc.into())
|
||||
.unwrap_or_default())
|
||||
};
|
||||
|
||||
futures::done(default_account()).boxed()
|
||||
.unwrap_or_default()
|
||||
).boxed()
|
||||
}
|
||||
|
||||
fn transactions_limit(&self) -> Result<usize, Error> {
|
||||
|
@ -142,41 +142,69 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn set_account_visibility(&self, _address: RpcH160, _dapp: RpcH256, _visible: bool) -> Result<bool, Error> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn set_dapps_addresses(&self, dapp: DappId, addresses: Vec<RpcH160>) -> Result<bool, Error> {
|
||||
fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<RpcH160>>) -> Result<bool, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store.set_dapps_addresses(dapp.into(), into_vec(addresses))
|
||||
store.set_dapp_addresses(dapp.into(), addresses.map(into_vec))
|
||||
.map_err(|e| errors::account("Couldn't set dapp addresses.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store.dapp_addresses(dapp.into())
|
||||
.map_err(|e| errors::account("Couldn't get dapp addresses.", e))
|
||||
.map(into_vec)
|
||||
}
|
||||
|
||||
fn set_dapp_default_address(&self, dapp: DappId, address: RpcH160) -> Result<bool, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store.set_dapp_default_address(dapp.into(), address.into())
|
||||
.map_err(|e| errors::account("Couldn't set dapp default address.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn dapp_default_address(&self, dapp: DappId) -> Result<RpcH160, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store.dapp_default_address(dapp.into())
|
||||
.map_err(|e| errors::account("Couldn't get dapp default address.", e))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn set_new_dapps_addresses(&self, addresses: Option<Vec<RpcH160>>) -> Result<bool, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store
|
||||
.set_new_dapps_addresses(addresses.map(into_vec))
|
||||
.map_err(|e| errors::account("Couldn't set dapps addresses.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn dapps_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>, Error> {
|
||||
fn new_dapps_addresses(&self) -> Result<Option<Vec<RpcH160>>, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store.dapps_addresses(dapp.into())
|
||||
store.new_dapps_addresses()
|
||||
.map_err(|e| errors::account("Couldn't get dapps addresses.", e))
|
||||
.map(into_vec)
|
||||
.map(|accounts| accounts.map(into_vec))
|
||||
}
|
||||
|
||||
fn set_new_dapps_whitelist(&self, whitelist: Option<Vec<RpcH160>>) -> Result<bool, Error> {
|
||||
fn set_new_dapps_default_address(&self, address: RpcH160) -> Result<bool, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store
|
||||
.set_new_dapps_whitelist(whitelist.map(into_vec))
|
||||
.map_err(|e| errors::account("Couldn't set dapps whitelist.", e))
|
||||
store.set_new_dapps_default_address(address.into())
|
||||
.map_err(|e| errors::account("Couldn't set new dapps default address.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn new_dapps_whitelist(&self) -> Result<Option<Vec<RpcH160>>, Error> {
|
||||
fn new_dapps_default_address(&self) -> Result<RpcH160, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
|
||||
store.new_dapps_whitelist()
|
||||
.map_err(|e| errors::account("Couldn't get dapps whitelist.", e))
|
||||
.map(|accounts| accounts.map(into_vec))
|
||||
store.new_dapps_default_address()
|
||||
.map_err(|e| errors::account("Couldn't get new dapps default address.", e))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn recent_dapps(&self) -> Result<BTreeMap<DappId, u64>, Error> {
|
||||
|
@ -101,7 +101,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
||||
let default = match request.from.as_ref() {
|
||||
Some(account) => Ok(account.clone().into()),
|
||||
None => accounts
|
||||
.default_address(meta.dapp_id().into())
|
||||
.dapp_default_address(meta.dapp_id().into())
|
||||
.map_err(|e| errors::account("Cannot find default account.", e)),
|
||||
};
|
||||
|
||||
|
@ -86,7 +86,7 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
|
||||
let accounts = take_weakf!(self.accounts);
|
||||
let default_account = match default_account {
|
||||
DefaultAccount::Provided(acc) => acc,
|
||||
DefaultAccount::ForDapp(dapp) => accounts.default_address(dapp).ok().unwrap_or_default(),
|
||||
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
|
||||
};
|
||||
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
|
@ -55,7 +55,7 @@ impl<D: Dispatcher + 'static> SigningUnsafeClient<D> {
|
||||
let accounts = take_weakf!(self.accounts);
|
||||
let default = match account {
|
||||
DefaultAccount::Provided(acc) => acc,
|
||||
DefaultAccount::ForDapp(dapp) => accounts.default_address(dapp).ok().unwrap_or_default(),
|
||||
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
|
||||
};
|
||||
|
||||
let dis = self.dispatcher.clone();
|
||||
|
@ -368,7 +368,7 @@ fn rpc_eth_gas_price() {
|
||||
fn rpc_eth_accounts() {
|
||||
let tester = EthTester::default();
|
||||
let address = tester.accounts_provider.new_account("").unwrap();
|
||||
tester.accounts_provider.set_new_dapps_whitelist(None).unwrap();
|
||||
tester.accounts_provider.set_new_dapps_addresses(None).unwrap();
|
||||
tester.accounts_provider.set_address_name(1.into(), "1".into());
|
||||
tester.accounts_provider.set_address_name(10.into(), "10".into());
|
||||
|
||||
@ -377,14 +377,14 @@ fn rpc_eth_accounts() {
|
||||
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
tester.accounts_provider.set_new_dapps_whitelist(Some(vec![1.into()])).unwrap();
|
||||
tester.accounts_provider.set_new_dapps_addresses(Some(vec![1.into()])).unwrap();
|
||||
// even with some account it should return empty list (no dapp detected)
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// when we add visible address it should return that.
|
||||
tester.accounts_provider.set_dapps_addresses("app1".into(), vec![10.into()]).unwrap();
|
||||
tester.accounts_provider.set_dapp_addresses("app1".into(), Some(vec![10.into()])).unwrap();
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
||||
let mut meta = Metadata::default();
|
||||
|
@ -110,17 +110,19 @@ fn rpc_parity_accounts_info() {
|
||||
assert_eq!(accounts.len(), 1);
|
||||
let address = accounts[0];
|
||||
|
||||
deps.accounts.set_account_name(address.clone(), "Test".to_owned()).unwrap();
|
||||
deps.accounts.set_account_meta(address.clone(), "{foo: 69}".to_owned()).unwrap();
|
||||
deps.accounts.set_address_name(1.into(), "XX".into());
|
||||
deps.accounts.set_account_name(address.clone(), "Test".into()).unwrap();
|
||||
deps.accounts.set_account_meta(address.clone(), "{foo: 69}".into()).unwrap();
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"name\":\"Test\"}}}},\"id\":1}}", address.hex());
|
||||
assert_eq!(io.handle_request_sync(request), Some(response));
|
||||
|
||||
// Change the whitelist
|
||||
deps.accounts.set_new_dapps_whitelist(Some(vec![1.into()])).unwrap();
|
||||
let address = Address::from(1);
|
||||
deps.accounts.set_new_dapps_addresses(Some(vec![address.clone()])).unwrap();
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{}},\"id\":1}}");
|
||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"name\":\"XX\"}}}},\"id\":1}}", address.hex());
|
||||
assert_eq!(io.handle_request_sync(request), Some(response));
|
||||
}
|
||||
|
||||
|
@ -125,48 +125,87 @@ fn rpc_parity_set_and_get_dapps_accounts() {
|
||||
// given
|
||||
let tester = setup();
|
||||
tester.accounts.set_address_name(10.into(), "10".into());
|
||||
assert_eq!(tester.accounts.dapps_addresses("app1".into()).unwrap(), vec![]);
|
||||
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![]);
|
||||
|
||||
// when
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setDappsAddresses","params":["app1",["0x000000000000000000000000000000000000000a","0x0000000000000000000000000000000000000001"]], "id": 1}"#;
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setDappAddresses","params":["app1",["0x000000000000000000000000000000000000000a","0x0000000000000000000000000000000000000001"]], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// then
|
||||
assert_eq!(tester.accounts.dapps_addresses("app1".into()).unwrap(), vec![10.into()]);
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getDappsAddresses","params":["app1"], "id": 1}"#;
|
||||
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![10.into()]);
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getDappAddresses","params":["app1"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_set_and_get_dapp_default_address() {
|
||||
// given
|
||||
let tester = setup();
|
||||
tester.accounts.set_address_name(10.into(), "10".into());
|
||||
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![]);
|
||||
|
||||
// when
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setDappDefaultAddress","params":["app1", "0x000000000000000000000000000000000000000a"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// then
|
||||
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![10.into()]);
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getDappDefaultAddress","params":["app1"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x000000000000000000000000000000000000000a","id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_set_and_get_new_dapps_whitelist() {
|
||||
// given
|
||||
let tester = setup();
|
||||
|
||||
// when set to whitelist
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsWhitelist","params":[["0x000000000000000000000000000000000000000a"]], "id": 1}"#;
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsAddresses","params":[["0x000000000000000000000000000000000000000a"]], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// then
|
||||
assert_eq!(tester.accounts.new_dapps_whitelist().unwrap(), Some(vec![10.into()]));
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsWhitelist","params":[], "id": 1}"#;
|
||||
assert_eq!(tester.accounts.new_dapps_addresses().unwrap(), Some(vec![10.into()]));
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsAddresses","params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// when set to empty
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsWhitelist","params":[null], "id": 1}"#;
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsAddresses","params":[null], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// then
|
||||
assert_eq!(tester.accounts.new_dapps_whitelist().unwrap(), None);
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsWhitelist","params":[], "id": 1}"#;
|
||||
assert_eq!(tester.accounts.new_dapps_addresses().unwrap(), None);
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsAddresses","params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_set_and_get_new_dapps_default_address() {
|
||||
// given
|
||||
let tester = setup();
|
||||
tester.accounts.set_address_name(10.into(), "10".into());
|
||||
assert_eq!(tester.accounts.new_dapps_default_address().unwrap(), 0.into());
|
||||
|
||||
// when
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsDefaultAddress","params":["0x000000000000000000000000000000000000000a"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
|
||||
// then
|
||||
assert_eq!(tester.accounts.new_dapps_default_address().unwrap(), 10.into());
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsDefaultAddress","params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x000000000000000000000000000000000000000a","id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_recent_dapps() {
|
||||
// given
|
||||
|
@ -70,28 +70,51 @@ build_rpc_trait! {
|
||||
#[rpc(name = "parity_setAccountMeta")]
|
||||
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
|
||||
|
||||
/// Sets account visibility.
|
||||
/// @unimplemented
|
||||
#[rpc(name = "parity_setAccountVisiblity")]
|
||||
fn set_account_visibility(&self, H160, H256, bool) -> Result<bool, Error>;
|
||||
|
||||
/// Sets accounts exposed for particular dapp.
|
||||
#[rpc(name = "parity_setDappsAddresses")]
|
||||
fn set_dapps_addresses(&self, DappId, Vec<H160>) -> Result<bool, Error>;
|
||||
/// Sets addresses exposed for particular dapp.
|
||||
/// Setting a non-empty list will also override default account.
|
||||
/// Setting `None` will resets visible account to what's visible for new dapps
|
||||
/// (does not affect default account though)
|
||||
#[rpc(name = "parity_setDappAddresses")]
|
||||
fn set_dapp_addresses(&self, DappId, Option<Vec<H160>>) -> Result<bool, Error>;
|
||||
|
||||
/// Gets accounts exposed for particular dapp.
|
||||
#[rpc(name = "parity_getDappsAddresses")]
|
||||
fn dapps_addresses(&self, DappId) -> Result<Vec<H160>, Error>;
|
||||
#[rpc(name = "parity_getDappAddresses")]
|
||||
fn dapp_addresses(&self, DappId) -> Result<Vec<H160>, Error>;
|
||||
|
||||
/// Changes dapp default address.
|
||||
/// Does not affect other accounts exposed for this dapp, but
|
||||
/// default account will always be retured as the first one.
|
||||
#[rpc(name = "parity_setDappDefaultAddress")]
|
||||
fn set_dapp_default_address(&self, DappId, H160) -> Result<bool, Error>;
|
||||
|
||||
/// Returns current dapp default address.
|
||||
/// If not set explicite for the dapp will return global default.
|
||||
#[rpc(name = "parity_getDappDefaultAddress")]
|
||||
fn dapp_default_address(&self, DappId) -> Result<H160, Error>;
|
||||
|
||||
/// Sets accounts exposed for new dapps.
|
||||
/// `None` means that all accounts will be exposed.
|
||||
#[rpc(name = "parity_setNewDappsWhitelist")]
|
||||
fn set_new_dapps_whitelist(&self, Option<Vec<H160>>) -> Result<bool, Error>;
|
||||
/// Setting a non-empty list will also override default account.
|
||||
/// Setting `None` exposes all internal-managed accounts.
|
||||
/// (does not affect default account though)
|
||||
#[rpc(name = "parity_setNewDappsAddresses")]
|
||||
fn set_new_dapps_addresses(&self, Option<Vec<H160>>) -> Result<bool, Error>;
|
||||
|
||||
/// Gets accounts exposed for new dapps.
|
||||
/// `None` means that all accounts will be exposed.
|
||||
#[rpc(name = "parity_getNewDappsWhitelist")]
|
||||
fn new_dapps_whitelist(&self) -> Result<Option<Vec<H160>>, Error>;
|
||||
/// `None` means that all accounts are exposes.
|
||||
#[rpc(name = "parity_getNewDappsAddresses")]
|
||||
fn new_dapps_addresses(&self) -> Result<Option<Vec<H160>>, Error>;
|
||||
|
||||
/// Changes default address for new dapps (global default address)
|
||||
/// Does not affect other accounts exposed for new dapps, but
|
||||
/// default account will always be retured as the first one.
|
||||
#[rpc(name = "parity_setNewDappsDefaultAddress")]
|
||||
fn set_new_dapps_default_address(&self, H160) -> Result<bool, Error>;
|
||||
|
||||
/// Returns current default address for new dapps (global default address)
|
||||
/// In case it's not set explicite will return first available account.
|
||||
/// If no accounts are available will return `0x0`
|
||||
#[rpc(name = "parity_getNewDappsDefaultAddress")]
|
||||
fn new_dapps_default_address(&self) -> Result<H160, Error>;
|
||||
|
||||
/// Returns identified dapps that recently used RPC
|
||||
/// Includes last usage timestamp.
|
||||
|
Loading…
Reference in New Issue
Block a user