Skip to content

Commit fd709ef

Browse files
authored
feat(rust/signed-doc): ContentTypeRule, add ContentType::SchemaJson validation (#571)
* update ContentTypeRule, add ContentType::SchemaJson validation * fix clippy
1 parent 92a937c commit fd709ef

File tree

1 file changed

+34
-40
lines changed

1 file changed

+34
-40
lines changed

rust/signed_doc/src/validator/rules/content_type.rs

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! `content-type` rule type impl.
22
3-
use crate::{metadata::ContentType, CatalystSignedDocument};
3+
use crate::{metadata::ContentType, validator::json_schema::JsonSchema, CatalystSignedDocument};
44

55
/// `content-type` field validation rule
66
#[derive(Debug)]
@@ -83,7 +83,7 @@ impl ContentTypeRule {
8383
);
8484
return Ok(false);
8585
};
86-
if self.validate(&content).is_err() {
86+
if !validate(*exp, &content) {
8787
doc.report().invalid_value(
8888
"payload",
8989
&hex::encode(content),
@@ -95,45 +95,39 @@ impl ContentTypeRule {
9595
}
9696
Ok(true)
9797
}
98+
}
9899

99-
/// Validates the provided `content` bytes to be a defined `ContentType`.
100-
fn validate(
101-
&self,
102-
content: &[u8],
103-
) -> anyhow::Result<()> {
104-
if let Self::Specified { exp } = self {
105-
match exp {
106-
ContentType::Json => {
107-
if let Err(e) = serde_json::from_slice::<&serde_json::value::RawValue>(content)
108-
{
109-
anyhow::bail!("Invalid {exp} content: {e}")
110-
}
111-
},
112-
ContentType::Cbor => {
113-
let mut decoder = minicbor::Decoder::new(content);
114-
115-
decoder.skip()?;
116-
117-
if decoder.position() != content.len() {
118-
anyhow::bail!("Unused bytes remain in the input after decoding")
119-
}
120-
},
121-
ContentType::Cddl
122-
| ContentType::SchemaJson
123-
| ContentType::Css
124-
| ContentType::CssHandlebars
125-
| ContentType::Html
126-
| ContentType::HtmlHandlebars
127-
| ContentType::Markdown
128-
| ContentType::MarkdownHandlebars
129-
| ContentType::Plain
130-
| ContentType::PlainHandlebars => {
131-
// TODO: not implemented yet
132-
anyhow::bail!("`{exp}` is valid but unavailable yet")
133-
},
134-
}
135-
}
136-
Ok(())
100+
/// Validates the provided `content` bytes to be a defined `ContentType`.
101+
fn validate(
102+
content_type: ContentType,
103+
content: &[u8],
104+
) -> bool {
105+
match content_type {
106+
ContentType::Json => {
107+
serde_json::from_slice::<&serde_json::value::RawValue>(content).is_ok()
108+
},
109+
ContentType::Cbor => {
110+
let mut decoder = minicbor::Decoder::new(content);
111+
decoder.skip().is_ok() && decoder.position() == content.len()
112+
},
113+
ContentType::SchemaJson => {
114+
let Ok(template_json_schema) = serde_json::from_slice(content) else {
115+
return false;
116+
};
117+
JsonSchema::try_from(&template_json_schema).is_ok()
118+
},
119+
ContentType::Cddl
120+
| ContentType::Css
121+
| ContentType::CssHandlebars
122+
| ContentType::Html
123+
| ContentType::HtmlHandlebars
124+
| ContentType::Markdown
125+
| ContentType::MarkdownHandlebars
126+
| ContentType::Plain
127+
| ContentType::PlainHandlebars => {
128+
// TODO: not implemented yet
129+
false
130+
},
137131
}
138132
}
139133

0 commit comments

Comments
 (0)