diff --git a/Cargo.toml b/Cargo.toml index 7f5937428..735645ca8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,6 +94,7 @@ tracing = { version = "0.1" } either = "1" void = "1" indexmap = { version = "2.4.0", features = ["serde"] } +enum_macro = { path = "./tools/enum_macro" } # ipfs dependency rust-ipfs = "0.14.0" diff --git a/extensions/warp-ipfs/src/lib.rs b/extensions/warp-ipfs/src/lib.rs index 294139d7c..7444896c0 100644 --- a/extensions/warp-ipfs/src/lib.rs +++ b/extensions/warp-ipfs/src/lib.rs @@ -24,9 +24,7 @@ use store::protocols; use tokio_util::compat::TokioAsyncReadCompatExt; use tracing::{Instrument, Span}; use uuid::Uuid; -use warp::raygun::community::{ - CommunityChannelPermission, CommunityPermission, CommunityRole, RoleId, -}; +use warp::raygun::community::{CommunityRole, RoleId}; use crate::config::{Bootstrap, DiscoveryType}; use crate::store::discovery::Discovery; @@ -1897,42 +1895,67 @@ impl RayGunCommunity for WarpIpfs { .edit_community_description(community_id, description) .await } - async fn grant_community_permission( + async fn grant_community_permission( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .grant_community_permission(community_id, permission, role_id) + .grant_community_permission(community_id, permission.to_string(), role_id) .await } - async fn revoke_community_permission( + async fn revoke_community_permission( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .revoke_community_permission(community_id, permission, role_id) + .revoke_community_permission(community_id, permission.to_string(), role_id) .await } - async fn grant_community_permission_for_all( + async fn grant_community_permission_for_all( &mut self, community_id: Uuid, - permission: CommunityPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .grant_community_permission_for_all(community_id, permission) + .grant_community_permission_for_all(community_id, permission.to_string()) .await } - async fn revoke_community_permission_for_all( + async fn revoke_community_permission_for_all( &mut self, community_id: Uuid, - permission: CommunityPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .revoke_community_permission_for_all(community_id, permission) + .revoke_community_permission_for_all(community_id, permission.to_string()) + .await + } + async fn has_community_permission( + &mut self, + community_id: Uuid, + permission: T, + member: DID, + ) -> Result + where + T: ToString + Send, + { + self.messaging_store()? + .has_community_permission(community_id, permission.to_string(), member) .await } async fn remove_community_member( @@ -1965,46 +1988,95 @@ impl RayGunCommunity for WarpIpfs { .edit_community_channel_description(community_id, channel_id, description) .await } - async fn grant_community_channel_permission( + async fn grant_community_channel_permission( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .grant_community_channel_permission(community_id, channel_id, permission, role_id) + .grant_community_channel_permission( + community_id, + channel_id, + permission.to_string(), + role_id, + ) .await } - async fn revoke_community_channel_permission( + async fn revoke_community_channel_permission( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .revoke_community_channel_permission(community_id, channel_id, permission, role_id) + .revoke_community_channel_permission( + community_id, + channel_id, + permission.to_string(), + role_id, + ) .await } - async fn grant_community_channel_permission_for_all( + async fn grant_community_channel_permission_for_all( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.messaging_store()? - .grant_community_channel_permission_for_all(community_id, channel_id, permission) + .grant_community_channel_permission_for_all( + community_id, + channel_id, + permission.to_string(), + ) .await } - async fn revoke_community_channel_permission_for_all( + async fn revoke_community_channel_permission_for_all( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { + self.messaging_store()? + .revoke_community_channel_permission_for_all( + community_id, + channel_id, + permission.to_string(), + ) + .await + } + async fn has_community_channel_permission( + &mut self, + community_id: Uuid, + channel_id: Uuid, + permission: T, + member: DID, + ) -> Result + where + T: ToString + Send, + { self.messaging_store()? - .revoke_community_channel_permission_for_all(community_id, channel_id, permission) + .has_community_channel_permission( + community_id, + channel_id, + permission.to_string(), + member, + ) .await } diff --git a/extensions/warp-ipfs/src/store/community.rs b/extensions/warp-ipfs/src/store/community.rs index b71acf270..eed09d649 100644 --- a/extensions/warp-ipfs/src/store/community.rs +++ b/extensions/warp-ipfs/src/store/community.rs @@ -22,9 +22,8 @@ use warp::{ error::Error, raygun::{ community::{ - Community, CommunityChannel, CommunityChannelPermission, CommunityChannelPermissions, - CommunityChannelType, CommunityInvite, CommunityPermission, CommunityPermissions, - CommunityRole, RoleId, + Community, CommunityChannel, CommunityChannelPermissions, CommunityChannelType, + CommunityInvite, CommunityPermission, CommunityPermissions, CommunityRole, RoleId, }, Message, MessageOptions, MessagePage, MessageReference, Messages, MessagesType, }, @@ -190,33 +189,9 @@ impl CommunityDocument { let creator = keypair.to_did()?; let mut permissions = CommunityPermissions::new(); - permissions.insert(CommunityPermission::EditName, IndexSet::new()); - permissions.insert(CommunityPermission::EditDescription, IndexSet::new()); - permissions.insert(CommunityPermission::EditIcon, IndexSet::new()); - permissions.insert(CommunityPermission::EditBanner, IndexSet::new()); - - permissions.insert(CommunityPermission::CreateRoles, IndexSet::new()); - permissions.insert(CommunityPermission::EditRoles, IndexSet::new()); - permissions.insert(CommunityPermission::DeleteRoles, IndexSet::new()); - - permissions.insert(CommunityPermission::GrantRoles, IndexSet::new()); - permissions.insert(CommunityPermission::RevokeRoles, IndexSet::new()); - - permissions.insert(CommunityPermission::GrantPermissions, IndexSet::new()); - permissions.insert(CommunityPermission::RevokePermissions, IndexSet::new()); - - permissions.insert(CommunityPermission::CreateChannels, IndexSet::new()); - permissions.insert(CommunityPermission::EditChannels, IndexSet::new()); - permissions.insert(CommunityPermission::DeleteChannels, IndexSet::new()); - - //We don't add CreateInvites permission since by default we leave it unrestricted. - permissions.insert(CommunityPermission::EditInvites, IndexSet::new()); - permissions.insert(CommunityPermission::DeleteInvites, IndexSet::new()); - - permissions.insert(CommunityPermission::RemoveMembers, IndexSet::new()); - - permissions.insert(CommunityPermission::DeleteMessages, IndexSet::new()); - permissions.insert(CommunityPermission::PinMessages, IndexSet::new()); + for permission in CommunityPermission::default_disabled() { + permissions.insert(permission.to_string(), IndexSet::new()); + } let mut members = IndexSet::new(); members.insert(creator.clone()); @@ -299,14 +274,17 @@ impl CommunityDocument { } false } - pub fn has_permission(&self, user: &DID, has_permission: &CommunityPermission) -> bool { + pub fn has_permission(&self, user: &DID, has_permission: &T) -> bool + where + T: ToString, + { if &self.owner == user { return true; } if !self.members.contains(user) { return false; } - let Some(authorized_roles) = self.permissions.get(has_permission) else { + let Some(authorized_roles) = self.permissions.get(&has_permission.to_string()) else { return true; }; for authorized_role in authorized_roles { @@ -318,13 +296,15 @@ impl CommunityDocument { } false } - - pub fn has_channel_permission( + pub fn has_channel_permission( &self, user: &DID, - has_permission: &CommunityChannelPermission, + has_permission: &T, channel_id: Uuid, - ) -> bool { + ) -> bool + where + T: ToString, + { if &self.owner == user { return true; } @@ -334,7 +314,7 @@ impl CommunityDocument { let Some(channel) = self.channels.get(&channel_id.to_string()) else { return false; }; - let Some(authorized_roles) = channel.permissions.get(has_permission) else { + let Some(authorized_roles) = channel.permissions.get(&has_permission.to_string()) else { return true; }; for authorized_role in authorized_roles { diff --git a/extensions/warp-ipfs/src/store/message.rs b/extensions/warp-ipfs/src/store/message.rs index dd31d7c5f..3a67c870f 100644 --- a/extensions/warp-ipfs/src/store/message.rs +++ b/extensions/warp-ipfs/src/store/message.rs @@ -53,8 +53,7 @@ use crate::store::{ use crate::store::community::CommunityDocument; use chrono::{DateTime, Utc}; use warp::raygun::community::{ - Community, CommunityChannel, CommunityChannelPermission, CommunityChannelType, CommunityInvite, - CommunityPermission, CommunityRole, RoleId, + Community, CommunityChannel, CommunityChannelType, CommunityInvite, CommunityRole, RoleId, }; use warp::raygun::{ConversationImage, GroupPermissionOpt, Message}; use warp::{ @@ -1373,7 +1372,7 @@ impl MessageStore { pub async fn grant_community_permission( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let inner = &*self.inner.read().await; @@ -1396,7 +1395,7 @@ impl MessageStore { pub async fn revoke_community_permission( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let inner = &*self.inner.read().await; @@ -1419,7 +1418,7 @@ impl MessageStore { pub async fn grant_community_permission_for_all( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: String, ) -> Result<(), Error> { let inner = &*self.inner.read().await; let community_meta = inner @@ -1437,10 +1436,33 @@ impl MessageStore { .await; rx.await.map_err(anyhow::Error::from)? } + pub async fn has_community_permission( + &mut self, + community_id: Uuid, + permission: String, + member: DID, + ) -> Result { + let inner = &*self.inner.read().await; + let community_meta = inner + .community_task + .get(&community_id) + .ok_or(Error::InvalidCommunity)?; + let (tx, rx) = oneshot::channel(); + let _ = community_meta + .command_tx + .clone() + .send(CommunityTaskCommand::HasCommunityPermission { + permission, + member, + response: tx, + }) + .await; + rx.await.map_err(anyhow::Error::from)? + } pub async fn revoke_community_permission_for_all( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: String, ) -> Result<(), Error> { let inner = &*self.inner.read().await; let community_meta = inner @@ -1530,7 +1552,7 @@ impl MessageStore { &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let inner = &*self.inner.read().await; @@ -1555,7 +1577,7 @@ impl MessageStore { &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let inner = &*self.inner.read().await; @@ -1580,7 +1602,7 @@ impl MessageStore { &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, ) -> Result<(), Error> { let inner = &*self.inner.read().await; let community_meta = inner @@ -1605,7 +1627,7 @@ impl MessageStore { &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, ) -> Result<(), Error> { let inner = &*self.inner.read().await; let community_meta = inner @@ -1626,6 +1648,31 @@ impl MessageStore { .await; rx.await.map_err(anyhow::Error::from)? } + pub async fn has_community_channel_permission( + &mut self, + community_id: Uuid, + channel_id: Uuid, + permission: String, + member: DID, + ) -> Result { + let inner = &*self.inner.read().await; + let community_meta = inner + .community_task + .get(&community_id) + .ok_or(Error::InvalidCommunity)?; + let (tx, rx) = oneshot::channel(); + let _ = community_meta + .command_tx + .clone() + .send(CommunityTaskCommand::HasCommunityChannelPermission { + channel_id, + permission, + member, + response: tx, + }) + .await; + rx.await.map_err(anyhow::Error::from)? + } pub async fn get_community_channel_message( &self, diff --git a/extensions/warp-ipfs/src/store/message/community_task.rs b/extensions/warp-ipfs/src/store/message/community_task.rs index bb5d9dc76..55c4e9bd7 100644 --- a/extensions/warp-ipfs/src/store/message/community_task.rs +++ b/extensions/warp-ipfs/src/store/message/community_task.rs @@ -155,23 +155,28 @@ pub enum CommunityTaskCommand { response: oneshot::Sender>, }, GrantCommunityPermission { - permission: CommunityPermission, + permission: String, role_id: RoleId, response: oneshot::Sender>, }, RevokeCommunityPermission { - permission: CommunityPermission, + permission: String, role_id: RoleId, response: oneshot::Sender>, }, GrantCommunityPermissionForAll { - permission: CommunityPermission, + permission: String, response: oneshot::Sender>, }, RevokeCommunityPermissionForAll { - permission: CommunityPermission, + permission: String, response: oneshot::Sender>, }, + HasCommunityPermission { + permission: String, + member: DID, + response: oneshot::Sender>, + }, RemoveCommunityMember { member: DID, response: oneshot::Sender>, @@ -188,26 +193,32 @@ pub enum CommunityTaskCommand { }, GrantCommunityChannelPermission { channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, role_id: RoleId, response: oneshot::Sender>, }, RevokeCommunityChannelPermission { channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, role_id: RoleId, response: oneshot::Sender>, }, GrantCommunityChannelPermissionForAll { channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, response: oneshot::Sender>, }, RevokeCommunityChannelPermissionForAll { channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, response: oneshot::Sender>, }, + HasCommunityChannelPermission { + channel_id: Uuid, + permission: String, + member: DID, + response: oneshot::Sender>, + }, GetCommunityChannelMessage { channel_id: Uuid, message_id: Uuid, @@ -854,6 +865,14 @@ impl CommunityTask { let result = self.revoke_community_permission_for_all(permission).await; let _ = response.send(result); } + CommunityTaskCommand::HasCommunityPermission { + response, + permission, + member, + } => { + let result = self.has_community_permission(permission, member).await; + let _ = response.send(result); + } CommunityTaskCommand::RemoveCommunityMember { response, member } => { let result = self.remove_community_member(member).await; let _ = response.send(result); @@ -918,6 +937,17 @@ impl CommunityTask { .await; let _ = response.send(result); } + CommunityTaskCommand::HasCommunityChannelPermission { + response, + channel_id, + permission, + member, + } => { + let result = self + .has_community_channel_permission(channel_id, permission, member) + .await; + let _ = response.send(result); + } CommunityTaskCommand::GetCommunityChannelMessage { channel_id, message_id, @@ -2201,7 +2231,7 @@ impl CommunityTask { pub async fn grant_community_permission( &mut self, - permission: CommunityPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); @@ -2212,14 +2242,23 @@ impl CommunityTask { return Err(Error::Unauthorized); } - match self.document.permissions.get_mut(&permission) { - Some(authorized_roles) => { - authorized_roles.insert(role_id); - } - None => { - let mut roles = IndexSet::new(); - roles.insert(role_id); - self.document.permissions.insert(permission, roles); + let permissions: Vec = CommunityPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + match self.document.permissions.get_mut(permission) { + Some(authorized_roles) => { + authorized_roles.insert(role_id); + } + None => { + let mut roles = IndexSet::new(); + roles.insert(role_id); + self.document.permissions.insert(permission.clone(), roles); + } } } self.set_document().await?; @@ -2228,7 +2267,7 @@ impl CommunityTask { .event_broadcast .send(MessageEventKind::GrantedCommunityPermission { community_id: self.community_id, - permission, + permissions: permissions.clone(), role_id, }); @@ -2237,7 +2276,7 @@ impl CommunityTask { CommunityMessagingEvents::UpdateCommunity { community: self.document.clone(), kind: CommunityUpdateKind::GrantCommunityPermission { - permission, + permissions, role_id, }, }, @@ -2247,7 +2286,7 @@ impl CommunityTask { } pub async fn revoke_community_permission( &mut self, - permission: CommunityPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); @@ -2258,16 +2297,24 @@ impl CommunityTask { return Err(Error::Unauthorized); } - if let Some(authorized_roles) = self.document.permissions.get_mut(&permission) { - authorized_roles.swap_remove(&role_id); + let permissions: Vec = CommunityPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + if let Some(authorized_roles) = self.document.permissions.get_mut(permission) { + authorized_roles.swap_remove(&role_id); + } } self.set_document().await?; - let _ = self .event_broadcast .send(MessageEventKind::RevokedCommunityPermission { community_id: self.community_id, - permission, + permissions: permissions.clone(), role_id, }); @@ -2276,7 +2323,7 @@ impl CommunityTask { CommunityMessagingEvents::UpdateCommunity { community: self.document.clone(), kind: CommunityUpdateKind::RevokeCommunityPermission { - permission, + permissions, role_id, }, }, @@ -2286,7 +2333,7 @@ impl CommunityTask { } pub async fn grant_community_permission_for_all( &mut self, - permission: CommunityPermission, + permission: String, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); if !self @@ -2296,25 +2343,34 @@ impl CommunityTask { return Err(Error::Unauthorized); } - if self.document.permissions.contains_key(&permission) { - self.document.permissions.swap_remove(&permission); - self.set_document().await?; - } else { - return Err(Error::PermissionAlreadyGranted); + let permissions: Vec = CommunityPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + if self.document.permissions.contains_key(permission) { + self.document.permissions.swap_remove(permission); + self.set_document().await?; + } else if permissions.len() == 1 { + return Err(Error::PermissionAlreadyGranted); + } } let _ = self .event_broadcast .send(MessageEventKind::GrantedCommunityPermissionForAll { community_id: self.community_id, - permission, + permissions: permissions.clone(), }); self.publish( None, CommunityMessagingEvents::UpdateCommunity { community: self.document.clone(), - kind: CommunityUpdateKind::GrantCommunityPermissionForAll { permission }, + kind: CommunityUpdateKind::GrantCommunityPermissionForAll { permissions }, }, true, ) @@ -2322,7 +2378,7 @@ impl CommunityTask { } pub async fn revoke_community_permission_for_all( &mut self, - permission: CommunityPermission, + permission: String, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); if !self @@ -2332,28 +2388,44 @@ impl CommunityTask { return Err(Error::Unauthorized); } - self.document - .permissions - .insert(permission, IndexSet::new()); + let permissions: Vec = CommunityPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + self.document + .permissions + .insert(permission.clone(), IndexSet::new()); + } self.set_document().await?; let _ = self .event_broadcast .send(MessageEventKind::RevokedCommunityPermissionForAll { community_id: self.community_id, - permission, + permissions: permissions.clone(), }); self.publish( None, CommunityMessagingEvents::UpdateCommunity { community: self.document.clone(), - kind: CommunityUpdateKind::RevokeCommunityPermissionForAll { permission }, + kind: CommunityUpdateKind::RevokeCommunityPermissionForAll { permissions }, }, true, ) .await } + pub async fn has_community_permission( + &mut self, + permission: String, + member: DID, + ) -> Result { + Ok(self.document.has_permission(&member, &permission)) + } pub async fn remove_community_member(&mut self, member: DID) -> Result<(), Error> { let own_did = &self.identity.did_key(); if !self @@ -2474,7 +2546,7 @@ impl CommunityTask { pub async fn grant_community_channel_permission( &mut self, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); @@ -2490,14 +2562,23 @@ impl CommunityTask { .channels .get_mut(&channel_id.to_string()) .ok_or(Error::CommunityChannelDoesntExist)?; - match channel_doc.permissions.get_mut(&permission) { - Some(authorized_roles) => { - authorized_roles.insert(role_id); - } - None => { - let mut roles = IndexSet::new(); - roles.insert(role_id); - channel_doc.permissions.insert(permission, roles); + let permissions: Vec = CommunityChannelPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + match channel_doc.permissions.get_mut(permission) { + Some(authorized_roles) => { + authorized_roles.insert(role_id); + } + None => { + let mut roles = IndexSet::new(); + roles.insert(role_id); + channel_doc.permissions.insert(permission.clone(), roles); + } } } self.set_document().await?; @@ -2507,7 +2588,7 @@ impl CommunityTask { .send(MessageEventKind::GrantedCommunityChannelPermission { community_id: self.community_id, channel_id, - permission, + permissions: permissions.clone(), role_id, }); @@ -2517,7 +2598,7 @@ impl CommunityTask { community: self.document.clone(), kind: CommunityUpdateKind::GrantCommunityChannelPermission { channel_id, - permission, + permissions, role_id, }, }, @@ -2528,7 +2609,7 @@ impl CommunityTask { pub async fn revoke_community_channel_permission( &mut self, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, role_id: RoleId, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); @@ -2544,8 +2625,17 @@ impl CommunityTask { .channels .get_mut(&channel_id.to_string()) .ok_or(Error::CommunityChannelDoesntExist)?; - if let Some(authorized_roles) = channel_doc.permissions.get_mut(&permission) { - authorized_roles.swap_remove(&role_id); + let permissions: Vec = CommunityChannelPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + if let Some(authorized_roles) = channel_doc.permissions.get_mut(permission) { + authorized_roles.swap_remove(&role_id); + } } self.set_document().await?; @@ -2554,7 +2644,7 @@ impl CommunityTask { .send(MessageEventKind::RevokedCommunityChannelPermission { community_id: self.community_id, channel_id, - permission, + permissions: permissions.clone(), role_id, }); @@ -2564,7 +2654,7 @@ impl CommunityTask { community: self.document.clone(), kind: CommunityUpdateKind::RevokeCommunityChannelPermission { channel_id, - permission, + permissions, role_id, }, }, @@ -2575,7 +2665,7 @@ impl CommunityTask { pub async fn grant_community_channel_permission_for_all( &mut self, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); if !self @@ -2590,19 +2680,27 @@ impl CommunityTask { .channels .get_mut(&channel_id.to_string()) .ok_or(Error::CommunityChannelDoesntExist)?; - if channel_doc.permissions.contains_key(&permission) { - channel_doc.permissions.swap_remove(&permission); - self.set_document().await?; - } else { - return Err(Error::PermissionAlreadyGranted); + let permissions: Vec = CommunityChannelPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); } - + for permission in &permissions { + if channel_doc.permissions.contains_key(permission) { + channel_doc.permissions.swap_remove(permission); + } else if permissions.len() == 1 { + return Err(Error::PermissionAlreadyGranted); + } + } + self.set_document().await?; let _ = self.event_broadcast .send(MessageEventKind::GrantedCommunityChannelPermissionForAll { community_id: self.community_id, channel_id, - permission, + permissions: permissions.clone(), }); self.publish( @@ -2611,7 +2709,7 @@ impl CommunityTask { community: self.document.clone(), kind: CommunityUpdateKind::GrantCommunityChannelPermissionForAll { channel_id, - permission, + permissions, }, }, true, @@ -2621,7 +2719,7 @@ impl CommunityTask { pub async fn revoke_community_channel_permission_for_all( &mut self, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: String, ) -> Result<(), Error> { let own_did = &self.identity.did_key(); if !self @@ -2636,7 +2734,18 @@ impl CommunityTask { .channels .get_mut(&channel_id.to_string()) .ok_or(Error::CommunityChannelDoesntExist)?; - channel_doc.permissions.insert(permission, IndexSet::new()); + let permissions: Vec = CommunityChannelPermission::sub_permissions(&permission) + .iter() + .map(|p| p.to_string()) + .collect(); + if permissions.is_empty() { + return Err(Error::InvalidPermission); + } + for permission in &permissions { + channel_doc + .permissions + .insert(permission.clone(), IndexSet::new()); + } self.set_document().await?; let _ = @@ -2644,7 +2753,7 @@ impl CommunityTask { .send(MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: self.community_id, channel_id, - permission, + permissions: permissions.clone(), }); self.publish( @@ -2653,13 +2762,23 @@ impl CommunityTask { community: self.document.clone(), kind: CommunityUpdateKind::RevokeCommunityChannelPermissionForAll { channel_id, - permission, + permissions, }, }, true, ) .await } + pub async fn has_community_channel_permission( + &mut self, + channel_id: Uuid, + permission: String, + member: DID, + ) -> Result { + Ok(self + .document + .has_channel_permission(&member, &permission, channel_id)) + } pub async fn get_community_channel_message( &self, @@ -4234,7 +4353,7 @@ async fn message_event( } } CommunityUpdateKind::GrantCommunityPermission { - permission, + permissions, role_id, } => { this.replace_document(community).await?; @@ -4242,7 +4361,7 @@ async fn message_event( this.event_broadcast .send(MessageEventKind::GrantedCommunityPermission { community_id, - permission, + permissions, role_id, }) { @@ -4250,7 +4369,7 @@ async fn message_event( } } CommunityUpdateKind::RevokeCommunityPermission { - permission, + permissions, role_id, } => { this.replace_document(community).await?; @@ -4258,30 +4377,30 @@ async fn message_event( this.event_broadcast .send(MessageEventKind::RevokedCommunityPermission { community_id, - permission, + permissions, role_id, }) { tracing::warn!(%community_id, error = %e, "Error broadcasting event"); } } - CommunityUpdateKind::GrantCommunityPermissionForAll { permission } => { + CommunityUpdateKind::GrantCommunityPermissionForAll { permissions } => { this.replace_document(community).await?; if let Err(e) = this.event_broadcast.send( MessageEventKind::GrantedCommunityPermissionForAll { community_id, - permission, + permissions, }, ) { tracing::warn!(%community_id, error = %e, "Error broadcasting event"); } } - CommunityUpdateKind::RevokeCommunityPermissionForAll { permission } => { + CommunityUpdateKind::RevokeCommunityPermissionForAll { permissions } => { this.replace_document(community).await?; if let Err(e) = this.event_broadcast.send( MessageEventKind::RevokedCommunityPermissionForAll { community_id, - permission, + permissions, }, ) { tracing::warn!(%community_id, error = %e, "Error broadcasting event"); @@ -4329,7 +4448,7 @@ async fn message_event( } CommunityUpdateKind::GrantCommunityChannelPermission { channel_id, - permission, + permissions, role_id, } => { this.replace_document(community).await?; @@ -4337,7 +4456,7 @@ async fn message_event( MessageEventKind::GrantedCommunityChannelPermission { community_id, channel_id, - permission, + permissions, role_id, }, ) { @@ -4346,7 +4465,7 @@ async fn message_event( } CommunityUpdateKind::RevokeCommunityChannelPermission { channel_id, - permission, + permissions, role_id, } => { this.replace_document(community).await?; @@ -4354,7 +4473,7 @@ async fn message_event( MessageEventKind::RevokedCommunityChannelPermission { community_id, channel_id, - permission, + permissions, role_id, }, ) { @@ -4363,14 +4482,14 @@ async fn message_event( } CommunityUpdateKind::GrantCommunityChannelPermissionForAll { channel_id, - permission, + permissions, } => { this.replace_document(community).await?; if let Err(e) = this.event_broadcast.send( MessageEventKind::GrantedCommunityChannelPermissionForAll { community_id, channel_id, - permission, + permissions, }, ) { tracing::warn!(%community_id, error = %e, "Error broadcasting event"); @@ -4378,14 +4497,14 @@ async fn message_event( } CommunityUpdateKind::RevokeCommunityChannelPermissionForAll { channel_id, - permission, + permissions, } => { this.replace_document(community).await?; if let Err(e) = this.event_broadcast.send( MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id, channel_id, - permission, + permissions, }, ) { tracing::warn!(%community_id, error = %e, "Error broadcasting event"); diff --git a/extensions/warp-ipfs/src/store/mod.rs b/extensions/warp-ipfs/src/store/mod.rs index ba3fbb919..118dfbad6 100644 --- a/extensions/warp-ipfs/src/store/mod.rs +++ b/extensions/warp-ipfs/src/store/mod.rs @@ -29,10 +29,7 @@ use warp::{ }, error::Error, multipass::identity::IdentityStatus, - raygun::{ - community::{CommunityChannelPermission, CommunityPermission, RoleId}, - GroupPermissions, MessageEvent, PinState, ReactionState, - }, + raygun::{community::RoleId, GroupPermissions, MessageEvent, PinState, ReactionState}, }; use conversation::{message::MessageDocument, ConversationDocument}; @@ -551,18 +548,18 @@ pub enum CommunityUpdateKind { EditIcon, EditBanner, GrantCommunityPermission { - permission: CommunityPermission, + permissions: Vec, role_id: RoleId, }, RevokeCommunityPermission { - permission: CommunityPermission, + permissions: Vec, role_id: RoleId, }, GrantCommunityPermissionForAll { - permission: CommunityPermission, + permissions: Vec, }, RevokeCommunityPermissionForAll { - permission: CommunityPermission, + permissions: Vec, }, RemoveCommunityMember { member: DID, @@ -577,21 +574,21 @@ pub enum CommunityUpdateKind { }, GrantCommunityChannelPermission { channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, role_id: RoleId, }, RevokeCommunityChannelPermission { channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, role_id: RoleId, }, GrantCommunityChannelPermissionForAll { channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, }, RevokeCommunityChannelPermissionForAll { channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, }, } diff --git a/extensions/warp-ipfs/tests/community.rs b/extensions/warp-ipfs/tests/community.rs index 31c8a4e14..f1bcd65ff 100644 --- a/extensions/warp-ipfs/tests/community.rs +++ b/extensions/warp-ipfs/tests/community.rs @@ -1772,7 +1772,7 @@ mod test { let community = instance_a.get_community(community.id()).await?; assert!(community .permissions() - .get(&CommunityPermission::EditName) + .get(&CommunityPermission::EditName.to_string()) .unwrap() .contains(&role.id())); Ok(()) @@ -2291,7 +2291,7 @@ mod test { .await?; assert!(channel .permissions() - .get(&CommunityChannelPermission::ViewChannel) + .get(&CommunityChannelPermission::ViewChannel.to_string()) .is_none()); Ok(()) } @@ -3462,7 +3462,7 @@ mod test { MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: community.id(), channel_id: channel.id(), - permission: CommunityChannelPermission::SendMessages, + permissions: vec![CommunityChannelPermission::SendMessages.to_string()], }, ) .await?; @@ -3648,7 +3648,7 @@ mod test { MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: community.id(), channel_id: channel.id(), - permission: CommunityChannelPermission::SendMessages, + permissions: vec![CommunityChannelPermission::SendMessages.to_string()], }, ) .await?; @@ -4021,7 +4021,7 @@ mod test { Duration::from_secs(60), MessageEventKind::RevokedCommunityPermissionForAll { community_id: community.id(), - permission: CommunityPermission::PinMessages, + permissions: vec![CommunityPermission::PinMessages.to_string()], }, ) .await?; @@ -4215,7 +4215,7 @@ mod test { MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: community.id(), channel_id: channel.id(), - permission: CommunityChannelPermission::ViewChannel, + permissions: vec![CommunityChannelPermission::ViewChannel.to_string()], }, ) .await?; @@ -4378,7 +4378,7 @@ mod test { MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: community.id(), channel_id: channel.id(), - permission: CommunityChannelPermission::SendAttachments, + permissions: vec![CommunityChannelPermission::SendAttachments.to_string()], }, ) .await?; @@ -4545,7 +4545,7 @@ mod test { MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: community.id(), channel_id: channel.id(), - permission: CommunityChannelPermission::ViewChannel, + permissions: vec![CommunityChannelPermission::ViewChannel.to_string()], }, ) .await?; @@ -4767,7 +4767,7 @@ mod test { MessageEventKind::RevokedCommunityChannelPermissionForAll { community_id: community.id(), channel_id: channel.id(), - permission: CommunityChannelPermission::ViewChannel, + permissions: vec![CommunityChannelPermission::ViewChannel.to_string()], }, ) .await?; diff --git a/tools/enum_macro/Cargo.toml b/tools/enum_macro/Cargo.toml new file mode 100644 index 000000000..b40b50536 --- /dev/null +++ b/tools/enum_macro/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "enum_macro" +version = "0.1.0" +edition = "2021" + +[dependencies] +syn = { version = "2.0.87", features = ["derive"] } +quote = "1.0.37" +proc-macro2 = "1.0.89" + +[lib] +proc-macro = true \ No newline at end of file diff --git a/tools/enum_macro/src/lib.rs b/tools/enum_macro/src/lib.rs new file mode 100644 index 000000000..2f38dee8b --- /dev/null +++ b/tools/enum_macro/src/lib.rs @@ -0,0 +1,36 @@ +extern crate proc_macro2; + +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, Data, DeriveInput}; + +/// Implements #values() for enum values that returns all defined values in the enum +/// E.g. +/// ``` +/// use enum_macro::EnumValues; +/// #[derive(EnumValues, PartialEq, Debug)] +/// pub enum SomeEnum { +/// SomeValue1, +/// SomeValue2 +/// } +/// +/// assert_eq!([SomeEnum::SomeValue1, SomeEnum::SomeValue2], SomeEnum::values()); +/// ``` +#[proc_macro_derive(EnumValues)] +pub fn enum_values(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + if let Data::Enum(enum_data) = input.data { + let variants: Vec<_> = enum_data.variants.into_iter().map(|v| v.ident).collect(); + let expanded = quote! { + impl #name { + pub fn values() -> &'static[#name] { + &[ #(#name::#variants),* ] + } + } + }; + TokenStream::from(expanded) + } else { + panic!("Only Enums are supported"); + } +} diff --git a/warp/Cargo.toml b/warp/Cargo.toml index 29d2f3b1d..296c5343d 100644 --- a/warp/Cargo.toml +++ b/warp/Cargo.toml @@ -60,6 +60,7 @@ tracing = { workspace = true } mediatype.workspace = true send_wrapper.workspace = true indexmap.workspace = true +enum_macro.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tokio = { workspace = true } diff --git a/warp/src/error.rs b/warp/src/error.rs index 583fecdf8..a4db1147e 100644 --- a/warp/src/error.rs +++ b/warp/src/error.rs @@ -274,6 +274,8 @@ pub enum Error { //Misc #[error("Unauthorized")] Unauthorized, + #[error("Invalid permission")] + InvalidPermission, #[error("Length for '{context}' is invalid. Current length: {current}. Minimum Length: {minimum:?}, Maximum: {maximum:?}")] InvalidLength { context: String, diff --git a/warp/src/raygun/community.rs b/warp/src/raygun/community.rs index fa6234dc6..d1f73b34d 100644 --- a/warp/src/raygun/community.rs +++ b/warp/src/raygun/community.rs @@ -1,3 +1,4 @@ +use std::fmt::Display; use std::path::PathBuf; use bytes::Bytes; @@ -15,11 +16,12 @@ use super::{ AttachmentEventStream, ConversationImage, Message, MessageEvent, MessageEventStream, MessageOptions, MessageReference, MessageStatus, Messages, PinState, ReactionState, }; +use enum_macro::EnumValues; pub type RoleId = Uuid; pub type CommunityRoles = IndexMap; -pub type CommunityPermissions = IndexMap>; -pub type CommunityChannelPermissions = IndexMap>; +pub type CommunityPermissions = IndexMap>; +pub type CommunityChannelPermissions = IndexMap>; #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct CommunityRole { @@ -237,46 +239,124 @@ pub enum CommunityChannelType { VoiceEnabled, } -#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] -#[serde(rename_all = "snake_case")] +#[derive(Debug, Copy, Clone, Serialize, Deserialize, EnumValues, PartialEq, Eq, Hash)] pub enum CommunityPermission { + #[serde(rename = "community.visuals.edit_name")] EditName, + #[serde(rename = "community.visuals.edit_description")] EditDescription, + #[serde(rename = "community.visuals.edit_icon")] EditIcon, + #[serde(rename = "community.visuals.edit_banner")] EditBanner, + #[serde(rename = "community.roles.create_roles")] CreateRoles, + #[serde(rename = "community.roles.edit_roles")] EditRoles, + #[serde(rename = "community.roles.delete_roles")] DeleteRoles, + #[serde(rename = "community.roles.grant_roles")] GrantRoles, + #[serde(rename = "community.roles.revoke_roles")] RevokeRoles, + #[serde(rename = "community.permissions.grant_permissions")] GrantPermissions, + #[serde(rename = "community.permissions.revoke_permissions")] RevokePermissions, + #[serde(rename = "community.invites.create_invites")] CreateInvites, + #[serde(rename = "community.invites.edit_invites")] EditInvites, + #[serde(rename = "community.invites.delete_invites")] DeleteInvites, + #[serde(rename = "community.channels.create_channels")] CreateChannels, + #[serde(rename = "community.channels.edit_channels")] EditChannels, + #[serde(rename = "community.channels.delete_channels")] DeleteChannels, + #[serde(rename = "community.members.remove_members")] RemoveMembers, + #[serde(rename = "community.messages.delete_messages")] DeleteMessages, + #[serde(rename = "community.messages.pin_messages")] PinMessages, } -#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] -#[serde(rename_all = "snake_case")] +impl Display for CommunityPermission { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&serde_json::to_string(self).unwrap()) + } +} + +impl CommunityPermission { + pub fn default_disabled() -> Vec { + vec![ + CommunityPermission::EditName, + CommunityPermission::EditDescription, + CommunityPermission::EditIcon, + CommunityPermission::EditBanner, + CommunityPermission::CreateRoles, + CommunityPermission::EditRoles, + CommunityPermission::DeleteRoles, + CommunityPermission::GrantRoles, + CommunityPermission::RevokeRoles, + CommunityPermission::GrantPermissions, + CommunityPermission::RevokePermissions, + //We don't add CreateInvites permission since by default we leave it unrestricted. + CommunityPermission::EditInvites, + CommunityPermission::DeleteInvites, + CommunityPermission::CreateChannels, + CommunityPermission::EditChannels, + CommunityPermission::DeleteChannels, + CommunityPermission::RemoveMembers, + CommunityPermission::DeleteMessages, + CommunityPermission::PinMessages, + ] + } + + pub fn sub_permissions(node: &str) -> Vec { + CommunityPermission::values() + .iter() + .filter(|p| p.to_string().starts_with(node)) + .cloned() + .collect() + } +} + +/// Built-in CommunityChannelPermission for ease of access +#[derive(Debug, Copy, Clone, Serialize, Deserialize, EnumValues, PartialEq, Eq, Hash)] pub enum CommunityChannelPermission { + #[serde(rename = "community_channel.view_channel")] ViewChannel, + #[serde(rename = "community_channel.messages.send_messages")] SendMessages, SendAttachments, } +impl Display for CommunityChannelPermission { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&serde_json::to_string(self).unwrap()) + } +} + +impl CommunityChannelPermission { + pub fn sub_permissions(node: &str) -> Vec { + CommunityChannelPermission::values() + .iter() + .filter(|p| p.to_string().starts_with(node)) + .cloned() + .collect() + } +} + #[async_trait::async_trait] pub trait RayGunCommunity: Sync + Send { async fn get_community_stream( @@ -440,34 +520,57 @@ pub trait RayGunCommunity: Sync + Send { ) -> Result<(), Error> { Err(Error::Unimplemented) } - async fn grant_community_permission( + async fn grant_community_permission( &mut self, _community_id: Uuid, - _permission: CommunityPermission, + _permission: T, _role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { Err(Error::Unimplemented) } - async fn revoke_community_permission( + async fn revoke_community_permission( &mut self, _community_id: Uuid, - _permission: CommunityPermission, + _permission: T, _role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { Err(Error::Unimplemented) } - async fn grant_community_permission_for_all( + async fn grant_community_permission_for_all( &mut self, _community_id: Uuid, - _permission: CommunityPermission, - ) -> Result<(), Error> { + _permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { Err(Error::Unimplemented) } - async fn revoke_community_permission_for_all( + async fn revoke_community_permission_for_all( &mut self, _community_id: Uuid, - _permission: CommunityPermission, - ) -> Result<(), Error> { + _permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { + Err(Error::Unimplemented) + } + async fn has_community_permission( + &mut self, + _community_id: Uuid, + _permission: T, + _member: DID, + ) -> Result + where + T: ToString + Send, + { Err(Error::Unimplemented) } async fn remove_community_member( @@ -494,38 +597,62 @@ pub trait RayGunCommunity: Sync + Send { ) -> Result<(), Error> { Err(Error::Unimplemented) } - async fn grant_community_channel_permission( + async fn grant_community_channel_permission( &mut self, _community_id: Uuid, _channel_id: Uuid, - _permission: CommunityChannelPermission, + _permission: T, _role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { Err(Error::Unimplemented) } - async fn revoke_community_channel_permission( + async fn revoke_community_channel_permission( &mut self, _community_id: Uuid, _channel_id: Uuid, - _permission: CommunityChannelPermission, + _permission: T, _role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { Err(Error::Unimplemented) } - async fn grant_community_channel_permission_for_all( + async fn grant_community_channel_permission_for_all( &mut self, _community_id: Uuid, _channel_id: Uuid, - _permission: CommunityChannelPermission, - ) -> Result<(), Error> { + _permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { Err(Error::Unimplemented) } - async fn revoke_community_channel_permission_for_all( + async fn revoke_community_channel_permission_for_all( &mut self, _community_id: Uuid, _channel_id: Uuid, - _permission: CommunityChannelPermission, - ) -> Result<(), Error> { + _permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { + Err(Error::Unimplemented) + } + async fn has_community_channel_permission( + &mut self, + _community_id: Uuid, + _channel_id: Uuid, + _permission: T, + _member: DID, + ) -> Result + where + T: ToString + Send, + { Err(Error::Unimplemented) } diff --git a/warp/src/raygun/mod.rs b/warp/src/raygun/mod.rs index e26febe1d..e339e95ef 100644 --- a/warp/src/raygun/mod.rs +++ b/warp/src/raygun/mod.rs @@ -8,10 +8,7 @@ use crate::error::Error; use crate::raygun::community::RayGunCommunity; use crate::{Extension, SingleHandle}; -use community::{ - CommunityChannel, CommunityChannelPermission, CommunityInvite, CommunityPermission, - CommunityRole, RoleId, -}; +use community::{CommunityChannel, CommunityInvite, CommunityRole, RoleId}; use derive_more::Display; use futures::stream::BoxStream; @@ -198,21 +195,21 @@ pub enum MessageEventKind { }, GrantedCommunityPermission { community_id: Uuid, - permission: CommunityPermission, + permissions: Vec, role_id: RoleId, }, RevokedCommunityPermission { community_id: Uuid, - permission: CommunityPermission, + permissions: Vec, role_id: RoleId, }, GrantedCommunityPermissionForAll { community_id: Uuid, - permission: CommunityPermission, + permissions: Vec, }, RevokedCommunityPermissionForAll { community_id: Uuid, - permission: CommunityPermission, + permissions: Vec, }, RemovedCommunityMember { community_id: Uuid, @@ -231,24 +228,24 @@ pub enum MessageEventKind { GrantedCommunityChannelPermission { community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, role_id: RoleId, }, RevokedCommunityChannelPermission { community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, role_id: RoleId, }, GrantedCommunityChannelPermissionForAll { community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, }, RevokedCommunityChannelPermissionForAll { community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permissions: Vec, }, CommunityMessageSent { community_id: Uuid, diff --git a/warp/src/warp.rs b/warp/src/warp.rs index a5f0c5c94..871b1d355 100644 --- a/warp/src/warp.rs +++ b/warp/src/warp.rs @@ -15,9 +15,7 @@ use crate::multipass::{ Friends, GetIdentity, IdentityImportOption, IdentityInformation, ImportLocation, LocalIdentity, MultiPass, MultiPassEvent, MultiPassEventStream, MultiPassImportExport, }; -use crate::raygun::community::{ - CommunityChannelPermission, CommunityPermission, CommunityRole, RoleId, -}; +use crate::raygun::community::{CommunityRole, RoleId}; use crate::raygun::{ community::{ Community, CommunityChannel, CommunityChannelType, CommunityInvite, RayGunCommunity, @@ -759,44 +757,69 @@ where .edit_community_description(community_id, description) .await } - async fn grant_community_permission( + async fn grant_community_permission( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .grant_community_permission(community_id, permission, role_id) .await } - async fn revoke_community_permission( + async fn revoke_community_permission( &mut self, community_id: Uuid, - permission: CommunityPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .revoke_community_permission(community_id, permission, role_id) .await } - async fn grant_community_permission_for_all( + async fn grant_community_permission_for_all( &mut self, community_id: Uuid, - permission: CommunityPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .grant_community_permission_for_all(community_id, permission) .await } - async fn revoke_community_permission_for_all( + async fn revoke_community_permission_for_all( &mut self, community_id: Uuid, - permission: CommunityPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .revoke_community_permission_for_all(community_id, permission) .await } + async fn has_community_permission( + &mut self, + community_id: Uuid, + permission: T, + member: DID, + ) -> Result + where + T: ToString + Send, + { + self.raygun + .has_community_permission(community_id, permission, member) + .await + } async fn remove_community_member( &mut self, community_id: Uuid, @@ -827,48 +850,74 @@ where .edit_community_channel_description(community_id, channel_id, description) .await } - async fn grant_community_channel_permission( + async fn grant_community_channel_permission( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .grant_community_channel_permission(community_id, channel_id, permission, role_id) .await } - async fn revoke_community_channel_permission( + async fn revoke_community_channel_permission( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, + permission: T, role_id: RoleId, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .revoke_community_channel_permission(community_id, channel_id, permission, role_id) .await } - async fn grant_community_channel_permission_for_all( + async fn grant_community_channel_permission_for_all( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .grant_community_channel_permission_for_all(community_id, channel_id, permission) .await } - async fn revoke_community_channel_permission_for_all( + async fn revoke_community_channel_permission_for_all( &mut self, community_id: Uuid, channel_id: Uuid, - permission: CommunityChannelPermission, - ) -> Result<(), Error> { + permission: T, + ) -> Result<(), Error> + where + T: ToString + Send, + { self.raygun .revoke_community_channel_permission_for_all(community_id, channel_id, permission) .await } + async fn has_community_channel_permission( + &mut self, + community_id: Uuid, + channel_id: Uuid, + permission: T, + member: DID, + ) -> Result + where + T: ToString + Send, + { + self.raygun + .has_community_channel_permission(community_id, channel_id, permission, member) + .await + } async fn get_community_channel_message( &self,