diff --git a/src/imp.rs b/src/imp.rs index 4fbb5e6..a64dded 100644 --- a/src/imp.rs +++ b/src/imp.rs @@ -4,6 +4,21 @@ use libcwtch::CwtchLib; use serde_json; +// Todo: move Behaviour + building to seperate file + +pub struct AllowList { + // list of peers to allow by handle + peers: Vec, + // list of groups to join and listen for peers in peer list from + groups: Vec, +} + +impl AllowList { + pub fn new(peers: Vec, groups: Vec) -> Self { + AllowList{peers: peers, groups: groups} + } +} + /// How new contacts should be treated pub enum NewContactPolicy { /// Do not react, leave it for the custom event handler @@ -12,6 +27,9 @@ pub enum NewContactPolicy { Block, /// Accept all new contacts Accept, + /// AllowList is a list of handles that connections will be allowed from and connected to, and will be accepted + /// everything else will be ignored + AllowList(AllowList) } /// Settings for the bot on how it should automatically behave @@ -89,12 +107,12 @@ impl BehaviourBuilder { /// Trait to be used by implementors of imp bots to supply their custom event handling /// the handle function is called after the default imp automatic event handling has run on each new event pub trait EventHandler { - fn handle(&mut self, cwtch: &dyn CwtchLib, profile: Option<&Profile>, event: Event); + fn handle(&mut self, cwtch: &dyn libcwtch::CwtchLib, profile: Option<&Profile>, event: Event); } /// Cwtch bot pub struct Imp { - cwtch: Box, + cwtch: Box, behaviour: Behaviour, password: String, home_dir: String, @@ -213,16 +231,7 @@ impl Imp { ); for (_id, conversation) in &profile.conversations { - match self.behaviour.new_contant_policy { - NewContactPolicy::Accept => { - self.cwtch - .accept_conversation(&profile.handle.clone(), conversation.identifier); - } - NewContactPolicy::Block => self - .cwtch - .block_contact(&profile.handle.clone(), conversation.identifier), - NewContactPolicy::Ignore => (), - } + self.process_contact(conversation.identifier); } self.profile = Some(profile); @@ -236,7 +245,6 @@ impl Imp { Event::ContactCreated { data } => { println!("Contact Created"); let convo_handle = data["RemotePeer"].to_string(); - let convo_id = data["ConversationID"].parse::().unwrap(); let acl: ACL = serde_json::from_str(&data["accessControlList"]).expect("Error parsing conversation"); @@ -251,20 +259,13 @@ impl Imp { is_group: false, // by definition }; + self.process_contact(conversation.identifier); + match self.profile.as_mut() { Some(profile) => { profile .conversations - .insert(data["RemotePeer"].to_string(), conversation); - - match self.behaviour.new_contant_policy { - NewContactPolicy::Accept => { - self.cwtch - .accept_conversation(&profile.handle.clone(), convo_id); - } - NewContactPolicy::Block => self.cwtch.block_contact(&profile.handle.clone(), convo_id), - NewContactPolicy::Ignore => (), - } + .insert(conversation.identifier, conversation); } None => (), }; @@ -277,4 +278,36 @@ impl Imp { handler.handle(self.cwtch.as_ref(), self.profile.as_ref(), event); } } + + fn process_contact(&self, conversation_id: i32) { + match &self.profile { + Some(profile) => { + let profile_handle = profile.handle.clone(); + + + match &self.behaviour.new_contant_policy { + NewContactPolicy::Accept => { + self.cwtch + .accept_conversation(&profile_handle.clone(), conversation_id); + } + NewContactPolicy::Block => self.cwtch.block_contact(&profile_handle.clone(), conversation_id), + NewContactPolicy::AllowList(allow_list) => { + match profile.conversations.get(&conversation_id) { + Some(conversation) => { + if allow_list.peers.contains(&conversation.handle) { + self.cwtch + .accept_conversation(&profile_handle.clone(), conversation_id); + } else { + self.cwtch.block_contact(&profile_handle.clone(), conversation_id); + } + }, + None => {}, + } + } + NewContactPolicy::Ignore => (), + } + }, + None => {}, + } + } }