use std::collections::BTreeSet;
use crate::error::{Error, Result};
use crate::value::Value;
pub const SECRET_MARKER: &str = "***SECRET***";
pub fn from_active_value(value: &active_core::Value) -> Value {
use active_core::Value as ActiveValue;
match value {
ActiveValue::Null => Value::Null,
ActiveValue::Bool(flag) => Value::Bool(*flag),
ActiveValue::Int(number) => Value::Int(*number),
ActiveValue::Float(number) => Value::Float(*number),
ActiveValue::String(text) => Value::Text(text.clone()),
ActiveValue::DurationMs(ms) => Value::Map(
[("ms".to_string(), Value::Int(*ms as i64))]
.into_iter()
.collect(),
),
ActiveValue::Quantity(amount, unit) => Value::Map(
[
("value".to_string(), Value::Float(*amount)),
("unit".to_string(), Value::Text(unit.suffix())),
]
.into_iter()
.collect(),
),
ActiveValue::Array(items) => Value::List(items.iter().map(from_active_value).collect()),
ActiveValue::Table(entries) => Value::Map(
entries
.iter()
.map(|(key, value)| (key.clone(), from_active_value(value)))
.collect(),
),
ActiveValue::Secret(_) => Value::Secret,
}
}
pub fn redact_cone_labels(labels: Vec<String>, tainted: &BTreeSet<String>) -> Vec<String> {
if labels.iter().any(|label| tainted.contains(label)) {
vec![SECRET_MARKER.to_string()]
} else {
labels
}
}
pub fn redact_value(value: Value) -> Value {
match value {
Value::Secret => Value::Secret,
Value::List(items) => Value::List(items.into_iter().map(redact_value).collect()),
Value::Map(entries) => Value::Map(
entries
.into_iter()
.map(|(key, value)| (key, redact_value(value)))
.collect(),
),
Value::Text(text) if text.contains(SECRET_MARKER) => Value::Secret,
other => other,
}
}
pub fn check_module_payload(bytes: &[u8]) -> Result<()> {
active_infinity::validate(bytes)
.map(|_| ())
.map_err(|error| Error::Payload(error.code().to_string()))
}
pub fn assert_no_secret_material(value: &Value) -> Result<()> {
match value {
Value::Secret => Err(Error::Provider {
code: "rpc/secret-material".to_string(),
}),
Value::List(items) => items.iter().try_for_each(assert_no_secret_material),
Value::Map(entries) => entries.values().try_for_each(assert_no_secret_material),
_ => Ok(()),
}
}