Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mediator coordination messages to aries-vcx messages crate #1052

Merged
merged 8 commits into from
Nov 13, 2023
22 changes: 22 additions & 0 deletions aries_vcx/src/handlers/util.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 8 additions & 2 deletions messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -68,6 +68,7 @@ pub enum AriesMessage {
OutOfBand(OutOfBand),
Notification(Notification),
Pickup(Pickup),
CoordinateMediation(CoordinateMediation),
}

impl DelayedSerde for AriesMessage {
Expand Down Expand Up @@ -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)
}
}
}

Expand All @@ -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),
}
}
}
Expand Down
86 changes: 86 additions & 0 deletions messages/src/msg_fields/protocols/coordinate_mediation/keylist.rs
Original file line number Diff line number Diff line change
@@ -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<KeylistContent, KeylistDecorators>;

#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)]
pub struct KeylistContent {
pub keys: Vec<KeylistItem>,
#[builder(default, setter(strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pagination: Option<KeylistPagination>,
}

#[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<Thread>,
}

#[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,
);
}
}
Original file line number Diff line number Diff line change
@@ -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<KeylistQueryContent>;

#[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<KeylistQueryPaginateParams>,
}

#[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<u64>,
#[builder(default, setter(strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
offset: Option<u64>,
}

#[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<Thread>,
}

#[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,
);
}
}
Original file line number Diff line number Diff line change
@@ -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<KeylistUpdateContent>;

#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)]
pub struct KeylistUpdateContent {
pub updates: Vec<KeylistUpdateItem>,
}

#[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<Thread>,
}

#[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,
);
}
}
Original file line number Diff line number Diff line change
@@ -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<KeylistUpdateResponseContent, KeylistUpdateResponseDecorators>;

#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, TypedBuilder)]
pub struct KeylistUpdateResponseContent {
pub updated: Vec<KeylistUpdateResponseItem>,
}

#[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<Thread>,
}

#[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,
);
}
}
Loading
Loading