use crate::{Error, secret::Password};
use aws_config::Region;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
pub struct S3Secret {
pub hostname: Option<String>,
pub access_key_id: Password,
pub secret_access_key: Password,
pub role_name: Option<Password>,
pub session_name: Option<String>,
pub region: Option<String>,
pub bucket: String,
}
impl S3Secret {
pub fn hostname(&self) -> Option<String> {
self
.hostname
.as_ref()
.map(|hostname| !hostname.contains("amazonaws.com"))
.unwrap_or_default()
.then_some(self.hostname.clone()?)
}
pub fn access_key(&self) -> &str {
&self.access_key_id.0
}
pub fn secret_key(&self) -> &str {
&self.secret_access_key.0
}
pub fn role_name(&self) -> Option<String> {
self
.role_name
.as_ref()
.map(|role_name| role_name.0.to_string())
}
pub fn session_name(&self) -> &Option<String> {
&self.session_name
}
pub fn region_as_string(&self) -> &Option<String> {
&self.region
}
pub fn bucket(&self) -> &str {
&self.bucket
}
pub fn region(&self) -> Result<Option<Region>, Error> {
match self.region_as_string() {
Some(region) => Ok(Some(Region::new(region.to_string()))),
None => Ok(None),
}
}
}
#[test]
pub fn test_s3_secret_getters() {
let hostname = Some("s3.server.name".to_string());
let access_key_id = "S3_ACCESS_KEY".to_string();
let secret_access_key = "S3_SECRET_KEY".to_string();
let region = Some("s3-region".to_string());
let role_name = "s3-role".to_string();
let session_name = Some("s3-session".to_string());
let bucket = "s3-bucket".to_string();
let secret = S3Secret {
hostname: hostname.clone(),
access_key_id: Password(access_key_id.clone()),
secret_access_key: Password(secret_access_key.clone()),
region: region.clone(),
role_name: Some(Password(role_name.clone())),
session_name: session_name.clone(),
bucket: bucket.clone(),
};
println!("secret: {secret:?}");
assert_eq!(secret.hostname(), hostname);
assert_eq!(secret.access_key(), &access_key_id);
assert_eq!(secret.secret_key(), &secret_access_key);
assert_eq!(secret.region_as_string(), ®ion);
assert_eq!(secret.role_name(), Some(role_name));
assert_eq!(secret.session_name(), &session_name);
assert_eq!(secret.bucket(), &bucket);
let secret = S3Secret {
hostname: hostname.clone(),
access_key_id: Password(access_key_id.clone()),
secret_access_key: Password(secret_access_key.clone()),
region: region.clone(),
role_name: None,
session_name: None,
bucket: bucket.clone(),
};
assert_eq!(secret.role_name(), None);
}
#[test]
pub fn test_s3_secret_get_region() {
let secret = S3Secret {
hostname: Some("s3.server.name".to_string()),
access_key_id: Password::from("s3_access_key"),
secret_access_key: Password::from("s3_secret_key"),
region: Some("s3-region".to_string()),
role_name: None,
session_name: None,
bucket: "".to_string(),
};
let expected = Some(Region::new("s3-region"));
let region = secret.region().unwrap();
assert_eq!(region, expected);
}
#[test]
pub fn test_s3_secret_get_region_no_hostname() {
let secret = S3Secret {
hostname: None,
access_key_id: Password::from("s3_access_key"),
secret_access_key: Password::from("s3_secret_key"),
region: Some("eu-west-3".to_string()),
role_name: None,
session_name: None,
bucket: "".to_string(),
};
let expected = Some(Region::new("eu-west-3"));
let region = secret.region().unwrap();
assert_eq!(region, expected);
}
#[test]
pub fn test_s3_secret_get_region_no_region() {
let secret = S3Secret {
hostname: Some("s3.server.name".to_string()),
access_key_id: Password::from("s3_access_key"),
secret_access_key: Password::from("s3_secret_key"),
region: None,
role_name: None,
session_name: None,
bucket: "".to_string(),
};
let expected = None;
let region = secret.region().unwrap();
assert_eq!(region, expected);
}
#[test]
pub fn test_s3_secret_get_region_no_hostname_nor_region() {
let secret = S3Secret {
hostname: None,
access_key_id: Password::from("s3_access_key"),
secret_access_key: Password::from("s3_secret_key"),
region: None,
role_name: None,
session_name: None,
bucket: "".to_string(),
};
let region = secret.region().unwrap();
assert_eq!(region, None);
}