add behaviours: ContactInteractionPolicy, GroupInteractionPolicy; move allow_list to Behaviour

This commit is contained in:
Dan Ballard 2024-02-21 17:53:54 -08:00
parent 76fa84bd66
commit d2abf3af24
3 changed files with 110 additions and 26 deletions

View File

@ -12,5 +12,5 @@ documentation = "https://docs.rs/cwtch-imp/"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libcwtch = "0.7.0"
libcwtch = {path = "./../libcwtch-rs"} # "0.7.0"
chrono = "0.4.19"

View File

@ -1,18 +1,16 @@
use libcwtch::event::{ContactIdentity, GroupID};
use libcwtch::event::{ContactIdentity};
/// defines a locked list of allowed peers and groups the bot may communicate with
/// others will be blocked, and peers listed here will be peered with actively
pub struct AllowListMembers {
/// list of peers to allow by handle
pub peers: Vec<ContactIdentity>,
/// list of groups to join and listen for peers in peer list from
pub groups: Vec<GroupID>,
}
impl AllowListMembers {
/// constructs a new AllowListMembers struct
pub fn new(peers: Vec<ContactIdentity>, groups: Vec<GroupID>) -> Self {
AllowListMembers {peers: peers, groups: groups}
pub fn new(peers: Vec<ContactIdentity>) -> Self {
AllowListMembers {peers: peers}
}
}
@ -26,16 +24,43 @@ pub enum NewContactPolicy {
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(AllowListMembers)
AllowList
}
pub enum ContactInteractionPolicy {
/// Do not react, leave it for the custom event handler
Ignore,
/// Accept all messages
Accept,
/// Only accept messages from contacts. Pairs strongly with NewContactPolicy of AllowList
AcceptFromContact,
/// 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
}
pub enum GroupInvitePolicy {
/// Ignore all group invites
IgnoreAll,
Ignore,
/// Accept all group invites
AcceptAll,
Accept,
/// Only accept group invites from contacts. Pairs strongly with NewContactPolicy of AllowList
AcceptFromContact,
/// AllowList is a list of handles that group invites will be allowed from and connected to,
/// and will be accepted. Everything else will be ignored
AllowList,
}
pub enum GroupInteractionPolicy {
/// Do not react, leave it for the custom event handler
Ignore,
/// Accept all messages
Accept,
/// Only accept messages from contacts. Pairs strongly with NewContactPolicy of AllowList
AcceptFromContact,
/// 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
}
/// Settings for the bot on how it should automatically behave
@ -57,8 +82,16 @@ pub struct Behaviour {
/// Policy dictacting how the bot should automatically handle ContactCreated events
pub new_contant_policy: NewContactPolicy,
/// Policy dictating how the bot should handle messages from p2p contacts
pub contact_interaction_policy: ContactInteractionPolicy,
/// Policy dictating how the bot should handle Group Invites
pub group_invite_policy: GroupInvitePolicy,
/// Policy dictacting how the bot should respond to @ messages in groups
pub group_interaction_policy: GroupInteractionPolicy,
pub allow_list: AllowListMembers,
}
/// intermediary struct for building a Behaviour using builder patern
@ -75,9 +108,12 @@ impl BehaviourBuilder {
proto_experiment_fileshare: false,
proto_experiment_groups: false,
new_contant_policy: NewContactPolicy::Ignore,
group_invite_policy: GroupInvitePolicy::IgnoreAll,
contact_interaction_policy: ContactInteractionPolicy::Ignore,
group_invite_policy: GroupInvitePolicy::Ignore,
group_interaction_policy: GroupInteractionPolicy::Ignore,
profile_name: "".to_string(),
profile_pic_path: None,
allow_list: AllowListMembers::new(vec!()),
},
};
}
@ -121,8 +157,23 @@ impl BehaviourBuilder {
self
}
pub fn contact_interaction_policy(mut self, val: ContactInteractionPolicy) -> Self {
self.behaviour.contact_interaction_policy = val;
self
}
pub fn group_invite_policy(mut self, val: GroupInvitePolicy) -> Self {
self.behaviour.group_invite_policy = val;
self
}
pub fn group_interaction_policy(mut self, val: GroupInteractionPolicy) -> Self {
self.behaviour.group_interaction_policy = val;
self
}
pub fn allow_list(mut self, val: AllowListMembers) -> Self {
self.behaviour.allow_list = val;
self
}
}

View File

