mod post { use remote_signer_consumer::{Error, RemoteSignerHttpConsumer}; use remote_signer_test::*; use reqwest::{ClientBuilder, Url}; use tokio::time::Duration; #[test] fn server_unavailable() { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let test_client = set_up_test_consumer(&test_signer.address); test_signer.shutdown(); let test_input = get_input_data_block(0xc137); let signature = do_sign_request(&test_client, test_input); match signature.unwrap_err() { Error::Reqwest(e) => { let error_msg = e.to_string(); assert!(error_msg.contains("error sending request for url")); assert!(error_msg.contains(PUBLIC_KEY_1)); assert!(error_msg.contains("error trying to connect")); assert!(error_msg.contains("tcp connect error")); assert!(error_msg.contains("Connection refused")); } e => panic!("{:?}", e), } } #[test] fn server_error() { let (test_signer, tmp_dir) = set_up_api_test_signer_to_sign_message(); set_permissions(tmp_dir.path(), 0o40311); set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40311); let test_client = set_up_test_consumer(&test_signer.address); let test_input = get_input_data_block(0xc137); let signature = do_sign_request(&test_client, test_input); set_permissions(tmp_dir.path(), 0o40755); set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40755); match signature.unwrap_err() { Error::ServerMessage(message) => assert_eq!(message, "Storage error: PermissionDenied"), e => panic!("{:?}", e), } test_signer.shutdown(); } #[test] fn invalid_url() { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let run_testcase = |u: &str| -> Result { let url: Url = u.parse().map_err(|e| format!("[ParseError] {:?}", e))?; let reqwest_client = ClientBuilder::new() .timeout(Duration::from_secs(12)) .build() .unwrap(); let test_client = RemoteSignerHttpConsumer::from_components(url, reqwest_client); let test_input = get_input_data_block(0xc137); let signature = do_sign_request(&test_client, test_input); signature.map_err(|e| match e { Error::InvalidUrl(message) => format!("[InvalidUrl] {:?}", message), Error::Reqwest(re) => { if re.is_builder() { format!("[Reqwest - Builder] {:?}", re.url().unwrap()) } else if re.is_request() { format!("[Reqwest - Request] {:?}", re.url().unwrap()) } else { format!("[Reqwest] {:?}", re) } } _ => format!("{:?}", e), }) }; let testcase = |u: &str, msg: &str| assert_eq!(run_testcase(u).unwrap_err(), msg); // url::parser::ParseError. // These cases don't even make it to the step of building a RemoteSignerHttpConsumer. testcase("", "[ParseError] RelativeUrlWithoutBase"); testcase("/4/8/15/16/23/42", "[ParseError] RelativeUrlWithoutBase"); testcase("localhost", "[ParseError] RelativeUrlWithoutBase"); testcase(":", "[ParseError] RelativeUrlWithoutBase"); testcase("0.0:0", "[ParseError] RelativeUrlWithoutBase"); testcase(":aa", "[ParseError] RelativeUrlWithoutBase"); testcase("0:", "[ParseError] RelativeUrlWithoutBase"); testcase("ftp://", "[ParseError] EmptyHost"); testcase("http://", "[ParseError] EmptyHost"); testcase("http://127.0.0.1:abcd", "[ParseError] InvalidPort"); testcase("http://280.0.0.1", "[ParseError] InvalidIpv4Address"); // `Error::InvalidUrl`. // The RemoteSignerHttpConsumer is created, but fails at `path_segments_mut()`. testcase("localhost:abcd", "[InvalidUrl] Url { scheme: \"localhost\", host: None, port: None, path: \"abcd\", query: None, fragment: None }"); testcase("localhost:", "[InvalidUrl] Url { scheme: \"localhost\", host: None, port: None, path: \"\", query: None, fragment: None }"); // `Reqwest::Error` of the `Builder` kind. // POST is not made. testcase( "unix:/run/foo.socket", &format!( "[Reqwest - Builder] Url {{ scheme: \"unix\", host: None, port: None, path: \"/run/foo.socket/sign/{}\", query: None, fragment: None }}", PUBLIC_KEY_1 ), ); // `Reqwest::Error` of the `Request` kind. testcase( "http://127.0.0.1:0", &format!( "[Reqwest - Request] Url {{ scheme: \"http\", host: Some(Ipv4(127.0.0.1)), port: Some(0), path: \"/sign/{}\", query: None, fragment: None }}", PUBLIC_KEY_1 ), ); test_signer.shutdown(); } #[test] fn wrong_url() { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let run_testcase = |u: &str| -> Result { let url: Url = u.parse().unwrap(); let reqwest_client = ClientBuilder::new() .timeout(Duration::from_secs(12)) .build() .unwrap(); let test_client = RemoteSignerHttpConsumer::from_components(url, reqwest_client); let test_input = get_input_data_block(0xc137); let signature = do_sign_request(&test_client, test_input); signature.map_err(|e| format!("{:?}", e)) }; let testcase = |u: &str, msgs: Vec<&str>| { let r = run_testcase(u).unwrap_err(); for msg in msgs.iter() { assert!(r.contains(msg), format!("{:?} should contain {:?}", r, msg)); } }; testcase( "http://error-dns", vec![ "reqwest::Error", "kind: Request", &format!("/sign/{}", PUBLIC_KEY_1), "hyper::Error(Connect, ConnectError", "dns error", "failed to lookup address information", ], ); test_signer.shutdown(); } #[test] fn wrong_public_key() { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let test_client = set_up_test_consumer(&test_signer.address); let mut test_input = get_input_data_block(0xc137); test_input.public_key = ABSENT_PUBLIC_KEY.to_string(); let signature = do_sign_request(&test_client, test_input); match signature.unwrap_err() { Error::ServerMessage(msg) => { assert_eq!(msg, format!("Key not found: {}", ABSENT_PUBLIC_KEY)) } e => panic!("{:?}", e), } } #[test] fn invalid_secret_key() { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let test_client = set_up_test_consumer(&test_signer.address); let mut test_input = get_input_data_block(0xc137); test_input.public_key = PUBLIC_KEY_FOR_INVALID_SECRET_KEY.to_string(); let signature = do_sign_request(&test_client, test_input); match signature.unwrap_err() { Error::ServerMessage(msg) => assert_eq!( msg, format!( "Invalid secret key: public_key: {}; Invalid hex character: W at index 0", PUBLIC_KEY_FOR_INVALID_SECRET_KEY ) ), e => panic!("{:?}", e), } } #[test] fn key_mismatch() { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let test_client = set_up_test_consumer(&test_signer.address); let mut test_input = get_input_data_block(0xc137); test_input.public_key = MISMATCHED_PUBLIC_KEY.to_string(); let signature = do_sign_request(&test_client, test_input); match signature.unwrap_err() { Error::ServerMessage(msg) => { assert_eq!(msg, format!("Key mismatch: {}", MISMATCHED_PUBLIC_KEY)) } e => panic!("{:?}", e), } } }