diff --git a/services/identity/Cargo.lock b/services/identity/Cargo.lock --- a/services/identity/Cargo.lock +++ b/services/identity/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -67,7 +67,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -603,7 +603,7 @@ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -791,7 +791,7 @@ "proc-macro2", "quote", "scratch", - "syn", + "syn 1.0.107", ] [[package]] @@ -808,7 +808,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -834,7 +834,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -847,7 +847,7 @@ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.107", ] [[package]] @@ -878,7 +878,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1006,7 +1006,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1320,6 +1320,8 @@ "opaque-ke 1.2.0", "prost", "rand", + "serde", + "serde_json", "siwe", "tokio", "tokio-stream", @@ -1645,7 +1647,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1673,7 +1675,7 @@ checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.107", ] [[package]] @@ -1685,7 +1687,7 @@ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "version_check", ] @@ -1702,9 +1704,9 @@ [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -1736,7 +1738,7 @@ "prost", "prost-types", "regex", - "syn", + "syn 1.0.107", "tempfile", "which", ] @@ -1751,7 +1753,7 @@ "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1766,9 +1768,9 @@ [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -1985,22 +1987,33 @@ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.13", +] + +[[package]] +name = "serde_json" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", ] [[package]] @@ -2128,6 +2141,17 @@ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -2142,7 +2166,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "unicode-xid", ] @@ -2192,7 +2216,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2278,7 +2302,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2359,7 +2383,7 @@ "proc-macro2", "prost-build", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2454,7 +2478,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2630,7 +2654,7 @@ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -2652,7 +2676,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2829,6 +2853,6 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "synstructure", ] diff --git a/services/identity/Cargo.toml b/services/identity/Cargo.toml --- a/services/identity/Cargo.toml +++ b/services/identity/Cargo.toml @@ -28,6 +28,8 @@ once_cell = "1.17" hex = "0.4" tonic-web = "0.5" +serde = { version = "1.0.159", features = [ "derive" ] } +serde_json = "1.0.95" [build-dependencies] tonic-build = "0.8" diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -11,6 +11,7 @@ use aws_sdk_dynamodb::{Client, Error as DynamoDBError}; use chrono::{DateTime, Utc}; use opaque_ke::{errors::ProtocolError, ServerRegistration}; +use serde::{Deserialize, Serialize}; use tracing::{debug, error, info, warn}; use crate::config::CONFIG; @@ -30,6 +31,32 @@ use crate::token::{AccessTokenData, AuthType}; use comm_opaque::Cipher; +#[derive(Serialize, Deserialize)] +pub struct OlmKeys { + curve25519: String, + ed25519: String, +} + +#[derive(Serialize, Deserialize)] +pub struct KeyPayload { + #[serde(rename = "notificationIdentityPublicKeys")] + notification_identity_public_keys: OlmKeys, + #[serde(rename = "primaryIdentityPublicKeys")] + primary_identity_public_keys: OlmKeys, +} + +impl KeyPayload { + // The payload is held in the database as an escaped JSON payload. + // Escaped double quotes need to trimmed before attempting to serialize + fn from_payload(payload: &str) -> Result { + serde_json::from_str(&payload.replace(r#"\""#, r#"""#)) + } + + fn to_payload(&self) -> Result { + Ok(serde_json::to_string(self)?.replace(r#"""#, r#"\""#)) + } +} + #[derive(Clone)] pub struct DatabaseClient { client: Arc, @@ -787,4 +814,31 @@ assert!(sort_key_attribute.is_some()); assert_eq!(sort_key_attribute, Some(AttributeValue::S(sort_key_value))) } + + #[test] + fn validate_keys() { + // Taken from test user + let example_payload = r#"{\"notificationIdentityPublicKeys\":{\"curve25519\":\"DYmV8VdkjwG/VtC8C53morogNJhpTPT/4jzW0/cxzQo\",\"ed25519\":\"D0BV2Y7Qm36VUtjwyQTJJWYAycN7aMSJmhEsRJpW2mk\"},\"primaryIdentityPublicKeys\":{\"curve25519\":\"Y4ZIqzpE1nv83kKGfvFP6rifya0itRg2hifqYtsISnk\",\"ed25519\":\"cSlL+VLLJDgtKSPlIwoCZg0h0EmHlQoJC08uV/O+jvg\"}}"#; + let serialized_payload = + KeyPayload::from_payload(&example_payload).unwrap(); + } + + #[test] + fn format_keys() { + let expected_payload = r#"{\"notificationIdentityPublicKeys\":{\"curve25519\":\"DYmV8VdkjwG/VtC8C53morogNJhpTPT/4jzW0/cxzQo\",\"ed25519\":\"D0BV2Y7Qm36VUtjwyQTJJWYAycN7aMSJmhEsRJpW2mk\"},\"primaryIdentityPublicKeys\":{\"curve25519\":\"Y4ZIqzpE1nv83kKGfvFP6rifya0itRg2hifqYtsISnk\",\"ed25519\":\"cSlL+VLLJDgtKSPlIwoCZg0h0EmHlQoJC08uV/O+jvg\"}}"#; + let notif_keys = OlmKeys { + curve25519: "DYmV8VdkjwG/VtC8C53morogNJhpTPT/4jzW0/cxzQo".to_string(), + ed25519: "D0BV2Y7Qm36VUtjwyQTJJWYAycN7aMSJmhEsRJpW2mk".to_string(), + }; + let identity_keys = OlmKeys { + curve25519: "Y4ZIqzpE1nv83kKGfvFP6rifya0itRg2hifqYtsISnk".to_string(), + ed25519: "cSlL+VLLJDgtKSPlIwoCZg0h0EmHlQoJC08uV/O+jvg".to_string(), + }; + let payload = KeyPayload { + notification_identity_public_keys: notif_keys, + primary_identity_public_keys: identity_keys, + }; + + assert_eq!(payload.to_payload().unwrap(), expected_payload); + } }