From 4263dd7141563927823373964c6f8f6d1121a973 Mon Sep 17 00:00:00 2001 From: nain-F49FF806 <126972030+nain-F49FF806@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:11:48 +0100 Subject: [PATCH] Add mediator coordination messages to aries-vcx messages crate (#1052) * Add support for mediator coordination messages Signed-off-by: Naian <126972030+nain-F49FF806@users.noreply.github.com> --- aries_vcx/src/handlers/util.rs | 22 ++++ messages/src/lib.rs | 10 +- .../protocols/coordinate_mediation/keylist.rs | 86 +++++++++++++ .../coordinate_mediation/keylist_query.rs | 72 +++++++++++ .../coordinate_mediation/keylist_update.rs | 75 +++++++++++ .../keylist_update_response.rs | 85 ++++++++++++ .../coordinate_mediation/mediate_deny.rs | 48 +++++++ .../coordinate_mediation/mediate_grant.rs | 58 +++++++++ .../coordinate_mediation/mediate_request.rs | 47 +++++++ .../protocols/coordinate_mediation/mod.rs | 121 ++++++++++++++++++ messages/src/msg_fields/protocols/mod.rs | 1 + .../protocols/coordinate_mediation.rs | 33 +++++ messages/src/msg_types/protocols/mod.rs | 13 +- messages/src/msg_types/protocols/pickup.rs | 2 +- messages/src/msg_types/registry.rs | 3 + messages/src/msg_types/role.rs | 1 + 16 files changed, 670 insertions(+), 7 deletions(-) create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/keylist.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/keylist_query.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/keylist_update.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/keylist_update_response.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/mediate_deny.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/mediate_grant.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/mediate_request.rs create mode 100644 messages/src/msg_fields/protocols/coordinate_mediation/mod.rs create mode 100644 messages/src/msg_types/protocols/coordinate_mediation.rs diff --git a/aries_vcx/src/handlers/util.rs b/aries_vcx/src/handlers/util.rs index ccfc7cf6e5..bffb85c9e4 100644 --- a/aries_vcx/src/handlers/util.rs +++ b/aries_vcx/src/handlers/util.rs @@ -1,6 +1,7 @@ use messages::{ msg_fields::protocols::{ connection::{invitation::Invitation, Connection}, + coordinate_mediation::CoordinateMediation, cred_issuance::{v1::CredentialIssuanceV1, v2::CredentialIssuanceV2, CredentialIssuance}, discover_features::DiscoverFeatures, notification::Notification, @@ -217,6 +218,27 @@ pub fn verify_thread_id(thread_id: &str, message: &AriesMessage) -> VcxResult<() AriesMessage::Pickup(Pickup::LiveDeliveryChange(msg)) => { matches_opt_thread_id!(msg, thread_id) } + AriesMessage::CoordinateMediation(CoordinateMediation::MediateRequest(msg)) => { + msg.id == thread_id + } + AriesMessage::CoordinateMediation(CoordinateMediation::MediateDeny(msg)) => { + matches_opt_thread_id!(msg, thread_id) + } + AriesMessage::CoordinateMediation(CoordinateMediation::MediateGrant(msg)) => { + matches_opt_thread_id!(msg, thread_id) + } + AriesMessage::CoordinateMediation(CoordinateMediation::KeylistUpdate(msg)) => { + msg.id == thread_id + } + AriesMessage::CoordinateMediation(CoordinateMediation::KeylistUpdateResponse(msg)) => { + matches_opt_thread_id!(msg, thread_id) + } + AriesMessage::CoordinateMediation(CoordinateMediation::KeylistQuery(msg)) => { + msg.id == thread_id + } + AriesMessage::CoordinateMediation(CoordinateMediation::Keylist(msg)) => { + matches_opt_thread_id!(msg, thread_id) + } }; if !is_match { diff --git a/messages/src/lib.rs b/messages/src/lib.rs index 90c49c51c0..dd3cbbb61b 100644 --- a/messages/src/lib.rs +++ b/messages/src/lib.rs @@ -29,8 +29,8 @@ use crate::{ msg_fields::{ protocols::{ basic_message::BasicMessage, connection::Connection, - discover_features::DiscoverFeatures, notification::Notification, - out_of_band::OutOfBand, present_proof::v1::PresentProofV1, + coordinate_mediation::CoordinateMediation, discover_features::DiscoverFeatures, + notification::Notification, out_of_band::OutOfBand, present_proof::v1::PresentProofV1, report_problem::ProblemReport, revocation::Revocation, routing::Forward, trust_ping::TrustPing, }, @@ -68,6 +68,7 @@ pub enum AriesMessage { OutOfBand(OutOfBand), Notification(Notification), Pickup(Pickup), + CoordinateMediation(CoordinateMediation), } impl DelayedSerde for AriesMessage { @@ -180,6 +181,10 @@ impl DelayedSerde for AriesMessage { Protocol::PickupType(msg_type) => { Pickup::delayed_deserialize((msg_type, kind_str), deserializer).map(From::from) } + Protocol::CoordinateMediationType(msg_type) => { + CoordinateMediation::delayed_deserialize((msg_type, kind_str), deserializer) + .map(From::from) + } } } @@ -202,6 +207,7 @@ impl DelayedSerde for AriesMessage { Self::OutOfBand(v) => v.delayed_serialize(serializer), Self::Notification(v) => v.delayed_serialize(serializer), Self::Pickup(v) => v.delayed_serialize(serializer), + Self::CoordinateMediation(v) => v.delayed_serialize(serializer), } } } diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/keylist.rs b/messages/src/msg_fields/protocols/coordinate_mediation/keylist.rs new file mode 100644 index 0000000000..b3974327ff --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/keylist.rs @@ -0,0 +1,86 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#key-list +pub type Keylist = MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistContent { + pub keys: Vec, + #[builder(default, setter(strip_option))] + #[serde(skip_serializing_if = "Option::is_none")] + pagination: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistItem { + pub recipient_key: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistPagination { + count: u64, + offset: u64, + remaining: u64, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_keylist() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/keylist", + "keys": [ + { + "recipient_key": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH" + } + ], + "pagination": { + "count": 30, + "offset": 30, + "remaining": 100 + } + } + ); + let key_item = KeylistItem::builder() + .recipient_key("did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH".to_owned()) + .build(); + let pagination_state = KeylistPagination::builder() + .count(30) + .offset(30) + .remaining(100) + .build(); + let content = KeylistContent::builder() + .pagination(pagination_state) + .keys(vec![key_item]) + .build(); + let decorators = KeylistDecorators::builder().build(); + + test_utils::test_msg( + content, + decorators, + CoordinateMediationTypeV1_0::Keylist, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/keylist_query.rs b/messages/src/msg_fields/protocols/coordinate_mediation/keylist_query.rs new file mode 100644 index 0000000000..04c06f6ffd --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/keylist_query.rs @@ -0,0 +1,72 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#key-list-query +pub type KeylistQuery = MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistQueryContent { + #[builder(default, setter(strip_option))] + #[serde(skip_serializing_if = "Option::is_none")] + paginate: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistQueryPaginateParams { + #[builder(default, setter(strip_option))] + #[serde(skip_serializing_if = "Option::is_none")] + limit: Option, + #[builder(default, setter(strip_option))] + #[serde(skip_serializing_if = "Option::is_none")] + offset: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistQueryDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_keylist_query() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/keylist-query", + "paginate": { + "limit": 30, + "offset": 0 + } + } + ); + let paginate_params = KeylistQueryPaginateParams::builder() + .limit(30) + .offset(0) + .build(); + let content = KeylistQueryContent::builder() + .paginate(paginate_params) + .build(); + + test_utils::test_msg( + content, + NoDecorators, + CoordinateMediationTypeV1_0::KeylistQuery, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/keylist_update.rs b/messages/src/msg_fields/protocols/coordinate_mediation/keylist_update.rs new file mode 100644 index 0000000000..25f29dc557 --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/keylist_update.rs @@ -0,0 +1,75 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#keylist-update +pub type KeylistUpdate = MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistUpdateContent { + pub updates: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] +pub struct KeylistUpdateItem { + pub recipient_key: String, + pub action: KeylistUpdateItemAction, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub enum KeylistUpdateItemAction { + #[serde(rename = "add")] + Add, + #[serde(rename = "remove")] + Remove, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistUpdateDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_key_list_update() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/keylist-update", + "updates":[ + { + "recipient_key": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH", + "action": "add" + } + ] + } + ); + let update_item1 = KeylistUpdateItem::builder() + .recipient_key("did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH".to_owned()) + .action(KeylistUpdateItemAction::Add) + .build(); + let content = KeylistUpdateContent::builder() + .updates(vec![update_item1]) + .build(); + test_utils::test_msg( + content, + NoDecorators, + CoordinateMediationTypeV1_0::KeylistUpdate, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/keylist_update_response.rs b/messages/src/msg_fields/protocols/coordinate_mediation/keylist_update_response.rs new file mode 100644 index 0000000000..7047adbfea --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/keylist_update_response.rs @@ -0,0 +1,85 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use super::keylist_update::KeylistUpdateItemAction; +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#keylist-update-response +pub type KeylistUpdateResponse = + MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistUpdateResponseContent { + pub updated: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, TypedBuilder)] +pub struct KeylistUpdateResponseItem { + pub recipient_key: String, + pub action: KeylistUpdateItemAction, + pub result: KeylistUpdateItemResult, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub enum KeylistUpdateItemResult { + #[serde(rename = "client_error")] + ClientError, + #[serde(rename = "server_error")] + ServerError, + #[serde(rename = "no_change")] + NoChange, + #[serde(rename = "success")] + Success, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct KeylistUpdateResponseDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_keylist_update_response() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/keylist-update-response", + "updated": [ + { + "recipient_key": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH", + "action": "add", // "add" or "remove" + "result": "client_error" // [client_error | server_error | no_change | success] + } + ] + } + ); + let update_item1 = KeylistUpdateResponseItem::builder() + .recipient_key("did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH".to_owned()) + .action(KeylistUpdateItemAction::Add) + .result(KeylistUpdateItemResult::ClientError) + .build(); + let content = KeylistUpdateResponseContent::builder() + .updated(vec![update_item1]) + .build(); + let decorators = KeylistUpdateResponseDecorators::builder().build(); + + test_utils::test_msg( + content, + decorators, + CoordinateMediationTypeV1_0::KeylistUpdateResponse, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/mediate_deny.rs b/messages/src/msg_fields/protocols/coordinate_mediation/mediate_deny.rs new file mode 100644 index 0000000000..24e7fdd3aa --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/mediate_deny.rs @@ -0,0 +1,48 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#mediation-deny +pub type MediateDeny = MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct MediateDenyContent {} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct MediateDenyDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_mediate_deny() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/mediate-deny", + } + ); + let content = MediateDenyContent::builder().build(); + let decorators = MediateDenyDecorators::builder().build(); + + test_utils::test_msg( + content, + decorators, + CoordinateMediationTypeV1_0::MediateDeny, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/mediate_grant.rs b/messages/src/msg_fields/protocols/coordinate_mediation/mediate_grant.rs new file mode 100644 index 0000000000..2c2b68a17b --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/mediate_grant.rs @@ -0,0 +1,58 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#mediation-grant +pub type MediateGrant = MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct MediateGrantContent { + pub endpoint: String, + pub routing_keys: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct MediateGrantDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_mediate_grant() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/mediate-grant", + "endpoint": "http://mediators-r-us.com", + "routing_keys": ["did:key:z6Mkfriq1MqLBoPWecGoDLjguo1sB9brj6wT3qZ5BxkKpuP6"] + } + ); + let content = MediateGrantContent::builder() + .endpoint("http://mediators-r-us.com".to_owned()) + .routing_keys(vec![ + "did:key:z6Mkfriq1MqLBoPWecGoDLjguo1sB9brj6wT3qZ5BxkKpuP6".to_owned(), + ]) + .build(); + let decorators = MediateGrantDecorators::builder().build(); + + test_utils::test_msg( + content, + decorators, + CoordinateMediationTypeV1_0::MediateGrant, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/mediate_request.rs b/messages/src/msg_fields/protocols/coordinate_mediation/mediate_request.rs new file mode 100644 index 0000000000..ac92f053c9 --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/mediate_request.rs @@ -0,0 +1,47 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +use crate::{decorators::thread::Thread, msg_parts::MsgParts}; + +/// https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md#mediation-request +pub type MediateRequest = MsgParts; + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct MediateRequestContent {} + +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)] +pub struct MediateRequestDecorators { + #[builder(default, setter(strip_option))] + #[serde(rename = "~thread")] + #[serde(skip_serializing_if = "Option::is_none")] + pub thread: Option, +} + +#[cfg(test)] +#[allow(clippy::field_reassign_with_default)] +mod tests { + use serde_json::json; + use shared_vcx::misc::serde_ignored::SerdeIgnored as NoDecorators; + + use super::*; + use crate::{ + misc::test_utils, msg_types::protocols::coordinate_mediation::CoordinateMediationTypeV1_0, + }; + + #[test] + fn test_mediate_request() { + let expected = json!( + { + "@id": "123456781", + "@type": "https://didcomm.org/coordinate-mediation/1.0/mediate-request", + } + ); + let content = MediateRequestContent::builder().build(); + test_utils::test_msg( + content, + NoDecorators, + CoordinateMediationTypeV1_0::MediateRequest, + expected, + ); + } +} diff --git a/messages/src/msg_fields/protocols/coordinate_mediation/mod.rs b/messages/src/msg_fields/protocols/coordinate_mediation/mod.rs new file mode 100644 index 0000000000..1ac01de2db --- /dev/null +++ b/messages/src/msg_fields/protocols/coordinate_mediation/mod.rs @@ -0,0 +1,121 @@ +pub mod keylist; +pub mod keylist_query; +pub mod keylist_update; +pub mod keylist_update_response; +mod mediate_deny; +mod mediate_grant; +mod mediate_request; +use derive_more::From; +use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; + +pub use self::{ + keylist::{Keylist, KeylistContent, KeylistDecorators}, + keylist_query::{KeylistQuery, KeylistQueryContent, KeylistQueryDecorators}, + keylist_update::{KeylistUpdate, KeylistUpdateContent, KeylistUpdateDecorators}, + keylist_update_response::{ + KeylistUpdateResponse, KeylistUpdateResponseContent, KeylistUpdateResponseDecorators, + }, + mediate_deny::{MediateDeny, MediateDenyContent, MediateDenyDecorators}, + mediate_grant::{MediateGrant, MediateGrantContent, MediateGrantDecorators}, + mediate_request::{MediateRequest, MediateRequestContent, MediateRequestDecorators}, +}; +use crate::{ + misc::utils::{into_msg_with_type, transit_to_aries_msg}, + msg_fields::traits::DelayedSerde, + msg_types::{ + protocols::coordinate_mediation::{ + CoordinateMediationType, CoordinateMediationTypeV1, CoordinateMediationTypeV1_0, + }, + MsgWithType, + }, +}; + +#[derive(Clone, Debug, From, PartialEq)] +pub enum CoordinateMediation { + MediateRequest(MediateRequest), + MediateDeny(MediateDeny), + MediateGrant(MediateGrant), + KeylistUpdate(KeylistUpdate), + KeylistUpdateResponse(KeylistUpdateResponse), + KeylistQuery(KeylistQuery), + Keylist(Keylist), +} + +impl DelayedSerde for CoordinateMediation { + type MsgType<'a> = (CoordinateMediationType, &'a str); + + fn delayed_deserialize<'de, D>( + msg_type: Self::MsgType<'de>, + deserializer: D, + ) -> Result + where + D: Deserializer<'de>, + { + let (protocol, kind_str) = msg_type; + + let kind = match protocol { + CoordinateMediationType::V1(CoordinateMediationTypeV1::V1_0(kind)) => { + kind.kind_from_str(kind_str) + } + }; + + match kind.map_err(D::Error::custom)? { + CoordinateMediationTypeV1_0::MediateRequest => { + MediateRequest::deserialize(deserializer).map(From::from) + } + CoordinateMediationTypeV1_0::MediateDeny => { + MediateDeny::deserialize(deserializer).map(From::from) + } + CoordinateMediationTypeV1_0::MediateGrant => { + MediateGrant::deserialize(deserializer).map(From::from) + } + CoordinateMediationTypeV1_0::KeylistUpdate => { + KeylistUpdate::deserialize(deserializer).map(From::from) + } + CoordinateMediationTypeV1_0::KeylistUpdateResponse => { + KeylistUpdateResponse::deserialize(deserializer).map(From::from) + } + CoordinateMediationTypeV1_0::KeylistQuery => { + KeylistQuery::deserialize(deserializer).map(From::from) + } + CoordinateMediationTypeV1_0::Keylist => { + Keylist::deserialize(deserializer).map(From::from) + } + } + } + + fn delayed_serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::MediateRequest(v) => MsgWithType::from(v).serialize(serializer), + Self::MediateDeny(v) => MsgWithType::from(v).serialize(serializer), + Self::MediateGrant(v) => MsgWithType::from(v).serialize(serializer), + Self::KeylistUpdate(v) => MsgWithType::from(v).serialize(serializer), + Self::KeylistUpdateResponse(v) => MsgWithType::from(v).serialize(serializer), + Self::KeylistQuery(v) => MsgWithType::from(v).serialize(serializer), + Self::Keylist(v) => MsgWithType::from(v).serialize(serializer), + } + } +} + +transit_to_aries_msg!(MediateRequestContent, CoordinateMediation); +transit_to_aries_msg!(MediateDenyContent: MediateDenyDecorators, CoordinateMediation); +transit_to_aries_msg!(MediateGrantContent: MediateGrantDecorators, CoordinateMediation); +transit_to_aries_msg!(KeylistUpdateContent, CoordinateMediation); +transit_to_aries_msg!(KeylistUpdateResponseContent: KeylistUpdateResponseDecorators, CoordinateMediation); +transit_to_aries_msg!(KeylistQueryContent, CoordinateMediation); +transit_to_aries_msg!(KeylistContent: KeylistDecorators, CoordinateMediation); + +into_msg_with_type!(MediateRequest, CoordinateMediationTypeV1_0, MediateRequest); +into_msg_with_type!(MediateDeny, CoordinateMediationTypeV1_0, MediateDeny); +into_msg_with_type!(MediateGrant, CoordinateMediationTypeV1_0, MediateGrant); +into_msg_with_type!(KeylistUpdate, CoordinateMediationTypeV1_0, KeylistUpdate); +into_msg_with_type!( + KeylistUpdateResponse, + CoordinateMediationTypeV1_0, + KeylistUpdateResponse +); +into_msg_with_type!(KeylistQuery, CoordinateMediationTypeV1_0, KeylistQuery); +into_msg_with_type!(Keylist, CoordinateMediationTypeV1_0, Keylist); diff --git a/messages/src/msg_fields/protocols/mod.rs b/messages/src/msg_fields/protocols/mod.rs index ae5b4a78ad..2c00443e20 100644 --- a/messages/src/msg_fields/protocols/mod.rs +++ b/messages/src/msg_fields/protocols/mod.rs @@ -1,6 +1,7 @@ pub mod basic_message; pub mod common; pub mod connection; +pub mod coordinate_mediation; pub mod cred_issuance; pub mod discover_features; pub mod notification; diff --git a/messages/src/msg_types/protocols/coordinate_mediation.rs b/messages/src/msg_types/protocols/coordinate_mediation.rs new file mode 100644 index 0000000000..b6afa8a266 --- /dev/null +++ b/messages/src/msg_types/protocols/coordinate_mediation.rs @@ -0,0 +1,33 @@ +use derive_more::{From, TryInto}; +use messages_macros::MessageType; +use strum_macros::{AsRefStr, EnumString}; +use transitive::Transitive; + +use super::Protocol; +use crate::msg_types::{MsgKindType, Role}; + +#[derive(Copy, Clone, Debug, From, TryInto, PartialEq, MessageType)] +#[msg_type(protocol = "coordinate-mediation")] +pub enum CoordinateMediationType { + V1(CoordinateMediationTypeV1), +} + +#[derive(Copy, Clone, Debug, From, TryInto, PartialEq, Transitive, MessageType)] +#[transitive(into(CoordinateMediationType, Protocol))] +#[msg_type(major = 1)] +pub enum CoordinateMediationTypeV1 { + #[msg_type(minor = 0, roles = "Role::Mediator, Role::Recipient")] + V1_0(MsgKindType), +} + +#[derive(Copy, Clone, Debug, AsRefStr, EnumString, PartialEq)] +#[strum(serialize_all = "kebab-case")] +pub enum CoordinateMediationTypeV1_0 { + MediateRequest, + MediateDeny, + MediateGrant, + KeylistUpdate, + KeylistUpdateResponse, + KeylistQuery, + Keylist, +} diff --git a/messages/src/msg_types/protocols/mod.rs b/messages/src/msg_types/protocols/mod.rs index 6064d636f7..412045f1b1 100644 --- a/messages/src/msg_types/protocols/mod.rs +++ b/messages/src/msg_types/protocols/mod.rs @@ -6,10 +6,11 @@ use shared_vcx::misc::utils::CowStr; use self::{ basic_message::BasicMessageType, connection::ConnectionType, - cred_issuance::CredentialIssuanceType, discover_features::DiscoverFeaturesType, - notification::NotificationType, out_of_band::OutOfBandType, pickup::PickupType, - present_proof::PresentProofType, report_problem::ReportProblemType, revocation::RevocationType, - routing::RoutingType, signature::SignatureType, trust_ping::TrustPingType, + coordinate_mediation::CoordinateMediationType, cred_issuance::CredentialIssuanceType, + discover_features::DiscoverFeaturesType, notification::NotificationType, + out_of_band::OutOfBandType, pickup::PickupType, present_proof::PresentProofType, + report_problem::ReportProblemType, revocation::RevocationType, routing::RoutingType, + signature::SignatureType, trust_ping::TrustPingType, }; use crate::{ error::{MsgTypeError, MsgTypeResult}, @@ -18,6 +19,7 @@ use crate::{ pub mod basic_message; pub mod connection; +pub mod coordinate_mediation; pub mod cred_issuance; pub mod discover_features; pub mod notification; @@ -60,6 +62,7 @@ pub enum Protocol { OutOfBandType(OutOfBandType), NotificationType(NotificationType), PickupType(PickupType), + CoordinateMediationType(CoordinateMediationType), } /// Utility macro to avoid harder to read and error prone calling @@ -96,6 +99,7 @@ impl Protocol { match_protocol!(OutOfBandType, protocol, major, minor); match_protocol!(NotificationType, protocol, major, minor); match_protocol!(PickupType, protocol, major, minor); + match_protocol!(CoordinateMediationType, protocol, major, minor); Err(MsgTypeError::unknown_protocol(protocol.to_owned())) } @@ -116,6 +120,7 @@ impl Protocol { Self::OutOfBandType(v) => v.as_protocol_parts(), Self::NotificationType(v) => v.as_protocol_parts(), Self::PickupType(v) => v.as_protocol_parts(), + Self::CoordinateMediationType(v) => v.as_protocol_parts(), } } diff --git a/messages/src/msg_types/protocols/pickup.rs b/messages/src/msg_types/protocols/pickup.rs index 90eb93fe89..381f5307e5 100644 --- a/messages/src/msg_types/protocols/pickup.rs +++ b/messages/src/msg_types/protocols/pickup.rs @@ -16,7 +16,7 @@ pub enum PickupType { #[transitive(into(PickupType, Protocol))] #[msg_type(major = 2)] pub enum PickupTypeV2 { - #[msg_type(minor = 0, roles = "Role::Mediator")] + #[msg_type(minor = 0, roles = "Role::Mediator, Role::Recipient")] V2_0(MsgKindType), } diff --git a/messages/src/msg_types/registry.rs b/messages/src/msg_types/registry.rs index addd216948..c3326e66bd 100644 --- a/messages/src/msg_types/registry.rs +++ b/messages/src/msg_types/registry.rs @@ -9,6 +9,7 @@ use crate::msg_types::{ protocols::{ basic_message::BasicMessageTypeV1, connection::ConnectionTypeV1, + coordinate_mediation::CoordinateMediationTypeV1, cred_issuance::{CredentialIssuanceTypeV1, CredentialIssuanceTypeV2}, discover_features::DiscoverFeaturesTypeV1, notification::NotificationTypeV1, @@ -93,6 +94,8 @@ lazy_static! { map_insert(&mut m, extract_parts!(RevocationTypeV2::new_v2_0())); map_insert(&mut m, extract_parts!(TrustPingTypeV1::new_v1_0())); map_insert(&mut m, extract_parts!(PickupTypeV2::new_v2_0())); + map_insert(&mut m, extract_parts!(CoordinateMediationTypeV1::new_v1_0())); + m }; diff --git a/messages/src/msg_types/role.rs b/messages/src/msg_types/role.rs index 878f3624e5..2e570e63af 100644 --- a/messages/src/msg_types/role.rs +++ b/messages/src/msg_types/role.rs @@ -18,4 +18,5 @@ pub enum Role { Notified, Notifier, Mediator, + Recipient, }