Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion rust/signed_doc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ impl ContentBuilder {
json: &serde_json::Value,
) -> anyhow::Result<SignaturesBuilder> {
anyhow::ensure!(
self.metadata.content_type() == Some(ContentType::Json),
self.metadata.content_type() == Some(ContentType::Json)
|| self.metadata.content_type() == Some(ContentType::SchemaJson),
"Already set metadata field `content-type` is not JSON value"
);

Expand Down
164 changes: 3 additions & 161 deletions rust/signed_doc/src/validator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,182 +5,24 @@ pub(crate) mod rules;

use std::{collections::HashMap, sync::LazyLock};

use catalyst_types::catalyst_id::role_index::RoleId;
use rules::{
ContentEncodingRule, ContentRule, ContentSchema, ContentTypeRule, IdRule, OriginalAuthorRule,
ParametersRule, RefRule, ReplyRule, Rules, SectionRule, SignatureKidRule, VerRule,
};
use rules::Rules;

use crate::{
doc_types::{
BRAND_PARAMETERS, CAMPAIGN_PARAMETERS, CATEGORY_PARAMETERS, PROPOSAL, PROPOSAL_COMMENT,
PROPOSAL_COMMENT_FORM_TEMPLATE, PROPOSAL_FORM_TEMPLATE, PROPOSAL_SUBMISSION_ACTION,
},
metadata::DocType,
providers::{CatalystIdProvider, CatalystSignedDocumentProvider},
validator::rules::{CollaboratorsRule, SignatureRule, TemplateRule},
CatalystSignedDocument, ContentEncoding, ContentType,
CatalystSignedDocument,
};

/// A table representing a full set or validation rules per document id.
static DOCUMENT_RULES: LazyLock<HashMap<DocType, Rules>> = LazyLock::new(document_rules_init);

/// Proposal
/// Require field: type, id, ver, template, parameters
/// <https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/docs/proposal/>
fn proposal_rule() -> Rules {
// Parameter can be either brand, campaign or category
let parameters = vec![
BRAND_PARAMETERS.clone(),
CAMPAIGN_PARAMETERS.clone(),
CATEGORY_PARAMETERS.clone(),
];
Rules {
id: IdRule,
ver: VerRule,
content_type: ContentTypeRule::Specified {
exp: ContentType::Json,
},
content_encoding: ContentEncodingRule::Specified {
exp: vec![ContentEncoding::Brotli],
optional: false,
},
template: TemplateRule::Specified {
allowed_type: PROPOSAL_FORM_TEMPLATE.clone(),
},
parameters: ParametersRule::Specified {
allowed_type: parameters.clone(),
optional: false,
},
doc_ref: RefRule::NotSpecified,
reply: ReplyRule::NotSpecified,
section: SectionRule::NotSpecified,
collaborators: CollaboratorsRule::NotSpecified,
content: ContentRule::NotNil,
kid: SignatureKidRule {
allowed_roles: [RoleId::Proposer].into_iter().collect(),
},
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
}
}

/// Proposal Comment
/// Require field: type, id, ver, ref, template, parameters
/// <https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/docs/proposal_comment_template/>
fn proposal_comment_rule() -> Rules {
// Parameter can be either brand, campaign or category
let parameters = vec![
BRAND_PARAMETERS.clone(),
CAMPAIGN_PARAMETERS.clone(),
CATEGORY_PARAMETERS.clone(),
];
Rules {
id: IdRule,
ver: VerRule,
content_type: ContentTypeRule::Specified {
exp: ContentType::Json,
},
content_encoding: ContentEncodingRule::Specified {
exp: vec![ContentEncoding::Brotli],
optional: false,
},
template: TemplateRule::Specified {
allowed_type: PROPOSAL_COMMENT_FORM_TEMPLATE.clone(),
},
doc_ref: RefRule::Specified {
allowed_type: vec![PROPOSAL.clone()],
multiple: false,
optional: false,
},
reply: ReplyRule::Specified {
allowed_type: PROPOSAL_COMMENT.clone(),
optional: true,
},
section: SectionRule::NotSpecified,
parameters: ParametersRule::Specified {
allowed_type: parameters.clone(),
optional: false,
},
collaborators: CollaboratorsRule::NotSpecified,
content: ContentRule::NotNil,
kid: SignatureKidRule {
allowed_roles: [RoleId::Role0].into_iter().collect(),
},
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
}
}

/// Proposal Submission Action
/// Require fields: type, id, ver, ref, parameters
/// <https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/docs/proposal_submission_action/>
#[allow(clippy::expect_used)]
fn proposal_submission_action_rule() -> Rules {
// Parameter can be either brand, campaign or category
let parameters = vec![
BRAND_PARAMETERS.clone(),
CAMPAIGN_PARAMETERS.clone(),
CATEGORY_PARAMETERS.clone(),
];

let proposal_action_json_schema_content = &serde_json::from_str(include_str!(
"./../../../../specs/definitions/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json"
))
.expect("Must be a valid json file");

let proposal_action_json_schema =
json_schema::JsonSchema::try_from(proposal_action_json_schema_content)
.expect("Must be a valid json scheme file");

Rules {
id: IdRule,
ver: VerRule,
content_type: ContentTypeRule::Specified {
exp: ContentType::Json,
},
content_encoding: ContentEncodingRule::Specified {
exp: vec![ContentEncoding::Brotli],
optional: false,
},
template: TemplateRule::NotSpecified,
parameters: ParametersRule::Specified {
allowed_type: parameters,
optional: false,
},
doc_ref: RefRule::Specified {
allowed_type: vec![PROPOSAL.clone()],
multiple: false,
optional: false,
},
reply: ReplyRule::NotSpecified,
section: SectionRule::NotSpecified,
collaborators: CollaboratorsRule::NotSpecified,
content: ContentRule::StaticSchema(ContentSchema::Json(proposal_action_json_schema)),
kid: SignatureKidRule {
allowed_roles: [RoleId::Proposer].into_iter().collect(),
},
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
}
}

/// `DOCUMENT_RULES` initialization function
#[allow(clippy::expect_used)]
fn document_rules_init() -> HashMap<DocType, Rules> {
let mut document_rules_map: HashMap<DocType, Rules> = Rules::documents_rules()
let document_rules_map: HashMap<DocType, Rules> = Rules::documents_rules()
.expect("cannot fail to initialize validation rules")
.collect();

// TODO: remove this redefinitions of the validation rules after
// `catalyst_signed_documents_rules!` macro would be fully finished
document_rules_map.insert(PROPOSAL.clone(), proposal_rule());
document_rules_map.insert(PROPOSAL_COMMENT.clone(), proposal_comment_rule());
document_rules_map.insert(
PROPOSAL_SUBMISSION_ACTION.clone(),
proposal_submission_action_rule(),
);

document_rules_map
}

Expand Down
2 changes: 1 addition & 1 deletion rust/signed_doc/src/validator/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod utils;
mod ver;

pub(crate) use collaborators::CollaboratorsRule;
pub(crate) use content::{ContentRule, ContentSchema};
pub(crate) use content::ContentRule;
pub(crate) use content_encoding::ContentEncodingRule;
pub(crate) use content_type::ContentTypeRule;
pub(crate) use doc_ref::RefRule;
Expand Down
27 changes: 13 additions & 14 deletions rust/signed_doc/src/validator/rules/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ impl TemplateRule {
return false;
};
match template_content_type {
ContentType::Json | ContentType::SchemaJson => {
templated_json_schema_check(doc, template_doc)
},
ContentType::Cddl
ContentType::SchemaJson => templated_json_schema_check(doc, template_doc),
ContentType::Json
| ContentType::Cddl
| ContentType::Cbor
| ContentType::Css
| ContentType::CssHandlebars
Expand All @@ -98,7 +97,7 @@ impl TemplateRule {
| ContentType::Plain
| ContentType::PlainHandlebars => {
// TODO: not implemented yet
true
false
},
}
};
Expand Down Expand Up @@ -183,7 +182,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand Down Expand Up @@ -212,7 +211,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand All @@ -238,7 +237,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand All @@ -265,7 +264,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand Down Expand Up @@ -293,7 +292,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(UuidV4::new().into()))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand Down Expand Up @@ -321,7 +320,7 @@ mod tests {
let doc = Builder::new()
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand Down Expand Up @@ -377,7 +376,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.build();
provider.add_document(None, &doc).unwrap();

Expand All @@ -404,7 +403,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(vec![1,2 ,3])
.build();
provider.add_document(None, &doc).unwrap();
Expand Down Expand Up @@ -478,7 +477,7 @@ mod tests {
.with_metadata_field(SupportedField::Id(*template_ref.id()))
.with_metadata_field(SupportedField::Ver(*template_ref.ver()))
.with_metadata_field(SupportedField::Type(allowed_type))
.with_metadata_field(SupportedField::ContentType(ContentType::Json))
.with_metadata_field(SupportedField::ContentType(ContentType::SchemaJson))
.with_content(json_schema)
.build();
provider.add_document(None, &doc).unwrap();
Expand Down
Loading
Loading