pub mod extractor;
pub mod router;
pub use extractor::TrustTaskHeader;
pub use router::TrustTaskRouter;
use crate::error::AppError;
pub const HEADER_NAME: &str = "Trust-Task";
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TrustTask(String);
impl TrustTask {
pub fn new(s: impl Into<String>) -> Result<Self, AppError> {
let s = s.into();
if s.is_empty() {
return Err(AppError::TrustTaskMalformed("<empty>".into()));
}
if !s.starts_with("https://") {
return Err(AppError::TrustTaskMalformed(s));
}
if s.chars().any(|c| c == '\r' || c == '\n' || c == '\0') {
return Err(AppError::TrustTaskMalformed(s));
}
Ok(Self(s))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl AsRef<str> for TrustTask {
fn as_ref(&self) -> &str {
&self.0
}
}
impl std::fmt::Display for TrustTask {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn accepts_well_formed_https_url() {
let t = TrustTask::new("https://trusttasks.org/openvtc/vtc/install/claim/1.0").unwrap();
assert_eq!(
t.as_str(),
"https://trusttasks.org/openvtc/vtc/install/claim/1.0"
);
}
#[test]
fn rejects_empty_string() {
let err = TrustTask::new("").expect_err("empty");
assert!(matches!(err, AppError::TrustTaskMalformed(_)));
}
#[test]
fn rejects_non_https() {
for s in [
"http://trusttasks.org/openvtc/vtc/install/claim/1.0",
"urn:openvtc:vtc:install:claim:1.0",
"trusttasks.org/openvtc/vtc/install/claim/1.0",
] {
let err = TrustTask::new(s).expect_err("non-https");
assert!(
matches!(err, AppError::TrustTaskMalformed(_)),
"{s} should be rejected"
);
}
}
#[test]
fn rejects_header_injection_attempts() {
for s in [
"https://trusttasks.org/x\r\nInjected: yes",
"https://trusttasks.org/x\nInjected: yes",
"https://trusttasks.org/x\0",
] {
let err = TrustTask::new(s).expect_err("control chars");
assert!(
matches!(err, AppError::TrustTaskMalformed(_)),
"{s:?} should be rejected"
);
}
}
#[test]
fn display_returns_full_url() {
let t = TrustTask::new("https://trusttasks.org/x/1.0").unwrap();
assert_eq!(format!("{t}"), "https://trusttasks.org/x/1.0");
}
}