@ -4,8 +4,7 @@ use libcwtch::CwtchLib;
use libcwtch::event::{ContactIdentity, ConversationID, Event};
use libcwtch::structs::MessageType::InviteGroup;
use crate::behaviour::{Behaviour, GroupInvitePolicy, NewContactPolicy};
use crate::behaviour::GroupInvitePolicy::AcceptAll;
use crate::behaviour::{Behaviour, ContactInteractionPolicy, GroupInteractionPolicy, GroupInvitePolicy, NewContactPolicy};
use crate::behaviour::NewContactPolicy::AllowList;
/// Trait to be used by implementors of imp bots to supply their custom event handling
@ -125,8 +124,8 @@ impl Imp {
}
// Allow list should add all people in the list
if let AllowList(allow_list) = &self.behaviour.new_contant_policy {
for contact_id in &allow_list.peers {
if let AllowList = &self.behaviour.new_contant_policy {
for contact_id in &self.behaviour.allow_list.peers {
if let None = ok_profile.find_conversation_id_by_handle(contact_id.clone()) {
self.cwtch.import_bundle(&profile_id, contact_id.clone().as_str());
}
@ -185,26 +184,62 @@ impl Imp {
Event::NewMessageFromPeer {profile_id, conversation_id,contact_id, nick, timestamp_received, message, notification, picture } => {
if message.o == InviteGroup {
if let Some(profile) = self.profile.as_ref() {
match self.behaviour.group_invite_policy {
GroupInvitePolicy::IgnoreAll => (),
GroupInvitePolicy::AcceptAll => self.cwtch.import_bundle(profile_id, message.d.as_str()),
match &self.behaviour.group_invite_policy {
GroupInvitePolicy::Ignore => (),
GroupInvitePolicy::Accept => self.cwtch.import_bundle(profile_id, message.d.as_str()),
GroupInvitePolicy::AcceptFromContact=> {
if profile.conversations[conversation_id].accepted {
self.cwtch.import_bundle(profile_id, message.d.as_str())
}
}
GroupInvitePolicy::AllowList => {
if let Some(conversation) = profile.conversations.get(&conversation_id) {
if self.behaviour.allow_list.peers.contains(&conversation.contact_id) {
self.cwtch.import_bundle(profile_id, message.d.as_str())
}
}
}
}
}
} else {
match self.profile.as_ref() {
Some(profile) => handler.on_new_message_from_contact(self.cwtch.as_ref(), profile, conversation_id.clone(), nick.clone(), timestamp_received.clone(), message.clone()),
None => {},
if let Some(profile) = self.profile.as_ref() {
match &self.behaviour.contact_interaction_policy {
ContactInteractionPolicy::Ignore => (),
ContactInteractionPolicy::Accept => handler.on_new_message_from_contact(self.cwtch.as_ref(), profile, conversation_id.clone(), nick.clone(), timestamp_received.clone(), message.clone()),
ContactInteractionPolicy::AcceptFromContact=> {
if profile.conversations[conversation_id].accepted {
handler.on_new_message_from_contact(self.cwtch.as_ref(), profile, conversation_id.clone(), nick.clone(), timestamp_received.clone(), message.clone());
}
},
ContactInteractionPolicy::AllowList => {
if let Some(conversation) = profile.conversations.get(&conversation_id) {
if self.behaviour.allow_list.peers.contains(&conversation.contact_id) {
handler.on_new_message_from_contact(self.cwtch.as_ref(), profile, conversation_id.clone(), nick.clone(), timestamp_received.clone(), message.clone());
}
}
}
}
}
}
}
Event::NewMessageFromGroup { profile_id, conversation_id, timestamp_sent, contact_id, index, message, content_hash, picture, notification, } => {
if let Some(profile )= self.profile.as_ref() {
handler.on_new_message_from_group(self.cwtch.as_ref(), profile, conversation_id.clone(), contact_id.clone(), timestamp_sent.clone(), message.clone())
if let Some(profile) = self.profile.as_ref() {
match &self.behaviour.group_interaction_policy {
GroupInteractionPolicy::Ignore => (),
GroupInteractionPolicy::Accept => handler.on_new_message_from_group(self.cwtch.as_ref(), profile, conversation_id.clone(), contact_id.clone(), timestamp_sent.clone(), message.clone()),
GroupInteractionPolicy::AcceptFromContact=> {
if let Some(contact_convo_id) = profile.find_conversation_id_by_handle(contact_id.clone()) {
if profile.conversations[&contact_convo_id].accepted {
handler.on_new_message_from_group(self.cwtch.as_ref(), profile, conversation_id.clone(), contact_id.clone(), timestamp_sent.clone(), message.clone())
}
}
},
GroupInteractionPolicy::AllowList => {
if self.behaviour.allow_list.peers.contains(&contact_id) {
handler.on_new_message_from_group(self.cwtch.as_ref(), profile, conversation_id.clone(), contact_id.clone(), timestamp_sent.clone(), message.clone())
}
}
}
}
}
Event::ErrUnhandled { name, data } => eprintln!("unhandled event: {}!", name),
@ -219,18 +254,16 @@ impl Imp {
match &self.profile {
Some(profile) => {
let profile_handle = profile.profile_id.clone();
match &self.behaviour.new_contant_policy {
NewContactPolicy::Accept => {
self.cwtch
.accept_conversation(&profile.profile_id, conversation_id);
}
NewContactPolicy::Block => self.cwtch.block_conversation(&profile_handle.clone(), conversation_id),
NewContactPolicy::AllowList(allow_list) => {
NewContactPolicy::AllowList => {
match profile.conversations.get(&conversation_id) {
Some(conversation) => {
if allow_list.peers.contains(&conversation.contact_id) {
if self.behaviour.allow_list.peers.contains(&conversation.contact_id) {
self.cwtch
.accept_conversation(&profile_handle.clone(), conversation_id);
} else {