Implement Basic Auth for API and Owner API (#1566)

* Add api_secret

* Add to base64 method

* Add basic auth in API

* Add Basic Auth to owner API

* Add flag to enable disable basic auth

* Add .api_secret file
This commit is contained in:
Quentin Le Sceller
2018-09-26 16:38:44 -04:00
committed by hashmap
parent acec59e249
commit 62fd8f2124
29 changed files with 427 additions and 228 deletions
+25 -14
View File
@@ -22,23 +22,25 @@ use config::GlobalConfig;
use p2p;
use servers::ServerConfig;
use term;
use util::file::get_first_line;
pub fn client_command(client_args: &ArgMatches, global_config: GlobalConfig) {
// just get defaults from the global config
let server_config = global_config.members.unwrap().server;
let api_secret = get_first_line(server_config.api_secret_path.clone());
match client_args.subcommand() {
("status", Some(_)) => {
show_status(&server_config);
show_status(&server_config, api_secret);
}
("listconnectedpeers", Some(_)) => {
list_connected_peers(&server_config);
list_connected_peers(&server_config, api_secret);
}
("ban", Some(peer_args)) => {
let peer = peer_args.value_of("peer").unwrap();
if let Ok(addr) = peer.parse() {
ban_peer(&server_config, &addr);
ban_peer(&server_config, &addr, api_secret);
} else {
panic!("Invalid peer address format");
}
@@ -47,7 +49,7 @@ pub fn client_command(client_args: &ArgMatches, global_config: GlobalConfig) {
let peer = peer_args.value_of("peer").unwrap();
if let Ok(addr) = peer.parse() {
unban_peer(&server_config, &addr);
unban_peer(&server_config, &addr, api_secret);
} else {
panic!("Invalid peer address format");
}
@@ -56,7 +58,7 @@ pub fn client_command(client_args: &ArgMatches, global_config: GlobalConfig) {
}
}
pub fn show_status(config: &ServerConfig) {
pub fn show_status(config: &ServerConfig, api_secret: Option<String>) {
println!();
let title = format!("Grin Server Status");
let mut t = term::stdout().unwrap();
@@ -65,7 +67,7 @@ pub fn show_status(config: &ServerConfig) {
writeln!(t, "{}", title).unwrap();
writeln!(t, "--------------------------").unwrap();
t.reset().unwrap();
match get_status_from_node(config) {
match get_status_from_node(config, api_secret) {
Ok(status) => {
writeln!(e, "Protocol version: {}", status.protocol_version).unwrap();
writeln!(e, "User agent: {}", status.user_agent).unwrap();
@@ -84,7 +86,7 @@ pub fn show_status(config: &ServerConfig) {
println!()
}
pub fn ban_peer(config: &ServerConfig, peer_addr: &SocketAddr) {
pub fn ban_peer(config: &ServerConfig, peer_addr: &SocketAddr, api_secret: Option<String>) {
let params = "";
let mut e = term::stdout().unwrap();
let url = format!(
@@ -92,14 +94,14 @@ pub fn ban_peer(config: &ServerConfig, peer_addr: &SocketAddr) {
config.api_http_addr,
peer_addr.to_string()
);
match api::client::post_no_ret(url.as_str(), &params).map_err(|e| Error::API(e)) {
match api::client::post_no_ret(url.as_str(), api_secret, &params).map_err(|e| Error::API(e)) {
Ok(_) => writeln!(e, "Successfully banned peer {}", peer_addr.to_string()).unwrap(),
Err(_) => writeln!(e, "Failed to ban peer {}", peer_addr).unwrap(),
};
e.reset().unwrap();
}
pub fn unban_peer(config: &ServerConfig, peer_addr: &SocketAddr) {
pub fn unban_peer(config: &ServerConfig, peer_addr: &SocketAddr, api_secret: Option<String>) {
let params = "";
let mut e = term::stdout().unwrap();
let url = format!(
@@ -107,17 +109,23 @@ pub fn unban_peer(config: &ServerConfig, peer_addr: &SocketAddr) {
config.api_http_addr,
peer_addr.to_string()
);
match api::client::post_no_ret(url.as_str(), &params).map_err(|e| Error::API(e)) {
let res: Result<(), api::Error>;
res = api::client::post_no_ret(url.as_str(), api_secret, &params);
match res.map_err(|e| Error::API(e)) {
Ok(_) => writeln!(e, "Successfully unbanned peer {}", peer_addr).unwrap(),
Err(_) => writeln!(e, "Failed to unban peer {}", peer_addr).unwrap(),
};
e.reset().unwrap();
}
pub fn list_connected_peers(config: &ServerConfig) {
pub fn list_connected_peers(config: &ServerConfig, api_secret: Option<String>) {
let mut e = term::stdout().unwrap();
let url = format!("http://{}/v1/peers/connected", config.api_http_addr);
match api::client::get::<Vec<p2p::PeerInfo>>(url.as_str()).map_err(|e| Error::API(e)) {
let peers_info: Result<Vec<p2p::PeerInfo>, api::Error>;
peers_info = api::client::get::<Vec<p2p::PeerInfo>>(url.as_str(), api_secret);
match peers_info.map_err(|e| Error::API(e)) {
Ok(connected_peers) => {
let mut index = 0;
for connected_peer in connected_peers {
@@ -137,9 +145,12 @@ pub fn list_connected_peers(config: &ServerConfig) {
e.reset().unwrap();
}
fn get_status_from_node(config: &ServerConfig) -> Result<api::Status, Error> {
fn get_status_from_node(
config: &ServerConfig,
api_secret: Option<String>,
) -> Result<api::Status, Error> {
let url = format!("http://{}/v1/status", config.api_http_addr);
api::client::get::<api::Status>(url.as_str()).map_err(|e| Error::API(e))
api::client::get::<api::Status>(url.as_str(), api_secret).map_err(|e| Error::API(e))
}
/// Error type wrapping underlying module errors.
+18 -12
View File
@@ -30,6 +30,7 @@ use grin_wallet::{self, controller, display, libwallet};
use grin_wallet::{HTTPWalletClient, LMDBBackend, WalletConfig, WalletInst, WalletSeed};
use keychain;
use servers::start_webwallet_server;
use util::file::get_first_line;
use util::LOGGER;
pub fn _init_wallet_seed(wallet_config: WalletConfig) {
@@ -129,6 +130,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
// Handle listener startup commands
{
let wallet = instantiate_wallet(wallet_config.clone(), passphrase);
let api_secret = get_first_line(wallet_config.api_secret_path.clone());
match wallet_args.subcommand() {
("listen", Some(listen_args)) => {
if let Some(port) = listen_args.value_of("port") {
@@ -143,22 +145,26 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
});
}
("owner_api", Some(_api_args)) => {
controller::owner_listener(wallet, "127.0.0.1:13420").unwrap_or_else(|e| {
panic!(
"Error creating wallet api listener: {:?} Config: {:?}",
e, wallet_config
)
});
controller::owner_listener(wallet, "127.0.0.1:13420", api_secret).unwrap_or_else(
|e| {
panic!(
"Error creating wallet api listener: {:?} Config: {:?}",
e, wallet_config
)
},
);
}
("web", Some(_api_args)) => {
// start owner listener and run static file server
start_webwallet_server();
controller::owner_listener(wallet, "127.0.0.1:13420").unwrap_or_else(|e| {
panic!(
"Error creating wallet api listener: {:?} Config: {:?}",
e, wallet_config
)
});
controller::owner_listener(wallet, "127.0.0.1:13420", api_secret).unwrap_or_else(
|e| {
panic!(
"Error creating wallet api listener: {:?} Config: {:?}",
e, wallet_config
)
},
);
}
_ => {}
};