Skip to content

Commit

Permalink
move non-group ds requests into in/out params
Browse files Browse the repository at this point in the history
  • Loading branch information
boxdot committed Feb 20, 2025
1 parent fc9da57 commit c9c8d18
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 176 deletions.
85 changes: 49 additions & 36 deletions apiclient/src/ds_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use mls_assist::{
},
};
use phnxtypes::{
credentials::keys::PseudonymousCredentialSigningKey,
credentials::keys::{ClientSigningKey, PseudonymousCredentialSigningKey},
crypto::{
ear::keys::GroupStateEarKey,
signatures::{signable::Signable, traits::SigningKeyBehaviour},
Expand All @@ -28,7 +28,7 @@ use phnxtypes::{
},
client_ds_out::{
ClientToDsMessageOut, ClientToDsMessageTbsOut, CreateGroupParamsOut,
DeleteGroupParamsOut, DsMessageTypeOut, DsProcessResponseIn, DsRequestParamsOut,
DeleteGroupParamsOut, DsGroupRequestParamsOut, DsProcessResponseIn, DsRequestParamsOut,
DsVersionedProcessResponseIn, DsVersionedRequestParamsOut, ExternalCommitInfoIn,
GroupOperationParamsOut, JoinConnectionGroupParamsOut, ResyncParamsOut,
SelfRemoveParamsOut, SendMessageParamsOut, UpdateParamsOut,
Expand Down Expand Up @@ -77,19 +77,17 @@ impl<'a, T: SigningKeyBehaviour + 'a> From<&'a T> for AuthenticationMethod<'a, T
}

impl ApiClient {
async fn prepare_and_send_ds_group_message<'a, T: SigningKeyBehaviour + 'a>(
async fn prepare_and_send_ds_message<'a, T: SigningKeyBehaviour + 'a>(
&self,
request_params: DsRequestParamsOut,
auth_method: impl Into<AuthenticationMethod<'a, T>>,
group_state_ear_key: &GroupStateEarKey,
) -> Result<DsProcessResponseIn, DsRequestError> {
let api_version = self.negotiated_versions().ds_api_version();

let auth_method = auth_method.into();
let request_params =
DsVersionedRequestParamsOut::with_version(request_params, api_version)?;
let auth_method = auth_method.into();
let tbs = ClientToDsMessageTbsOut::new(group_state_ear_key.clone(), request_params);
let message = sign_ds_params(tbs, &auth_method)?;
let message = sign_ds_params(request_params, &auth_method)?;

let response = self.send_ds_http_request(&message).await?;

Expand All @@ -98,27 +96,38 @@ impl ApiClient {
return handle_ds_response(response).await;
};

let tbs = match message {
DsMessageTypeOut::Group(message) => message.into_payload(),
DsMessageTypeOut::NonGroup => {
// For non-group messages, the API is not versioned.
return handle_ds_response(response).await;
}
};

let supported_versions = SUPPORTED_DS_API_VERSIONS;
let accepted_version = negotiate_api_version(accepted_versions, supported_versions)
.ok_or_else(|| VersionError::new(api_version, supported_versions))?;
self.negotiated_versions()
.set_ds_api_version(accepted_version);

let (tbs, _) = tbs.change_version(accepted_version)?;
let message = sign_ds_params(tbs, &auth_method)?;
let (request_params, _) = message
.into_payload()
.into_body()
.change_version(accepted_version)?;
let message = sign_ds_params(request_params, &auth_method)?;

let response = self.send_ds_http_request(&message).await?;
handle_ds_response(response).await
}

async fn prepare_and_send_ds_group_message<'a, T: SigningKeyBehaviour + 'a>(
&self,
request_params: DsGroupRequestParamsOut,
auth_method: impl Into<AuthenticationMethod<'a, T>>,
group_state_ear_key: &GroupStateEarKey,
) -> Result<DsProcessResponseIn, DsRequestError> {
self.prepare_and_send_ds_message(
DsRequestParamsOut::Group {
group_state_ear_key: group_state_ear_key.clone(),
request_params,
},
auth_method,
)
.await
}

/// Creates a new group on the DS.
pub async fn ds_create_group(
&self,
Expand All @@ -127,7 +136,7 @@ impl ApiClient {
group_state_ear_key: &GroupStateEarKey,
) -> Result<(), DsRequestError> {
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::CreateGroupParams(payload),
DsGroupRequestParamsOut::CreateGroupParams(payload),
signing_key,
group_state_ear_key,
)
Expand All @@ -150,7 +159,7 @@ impl ApiClient {
group_state_ear_key: &GroupStateEarKey,
) -> Result<TimeStamp, DsRequestError> {
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::GroupOperation(payload),
DsGroupRequestParamsOut::GroupOperation(payload),
signing_key,
group_state_ear_key,
)
Expand Down Expand Up @@ -179,7 +188,7 @@ impl ApiClient {
epoch,
};
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::WelcomeInfo(payload),
DsGroupRequestParamsOut::WelcomeInfo(payload),
signing_key,
group_state_ear_key,
)
Expand All @@ -202,7 +211,7 @@ impl ApiClient {
) -> Result<ExternalCommitInfoIn, DsRequestError> {
let payload = ExternalCommitInfoParams { group_id };
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::ExternalCommitInfo(payload),
DsGroupRequestParamsOut::ExternalCommitInfo(payload),
AuthenticationMethod::<PseudonymousCredentialSigningKey>::None,
group_state_ear_key,
)
Expand All @@ -225,7 +234,7 @@ impl ApiClient {
) -> Result<ExternalCommitInfoIn, DsRequestError> {
let payload = ConnectionGroupInfoParams { group_id };
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::ConnectionGroupInfo(payload),
DsGroupRequestParamsOut::ConnectionGroupInfo(payload),
AuthenticationMethod::<PseudonymousCredentialSigningKey>::None,
group_state_ear_key,
)
Expand All @@ -249,7 +258,7 @@ impl ApiClient {
group_state_ear_key: &GroupStateEarKey,
) -> Result<TimeStamp, DsRequestError> {
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::Update(params),
DsGroupRequestParamsOut::Update(params),
signing_key,
group_state_ear_key,
)
Expand Down Expand Up @@ -279,7 +288,7 @@ impl ApiClient {
qs_client_reference,
};
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::JoinConnectionGroup(payload),
DsGroupRequestParamsOut::JoinConnectionGroup(payload),
AuthenticationMethod::<PseudonymousCredentialSigningKey>::None,
group_state_ear_key,
)
Expand Down Expand Up @@ -307,7 +316,7 @@ impl ApiClient {
sender_index: own_leaf_index,
};
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::Resync(payload),
DsGroupRequestParamsOut::Resync(payload),
signing_key,
group_state_ear_key,
)
Expand All @@ -330,7 +339,7 @@ impl ApiClient {
group_state_ear_key: &GroupStateEarKey,
) -> Result<TimeStamp, DsRequestError> {
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::SelfRemove(params),
DsGroupRequestParamsOut::SelfRemove(params),
signing_key,
group_state_ear_key,
)
Expand All @@ -353,7 +362,7 @@ impl ApiClient {
group_state_ear_key: &GroupStateEarKey,
) -> Result<TimeStamp, DsRequestError> {
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::SendMessage(params),
DsGroupRequestParamsOut::SendMessage(params),
signing_key,
group_state_ear_key,
)
Expand All @@ -376,7 +385,7 @@ impl ApiClient {
group_state_ear_key: &GroupStateEarKey,
) -> Result<TimeStamp, DsRequestError> {
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::DeleteGroup(params),
DsGroupRequestParamsOut::DeleteGroup(params),
signing_key,
group_state_ear_key,
)
Expand Down Expand Up @@ -406,7 +415,7 @@ impl ApiClient {
new_qs_reference: new_queue_config,
};
self.prepare_and_send_ds_group_message(
DsRequestParamsOut::UpdateQsClientReference(payload),
DsGroupRequestParamsOut::UpdateQsClientReference(payload),
signing_key,
group_state_ear_key,
)
Expand All @@ -423,9 +432,12 @@ impl ApiClient {

/// Delete the given group.
pub async fn ds_request_group_id(&self) -> Result<GroupId, DsRequestError> {
let message_type = DsMessageTypeOut::NonGroup;
let response = self.send_ds_http_request(&message_type).await?;
let ds_response = handle_ds_response(response).await?;
let ds_response = self
.prepare_and_send_ds_message::<ClientSigningKey>(
DsRequestParamsOut::NonGroup,
AuthenticationMethod::None,
)
.await?;
if let DsProcessResponseIn::GroupId(group_id) = ds_response {
Ok(group_id)
} else {
Expand All @@ -435,7 +447,7 @@ impl ApiClient {

async fn send_ds_http_request(
&self,
message: &DsMessageTypeOut,
message: &ClientToDsMessageOut,
) -> Result<reqwest::Response, DsRequestError> {
let message_bytes = message.tls_serialize_detached()?;
let endpoint = self.build_url(Protocol::Http, ENDPOINT_DS_GROUPS);
Expand Down Expand Up @@ -478,12 +490,13 @@ async fn handle_ds_response(res: reqwest::Response) -> Result<DsProcessResponseI
}

fn sign_ds_params<'a, T: SigningKeyBehaviour + 'a>(
tbs: ClientToDsMessageTbsOut,
request_params: DsVersionedRequestParamsOut,
auth_method: &AuthenticationMethod<'a, T>,
) -> Result<DsMessageTypeOut, DsRequestError> {
) -> Result<ClientToDsMessageOut, DsRequestError> {
let tbs = ClientToDsMessageTbsOut::new(request_params);
let message = match auth_method {
AuthenticationMethod::Signature(signer) => tbs.sign(*signer)?,
AuthenticationMethod::None => ClientToDsMessageOut::without_signature(tbs),
};
Ok(DsMessageTypeOut::Group(message))
Ok(message)
}
Loading

0 comments on commit c9c8d18

Please sign in to comment.