| use std::env; |
| use std::time::Duration; |
| |
| use anyhow::Result; |
| use http::StatusCode; |
| use log::debug; |
| use log::warn; |
| use reqsign::GoogleCredentialLoader; |
| use reqsign::GoogleSigner; |
| use reqsign::GoogleTokenLoader; |
| use reqwest::Client; |
| |
| async fn init_signer() -> Option<(GoogleCredentialLoader, GoogleTokenLoader, GoogleSigner)> { |
| let _ = env_logger::builder().is_test(true).try_init(); |
| |
| dotenv::from_filename(".env").ok(); |
| |
| if env::var("REQSIGN_GOOGLE_TEST").is_err() || env::var("REQSIGN_GOOGLE_TEST").unwrap() != "on" |
| { |
| return None; |
| } |
| |
| let cred_loader = GoogleCredentialLoader::default().with_content( |
| &env::var("REQSIGN_GOOGLE_CREDENTIAL").expect("env REQSIGN_GOOGLE_CREDENTIAL must set"), |
| ); |
| |
| let token_loader = GoogleTokenLoader::new( |
| &env::var("REQSIGN_GOOGLE_CLOUD_STORAGE_SCOPE") |
| .expect("env REQSIGN_GOOGLE_CLOUD_STORAGE_SCOPE must set"), |
| Client::new(), |
| ) |
| .with_credentials(cred_loader.load().unwrap().unwrap()); |
| |
| let signer = GoogleSigner::new("storage"); |
| |
| Some((cred_loader, token_loader, signer)) |
| } |
| |
| #[tokio::test] |
| async fn test_get_object() -> Result<()> { |
| let signer = init_signer().await; |
| if signer.is_none() { |
| warn!("REQSIGN_GOOGLE_TEST is not set, skipped"); |
| return Ok(()); |
| } |
| let (_, token_loader, signer) = signer.unwrap(); |
| |
| let url = &env::var("REQSIGN_GOOGLE_CLOUD_STORAGE_URL") |
| .expect("env REQSIGN_GOOGLE_CLOUD_STORAGE_URL must set"); |
| |
| let mut builder = http::Request::builder(); |
| builder = builder.method(http::Method::GET); |
| builder = builder.uri(format!("{}/o/{}", url, "not_exist_file")); |
| let mut req = builder.body("")?; |
| |
| let token = token_loader.load().await?.unwrap(); |
| signer |
| .sign(&mut req, &token) |
| .expect("sign request must success"); |
| |
| debug!("signed request: {:?}", req); |
| |
| let client = Client::new(); |
| let resp = client |
| .execute(req.try_into()?) |
| .await |
| .expect("request must succeed"); |
| |
| debug!("got response: {:?}", resp); |
| assert_eq!(StatusCode::NOT_FOUND, resp.status()); |
| Ok(()) |
| } |
| |
| #[tokio::test] |
| async fn test_list_objects() -> Result<()> { |
| let signer = init_signer().await; |
| if signer.is_none() { |
| warn!("REQSIGN_GOOGLE_TEST is not set, skipped"); |
| return Ok(()); |
| } |
| let (_, token_loader, signer) = signer.unwrap(); |
| |
| let url = &env::var("REQSIGN_GOOGLE_CLOUD_STORAGE_URL") |
| .expect("env REQSIGN_GOOGLE_CLOUD_STORAGE_URL must set"); |
| |
| let mut builder = http::Request::builder(); |
| builder = builder.method(http::Method::GET); |
| builder = builder.uri(format!("{url}/o")); |
| let mut req = builder.body("")?; |
| |
| let token = token_loader.load().await?.unwrap(); |
| signer |
| .sign(&mut req, &token) |
| .expect("sign request must success"); |
| |
| debug!("signed request: {:?}", req); |
| |
| let client = Client::new(); |
| let resp = client |
| .execute(req.try_into()?) |
| .await |
| .expect("request must succeed"); |
| |
| debug!("got response: {:?}", resp); |
| assert_eq!(StatusCode::OK, resp.status()); |
| Ok(()) |
| } |
| |
| #[tokio::test] |
| async fn test_get_object_with_query() -> Result<()> { |
| let signer = init_signer().await; |
| if signer.is_none() { |
| warn!("REQSIGN_GOOGLE_TEST is not set, skipped"); |
| return Ok(()); |
| } |
| let (cred_loader, _, signer) = signer.unwrap(); |
| |
| let url = &env::var("REQSIGN_GOOGLE_CLOUD_STORAGE_URL") |
| .expect("env REQSIGN_GOOGLE_CLOUD_STORAGE_URL must set"); |
| |
| let mut builder = http::Request::builder(); |
| builder = builder.method(http::Method::GET); |
| builder = builder.uri(format!( |
| "{}/{}", |
| url.replace("storage/v1/b/", ""), |
| "not_exist_file" |
| )); |
| let mut req = builder.body("")?; |
| |
| let cred = cred_loader.load()?.unwrap(); |
| signer |
| .sign_query(&mut req, Duration::from_secs(3600), &cred) |
| .expect("sign request must success"); |
| |
| debug!("signed request: {:?}", req); |
| |
| let client = Client::new(); |
| let resp = client |
| .execute(req.try_into()?) |
| .await |
| .expect("request must succeed"); |
| |
| let code = resp.status(); |
| debug!("got response: {:?}", resp); |
| debug!("got body: {}", resp.text().await?); |
| assert_eq!(StatusCode::NOT_FOUND, code); |
| Ok(()) |
| } |