Add structs for OpenPGP for XMPP (XEP-0373).

Maxime “pep” Buquet created

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>

Change summary

ChangeLog      |   5 ++
src/lib.rs     |   3 +
src/ns.rs      |   5 ++
src/openpgp.rs | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)

Detailed changes

ChangeLog 🔗

@@ -1,3 +1,8 @@
+Version NEXT:
+DATE  Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+    * New parsers/serialisers:
+        - OpenPGP for XMPP (XEP-0373)
+
 Version 0.15.0:
 2019-09-06  Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
     * New parsers/serialisers:

src/lib.rs 🔗

@@ -183,6 +183,9 @@ pub mod jingle_message;
 /// XEP-0359: Unique and Stable Stanza IDs
 pub mod stanza_id;
 
+/// XEP-0373: OpenPGP for XMPP
+pub mod openpgp;
+
 /// XEP-0380: Explicit Message Encryption
 pub mod eme;
 

src/ns.rs 🔗

@@ -188,6 +188,11 @@ pub const JINGLE_MESSAGE: &str = "urn:xmpp:jingle-message:0";
 /// XEP-0359: Unique and Stable Stanza IDs
 pub const SID: &str = "urn:xmpp:sid:0";
 
+/// XEP-0373: OpenPGP for XMPP
+pub const OX: &str = "urn:xmpp:openpgp:0";
+/// XEP-0373: OpenPGP for XMPP
+pub const OX_PUBKEYS: &str = "urn:xmpp:openpgp:0:public-keys";
+
 /// XEP-0380: Explicit Message Encryption
 pub const EME: &str = "urn:xmpp:eme:0";
 

src/openpgp.rs 🔗

@@ -0,0 +1,104 @@
+// Copyright (c) 2019 Maxime “pep” Buquet <pep@bouah.net>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+use crate::date::DateTime;
+use crate::util::helpers::Base64;
+use crate::pubsub::PubSubPayload;
+
+// TODO: Merge this container with the PubKey struct
+generate_element!(
+    /// Data contained in the PubKey element
+    PubKeyData, "data", OX,
+    text: (
+        /// Base64 data
+        data: Base64<Vec<u8>>
+    )
+);
+
+generate_element!(
+    /// Pubkey element to be used in PubSub publish payloads.
+    PubKey, "pubkey", OX,
+    attributes: [
+        /// Last updated date
+        date: Option<DateTime> = "date"
+    ],
+    children: [
+        /// Public key as base64 data
+        data: Required<PubKeyData> = ("data", OX) => PubKeyData
+    ]
+);
+
+impl PubSubPayload for PubKey {}
+
+generate_element!(
+    /// Public key metadata
+    PubKeyMeta, "pubkey-metadata", OX,
+    attributes: [
+        /// OpenPGP v4 fingerprint
+        v4fingerprint: Required<String> = "v4-fingerprint",
+        /// Time the key was published or updated
+        date: Required<DateTime> = "date",
+    ]
+);
+
+generate_element!(
+    /// List of public key metadata
+    PubKeysMeta, "public-key-list", OX,
+    children: [
+        /// Public keys
+        pubkeys: Vec<PubKeyMeta> = ("pubkey-metadata", OX) => PubKeyMeta
+    ]
+);
+
+impl PubSubPayload for PubKeysMeta {}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::ns;
+    use std::str::FromStr;
+    use crate::pubsub::{NodeName, Item, pubsub::{Item as PubSubItem, Publish}};
+
+    #[test]
+    fn pubsub_publish_pubkey_data() {
+        let pubkey = PubKey {
+            date: None,
+            data: PubKeyData {
+                data: (&"Foo").as_bytes().to_vec(),
+            }
+        };
+        println!("Foo1: {:?}", pubkey);
+
+        let pubsub = Publish {
+            node: NodeName(format!("{}:{}", ns::OX_PUBKEYS, "some-fingerprint")),
+            items: vec![
+                PubSubItem(Item::new(None, None, Some(pubkey))),
+            ],
+        };
+        println!("Foo2: {:?}", pubsub);
+    }
+
+    #[test]
+    fn pubsub_publish_pubkey_meta() {
+        let pubkeymeta = PubKeysMeta {
+            pubkeys: vec![
+                PubKeyMeta {
+                    v4fingerprint: "some-fingerprint".to_owned(),
+                    date: DateTime::from_str("2019-03-30T18:30:25Z").unwrap(),
+                },
+            ],
+        };
+        println!("Foo1: {:?}", pubkeymeta);
+
+        let pubsub = Publish {
+            node: NodeName("foo".to_owned()),
+            items: vec![
+                PubSubItem(Item::new(None, None, Some(pubkeymeta))),
+            ],
+        };
+        println!("Foo2: {:?}", pubsub);
+    }
+}