Skip to content

Commit 7c7316e

Browse files
authored
Merge branch 'main' into feat/ref-list-stream
2 parents 439ed87 + 90a6e83 commit 7c7316e

File tree

11 files changed

+548
-640
lines changed

11 files changed

+548
-640
lines changed

extensions/warp-ipfs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ image = { workspace = true }
3838
derive_more.workspace = true
3939
mediatype.workspace = true
4040

41-
async-rt = "0.1.2"
41+
async-rt = "0.1.3"
4242

4343
bincode.workspace = true
4444
bytes.workspace = true

extensions/warp-ipfs/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,13 +1780,9 @@ impl RayGunCommunity for WarpIpfs {
17801780
.get_community_invite(community_id, invite_id)
17811781
.await
17821782
}
1783-
async fn accept_community_invite(
1784-
&mut self,
1785-
community_id: Uuid,
1786-
invite_id: Uuid,
1787-
) -> Result<(), Error> {
1783+
async fn request_join_community(&mut self, community_id: Uuid) -> Result<(), Error> {
17881784
self.messaging_store()?
1789-
.accept_community_invite(community_id, invite_id)
1785+
.request_join_community(community_id)
17901786
.await
17911787
}
17921788
async fn edit_community_invite(

extensions/warp-ipfs/src/store/community.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ impl CommunityDocument {
139139
self.id.exchange_topic(did)
140140
}
141141

142+
pub fn join_topic(&self) -> String {
143+
self.id.join_topic()
144+
}
145+
142146
pub fn sign(&mut self, keypair: &Keypair) -> Result<(), Error> {
143147
let construct = warp::crypto::hash::sha256_iter(
144148
[
@@ -275,12 +279,9 @@ impl From<CommunityDocument> for Community {
275279
}
276280
impl CommunityDocument {
277281
pub fn participants(&self) -> IndexSet<DID> {
278-
self.invites
279-
.iter()
280-
.filter_map(|(_, invite)| invite.target_user.clone())
281-
.chain(self.members.clone())
282-
.chain(std::iter::once(self.owner.clone()))
283-
.collect::<IndexSet<_>>()
282+
let mut participants = self.members.clone();
283+
participants.insert(self.owner.clone());
284+
participants
284285
}
285286
pub fn has_valid_invite(&self, user: &DID) -> bool {
286287
for (_, invite) in &self.invites {

extensions/warp-ipfs/src/store/message.rs

Lines changed: 147 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ use rust_ipfs::{Ipfs, PeerId};
3232
use serde::{Deserialize, Serialize};
3333
use uuid::Uuid;
3434

35+
use super::community::CommunityInviteDocument;
36+
use super::topics::ConversationTopic;
3537
use super::{document::root::RootDocumentMap, ds_key::DataStoreKey, PeerIdExt};
38+
use crate::store::CommunityJoinEvents;
3639
use crate::store::{
3740
conversation::ConversationDocument,
3841
discovery::Discovery,
@@ -92,6 +95,7 @@ impl MessageStore {
9295
ipfs: ipfs.clone(),
9396
conversation_task: HashMap::new(),
9497
community_task: HashMap::new(),
98+
community_invites: vec![],
9599
identity: identity.clone(),
96100
root,
97101
discovery,
@@ -903,8 +907,12 @@ impl MessageStore {
903907
inner.list_communities_joined().await
904908
}
905909
pub async fn list_communities_invited_to(&self) -> Result<Vec<(Uuid, CommunityInvite)>, Error> {
906-
let inner = &mut *self.inner.write().await;
907-
inner.list_communities_invited_to().await
910+
let inner = &*self.inner.read().await;
911+
Ok(inner
912+
.community_invites
913+
.iter()
914+
.map(|(community_id, i)| (*community_id, CommunityInvite::from(i.clone())))
915+
.collect())
908916
}
909917
pub async fn leave_community(&mut self, community_id: Uuid) -> Result<(), Error> {
910918
let inner = &*self.inner.read().await;
@@ -1024,20 +1032,38 @@ impl MessageStore {
10241032
invite_id: Uuid,
10251033
) -> Result<(), Error> {
10261034
let inner = &*self.inner.read().await;
1027-
let community_meta = inner
1028-
.community_task
1029-
.get(&community_id)
1030-
.ok_or(Error::InvalidCommunity)?;
1031-
let (tx, rx) = oneshot::channel();
1032-
let _ = community_meta
1033-
.command_tx
1034-
.clone()
1035-
.send(CommunityTaskCommand::DeleteCommunityInvite {
1036-
invite_id,
1037-
response: tx,
1038-
})
1039-
.await;
1040-
rx.await.map_err(anyhow::Error::from)?
1035+
match inner.community_task.get(&community_id) {
1036+
None => {
1037+
let keypair = inner.root.keypair();
1038+
1039+
let event = CommunityJoinEvents::DeleteInvite { invite_id };
1040+
let payload = PayloadBuilder::new(keypair, event)
1041+
.from_ipfs(&inner.ipfs)
1042+
.await?;
1043+
let bytes = payload.to_bytes()?;
1044+
1045+
if let Err(e) = inner
1046+
.ipfs
1047+
.pubsub_publish(community_id.join_topic(), bytes)
1048+
.await
1049+
{
1050+
tracing::error!(id=%community_id, "Unable to send event: {e}");
1051+
}
1052+
}
1053+
Some(community_meta) => {
1054+
let (tx, rx) = oneshot::channel();
1055+
let _ = community_meta
1056+
.command_tx
1057+
.clone()
1058+
.send(CommunityTaskCommand::DeleteCommunityInvite {
1059+
invite_id,
1060+
response: tx,
1061+
})
1062+
.await;
1063+
return rx.await.map_err(anyhow::Error::from)?;
1064+
}
1065+
}
1066+
Ok(())
10411067
}
10421068
pub async fn get_community_invite(
10431069
&mut self,
@@ -1060,26 +1086,24 @@ impl MessageStore {
10601086
.await;
10611087
rx.await.map_err(anyhow::Error::from)?
10621088
}
1063-
pub async fn accept_community_invite(
1064-
&mut self,
1065-
community_id: Uuid,
1066-
invite_id: Uuid,
1067-
) -> Result<(), Error> {
1089+
pub async fn request_join_community(&mut self, community_id: Uuid) -> Result<(), Error> {
10681090
let inner = &*self.inner.read().await;
1069-
let community_meta = inner
1070-
.community_task
1071-
.get(&community_id)
1072-
.ok_or(Error::InvalidCommunity)?;
1073-
let (tx, rx) = oneshot::channel();
1074-
let _ = community_meta
1075-
.command_tx
1076-
.clone()
1077-
.send(CommunityTaskCommand::AcceptCommunityInvite {
1078-
invite_id,
1079-
response: tx,
1080-
})
1081-
.await;
1082-
rx.await.map_err(anyhow::Error::from)?
1091+
let keypair = inner.root.keypair();
1092+
1093+
let event = CommunityJoinEvents::Join;
1094+
let payload = PayloadBuilder::new(keypair, event)
1095+
.from_ipfs(&inner.ipfs)
1096+
.await?;
1097+
let bytes = payload.to_bytes()?;
1098+
1099+
if let Err(e) = inner
1100+
.ipfs
1101+
.pubsub_publish(community_id.join_topic(), bytes)
1102+
.await
1103+
{
1104+
tracing::error!(id=%community_id, "Unable to send event: {e}");
1105+
}
1106+
Ok(())
10831107
}
10841108
pub async fn edit_community_invite(
10851109
&mut self,
@@ -2105,6 +2129,7 @@ struct ConversationInner {
21052129
ipfs: Ipfs,
21062130
conversation_task: HashMap<Uuid, ConversationInnerMeta>,
21072131
community_task: HashMap<Uuid, CommunityInnerMeta>,
2132+
community_invites: Vec<(Uuid, CommunityInviteDocument)>,
21082133
root: RootDocumentMap,
21092134
file: FileStore,
21102135
event: EventSubscription<RayGunEventKind>,
@@ -3016,8 +3041,7 @@ impl ConversationInner {
30163041
pub async fn get_community(&mut self, community_id: Uuid) -> Result<Community, Error> {
30173042
let doc = self.get_community_document(community_id).await?;
30183043
let own_did = &self.identity.did_key();
3019-
if own_did != &doc.owner && !doc.has_valid_invite(own_did) && !doc.members.contains(own_did)
3020-
{
3044+
if !doc.participants().contains(own_did) {
30213045
return Err(Error::Unauthorized);
30223046
}
30233047
Ok(doc.into())
@@ -3038,24 +3062,6 @@ impl ConversationInner {
30383062
})
30393063
.collect())
30403064
}
3041-
pub async fn list_communities_invited_to(&self) -> Result<Vec<(Uuid, CommunityInvite)>, Error> {
3042-
let own_did = &self.identity.did_key();
3043-
Ok(self
3044-
.list_community()
3045-
.await
3046-
.iter()
3047-
.filter_map(|c| {
3048-
for (_, invite) in &c.invites {
3049-
if let Some(target) = &invite.target_user {
3050-
if target == own_did {
3051-
return Some((c.id, CommunityInvite::from(invite.clone())));
3052-
}
3053-
}
3054-
}
3055-
None
3056-
})
3057-
.collect())
3058-
}
30593065
}
30603066

30613067
async fn process_conversation(
@@ -3196,30 +3202,18 @@ async fn process_conversation(
31963202
ConversationEvents::NewCommunityInvite {
31973203
community_id,
31983204
invite,
3199-
community_document,
32003205
} => {
3201-
let did = this.identity.did_key();
3202-
3203-
if this.contains_community(community_id).await {
3204-
return Err(anyhow::anyhow!("Already apart of {community_id}").into());
3205-
}
3206-
3207-
let recipients = community_document.participants().clone();
3208-
3209-
for recipient in &recipients {
3210-
if !this.discovery.contains(recipient).await {
3211-
let _ = this.discovery.insert(recipient).await;
3206+
let mut updated = false;
3207+
for i in this.community_invites.len()..0 {
3208+
let (community, invitation) = this.community_invites[i].clone();
3209+
if community == community_id && invitation.id == invite.id {
3210+
this.community_invites[i] = (community_id, invite.clone());
3211+
updated = true;
3212+
break;
32123213
}
32133214
}
3214-
3215-
this.set_community_document(community_document).await?;
3216-
3217-
this.create_community_task(community_id).await?;
3218-
3219-
for recipient in recipients.iter().filter(|d| did.ne(d)) {
3220-
if let Err(e) = this.request_community_key(community_id, recipient).await {
3221-
tracing::warn!(%community_id, error = %e, %recipient, "Failed to send exchange request");
3222-
}
3215+
if !updated {
3216+
this.community_invites.push((community_id, invite.clone()));
32233217
}
32243218

32253219
this.event
@@ -3229,6 +3223,83 @@ async fn process_conversation(
32293223
})
32303224
.await;
32313225
}
3226+
ConversationEvents::DeleteCommunityInvite {
3227+
community_id,
3228+
invite,
3229+
} => {
3230+
for i in this.community_invites.len()..0 {
3231+
let (community, invitation) = this.community_invites[i].clone();
3232+
if community == community_id && invitation.id == invite.id {
3233+
this.community_invites.swap_remove(i);
3234+
this.event
3235+
.emit(RayGunEventKind::CommunityUninvited {
3236+
community_id,
3237+
invite_id: invite.id,
3238+
})
3239+
.await;
3240+
break;
3241+
}
3242+
}
3243+
}
3244+
ConversationEvents::JoinCommunity {
3245+
community_id,
3246+
community_document: result,
3247+
} => match result {
3248+
None => {
3249+
this.event
3250+
.emit(RayGunEventKind::CommunityJoinRejected { community_id })
3251+
.await;
3252+
return Ok(());
3253+
}
3254+
Some(community_document) => {
3255+
for i in this.community_invites.len()..0 {
3256+
let (community, _) = this.community_invites[i];
3257+
if community == community_id {
3258+
this.community_invites.swap_remove(i);
3259+
}
3260+
}
3261+
3262+
let did = this.identity.did_key();
3263+
3264+
if this.contains_community(community_id).await {
3265+
return Ok(());
3266+
}
3267+
3268+
let recipients = community_document.participants().clone();
3269+
3270+
for recipient in &recipients {
3271+
if !this.discovery.contains(recipient).await {
3272+
let _ = this.discovery.insert(recipient).await;
3273+
}
3274+
}
3275+
3276+
this.set_community_document(community_document).await?;
3277+
3278+
this.create_community_task(community_id).await?;
3279+
3280+
for recipient in recipients.iter().filter(|d| did.ne(d)) {
3281+
if let Err(e) = this.request_community_key(community_id, recipient).await {
3282+
tracing::warn!(%community_id, error = %e, %recipient, "Failed to send exchange request");
3283+
}
3284+
}
3285+
3286+
let community_meta = this
3287+
.community_task
3288+
.get(&community_id)
3289+
.ok_or(Error::InvalidCommunity)?;
3290+
let (tx, rx) = oneshot::channel();
3291+
let _ = community_meta
3292+
.command_tx
3293+
.clone()
3294+
.send(CommunityTaskCommand::SendJoinedCommunityEvent { response: tx })
3295+
.await;
3296+
let _ = rx.await.map_err(anyhow::Error::from)?;
3297+
3298+
this.event
3299+
.emit(RayGunEventKind::CommunityJoined { community_id })
3300+
.await;
3301+
}
3302+
},
32323303
ConversationEvents::DeleteCommunity { community_id } => {
32333304
tracing::trace!("Delete community event received for {community_id}");
32343305
if !this.contains_community(community_id).await {

0 commit comments

Comments
 (0)