use crate::actions::ArtifactValue;
use crate::executor::ExecutionError;
use rite_model::ArtifactId;
use rite_sdk::{KeyAlgorithm, KeyId, PublicKeyDer};
use std::collections::HashMap;
use std::hash::BuildHasher;
pub fn resolve_artifact_bytes<S: BuildHasher>(
artifacts: &HashMap<ArtifactId, ArtifactValue, S>,
artifact_id: &ArtifactId,
property: Option<&str>,
) -> Result<Vec<u8>, ExecutionError> {
let artifact = artifacts.get(artifact_id).ok_or_else(|| {
ExecutionError::InvalidParams(format!("Artifact '{artifact_id}' not found"))
})?;
match (artifact, property) {
(
ArtifactValue::BackendKey {
public_key: Some(pub_key),
..
},
Some("public"),
) => Ok(pub_key.as_bytes().to_vec()),
(
ArtifactValue::BackendKey {
public_key: None, ..
},
Some("public"),
) => {
let id = artifact_id.as_str();
Err(ExecutionError::InvalidParams(format!(
"Public key for '{id}' is not exportable from backend"
)))
}
(ArtifactValue::BackendKey { .. }, Some("private")) => {
let id = artifact_id.as_str();
Err(ExecutionError::InvalidParams(format!(
"Cannot access private key from backend-managed key '{id}'"
)))
}
(ArtifactValue::PublicKey(key), None) => Ok(key.as_bytes().to_vec()),
(ArtifactValue::WrappedKey { data, .. }, None) => Ok(data.clone()),
(ArtifactValue::Bytes(bytes), None) => Ok(bytes.clone()),
(ArtifactValue::Text(text), None) => Ok(text.as_bytes().to_vec()),
(ArtifactValue::Certificate(certificate), None) => Ok(certificate.as_bytes().to_vec()),
_ => Err(ExecutionError::InvalidParams(format!(
"Cannot extract bytes from artifact '{artifact_id}' with property '{property:?}'"
))),
}
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct BackendKeyMeta<'a> {
pub backend_name: &'a str,
pub key_id: &'a KeyId,
pub algorithm: KeyAlgorithm,
pub public_key: Option<&'a PublicKeyDer>,
}
pub fn resolve_backend_key<'a, S: BuildHasher>(
artifacts: &'a HashMap<ArtifactId, ArtifactValue, S>,
artifact_id: &ArtifactId,
) -> Result<BackendKeyMeta<'a>, ExecutionError> {
let id = artifact_id.as_str();
let artifact = artifacts
.get(artifact_id)
.ok_or_else(|| ExecutionError::InvalidParams(format!("Artifact '{id}' not found")))?;
match artifact {
ArtifactValue::BackendKey {
backend_name,
key_id,
algorithm,
public_key,
} => Ok(BackendKeyMeta {
backend_name: backend_name.as_str(),
key_id,
algorithm: *algorithm,
public_key: public_key.as_ref(),
}),
_ => Err(ExecutionError::InvalidParams(format!(
"Artifact '{id}' is not a backend-managed key"
))),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_resolve_bytes() {
let mut artifacts = HashMap::new();
artifacts.insert(
ArtifactId::new("ksr"),
ArtifactValue::Bytes(b"test content".to_vec()),
);
let result = resolve_artifact_bytes(&artifacts, &ArtifactId::new("ksr"), None).unwrap();
assert_eq!(result, b"test content");
}
#[test]
fn test_resolve_text() {
let mut artifacts = HashMap::new();
artifacts.insert(
ArtifactId::new("usb_drive"),
ArtifactValue::Text("USB Drive".to_string()),
);
let result =
resolve_artifact_bytes(&artifacts, &ArtifactId::new("usb_drive"), None).unwrap();
assert_eq!(result, b"USB Drive");
}
#[test]
fn test_resolve_not_found() {
let artifacts: HashMap<ArtifactId, ArtifactValue> = HashMap::new();
let result = resolve_artifact_bytes(&artifacts, &ArtifactId::new("missing"), None);
assert!(result.is_err());
}
}