Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Set JSON schema supported versions #62

Merged
merged 1 commit into from
Jun 26, 2024
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
2 changes: 1 addition & 1 deletion crates/tbdex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ build = "build.rs"
base64 = "0.22.0"
chrono = "0.4.38"
josekit = "0.8.6"
jsonschema = "0.18.0"
jsonschema = { version = "0.18.0", features = ["draft201909", "draft202012"] }
rand = "0.8.5"
reqwest = { version = "0.12.5", features = ["blocking"] }
sha2 = "0.10.8"
Expand Down
20 changes: 17 additions & 3 deletions crates/tbdex/src/json_schemas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub enum JsonSchemaError {
SerdeJson(String),
#[error("json schema failure {0:?}")]
JsonSchema(Vec<String>),
#[error("unsupported json schema version {0}")]
UnsupportedVersion(String),
}

impl From<SerdeJsonError> for JsonSchemaError {
Expand Down Expand Up @@ -55,12 +57,24 @@ impl SchemaResolver for LocalSchemaResolver {
}
}

pub fn validate<T: Serialize>(schema: &str, value: &T) -> Result<()> {
let schema_value = serde_json::from_str::<serde_json::Value>(&schema.replace("\\#", "#"))?;
pub fn validate_from_str<T: Serialize>(schema_str: &str, value: &T) -> Result<()> {
let schema = &serde_json::from_str::<serde_json::Value>(&schema_str.replace("\\#", "#"))?;

validate(schema, value)?;

Ok(())
}

pub fn validate<T: Serialize>(schema: &serde_json::Value, value: &T) -> Result<()> {
if let Some(serde_json::Value::String(url)) = schema.get("$schema") {
if url.contains("draft-04") || url.contains("draft-06") {
return Err(JsonSchemaError::UnsupportedVersion(url.to_string()));
}
}

let compiled = JSONSchema::options()
.with_resolver(LocalSchemaResolver::new())
.compile(&schema_value)
.compile(schema)
.map_err(|e| JsonSchemaError::JsonSchema(vec![e.to_string()]))?;

let instance = serde_json::to_value(value)?;
Expand Down
4 changes: 2 additions & 2 deletions crates/tbdex/src/messages/close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ impl Close {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(MESSAGE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(MESSAGE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(CLOSE_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(CLOSE_DATA_JSON_SCHEMA, &self.data)?;

// verify signature
crate::signature::verify(
Expand Down
4 changes: 2 additions & 2 deletions crates/tbdex/src/messages/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ impl Order {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(MESSAGE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(MESSAGE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(ORDER_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(ORDER_DATA_JSON_SCHEMA, &self.data)?;

// verify signature
crate::signature::verify(
Expand Down
4 changes: 2 additions & 2 deletions crates/tbdex/src/messages/order_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ impl OrderStatus {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(MESSAGE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(MESSAGE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(ORDER_STATUS_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(ORDER_STATUS_DATA_JSON_SCHEMA, &self.data)?;

// verify signature
crate::signature::verify(
Expand Down
4 changes: 2 additions & 2 deletions crates/tbdex/src/messages/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ impl Quote {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(MESSAGE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(MESSAGE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(QUOTE_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(QUOTE_DATA_JSON_SCHEMA, &self.data)?;

// verify signature
crate::signature::verify(
Expand Down
69 changes: 29 additions & 40 deletions crates/tbdex/src/messages/rfq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::{
};
use base64::{engine::general_purpose, Engine as _};
use chrono::Utc;
use jsonschema::JSONSchema;
use rand::{rngs::OsRng, RngCore};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
Expand Down Expand Up @@ -82,13 +81,13 @@ impl Rfq {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(MESSAGE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(MESSAGE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(RFQ_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(RFQ_DATA_JSON_SCHEMA, &self.data)?;

// verify private data json schema
crate::json_schemas::validate(RFQ_PRIVATE_DATA_JSON_SCHEMA, &self.private_data)?;
crate::json_schemas::validate_from_str(RFQ_PRIVATE_DATA_JSON_SCHEMA, &self.private_data)?;

// verify signature
crate::signature::verify(
Expand Down Expand Up @@ -181,25 +180,20 @@ impl Rfq {
)
})?;

let compiled = JSONSchema::compile(json_schema).map_err(|_| {
MessageError::OfferingVerification(
"failed to compile offering JSON schema".to_string(),
)
})?;

let payin_details = self.private_data.payin.as_ref().ok_or_else(|| {
MessageError::OfferingVerification("missing private payin data".to_string())
})?;

let payment_details = payin_details.payment_details.as_ref().ok_or_else(|| {
MessageError::OfferingVerification("missing payment details".to_string())
})?;
let payment_details = self
.private_data
.payin
.as_ref()
.ok_or_else(|| {
MessageError::OfferingVerification("missing private payin data".to_string())
})?
.payment_details
.as_ref()
.ok_or_else(|| {
MessageError::OfferingVerification("missing payment details".to_string())
})?;

if !compiled.is_valid(payment_details) {
return Err(MessageError::OfferingVerification(
"payin failed JSON schema validation".to_string(),
));
}
crate::json_schemas::validate(json_schema, payment_details)?;
} else {
return Err(MessageError::OfferingVerification(format!(
"kind {} not found in offering",
Expand All @@ -224,25 +218,20 @@ impl Rfq {
)
})?;

let compiled = JSONSchema::compile(json_schema).map_err(|_| {
MessageError::OfferingVerification(
"failed to compile offering JSON schema".to_string(),
)
})?;

let payout_details = self.private_data.payout.as_ref().ok_or_else(|| {
MessageError::OfferingVerification("missing private payout data".to_string())
})?;

let payment_details = payout_details.payment_details.as_ref().ok_or_else(|| {
MessageError::OfferingVerification("missing payment details".to_string())
})?;
let payment_details = self
.private_data
.payout
.as_ref()
.ok_or_else(|| {
MessageError::OfferingVerification("missing private payout data".to_string())
})?
.payment_details
.as_ref()
.ok_or_else(|| {
MessageError::OfferingVerification("missing payment details".to_string())
})?;

if !compiled.is_valid(payment_details) {
return Err(MessageError::OfferingVerification(
"payout failed JSON schema validation".to_string(),
));
}
crate::json_schemas::validate(json_schema, payment_details)?;
} else {
return Err(MessageError::OfferingVerification(format!(
"kind {} not found in offering",
Expand Down
4 changes: 2 additions & 2 deletions crates/tbdex/src/resources/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ impl Balance {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(RESOURCE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(RESOURCE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(BALANCE_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(BALANCE_DATA_JSON_SCHEMA, &self.data)?;

// verify signature
crate::signature::verify(
Expand Down
4 changes: 2 additions & 2 deletions crates/tbdex/src/resources/offering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ impl Offering {

pub fn verify(&self) -> Result<()> {
// verify resource json schema
crate::json_schemas::validate(RESOURCE_JSON_SCHEMA, self)?;
crate::json_schemas::validate_from_str(RESOURCE_JSON_SCHEMA, self)?;

// verify data json schema
crate::json_schemas::validate(OFFERING_DATA_JSON_SCHEMA, &self.data)?;
crate::json_schemas::validate_from_str(OFFERING_DATA_JSON_SCHEMA, &self.data)?;

// verify signature
crate::signature::verify(
Expand Down
Loading