Skip to content

Commit

Permalink
add recordId validation
Browse files Browse the repository at this point in the history
  • Loading branch information
kayhhh committed Dec 18, 2023
1 parent f4dce8c commit b20c5d7
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 79 deletions.
63 changes: 63 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 57 additions & 28 deletions dwn-server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use std::net::SocketAddr;

use axum::{http::StatusCode, routing::post, Json, Router};
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
routing::post,
Json, Router,
};
use dwn::data::{Message, RecordIdGenerator};
use tracing::{error, info, span, warn};

/// Start the server.
Expand All @@ -25,36 +31,59 @@ pub async fn start() {
}
}

async fn post_handler(body: Json<dwn::data::RequestBody>) -> StatusCode {
// https://identity.foundation/decentralized-web-node/spec/#request-level-status-coding
const DID_NOT_FOUND: (StatusCode, &str) = (StatusCode::NOT_FOUND, "DID not found");
const SERVER_ERROR: (StatusCode, &str) = (
StatusCode::INTERNAL_SERVER_ERROR,
"The request could not be processed correctly",
);

async fn post_handler(body: Json<dwn::data::RequestBody>) -> Response {
for message in body.0.messages.iter() {
span!(tracing::Level::INFO, "message", ?message);

// Validate message
if message.data.is_some() {
match &message.descriptor.data_cid {
Some(_) => {
// TODO: Validate data_cid
}
None => {
warn!("Message has data but dataCid is None");
return StatusCode::BAD_REQUEST;
}
};

match &message.descriptor.data_format {
Some(_) => {
// TODO: Validate data_format
}
None => {
warn!("Message has data but dataFormat is None");
return StatusCode::BAD_REQUEST;
}
};
if let Err(e) = process_message(message) {
warn!("{}", e);
return SERVER_ERROR.into_response();
}
}

StatusCode::OK.into_response()
}

fn process_message(message: &Message) -> Result<(), Box<dyn std::error::Error>> {
span!(tracing::Level::INFO, "message", ?message);

{
// Validate record_id
let generator = RecordIdGenerator::try_from(&message.descriptor)?;
let cid = generator.generate_cid()?;

// Process message
info!("Received message: {:?}", message);
if cid != message.record_id {
return Err("Record ID not valid".into());
}
}

StatusCode::OK
if message.data.is_some() {
match &message.descriptor.data_cid {
Some(_) => {
// TODO: Validate data_cid
}
None => {
return Err("Message has data but dataCid is None".into());
}
};

match &message.descriptor.data_format {
Some(_) => {
// TODO: Validate data_format
}
None => {
return Err("Message has data but dataFormat is None".into());
}
};
}

// Process message
info!("Received message: {:?}", message);

Ok(())
}
82 changes: 55 additions & 27 deletions dwn-server/tests/messages.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use dwn::data::{Descriptor, Message};
use dwn::data::{Descriptor, Message, RequestBody};
use reqwest::StatusCode;

const SERVER_ADDR: &str = "http://localhost:3000";
Expand Down Expand Up @@ -29,41 +29,60 @@ async fn send_post(data: dwn::data::RequestBody) -> StatusCode {
res.status()
}

fn empty_message() -> Message {
let mut msg = Message {
record_id: String::new(),
data: None,
descriptor: Descriptor {
method: "application/json".to_string(),
interface: "test interface".to_string(),
data_cid: None,
data_format: None,
},
};

msg.generate_record_id()
.expect("Failed to generate record_id");

msg
}

#[tokio::test]
async fn recieve_post() {
spawn_server();

let data = dwn::data::RequestBody {
messages: vec![Message {
record_id: String::new(),
data: None,
descriptor: Descriptor {
method: "application/json".to_string(),
interface: "test_interface".to_string(),
data_cid: None,
data_format: None,
},
}],
let body = RequestBody {
messages: vec![empty_message()],
};

assert_eq!(send_post(body).await, StatusCode::OK);
}

#[tokio::test]
async fn requires_valid_record_id() {
spawn_server();

let mut msg = empty_message();
msg.record_id = "invalid record id".to_string();

let body = RequestBody {
messages: vec![msg],
};

assert_eq!(send_post(data).await, StatusCode::OK);
assert_eq!(send_post(body).await, StatusCode::INTERNAL_SERVER_ERROR);
}

#[tokio::test]
async fn requires_data_descriptors() {
spawn_server();

let body = dwn::data::RequestBody {
messages: vec![Message {
record_id: String::new(),
data: Some("test_data".to_string()),
descriptor: Descriptor {
method: "application/json".to_string(),
interface: "test_interface".to_string(),
data_cid: Some("test_data_cid".to_string()),
data_format: Some("test_data_format".to_string()),
},
}],
let mut msg = empty_message();
msg.data = Some("test data".to_string());
msg.descriptor.data_cid = Some("test data cid".to_string());
msg.descriptor.data_format = Some("test data format".to_string());

let body = RequestBody {
messages: vec![msg],
};

let mut without_cid = body.clone();
Expand All @@ -76,7 +95,16 @@ async fn requires_data_descriptors() {
without_both.messages[0].descriptor.data_cid = None;
without_both.messages[0].descriptor.data_format = None;

assert_eq!(send_post(without_cid).await, StatusCode::BAD_REQUEST);
assert_eq!(send_post(without_format).await, StatusCode::BAD_REQUEST);
assert_eq!(send_post(without_both).await, StatusCode::BAD_REQUEST);
assert_eq!(
send_post(without_cid).await,
StatusCode::INTERNAL_SERVER_ERROR
);
assert_eq!(
send_post(without_format).await,
StatusCode::INTERNAL_SERVER_ERROR
);
assert_eq!(
send_post(without_both).await,
StatusCode::INTERNAL_SERVER_ERROR
);
}
2 changes: 2 additions & 0 deletions dwn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ license.workspace = true

[dependencies]
cid = "0.11.0"
libipld-core = "0.16.0"
libipld-pb = "0.16.0"
multihash-codetable = { version = "0.1.1", features = ["digest", "sha2"] }
serde = { version = "1.0.193", features = ["derive"] }
serde_ipld_dagcbor = "0.4.2"
Expand Down
Loading

0 comments on commit b20c5d7

Please sign in to comment.