use greentic_deploy_spec::{EnvId, Environment};
use super::credentials::AssumedSession;
use crate::cli::OpError;
use crate::environment::LocalFsStore;
pub(crate) fn resolve_bound_session(
store: &LocalFsStore,
env: &Environment,
env_id: &EnvId,
) -> Result<Option<AssumedSession>, OpError> {
match crate::cli::secrets::resolve_credentials_token(store, env, env_id)? {
None => Ok(None),
Some(material) => Ok(Some(parse_session_material(env_id, &material)?)),
}
}
fn parse_session_material(env_id: &EnvId, material: &str) -> Result<AssumedSession, OpError> {
serde_json::from_str(material).map_err(|e| {
OpError::Conflict(format!(
"environment `{}` has a bound deployer credential, but its material is not a valid \
AWS assumed-session blob: {e}; re-bind the deployer role \
(`op env bootstrap --bind`) or refresh it (`op credentials rotate`)",
env_id.as_str()
))
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cli::tests_common::make_env;
use crate::environment::EnvironmentStore;
use tempfile::tempdir;
#[test]
fn no_bound_ref_resolves_to_none() {
let dir = tempdir().unwrap();
let store = LocalFsStore::new(dir.path());
let env = make_env("local"); store.save(&env).unwrap();
let env_id = EnvId::try_from("local").unwrap();
assert!(
resolve_bound_session(&store, &env, &env_id)
.unwrap()
.is_none()
);
}
#[test]
fn unparseable_material_is_fail_closed() {
let env_id = EnvId::try_from("local").unwrap();
let err = parse_session_material(&env_id, "not a session blob").unwrap_err();
match err {
OpError::Conflict(msg) => assert!(msg.contains("assumed-session blob"), "{msg}"),
other => panic!("expected Conflict, got {other}"),
}
}
#[test]
fn valid_material_parses_to_the_session() {
let env_id = EnvId::try_from("local").unwrap();
let material = serde_json::json!({
"access_key_id": "AKIAEXAMPLE",
"secret_access_key": "shh",
"session_token": "blob",
"expiration": "2030-01-01T00:00:00Z",
"issued_at": "2029-12-31T00:00:00Z",
})
.to_string();
let session = parse_session_material(&env_id, &material).unwrap();
assert_eq!(session.access_key_id, "AKIAEXAMPLE");
assert_eq!(session.session_token, "blob");
}
}