blob: 2390319511d2a0335b2d9c94919e734767e5e803 [file] [log] [blame]
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(())
}