APIs wildcards and simple arithmetic. (#5402)

This commit is contained in:
Tomasz Drwięga 2017-04-06 19:38:33 +02:00 committed by Gav Wood
parent d74e044be4
commit f223ed21a5
3 changed files with 95 additions and 25 deletions

View File

@ -147,8 +147,9 @@ API and Console Options:
(default: {flag_jsonrpc_cors:?}) (default: {flag_jsonrpc_cors:?})
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC --jsonrpc-apis APIS Specify the APIs available through the JSONRPC
interface. APIS is a comma-delimited list of API interface. APIS is a comma-delimited list of API
name. Possible name are web3, eth, net, personal, name. Possible name are all, safe, web3, eth, net, personal,
parity, parity_set, traces, rpc, parity_accounts. parity, parity_set, traces, rpc, parity_accounts.
You can also disable a specific API by putting '-' in the front: all,-personal
(default: {flag_jsonrpc_apis}). (default: {flag_jsonrpc_apis}).
--jsonrpc-hosts HOSTS List of allowed Host header values. This option will --jsonrpc-hosts HOSTS List of allowed Host header values. This option will
validate the Host header sent by the browser, it validate the Host header sent by the browser, it

View File

@ -30,6 +30,7 @@ use ethcore::miner::{MinerOptions, Banning, StratumOptions};
use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::VerifierSettings;
use rpc::{IpcConfiguration, HttpConfiguration}; use rpc::{IpcConfiguration, HttpConfiguration};
use rpc_apis::ApiSet;
use ethcore_rpc::NetworkSettings; use ethcore_rpc::NetworkSettings;
use cache::CacheConfig; use cache::CacheConfig;
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_for_db, use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_for_db,
@ -718,16 +719,7 @@ impl Configuration {
.collect(); .collect();
if self.args.flag_geth { if self.args.flag_geth {
apis.push("personal"); apis.insert(0, "personal");
}
if self.args.flag_public_node {
apis.retain(|api| {
match *api {
"eth" | "net" | "parity" | "rpc" | "web3" => true,
_ => false
}
});
} }
apis.join(",") apis.join(",")
@ -788,7 +780,10 @@ impl Configuration {
enabled: self.rpc_enabled(), enabled: self.rpc_enabled(),
interface: self.rpc_interface(), interface: self.rpc_interface(),
port: self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port), port: self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port),
apis: self.rpc_apis().parse()?, apis: match self.args.flag_public_node {
false => self.rpc_apis().parse()?,
true => self.rpc_apis().parse::<ApiSet>()?.retain(ApiSet::PublicContext),
},
hosts: self.rpc_hosts(), hosts: self.rpc_hosts(),
cors: self.rpc_cors(), cors: self.rpc_cors(),
threads: match self.args.flag_jsonrpc_threads { threads: match self.args.flag_jsonrpc_threads {

View File

@ -85,9 +85,17 @@ impl FromStr for Api {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ApiSet { pub enum ApiSet {
// Safe context (like token-protected WS interface)
SafeContext, SafeContext,
// Unsafe context (like jsonrpc over http)
UnsafeContext, UnsafeContext,
// Public context (like public jsonrpc over http)
PublicContext,
// All possible APIs
All,
// Local "unsafe" context and accounts access
IpcContext, IpcContext,
// Fixed list of APis
List(HashSet<Api>), List(HashSet<Api>),
} }
@ -107,10 +115,30 @@ impl FromStr for ApiSet {
type Err = String; type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
s.split(',') let mut apis = HashSet::new();
.map(Api::from_str)
.collect::<Result<_, _>>() for api in s.split(',') {
.map(ApiSet::List) match api {
"all" => {
apis.extend(ApiSet::All.list_apis());
},
"safe" => {
// Safe APIs are those that are safe even in UnsafeContext.
apis.extend(ApiSet::UnsafeContext.list_apis());
},
// Remove the API
api if api.starts_with("-") => {
let api = api[1..].parse()?;
apis.remove(&api);
},
api => {
let api = api.parse()?;
apis.insert(api);
},
}
}
Ok(ApiSet::List(apis))
} }
} }
@ -403,21 +431,41 @@ impl Dependencies for LightDependencies {
} }
impl ApiSet { impl ApiSet {
/// Retains only APIs in given set.
pub fn retain(self, set: Self) -> Self {
ApiSet::List(&self.list_apis() & &set.list_apis())
}
pub fn list_apis(&self) -> HashSet<Api> { pub fn list_apis(&self) -> HashSet<Api> {
let mut safe_list = vec![Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc] let mut public_list = vec![
.into_iter().collect(); Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Rpc,
].into_iter().collect();
match *self { match *self {
ApiSet::List(ref apis) => apis.clone(), ApiSet::List(ref apis) => apis.clone(),
ApiSet::UnsafeContext => safe_list, ApiSet::PublicContext => public_list,
ApiSet::UnsafeContext => {
public_list.insert(Api::Traces);
public_list
},
ApiSet::IpcContext => { ApiSet::IpcContext => {
safe_list.insert(Api::ParityAccounts); public_list.insert(Api::Traces);
safe_list public_list.insert(Api::ParityAccounts);
public_list
}, },
ApiSet::SafeContext => { ApiSet::SafeContext => {
safe_list.insert(Api::ParityAccounts); public_list.insert(Api::Traces);
safe_list.insert(Api::ParitySet); public_list.insert(Api::ParityAccounts);
safe_list.insert(Api::Signer); public_list.insert(Api::ParitySet);
safe_list public_list.insert(Api::Signer);
public_list
},
ApiSet::All => {
public_list.insert(Api::Traces);
public_list.insert(Api::ParityAccounts);
public_list.insert(Api::ParitySet);
public_list.insert(Api::Signer);
public_list.insert(Api::Personal);
public_list
}, },
} }
} }
@ -493,4 +541,30 @@ mod test {
].into_iter().collect(); ].into_iter().collect();
assert_eq!(ApiSet::SafeContext.list_apis(), expected); assert_eq!(ApiSet::SafeContext.list_apis(), expected);
} }
#[test]
fn test_all_apis() {
assert_eq!("all".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
Api::ParityAccounts,
Api::ParitySet, Api::Signer,
Api::Personal
].into_iter().collect()));
}
#[test]
fn test_all_without_personal_apis() {
assert_eq!("personal,all,-personal".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
Api::ParityAccounts,
Api::ParitySet, Api::Signer,
].into_iter().collect()));
}
#[test]
fn test_safe_parsing() {
assert_eq!("safe".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
].into_iter().collect()));
}
} }