mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-08-26 23:51:14 +00:00
Add senderId to ConvoOutcome::Content
This commit is contained in:
@@ -13,6 +13,7 @@ use std::collections::VecDeque;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::conversation::ConversationIdRef;
|
||||
use crate::conversation::mls_utils::signer_for_sender;
|
||||
use crate::inbox_v2::MlsProvider;
|
||||
use crate::service_context::{ExternalServices, ServiceContext};
|
||||
|
||||
@@ -263,6 +264,9 @@ impl<S: ExternalServices> Convo<S> for GroupV1Convo {
|
||||
.process_message(&cx.mls_provider, protocol_message)
|
||||
.map_err(ChatError::generic)?;
|
||||
|
||||
// Sender Id is not validated, the AuthService/Client is responsible for validating that the credential
|
||||
// is valid for the sender
|
||||
let sender_id = signer_for_sender(&self.mls_group, &processed)?;
|
||||
let cred_bytes = processed.credential().serialized_content().to_vec();
|
||||
|
||||
let content = match processed.into_content() {
|
||||
@@ -271,6 +275,7 @@ impl<S: ExternalServices> Convo<S> for GroupV1Convo {
|
||||
cx.causal.on_receive(&self.convo_id, &reliable);
|
||||
Some(Content {
|
||||
bytes: reliable.content.to_vec(),
|
||||
sender_id,
|
||||
encoded_credential: cred_bytes,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -471,7 +471,8 @@ impl GroupV2Convo {
|
||||
payload: Some(app_message::Payload::ConversationMessage(cm)),
|
||||
}) => Some(Content {
|
||||
bytes: cm.message.clone(),
|
||||
encoded_credential: cm.sender.clone(),
|
||||
sender_id: cm.sender.as_slice().into(),
|
||||
encoded_credential: cm.sender_credential.clone(),
|
||||
}),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
use openmls::{
|
||||
framing::{ProcessedMessage, Sender},
|
||||
group::MlsGroup,
|
||||
};
|
||||
|
||||
use crate::{ChatError, SignerId};
|
||||
|
||||
pub fn signer_for_sender(
|
||||
mls_group: &MlsGroup,
|
||||
processed: &ProcessedMessage,
|
||||
) -> Result<SignerId, ChatError> {
|
||||
// The signature key openmls just verified this message under.
|
||||
let sender_sig_key: Vec<u8> = match processed.sender() {
|
||||
Sender::Member(leaf_index) => {
|
||||
mls_group
|
||||
.member_at(*leaf_index)
|
||||
.ok_or_else(|| ChatError::generic("sender leaf not in tree"))?
|
||||
.signature_key
|
||||
}
|
||||
// Application/private messages always come from a Member; anything else
|
||||
// here is a protocol violation.
|
||||
other => {
|
||||
return Err(ChatError::generic(format!("unexpected sender: {other:?}")));
|
||||
}
|
||||
};
|
||||
Ok(sender_sig_key.into())
|
||||
}
|
||||
@@ -28,10 +28,10 @@ pub use outcomes::{
|
||||
Content, ConversationClass, ConvoOutcome, InboxOutcome, NewConversation, PayloadOutcome,
|
||||
};
|
||||
pub use service_context::ExternalServices;
|
||||
pub use shared_traits::{IdentId, IdentIdRef, IdentityProvider};
|
||||
pub use service_traits::{
|
||||
AuthResult, AuthVerifyService, DeliveryService, RegistrationService, WakeupService,
|
||||
};
|
||||
pub use shared_traits::{IdentId, IdentIdRef, IdentityProvider, SignerId};
|
||||
pub use storage::{ChatStore, ConversationKind};
|
||||
pub use types::{AddressedEnvelope, ConvoMetadata};
|
||||
pub use utils::{hex_trunc, trunc};
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
use storage::ConversationKind;
|
||||
|
||||
use crate::SignerId;
|
||||
use crate::conversation::ConversationId;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Content {
|
||||
pub bytes: Vec<u8>,
|
||||
/// Hex-encoded [`DelegateCredential`] of the sender, if present in the message.
|
||||
/// Empty when the sender did not attach a credential.
|
||||
pub sender_id: SignerId,
|
||||
pub encoded_credential: Vec<u8>,
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,37 @@ impl AsRef<str> for IdentId {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SignerId(Vec<u8>);
|
||||
|
||||
impl SignerId {
|
||||
pub fn from_ed25519(key: &Ed25519VerifyingKey) -> Self {
|
||||
Self(key.as_ref().to_vec())
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for SignerId {
|
||||
fn from(value: Vec<u8>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[u8]> for SignerId {
|
||||
fn from(value: &[u8]) -> Self {
|
||||
Self(value.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for SignerId {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an external Identity
|
||||
/// Implement this to provide an Authentication model for users/installations
|
||||
pub trait IdentityProvider {
|
||||
|
||||
Reference in New Issue
Block a user