Skip to content

Commit 031b613

Browse files
authored
feat(rust/signed-doc): add 'NotSpecified' variant to Content Encoding (#529)
* Updated validation rule to be an enum with the NotSpecified variant. * Updated tests and relevant modules.
1 parent 57f314c commit 031b613

File tree

3 files changed

+83
-40
lines changed

3 files changed

+83
-40
lines changed

rust/catalyst-signed-doc-macro/src/rules/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub(crate) fn catalyst_signed_documents_rules_impl() -> anyhow::Result<TokenStre
2121
content_type: crate::validator::rules::ContentTypeRule {
2222
exp: ContentType::Json,
2323
},
24-
content_encoding: crate::validator::rules::ContentEncodingRule {
24+
content_encoding: crate::validator::rules::ContentEncodingRule::Specified {
2525
exp: ContentEncoding::Brotli,
2626
optional: false,
2727
},

rust/signed_doc/src/validator/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn proposal_rule() -> Rules {
4444
content_type: ContentTypeRule {
4545
exp: ContentType::Json,
4646
},
47-
content_encoding: ContentEncodingRule {
47+
content_encoding: ContentEncodingRule::Specified {
4848
exp: ContentEncoding::Brotli,
4949
optional: false,
5050
},
@@ -82,7 +82,7 @@ fn proposal_comment_rule() -> Rules {
8282
content_type: ContentTypeRule {
8383
exp: ContentType::Json,
8484
},
85-
content_encoding: ContentEncodingRule {
85+
content_encoding: ContentEncodingRule::Specified {
8686
exp: ContentEncoding::Brotli,
8787
optional: false,
8888
},
@@ -138,7 +138,7 @@ fn proposal_submission_action_rule() -> Rules {
138138
content_type: ContentTypeRule {
139139
exp: ContentType::Json,
140140
},
141-
content_encoding: ContentEncodingRule {
141+
content_encoding: ContentEncodingRule::Specified {
142142
exp: ContentEncoding::Brotli,
143143
optional: false,
144144
},

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

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22
33
use crate::{metadata::ContentEncoding, CatalystSignedDocument};
44

5-
/// `content-encoding` field validation rule
5+
/// `content-encoding` field validation rule.
66
#[derive(Debug)]
7-
pub(crate) struct ContentEncodingRule {
8-
/// expected `content-encoding` field
9-
pub(crate) exp: ContentEncoding,
10-
/// optional flag for the `content-encoding` field
11-
pub(crate) optional: bool,
7+
pub(crate) enum ContentEncodingRule {
8+
/// Content Encoding field is optionally present in the document.
9+
Specified {
10+
/// expected `content-encoding` field.
11+
exp: ContentEncoding,
12+
/// optional flag for the `content-encoding` field.
13+
optional: bool,
14+
},
15+
/// Content Encoding field must not be present in the document.
16+
#[allow(dead_code)]
17+
NotSpecified,
1218
}
1319

1420
impl ContentEncodingRule {
@@ -18,33 +24,50 @@ impl ContentEncodingRule {
1824
&self,
1925
doc: &CatalystSignedDocument,
2026
) -> anyhow::Result<bool> {
21-
if let Some(content_encoding) = doc.doc_content_encoding() {
22-
if content_encoding != self.exp {
23-
doc.report().invalid_value(
24-
"content-encoding",
25-
content_encoding.to_string().as_str(),
26-
self.exp.to_string().as_str(),
27-
"Invalid Document content-encoding value",
28-
);
29-
return Ok(false);
30-
}
31-
if content_encoding.decode(doc.encoded_content()).is_err() {
32-
doc.report().invalid_value(
33-
"payload",
34-
&hex::encode(doc.encoded_content()),
35-
&format!(
36-
"Document content (payload) must decodable by the set content encoding type: {content_encoding}"
37-
),
38-
"Invalid Document content value",
39-
);
40-
return Ok(false);
41-
}
42-
} else if !self.optional {
43-
doc.report().missing_field(
44-
"content-encoding",
45-
"Document must have a content-encoding field",
46-
);
47-
return Ok(false);
27+
let context = "Content Encoding Rule check";
28+
match self {
29+
Self::NotSpecified => {
30+
if let Some(content_encoding) = doc.doc_content_encoding() {
31+
doc.report().unknown_field(
32+
"content-encoding",
33+
&content_encoding.to_string(),
34+
&format!(
35+
"{context}, document does not expect to have a content-encoding field"
36+
),
37+
);
38+
return Ok(false);
39+
}
40+
},
41+
Self::Specified { exp, optional } => {
42+
if let Some(content_encoding) = doc.doc_content_encoding() {
43+
if content_encoding != *exp {
44+
doc.report().invalid_value(
45+
"content-encoding",
46+
content_encoding.to_string().as_str(),
47+
exp.to_string().as_str(),
48+
"Invalid Document content-encoding value",
49+
);
50+
return Ok(false);
51+
}
52+
if content_encoding.decode(doc.encoded_content()).is_err() {
53+
doc.report().invalid_value(
54+
"payload",
55+
&hex::encode(doc.encoded_content()),
56+
&format!(
57+
"Document content (payload) must decodable by the set content encoding type: {content_encoding}"
58+
),
59+
"Invalid Document content value",
60+
);
61+
return Ok(false);
62+
}
63+
} else if !optional {
64+
doc.report().missing_field(
65+
"content-encoding",
66+
"Document must have a content-encoding field",
67+
);
68+
return Ok(false);
69+
}
70+
},
4871
}
4972
Ok(true)
5073
}
@@ -56,10 +79,10 @@ mod tests {
5679
use crate::{builder::tests::Builder, metadata::SupportedField};
5780

5881
#[tokio::test]
59-
async fn content_encoding_rule_test() {
82+
async fn content_encoding_is_specified_rule_test() {
6083
let content_encoding = ContentEncoding::Brotli;
6184

62-
let mut rule = ContentEncodingRule {
85+
let rule = ContentEncodingRule::Specified {
6386
exp: content_encoding,
6487
optional: true,
6588
};
@@ -79,7 +102,27 @@ mod tests {
79102
let doc = Builder::new().build();
80103
assert!(rule.check(&doc).await.unwrap());
81104

82-
rule.optional = false;
105+
let rule = ContentEncodingRule::Specified {
106+
exp: content_encoding,
107+
optional: false,
108+
};
83109
assert!(!rule.check(&doc).await.unwrap());
84110
}
111+
112+
#[tokio::test]
113+
async fn content_encoding_is_not_specified_rule_test() {
114+
let content_encoding = ContentEncoding::Brotli;
115+
116+
let rule = ContentEncodingRule::NotSpecified;
117+
118+
// With Brotli content encoding
119+
let doc = Builder::new()
120+
.with_metadata_field(SupportedField::ContentEncoding(content_encoding))
121+
.build();
122+
assert!(!rule.check(&doc).await.unwrap());
123+
124+
// No content encoding
125+
let doc = Builder::new().build();
126+
assert!(rule.check(&doc).await.unwrap());
127+
}
85128
}

0 commit comments

Comments
 (0)