diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index fb57dfc..568683a 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -77,7 +77,7 @@ pub async fn init(mgr: Arc) { /* There should be additional validation checks - BotAdmins can only run instance level (-i) enables - - If BotAdmins need to enable/disable at instance level, they must Promote themselves to be a Mod at least + - If BotAdmins need to enable/disable at Channel level, they must Promote themselves to be a Mod at least - Other Special Roles (Mod,SupMod,Broadcaster) can run without issues to enable the module at Channel Level */ @@ -107,11 +107,102 @@ pub async fn init(mgr: Arc) { */ - /* - exec_enable(Self,requestor,requestor_badge,trg_module,Channel) -> ChangeResult + + // [ ] Unwraps arguments from message + + let (arg1, arg2) = { + + let mut argv = msg.message_text.split(' '); + + argv.next(); // Skip the command name + + let arg1 = argv.next(); + + let arg2 = argv.next(); + + (arg1, arg2) + }; + + + /* -- Related function to call later + exec_enable( + &self, + requestor: String, + requestor_badge: Option, + trg_module: ModType, + // channel: Option, + trg_level: StatusLvl, + bot: BotAR, + ) -> ChangeResult */ + // [ ] requestor: String, + let requester = msg.clone().sender.name; + + + // [ ] requestor_badge: Option, + + let mut requestor_badge_mut: Option = None; + + for b in &msg.badges { + if b.name == "moderator" { + requestor_badge_mut = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + requestor_badge_mut = Some(ChatBadge::Broadcaster); + } + } + + let requestor_badge = requestor_badge_mut; + + + // [ ] trg_module: ModType, + // - [ ] Need to validate an actual ModType - otherwise, fail or exit the cmd + + let trg_module = if (arg1 == Some("-i")) || (arg1 == Some("-f")) { arg2 } else { arg1 }; + + if let Some(trg_module_str) = trg_module { + + let botlock = bot.read().await; + let modmgr = Arc::clone(&botlock.botmodules); + let modlist = modmgr.moduleslist().await; + let rslt = modlist.get(&ModType::BotModule(trg_module_str.to_string())); + + if let None = rslt { + + let outmsg = "uuh module doesn't exist"; + + botlog::debug( + outmsg, + Some("botmodules.rs > cmd_enable()".to_string()), + Some(&msg), + ); + + botlock + .botmgrs + .chat + .say_in_reply_to(&msg, outmsg.to_string()) + .await; + + return; + } + + } + + + // [ ] trg_level: StatusLvl, + + let currchnl = msg.channel_login.to_lowercase(); + + let trg_level = + if arg1 == Some("-i") { StatusLvl::Instance } + else if arg1 == Some("-f") { StatusLvl::Instance } + else { StatusLvl::Ch(ChType::Channel(currchnl)) } + ; + + + + } @@ -138,10 +229,10 @@ pub async fn init(mgr: Arc) { async fn cmd_disable(bot: BotAR, msg: PrivmsgMessage) { /* There should be additional validation checks - - BotAdmins can only run instance level (-i) disables - - If BotAdmins need to enable/disable at instance level, they must Promote themselves to be a Mod at least + - BotAdmins can only run instance level (-i) disables and (-f) force disable + - If BotAdmins need to enable/disable at Channel level, they must Promote themselves to be a Mod at least - Other Special Roles (Mod,SupMod,Broadcaster) can run without issues to disable the module at Channel Level - */ + */ /* disable -i // disables at Instance @@ -149,6 +240,26 @@ pub async fn init(mgr: Arc) { disable -f // force disables (instance and enabled are removed) */ + /* + + 1. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster) + 1. can_user_run for cmdreqRoles including BotAdmin & not can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) + 1a. , and has no special flags (-i / -f) , return a Failure recommending BotAdmin promote themselves first + 1b. , and is -i (to instance) , return a Success + 1c. , and is -f (forced) , return a Success + + 2. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) + 2. not can_user_run for cmdreqRoles including BotAdmin & can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) + 2a. , and has no special flags (-i / -f) , return a Success + 2b. , and is -i (to instance) , return a Failure they are not allowed + 2c. , and is -f (forced) , return a Failure they are not allowed + + 3. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin + 3. can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) & can_user_run for cmdreqRoles including BotAdmin + 3a. , and has no special flags (-i / -f) , return a Success + 3b. , and is -i (to instance) , return a Success + 3c. , and is -f (forced) , return a Success + */ } @@ -348,6 +459,24 @@ impl ModulesManager { mgrarc } + + pub async fn moduleslist(&self) -> HashMap + { + + // let db = Arc::clone(&self.statusdb); + let db = self.statusdb.clone(); + let dblock = db.read().await; + + let mut outmap = HashMap::new(); + + for (k,v) in &(*dblock) { + let (mgrp,_) = v; + let mtype = k; + outmap.insert((*mtype).clone(), (*mgrp).clone()); + } + outmap + } + pub async fn modstatus(&self, in_module: ModType, in_chnl: ChType) -> StatusType { // Example usage : botmanager.modstatus( // BotModule("GambaCore"), @@ -641,7 +770,161 @@ impl ModulesManager { - ChangeResult::NoChange("ERROR : Not implemented yet".to_string()) + ChangeResult::Failed("ERROR : Not implemented yet".to_string()) + } + + + pub async fn exec_disable( + &self, + requestor: String, + requestor_badge: Option, + trg_module: ModType, + // channel: Option, + trg_level: StatusLvl, + force: bool, + bot: BotAR, + ) -> ChangeResult + { + + /* + + 1. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster) + 1. can_user_run for cmdreqRoles including BotAdmin & not can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) + 1a. , and has no special flags (-i / -f) , return a Failure recommending BotAdmin promote themselves first + 1b. , and is -i (to instance) , return a Success + 1c. , and is -f (forced) , return a Success + + 2. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) + 2. not can_user_run for cmdreqRoles including BotAdmin & can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) + 2a. , and has no special flags (-i / -f) , return a Success + 2b. , and is -i (to instance) , return a Failure they are not allowed + 2c. , and is -f (forced) , return a Failure they are not allowed + + 3. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin + 3. can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) & can_user_run for cmdreqRoles including BotAdmin + 3a. , and has no special flags (-i / -f) , return a Success + 3b. , and is -i (to instance) , return a Success + 3c. , and is -f (forced) , return a Success + */ + + + + let botlock = bot.read().await; + let id = botlock.get_identity(); + let mut idlock = id.write().await; + + // if trg_level = StatusLvl::Instance , the temp_chnl = the broadcaster's or the chatter's + + let arb_chnl = match trg_level.clone() { + StatusLvl::Instance => ChType::Channel(requestor.to_lowercase()), + StatusLvl::Ch(a) => a, + }; + + const OF_CMD_CHANNEL:ChType = Channel(String::new()); + + let (admin_level_access,_) = idlock.can_user_run(requestor.clone(), arb_chnl.clone(), requestor_badge.clone(), + vec![ + identity::UserRole::BotAdmin, + ]).await; + + + let (chnl_elevated_access,_) = idlock.can_user_run(requestor, arb_chnl, requestor_badge.clone(), + vec![ + identity::UserRole::Mod(OF_CMD_CHANNEL), + identity::UserRole::SupMod(OF_CMD_CHANNEL), + identity::UserRole::Broadcaster, + ]).await; + + + /* + + [ ] 1. If CmdSender is BotAdmin but not (Mod,SupMod,Broadcaster) + 1. can_user_run for cmdreqRoles including BotAdmin & not can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) + 1a. , and is -f (forced) , return a Success + 1b. , and is -i (to instance) , return a Success + 1c. , and has no special flags (-i / -f) , return a Failure recommending BotAdmin promote themselves first + + */ + + if let Permissible::Allow = admin_level_access { + if let Permissible::Block = chnl_elevated_access { + if force { + self.force_disable(trg_module.clone()).await; + return ChangeResult::Success("Forced Disable".to_string()); + } else { + match trg_level { + StatusLvl::Instance => { + self.set_instance_disabled(trg_module.clone()).await; + ChangeResult::Success("Disabled at Instance Level".to_string()) + }, + StatusLvl::Ch(_) => { + ChangeResult::Failed("Promote yourself Temporarily First".to_string()) + }, + }; + } + } + } + + + /* + [ ] 2. If CmdSender not a BotAdmin but is (Mod,SupMod,Broadcaster) + 2. not can_user_run for cmdreqRoles including BotAdmin & can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) + 2a. , and is -f (forced) , return a Failure they are not allowed + 2b. , and is -i (to instance) , return a Failure they are not allowed + 2c. , and has no special flags (-i / -f) , return a Success + + */ + + if let Permissible::Block = admin_level_access { + if let Permissible::Allow = chnl_elevated_access { + if force { + return ChangeResult::Failed("You're not allowed".to_string()); + } else { + match trg_level.clone() { + StatusLvl::Instance => { + ChangeResult::Failed("You're not allowed".to_string()) + }, + StatusLvl::Ch(in_chnl) => { + self.set_ch_disabled(trg_module.clone(), in_chnl).await; + ChangeResult::Success("Disabled at Channel Level".to_string()) + }, + }; + } + } + } + + + /* + [ ] 3. If CmdSender is (Mod,SupMod,Broadcaster) and a BotAdmin + 3. can_user_run for cmdreqRoles (Mod,SupMod,Broadcaster) & can_user_run for cmdreqRoles including BotAdmin + 3a. , and is -f (forced) , return a Success + 3b. , and is -i (to instance) , return a Success + 3c. , and has no special flags (-i / -f) , return a Success + + */ + + if let Permissible::Allow = admin_level_access { + if let Permissible::Allow = chnl_elevated_access { + if force { + self.force_disable(trg_module.clone()).await; + return ChangeResult::Success("Forced Disable".to_string()); + } else { + match trg_level { + StatusLvl::Instance => { + self.set_instance_disabled(trg_module.clone()).await; + ChangeResult::Success("Disabled at Instance Level".to_string()) + }, + StatusLvl::Ch(in_chnl) => { + self.set_ch_disabled(trg_module.clone(), in_chnl).await; + ChangeResult::Success("Disabled at Channel Level".to_string()) + }, + }; + } + } + } + + + ChangeResult::Failed("ERROR : Not implemented yet".to_string()) } pub async fn set_instance_disabled(&self, in_module: ModType) -> (StatusType,ChangeResult) { @@ -1003,6 +1286,17 @@ mod core_modulesmanager { use super::*; + #[test] + fn WIP_case_insensitive_test() { + Log::set_file_ext(Extension::Log); + assert_eq!( + BotModule("test".to_string()), + BotModule("Test".to_lowercase()) + ); + } + + + /* Possible Tests