use anyhow::Result;
use s3util_rs::config::ClientConfig;
use s3util_rs::config::args::get_bucket_policy::GetBucketPolicyArgs;
use s3util_rs::output::json::get_bucket_policy_to_json;
use s3util_rs::storage::s3::api::{self, HeadError};
use super::ExitStatus;
pub async fn run_get_bucket_policy(
args: GetBucketPolicyArgs,
client_config: ClientConfig,
) -> Result<ExitStatus> {
let bucket = args
.bucket_name()
.map_err(|e| anyhow::anyhow!("{}", e.trim_end()))?;
let client = client_config.create_client().await;
match api::get_bucket_policy(&client, &bucket).await {
Ok(out) => {
let pretty = if args.policy_only {
render_policy_only(out.policy())?
} else {
serde_json::to_string_pretty(&get_bucket_policy_to_json(&out))?
};
println!("{pretty}");
Ok(ExitStatus::Success)
}
Err(HeadError::BucketNotFound) => {
tracing::error!("bucket s3://{bucket} not found");
Ok(ExitStatus::NotFound)
}
Err(HeadError::NotFound) => {
tracing::error!("policy for s3://{bucket} not found");
Ok(ExitStatus::NotFound)
}
Err(HeadError::Other(e)) => Err(e),
}
}
fn render_policy_only(policy: Option<&str>) -> Result<String> {
let Some(policy) = policy else {
return Ok("{}".to_string());
};
match serde_json::from_str::<serde_json::Value>(policy) {
Ok(v) => Ok(serde_json::to_string_pretty(&v)?),
Err(_) => Ok(policy.to_string()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_policy_only_pretty_prints_valid_json() {
let raw = r#"{"Version":"2012-10-17","Statement":[]}"#;
let got = render_policy_only(Some(raw)).unwrap();
assert!(got.contains('\n'), "expected pretty-printed output: {got}");
let reparsed: serde_json::Value = serde_json::from_str(&got).unwrap();
let original: serde_json::Value = serde_json::from_str(raw).unwrap();
assert_eq!(reparsed, original);
}
#[test]
fn render_policy_only_falls_back_to_raw_for_invalid_json() {
let raw = "not-json";
let got = render_policy_only(Some(raw)).unwrap();
assert_eq!(got, "not-json");
}
#[test]
fn render_policy_only_emits_empty_object_when_policy_missing() {
let got = render_policy_only(None).unwrap();
assert_eq!(got, "{}");
}
}