From 6eb8f575ca8cfd4a6bacbf40a8af8609673c847e Mon Sep 17 00:00:00 2001 From: Cecylia Bocovich Date: Mon, 30 Jan 2023 15:24:58 -0500 Subject: [PATCH] Add proto.rs after module refactor --- crates/rdsys-backend/src/proto.rs | 206 ++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 crates/rdsys-backend/src/proto.rs diff --git a/crates/rdsys-backend/src/proto.rs b/crates/rdsys-backend/src/proto.rs new file mode 100644 index 0000000..bb96fb6 --- /dev/null +++ b/crates/rdsys-backend/src/proto.rs @@ -0,0 +1,206 @@ +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; + +/// The body of the request for resources made to the rdsys backend +#[derive(Serialize)] +pub struct ResourceRequest { + pub request_origin: String, + pub resource_types: Vec, +} + +/// Representation of a bridge resource +#[derive(Deserialize, PartialEq, Debug)] +pub struct Resource { + pub r#type: String, + pub blocked_in: HashMap, + pub protocol: String, + pub address: String, + pub port: u16, + pub fingerprint: String, + #[serde(rename = "or-addresses")] + pub or_addresses: Option>, + pub distribution: String, + pub flags: Option>, + pub params: Option>, +} + +/// A ResourceDiff holds information about new, changed, or pruned resources +#[derive(Deserialize, PartialEq, Debug)] +pub struct ResourceDiff { + pub new: Option>>, + pub changed: Option>>, + pub gone: Option>>, + pub full_update: bool, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize_resource_request() { + let req = ResourceRequest { + request_origin: String::from("https"), + resource_types: vec![String::from("obfs2"), String::from("scramblesuit")], + }; + let json = serde_json::to_string(&req).unwrap(); + assert_eq!( + json, + "{\"request_origin\":\"https\",\"resource_types\":[\"obfs2\",\"scramblesuit\"]}" + ) + } + + #[test] + fn deserialize_resource() { + let mut flags = HashMap::new(); + flags.insert(String::from("fast"), true); + flags.insert(String::from("stable"), true); + let mut params = HashMap::new(); + params.insert( + String::from("password"), + String::from("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"), + ); + let bridge = Resource { + r#type: String::from("scramblesuit"), + blocked_in: HashMap::new(), + protocol: String::from("tcp"), + address: String::from("216.117.3.62"), + port: 63174, + fingerprint: String::from("BE84A97D02130470A1C77839954392BA979F7EE1"), + or_addresses: None, + distribution: String::from("https"), + flags: Some(flags), + params: Some(params), + }; + + let data = r#" + { + "type": "scramblesuit", + "blocked_in": {}, + "protocol": "tcp", + "address": "216.117.3.62", + "port": 63174, + "fingerprint": "BE84A97D02130470A1C77839954392BA979F7EE1", + "or-addresses": null, + "distribution": "https", + "flags": { + "fast": true, + "stable": true + }, + "params": { + "password": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" + } + }"#; + let res: Resource = serde_json::from_str(data).unwrap(); + assert_eq!(bridge, res); + } + + #[test] + fn deserialize_resource_diff() { + let data = r#" + { + "new": { + "obfs2": [ + { + "type": "obfs2", + "blocked_in": {}, + "Location": null, + "protocol": "tcp", + "address": "176.247.216.207", + "port": 42810, + "fingerprint": "10282810115283F99ADE5CFE42D49644F45D715D", + "or-addresses": null, + "distribution": "https", + "flags": { + "fast": true, + "stable": true, + "running": true, + "valid": true + } + }, + { + "type": "obfs2", + "blocked_in": {}, + "protocol": "tcp", + "address": "133.69.16.145", + "port": 58314, + "fingerprint": "BE84A97D02130470A1C77839954392BA979F7EE1", + "or-addresses": null, + "distribution": "https", + "flags": { + "fast": true, + "stable": true, + "running": true, + "valid": true + } + } + ], + "scramblesuit": [ + { + "type": "scramblesuit", + "blocked_in": {}, + "protocol": "tcp", + "address": "216.117.3.62", + "port": 63174, + "fingerprint": "BE84A97D02130470A1C77839954392BA979F7EE1", + "or-addresses": null, + "distribution": "https", + "flags": { + "fast": true, + "stable": true, + "running": true, + "valid": true + }, + "params": { + "password": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" + } + } + ] + }, + "changed": null, + "gone": null, + "full_update": true + }"#; + let diff: ResourceDiff = serde_json::from_str(data).unwrap(); + assert_ne!(diff.new, None); + assert_eq!(diff.changed, None); + assert_eq!(diff.gone, None); + assert_eq!(diff.full_update, true); + if let Some(new) = diff.new { + assert_eq!(new["obfs2"][0].r#type, "obfs2"); + } + } + + #[test] + fn deserialize_empty_resource_diff() { + let data = r#" + { + "new": null, + "changed": null, + "gone": null, + "full_update": true + }"#; + let diff: ResourceDiff = serde_json::from_str(data).unwrap(); + let empty_diff = ResourceDiff { + new: None, + changed: None, + gone: None, + full_update: true, + }; + assert_eq!(diff, empty_diff); + } + + #[test] + fn deserialize_empty_condensed_diff() { + let data = "{\"new\": null,\"changed\": null,\"gone\": null,\"full_update\": true}"; + let diff: ResourceDiff = serde_json::from_str(data).unwrap(); + let empty_diff = ResourceDiff { + new: None, + changed: None, + gone: None, + full_update: true, + }; + assert_eq!(diff, empty_diff); + } +}