src/lib.rs π
@@ -194,3 +194,6 @@ pub mod eme;
/// XEP-0390: Entity Capabilities 2.0
pub mod ecaps2;
+
+/// XEP-0421: Anonymous unique occupant identifiers for MUCs
+pub mod occupant_id;
Emmanuel Gil Peyrot created
src/lib.rs | 3 +
src/ns.rs | 3 +
src/occupant_id.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)
@@ -194,3 +194,6 @@ pub mod eme;
/// XEP-0390: Entity Capabilities 2.0
pub mod ecaps2;
+
+/// XEP-0421: Anonymous unique occupant identifiers for MUCs
+pub mod occupant_id;
@@ -204,6 +204,9 @@ pub const ECAPS2: &str = "urn:xmpp:caps";
/// XEP-0390: Entity Capabilities 2.0
pub const ECAPS2_OPTIMIZE: &str = "urn:xmpp:caps:optimize";
+/// XEP-0421: Anonymous unique occupant identifiers for MUCs
+pub const OID: &str = "urn:xmpp:occupant-id:0";
+
/// Alias for the main namespace of the stream, that is "jabber:client" when
/// the component feature isnβt enabled.
#[cfg(not(feature = "component"))]
@@ -0,0 +1,89 @@
+// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+//
+// 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::message::MessagePayload;
+use crate::presence::PresencePayload;
+
+generate_element!(
+ /// Unique identifier given to a MUC participant.
+ ///
+ /// It allows clients to identify a MUC participant across reconnects and
+ /// renames. It thus prevents impersonification of anonymous users.
+ OccupantId, "occupant-id", OID,
+
+ attributes: [
+ /// The id associated to the sending user by the MUC service.
+ id: Required<String> = "id",
+ ]
+);
+
+impl MessagePayload for OccupantId {}
+impl PresencePayload for OccupantId {}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::util::error::Error;
+ use minidom::Element;
+ use std::convert::TryFrom;
+
+ #[cfg(target_pointer_width = "32")]
+ #[test]
+ fn test_size() {
+ assert_size!(OccupantId, 12);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_size() {
+ assert_size!(OccupantId, 24);
+ }
+
+ #[test]
+ fn test_simple() {
+ let elem: Element = "<occupant-id xmlns='urn:xmpp:occupant-id:0' id='coucou'/>"
+ .parse()
+ .unwrap();
+ let origin_id = OccupantId::try_from(elem).unwrap();
+ assert_eq!(origin_id.id, "coucou");
+ }
+
+ #[test]
+ fn test_invalid_child() {
+ let elem: Element = "<occupant-id xmlns='urn:xmpp:occupant-id:0'><coucou/></occupant-id>"
+ .parse()
+ .unwrap();
+ let error = OccupantId::try_from(elem).unwrap_err();
+ let message = match error {
+ Error::ParseError(string) => string,
+ _ => panic!(),
+ };
+ assert_eq!(message, "Unknown child in occupant-id element.");
+ }
+
+ #[test]
+ fn test_invalid_id() {
+ let elem: Element = "<occupant-id xmlns='urn:xmpp:occupant-id:0'/>".parse().unwrap();
+ let error = OccupantId::try_from(elem).unwrap_err();
+ let message = match error {
+ Error::ParseError(string) => string,
+ _ => panic!(),
+ };
+ assert_eq!(message, "Required attribute 'id' missing.");
+ }
+
+ #[test]
+ fn test_serialise() {
+ let elem: Element = "<occupant-id xmlns='urn:xmpp:occupant-id:0' id='coucou'/>"
+ .parse()
+ .unwrap();
+ let occupant_id = OccupantId {
+ id: String::from("coucou"),
+ };
+ let elem2 = occupant_id.into();
+ assert_eq!(elem, elem2);
+ }
+}