From b079bccabd6b0c45c47d68cce85e4cf411221272 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:49:36 -0500 Subject: [PATCH] (cont) identity > promote() --- src/core/identity.rs | 403 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 357 insertions(+), 46 deletions(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index a628aa6..d745684 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -21,6 +21,8 @@ use std::cell::RefCell; use std::sync::{Arc}; use tokio::sync::RwLock; +use casual_logger::{Level,Log}; + use super::botmodules::bot_actions::actions_util::BotAR; @@ -115,35 +117,58 @@ pub async fn init(mgr:Arc) match arg1 { - Some(a1) if a1 == String::from("admin") => { - // - BotAdmins can promote admin to give BotAdmin UserRole + Some(a1) if a1 == String::from("-admin") => { + // - [ ] BotAdmins can promote admin to give BotAdmin UserRole let botlock = bot.read().await; - let ta = botlock.get_identity(); - let ta = ta.read().await; - let ta = ta.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))).await; - let ta = ta.unwrap(); - let a = ta.read().await; + let idlock = botlock.get_identity(); + let id = idlock.read().await; + // let ta = ta.getspecialuserroles(String::from("Hello"), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + // let ta = ta.getspecialuserroles(arg2.unwrap().to_string(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + let rolesfut = id.getspecialuserroles(msg.sender.name.to_lowercase(), Some(ChType::Channel(msg.channel_login.to_lowercase()))); + let usrroles = rolesfut.await; + // let ta = ta.unwrap(); + // let a = ta.read().await; // let ta = *ta; // let ta = *ta; // if let Some(a) = *ta { - if a.contains(&UserRole::BotAdmin) { + if usrroles.contains(&UserRole::BotAdmin) { // println!("BotAdmin allowed to promote admin"); botinstance::botlog::debug("BotAdmin allowed to promote admin", Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); { - let botlock = Arc::clone(&bot.read().await.get_identity()); - let idlock = botlock.write().await; + let idlock = Arc::clone(&bot.read().await.get_identity()); + // let idlock = idlock.write().await; + let idlock = idlock.read().await; // let mut idlock = *idlock; - let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + // let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await; + let ta = idlock.promote(arg2.unwrap().to_string().to_lowercase(), None, Some(UserRole::BotAdmin)).await; match ta { - ChangeResult::Success(a) => println!("Succesfully promoted : {a} ;"), - ChangeResult::Failed(a) => println!("Failed to promote : {a} ; "), - ChangeResult::NoChange(a) => println!("No Changes Made : {a} ; "), + ChangeResult::Success(a) => { + // println!("Succesfully promoted : {a} ;"); + botinstance::botlog::debug(&format!("BotAdmin Successful Promotion : {a}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + let outmsg = "o7 Successfully promoted : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg).await; + }, + ChangeResult::Failed(a) => { + // println!("Failed to promote : {a} ; "); + botinstance::botlog::debug(&format!("BotAdmin Failed Promotion : {a}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + let outmsg = "PoroSad failed to promote : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg).await; + }, + ChangeResult::NoChange(a) => { + // println!("No Changes Made : {a} ; "); + botinstance::botlog::debug(&format!("BotAdmin No Change in Promotion : {a}"), + Some("identity.rs > cmd_prommote()".to_string()), Some(&msg)); + let outmsg = "uuh No Promotion Change : ".to_string(); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg).await; + }, } } @@ -151,6 +176,9 @@ pub async fn init(mgr:Arc) } // }, + Some(arg1) => { + + } _ => (), } @@ -334,7 +362,10 @@ pub async fn init(mgr:Arc) // let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None); // println!("Retrieved User Roles >> {:?}",a); // let a = idlock.read().await; - idlock.getspecialuserroles(String::from(targetuser),None).await + // idlock.getspecialuserroles(String::from(targetuser),None).await + + // [ ] If targetchnl is not provided, default to pulling the current channel + idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(msg.channel_login.to_lowercase()))).await }, Some(targetchnl) => { // let bot = Rc::clone(&bot); @@ -348,19 +379,129 @@ pub async fn init(mgr:Arc) // println!("Retrieved User Roles >> {:?}",a); // bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None) // let a = a.read().await; - idlock.getspecialuserroles(String::from(targetuser),None).await + + // [ ] If caller is not a BotAdmin, they can only pull those related to the current channel for the target user + // [ ] If caller is a BotAdmin, allow & return for target channel + // let mut sender_badge:Option = None; + + // for b in &msg.badges { + // if b.name == "moderator" { + // sender_badge = Some(ChatBadge::Mod); + // } else if b.name == "broadcaster" { + // sender_badge = Some(ChatBadge::Broadcaster); + // } + // } + + // match sender_badge { + // Some(ChatBadge::Mod) => { + + // } , + // Some(ChatBadge::Broadcaster) => { + + // } + // _ => { + + // } + // } + + // [x]gets special roles for caller + let callersproles = idlock.getspecialuserroles(msg.sender.name.to_lowercase(),Some(ChType::Channel(targetchnl.to_lowercase().to_string()))).await; + // idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(targetchnl.to_lowercase().to_string()))).await + // let a = callersproles.contains(&UserRole::Mod(ChType::Channel(targetchnl.to_lowercase().to_string()))); + if callersproles.contains(&UserRole::Mod(ChType::Channel(targetchnl.to_lowercase().to_string()))) || + callersproles.contains(&UserRole::SupMod(ChType::Channel(targetchnl.to_lowercase().to_string()))) || + callersproles.contains(&&UserRole::Broadcaster) { + idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(targetchnl.to_lowercase()))).await + // callersproles + } else { + // Otherwise, don't get the target channel, return the current channel instead + idlock.getspecialuserroles(String::from(targetuser),Some(ChType::Channel(msg.channel_login.to_lowercase()))).await + } + + }, }; + // let sproles = idlock.getspecialuserroles(String::from(targetuser),).await; + // println!("Retrieved User Roles >> {:?}",sproles); - botinstance::botlog::debug(&format!("Retrieved User Roles >> {:?}",sproles), + botinstance::botlog::debug(&format!("User roles of Target Chatter >> {:?}",sproles), Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + + // # I believe at this stage I still have botlock active + botinstance::botlog::debug(&format!("Evaluating special roles"), + Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + + // let mut outmsg = String::new(); + + let sproles = sproles; + // let arg2 = arg2.unwrap(); + + let outmsg = if ((targetuser.to_lowercase() == msg.channel_login.to_lowercase()) && arg2.is_none()) || (arg2.is_some() && arg2.unwrap() == targetuser.to_lowercase()) + { + // First evaluates if they're broadcaster + format!("FeelsWowMan they're the broadcaster ") + } + else if sproles.contains(&UserRole::Mod(ChType::Channel(msg.channel_login.to_lowercase()))) || + sproles.contains(&UserRole::SupMod(ChType::Channel(msg.channel_login.to_lowercase()))) || + sproles.contains(&UserRole::BotAdmin) { + format!("Target chatter's user roles are : {:?}",sproles) + } + else { + format!("Target chatter has no special roles LULE ") + }; + + + // if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { + + // } else if sproles.contains(&UserRole::Mod(msg.channel_login.to_lowercase())) { + + // } + + // let outmsg = match sproles + // { + + // // let mut outmsg = String::new(); + // Some(sproles) => { + + // let sproles = sproles.read().await; + + // format!("Target chatter's user roles are : {:?}",sproles) + + // } + // None => { + // // # NOTE : Broadcaster could be included in this + + // // # below is checking if the provided text includes the username + // // let msg = msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase()); + // botinstance::botlog::debug(&format!("Evaluating special roles > channel login : {} ; message text : {} ; ",&msg.channel_login,&msg.message_text), + // Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + // botinstance::botlog::debug(&format!("Evaluating special roles > bool evaluation : {} ", + // msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase())), + // Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + + // if msg.message_text.to_lowercase().contains(&msg.channel_login.to_lowercase()) { + // format!("FeelsWowMan they're the broadcaster ") + // } else { + // format!("Target chatter has no special roles LULE ") + // } + + // } + + // }; // let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot")))); // println!("{:?}",a); + botinstance::botlog::debug(&format!("Chat Say Reply message : {:?}",outmsg), + Some("identity.rs > init > getroles()".to_string()), Some(&msg)); + botlock.botmgrs.chat.say_in_reply_to(&msg, outmsg).await; + + // [ ] NOTE : After the above, I should receive only the roles in the context of the current channel I received this ideally and maybe BotAdmin ; not outside + + } @@ -369,6 +510,8 @@ pub async fn init(mgr:Arc) botinstance::botlog::trace("End of Init MOdule add", Some("identity.rs > init ".to_string()), None); + Log::flush(); + } @@ -458,7 +601,9 @@ impl IdentityManager { // } - if let Some(sender_badge) = sender_badge { + // if let Some(sender_badge) = sender_badge { + // match sender_badge { + // Some(sender_badge) => { // return &self.can_user_run(msg.sender.name.to_owned(), // ChType::Channel(msg.channel_login.to_owned()), // sender_badge, @@ -489,25 +634,38 @@ impl IdentityManager { // * NOTE : We're preferring to pass the ChangeResult up , where we have access to Chat via BotInstance // that have more strained chatting rules - return self.can_user_run(msg.sender.name.to_owned(), - ChType::Channel(msg.channel_login.to_owned()), - sender_badge, - cmdreqroles - ).await - } + // let evalpermissible = self.can_user_run(msg.sender.name.to_owned(), + // ChType::Channel(msg.channel_login.to_owned()), + // sender_badge, + // cmdreqroles + // ).await ; + // evalpermissible + // // } + // None => { + + // } + // here , sender_badge is likely None + // This could be a regular chatter, BotAdmin,SupserMod // [ ] Call can_user_run() // (self,Permissible::Block) - (Permissible::Block,ChangeResult::NoChange("".to_string())) + // (Permissible::Block,ChangeResult::NoChange("".to_string())) + + + self.can_user_run(msg.sender.name.to_owned(), + ChType::Channel(msg.channel_login.to_owned()), + sender_badge, + cmdreqroles + ).await } pub async fn can_user_run(&mut self, usr:String, channelname:ChType, - chat_badge:ChatBadge, + chat_badge:Option, cmdreqroles:Vec // ) -> Result> { ) -> (Permissible,ChangeResult) { @@ -570,7 +728,7 @@ impl IdentityManager { // [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow) // [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow) - ChatBadge::Broadcaster => { + Some(ChatBadge::Broadcaster) => { if cmdreqroles.contains(&UserRole::Broadcaster) || cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) || cmdreqroles.contains(&UserRole::SupMod(ChType::Channel(String::new()))) { @@ -583,7 +741,7 @@ impl IdentityManager { // [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) // [x] If not, assign them UserRole::Mod(channelname::ChType) - ChatBadge::Mod => { + Some(ChatBadge::Mod) => { // println!("Mod Chatbadge detected"); botinstance::botlog::info("Mod Chatbadge detected", @@ -647,7 +805,7 @@ impl IdentityManager { } }, - // _ => (), + _ => (), // Don't handle other roles here } // [x] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow) @@ -751,27 +909,51 @@ impl IdentityManager { // _ => &(emptyvec), // }; - let chatterroles = chatterroles.unwrap(); - let chatterroles = chatterroles.read().await; - let rolemap = &(*chatterroles); + // let chatterroles = chatterroles.unwrap(); + // let chatterroles = chatterroles.read().await; + //let rolemap = &(*chatterroles); + let rolemap = chatterroles; match trg_role { Some(UserRole::Mod(a)) => { - if let Some(trg_chnl) = channel { + if let Some(trg_chnl) = channel.clone() { + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rolemap = chatterroles; // let rolemap = rolemap.unwrap(); if rolemap.contains(&UserRole::Mod(trg_chnl.clone())) { return ChangeResult::NoChange(String::from("Target User already has Target Role")); } // # otherwise, trg_role for the given chnl is not assigned to the trgchatter // chatterroles.push(UserRole::Mod(trg_chnl.clone())); - self.special_roles_users - .write().await - .get_mut(&trgchatter) - .expect("Error getting roles") - .write().await - .push(UserRole::Mod(trg_chnl)); + // let a = self.special_roles_users; + // let b = a.write().await; + // // let c = b.get_mut(&trgchatter); + // let c = (*b).; + + // [x] (!!) AROUND HERE - check if the user exists first, and at least add the user as we're promoting anyway + + { + let mut srulock = self.special_roles_users.write().await; + srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); + botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + { + let mut srulock = self.special_roles_users.write().await; + srulock + .get_mut(&trgchatter) + .expect("Error getting roles") + // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + .write().await + .push(UserRole::Mod(trg_chnl)); + botinstance::botlog::trace(&format!("SRLOCK - 2st write > {:?}",srulock.entry(trgchatter.clone())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } return ChangeResult::Success(String::from("Promotion Successful")); } @@ -779,7 +961,61 @@ impl IdentityManager { }, Some(UserRole::SupMod(a)) => (), - Some(UserRole::BotAdmin) => (), + Some(UserRole::BotAdmin) => { + + let chatterroles = self.getspecialuserroles(trgchatter.clone(), channel.clone()).await; + let rolemap = chatterroles; + + botinstance::botlog::trace(&format!("Target Role : BotAdmin"), + Some("identity.rs > promote()".to_string()), None); + + // [x] 1. Check their roles first if they already have botadmin + // [x] 2. Know that prior to promote() , BotAdmins should have been validated before being able to pass the BotAdmin target + + // [x] 1. Check target chatter's roles first if they already have botadmin + botinstance::botlog::trace(&format!("Eval rolemap.contains(BotAdmin) : {}",rolemap.contains(&UserRole::BotAdmin)), + Some("identity.rs > promote()".to_string()), None); + + botinstance::botlog::trace(&format!("Eval rolemap.contains(BotAdmin) > Rolemap : {:?}",rolemap), + Some("identity.rs > promote()".to_string()), None); + + // [ ] (!) This seems to be an issue - rolemap by this point is blank + if rolemap.contains(&UserRole::BotAdmin) { + return ChangeResult::NoChange(String::from("Target User already has Target Role")); + } + // # otherwise, trg_role for the given chnl is not assigned to the trgchatter + // chatterroles.push(UserRole::Mod(trg_chnl.clone())); + + // [x] (!!) AROUND HERE - check if the user exists first, and at least add the user as we're promoting anyway + + { + let mut srulock = self.special_roles_users.write().await; + + srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![]))); + botinstance::botlog::trace(&format!("SRLOCK - 1st write > {:?}",srulock.entry(trgchatter.clone())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + + { + + let mut srulock = self.special_roles_users.write().await; + + srulock + .get_mut(&trgchatter) + // !! [ ] Unsure what happens if promoting a chatter that doesn't exist at + .expect("Error getting roles") + .write().await + .push(UserRole::BotAdmin); + botinstance::botlog::trace(&format!("SRLOCK - 2nd write > {:?}",srulock.entry(trgchatter.clone())), + Some("identity.rs > promote()".to_string()), None); + Log::flush(); + } + botinstance::botlog::trace(&format!("Target Role : BotAdmin >> Successful"), + Some("identity.rs > promote()".to_string()), None); + + return ChangeResult::Success(String::from("Promotion Successful")); + }, Some(_) => (), None => (), } @@ -856,27 +1092,102 @@ impl IdentityManager { ChangeResult::Success(String::from("TEST > Promotion Successful")) } - pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { + // pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Option>>> { + pub async fn getspecialuserroles(&self,chattername:String,channel:Option) -> Vec { /* Note : Ideally this be called for a given chatter name ? */ + // [ ] !!! TODO: I don't think below is evaluating by given channel + botinstance::botlog::debug(&format!("IN VARS > chattername {} ; channel {:?}", chattername,channel), + Some("IdentityManager > getspecialuserroles()".to_string()), None); + + // resulting vector + let mut evalsproles = vec![]; let chattername = chattername.to_lowercase(); + // Checks if broadcaster + let channel_out = match channel { + Some(channel_tmp) => { + match channel_tmp { + ChType::Channel(channel_tmp) => { + // In this block, Some input channel is given + // We're comparing the channel name with chattername to determine if they're a broadcaster + if chattername == channel_tmp.to_lowercase() { + evalsproles.push(UserRole::Broadcaster); + } + + Some(ChType::Channel(channel_tmp)) + }, + // _ => () + } + } + None => None, + }; + + let rolesa = Arc::clone(&self.special_roles_users); let a = rolesa.read().await; // let a = Arc::clone(a) let a = a; - let outr = &(*a); - let outr = outr.get(&chattername); - match outr { - Some(a) => Some(Arc::clone(a)), - None => None, + let vecroles = &(*a); + let vecroles = vecroles.get(&chattername); + match vecroles { + Some(a) => { + // [ ] This needs to take the user roles for the user, then yield only the one for the channel if channel is explicitely provided + // Some(Arc::clone(a)) + match channel_out { + Some(channel) => { + // let eval = a.read().await.contains(&UserRole::Mod(channel)); + // let eval = a.read().await.contains(&UserRole::SupMod(channel)); + botinstance::botlog::debug(&format!("INTERNAL > All Roles found {:?}", &a), + Some("IdentityManager > getspecialuserroles()".to_string()), None); + + // a.read().await.contains(&UserRole::BotAdmin) + botinstance::botlog::trace(&format!("INTERNAL > eval special roles contains botadmin : {:?}", a.read().await.contains(&UserRole::BotAdmin)), + Some("IdentityManager > getspecialuserroles()".to_string()), None); + + if a.read().await.contains(&UserRole::BotAdmin) { + evalsproles.push(UserRole::BotAdmin); + } + if a.read().await.contains(&UserRole::Mod(channel.clone())) { + evalsproles.push(UserRole::Mod(channel.clone())); + } + if a.read().await.contains(&UserRole::SupMod(channel.clone())) { + evalsproles.push(UserRole::SupMod(channel.clone())); + } + // else {}; + + } + None => { + // here , do nothing if the channel not provided + // [ ] TODO : Future is to provide all maybe ? + // ... no I think missing this is an issue for when the flag is -admin and channel is None? + // + // => 02.13 - Decided That None is provided as a Channel, we can output non-channel related roles like BotAdmin + if a.read().await.contains(&UserRole::BotAdmin) { + evalsproles.push(UserRole::BotAdmin); + } + } + } + + }, + None => { + // here, the user has no special listed roles. Note though Broadcaster is not stored in special roles + // Do nothing in this case + // There may be an issue if the chattername does not exist at the moment in special_roles_users + // In this case, evalsproles would only contain Broadcaster flags if any + }, } + botinstance::botlog::debug(&format!("OUT > evalsproles {:?}", &evalsproles), + Some("IdentityManager > getspecialuserroles()".to_string()), None); + + return evalsproles; + }