2024-01-29 06:18:27 -05:00
2024-02-04 14:28:37 -05:00
use std ::borrow ::Borrow ;
2024-01-29 06:18:27 -05:00
use std ::collections ::HashMap ;
2024-01-29 12:41:26 -05:00
use std ::error ::Error ;
2024-01-29 11:09:33 -05:00
use crate ::core ::botmodules ::{ ModulesManager , Listener , BotModule , BotActionTrait , BotCommand } ;
use crate ::core ::botmodules ::bot_actions ::actions_util ;
2024-02-18 15:23:58 -05:00
use crate ::core ::botinstance ::{ self , botlog , BotInstance , ChType } ;
2024-02-04 14:28:37 -05:00
use futures ::lock ::Mutex ;
2024-01-29 22:57:07 -05:00
use twitch_irc ::message ::{ Badge , PrivmsgMessage } ;
2024-01-29 11:09:33 -05:00
2024-02-18 15:23:58 -05:00
// use crate::core::botmodules::ChType;
2024-01-29 12:41:26 -05:00
2024-02-04 14:28:37 -05:00
use crate ::core ::botinstance ::ArcBox ;
use std ::rc ::Rc ;
use std ::cell ::RefCell ;
2024-02-12 05:25:38 -05:00
use std ::sync ::{ Arc } ;
use tokio ::sync ::RwLock ;
2024-02-13 19:49:36 -05:00
use casual_logger ::{ Level , Log } ;
2024-02-04 14:28:37 -05:00
2024-02-12 01:25:12 -05:00
use super ::botmodules ::bot_actions ::actions_util ::BotAR ;
2024-01-29 06:18:27 -05:00
fn adminvector ( ) -> Vec < String > {
vec! [ String ::from ( " ModulatingForce " ) ]
2024-02-18 15:23:58 -05:00
//vec![]
2024-01-29 06:18:27 -05:00
}
2024-02-04 14:28:37 -05:00
// pub fn init(mgr:&mut ModulesManager)
2024-02-12 02:34:32 -05:00
pub async fn init ( mgr :Arc < ModulesManager > )
2024-01-29 11:09:33 -05:00
{
2024-02-13 10:11:49 -05:00
// println!("Went into Identiy Module init");
botinstance ::botlog ::trace ( " Went into Identiy Module init " ,
Some ( " identity.rs > init() " . to_string ( ) ) , None ) ;
2024-02-12 01:25:12 -05:00
2024-02-12 02:34:32 -05:00
// let a = actions_util::asyncbox(cmd_promote) ;
let tempb = BotCommand {
2024-01-29 11:09:33 -05:00
module : BotModule ( String ::from ( " identity " ) ) ,
command : String ::from ( " promote " ) , // command call name
alias : vec ! [ ] , // String of alternative names
exec_body : actions_util ::asyncbox ( cmd_promote ) ,
help : String ::from ( " promote " ) ,
2024-01-30 09:13:59 -05:00
required_roles : vec ! [
UserRole ::Mod ( ChType ::Channel ( String ::new ( ) ) ) ,
UserRole ::SupMod ( ChType ::Channel ( String ::new ( ) ) ) ,
UserRole ::Broadcaster ,
UserRole ::BotAdmin ,
] ,
2024-02-12 02:34:32 -05:00
} ;
2024-02-12 05:25:38 -05:00
tempb . add_to_modmgr ( Arc ::clone ( & mgr ) ) . await ;
2024-01-29 11:09:33 -05:00
2024-02-12 01:25:12 -05:00
async fn cmd_promote ( bot :BotAR , msg :PrivmsgMessage ) -> ( )
2024-02-04 14:28:37 -05:00
{
2024-01-29 11:09:33 -05:00
//println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
2024-02-13 10:11:49 -05:00
// println!("Called cmd promote");
botinstance ::botlog ::trace ( " Called cmd promote " ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-01-29 12:41:26 -05:00
2024-01-31 21:30:08 -05:00
// -- If the BotCommand.command was called (e.g., promote) & required roles were validated OUTSIDE of this call
// , this is the current function body to execute
2024-01-30 15:07:40 -05:00
/*
- ` promote ` / ` demote `
- [ ] ` SupMod ` & ` Broadcaster ` & ` BotAdmin ` can run
- [ ] ` UserRole ` s that can run , can
- [ ] run ` promote ` on a regular ` Chatter ` to make them a ` Mod `
- [ ] run ` demote ` on a ` Mod ` to make them a ` Chatter `
- [ ] Only ` BotAdmin ` can :
- [ ] target themselves to ` promote ` / ` demote ` , in the case that they want to make themselves either a ` Mod ` or ` SupMod ` for the channel temporarily
- [ ] ` promote admin < Chatter > ` to assign them ` BotAdmin ` role
2024-02-14 01:09:55 -05:00
- ` [ ] Broadcaster ` & ` BotAdmin ` can ` demote ` a ` SupMod ` to make them a ` Mod ` or ` promote ` the other way
2024-01-30 15:07:40 -05:00
* /
2024-01-31 21:30:08 -05:00
/*
Usage :
2024-02-14 01:09:55 -05:00
promote < user >
2024-01-31 21:30:08 -05:00
2024-02-14 01:09:55 -05:00
demote < user >
2024-01-31 21:30:08 -05:00
2024-02-14 01:09:55 -05:00
promote - admin < user >
2024-01-31 21:30:08 -05:00
* /
2024-02-04 14:28:37 -05:00
2024-02-13 10:11:49 -05:00
// println!("{}",msg.message_text);
2024-02-14 01:09:55 -05:00
botinstance ::botlog ::trace ( & format! ( " Twich Message > {} " , msg . message_text ) ,
Some ( " identity.rs > cmd_promote() " . to_string ( ) ) , None ) ;
2024-02-13 10:11:49 -05:00
2024-02-18 15:23:58 -05:00
let sendername = msg . clone ( ) . sender . name ;
2024-02-01 08:40:09 -05:00
let mut argv = msg . message_text . split ( " " ) ;
argv . next ( ) ; // Skip the command name
let arg1 = argv . next ( ) ;
let arg2 = argv . next ( ) ;
let mut sender_badge :Option < ChatBadge > = 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 ) ;
}
}
2024-02-18 15:23:58 -05:00
let targetchnl = msg . channel_login . to_lowercase ( ) ;
/*
[ x ] 1. Get trgusr ( regardless of - admin flag )
[ x ] 2. promote trguser
[ x ] 3. Output resulting change
* /
// [x] 1. Get trgusr (regardless of -admin flag)
let targetusr = if arg1 = = Some ( " -admin " ) { arg2 } else { arg1 } ;
2024-02-01 08:40:09 -05:00
2024-02-18 15:23:58 -05:00
// [x] 2. promote trguser
// [x] Get a required lock first
let botlock = bot . read ( ) . await ;
let id = botlock . get_identity ( ) ;
let idlock = id . read ( ) . await ;
let rslt = match targetusr {
Some ( targetusr ) = > {
botinstance ::botlog ::debug ( & format! ( " running promote() " ) ,
Some ( " identity.rs > cmd_promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
let target_bot_admin_role = if arg1 = = Some ( " -admin " ) { Some ( UserRole ::BotAdmin ) } else { None } ;
idlock . promote (
sendername . clone ( ) ,
& sender_badge ,
targetusr . to_string ( ) ,
Some ( ChType ::Channel ( targetchnl . clone ( ) ) ) ,
target_bot_admin_role ,
) . await
}
None = > {
botinstance ::botlog ::debug ( & format! ( " No Targer User argument " ) ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
ChangeResult ::NoChange ( " No Targer User " . to_string ( ) )
}
} ;
// [x] 3. Output resulting change
match rslt {
ChangeResult ::Success ( a ) = > {
// println!("Succesfully promoted : {a} ;");
let outmsg = & format! ( " o7 Successfully promoted : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
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 . to_string ( ) ) . await ;
} ,
ChangeResult ::Failed ( a ) = > {
// println!("Failed to promote : {a} ; ");
let outmsg = & format! ( " PoroSad failed to promote : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
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 . to_string ( ) ) . await ;
} ,
ChangeResult ::NoChange ( a ) = > {
// println!("No Changes Made : {a} ; ");
let outmsg = & format! ( " uuh No Promotion Change : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
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 . to_string ( ) ) . await ;
} ,
}
/*
2024-02-01 08:40:09 -05:00
match arg1 {
2024-02-13 19:49:36 -05:00
Some ( a1 ) if a1 = = String ::from ( " -admin " ) = > {
2024-02-14 01:09:55 -05:00
// - [x] BotAdmins can promote admin to give BotAdmin UserRole
2024-02-12 14:54:35 -05:00
2024-02-12 01:25:12 -05:00
let botlock = bot . read ( ) . await ;
2024-02-13 19:49:36 -05:00
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())));
2024-02-14 01:09:55 -05:00
let rolesfut = id . getspecialuserroles (
msg . sender . name . to_lowercase ( ) ,
Some ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) ;
2024-02-13 19:49:36 -05:00
let usrroles = rolesfut . await ;
// let ta = ta.unwrap();
// let a = ta.read().await;
2024-02-12 05:25:38 -05:00
// let ta = *ta;
// let ta = *ta;
// if let Some(a) = *ta {
2024-02-01 08:40:09 -05:00
2024-02-13 19:49:36 -05:00
if usrroles . contains ( & UserRole ::BotAdmin ) {
2024-02-13 10:11:49 -05:00
// println!("BotAdmin allowed to promote admin");
botinstance ::botlog ::debug ( " BotAdmin allowed to promote admin " ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-04 14:28:37 -05:00
{
2024-02-12 14:54:35 -05:00
2024-02-13 19:49:36 -05:00
let idlock = Arc ::clone ( & bot . read ( ) . await . get_identity ( ) ) ;
// let idlock = idlock.write().await;
let idlock = idlock . read ( ) . await ;
2024-02-12 01:25:12 -05:00
// let mut idlock = *idlock;
2024-02-13 19:49:36 -05:00
// 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 ;
2024-02-04 14:28:37 -05:00
match ta {
2024-02-13 19:49:36 -05:00
ChangeResult ::Success ( a ) = > {
// println!("Succesfully promoted : {a} ;");
2024-02-14 01:09:55 -05:00
let outmsg = & format! ( " o7 Successfully promoted : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
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 . to_string ( ) ) . await ;
2024-02-13 19:49:36 -05:00
} ,
ChangeResult ::Failed ( a ) = > {
// println!("Failed to promote : {a} ; ");
2024-02-14 01:09:55 -05:00
let outmsg = & format! ( " PoroSad failed to promote : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
2024-02-13 19:49:36 -05:00
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-14 01:09:55 -05:00
// let outmsg = "PoroSad failed to promote : ".to_string();
botlock . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
2024-02-13 19:49:36 -05:00
} ,
ChangeResult ::NoChange ( a ) = > {
// println!("No Changes Made : {a} ; ");
2024-02-14 01:09:55 -05:00
let outmsg = & format! ( " uuh No Promotion Change : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
2024-02-13 19:49:36 -05:00
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-14 01:09:55 -05:00
// let outmsg = "uuh No Promotion Change : ".to_string();
botlock . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
2024-02-13 19:49:36 -05:00
} ,
2024-02-04 14:28:37 -05:00
}
2024-02-01 08:40:09 -05:00
}
2024-02-14 01:09:55 -05:00
} // if usrroles.contains(&UserRole::BotAdmin)
2024-02-01 08:40:09 -05:00
}
2024-02-12 14:54:35 -05:00
2024-02-12 05:25:38 -05:00
// },
2024-02-13 19:49:36 -05:00
Some ( arg1 ) = > {
2024-02-14 01:09:55 -05:00
// In the case of promoting another chatter
// Check caller's roles
// Check targer chatter's roles
// - Also check if target chatter alread has target roles
// if caller's role is Broadcaster, SupMod, BotAdmin , they can Promote target Chatters to become Mod (i.e., the target user is not a Mod,SupMod,BotAdmin)
// if caller is BotAdmin, they can promote BotAdmins to Mod
// if caller's role is Broadcaster, BotAdmin, they can Promote target Mod to SupMod
botinstance ::botlog ::debug ( & format! ( " Evaluating arg1: {arg1} " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
let idlock = Arc ::clone ( & bot . read ( ) . await . get_identity ( ) ) ;
let idlock = idlock . read ( ) . await ;
// let ta = idlock.promote(msg.sender.name.to_lowercase(), None, Some(UserRole::BotAdmin)).await;
let senderroles = idlock . getspecialuserroles (
msg . sender . name . to_lowercase ( ) ,
Some ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) . await ;
let trgusrroles = idlock . getspecialuserroles (
arg1 . to_lowercase ( ) ,
Some ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) . await ;
botinstance ::botlog ::debug ( & format! ( " Ready to evaluate sender and targer user roles " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
botinstance ::botlog ::trace ( & format! ( " Related Vars : sender roles : {:?} ; targer usr roles : {:?} " ,
senderroles , trgusrroles ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
if ( senderroles . contains ( & UserRole ::Broadcaster ) | |
senderroles . contains ( & UserRole ::SupMod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) | |
senderroles . contains ( & UserRole ::BotAdmin ) ) & &
( ! trgusrroles . contains ( & UserRole ::Broadcaster ) & &
// !trgusrroles.contains(&UserRole::BotAdmin) && // target users that are BotAdmins can promote themselves to Mod or SupMod
! trgusrroles . contains ( & UserRole ::SupMod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) & &
! trgusrroles . contains ( & UserRole ::Mod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) )
)
{
// if caller's role is Broadcaster, SupMod, BotAdmin , they can Promote target Chatters to become Mod (i.e., the target user is not a Mod,SupMod,BotAdmin)
botinstance ::botlog ::trace ( & format! ( " Attempting promote... " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
let ta = idlock . promote ( arg1 . to_string ( ) . to_lowercase ( ) ,
Some ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ,
Some ( UserRole ::Mod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) ) . await ;
match ta {
ChangeResult ::Success ( a ) = > {
// println!("Succesfully promoted : {a} ;");
let outmsg = & format! ( " Successful Promotion : {a} " ) ;
botinstance ::botlog ::debug ( & format! ( " Successful Promotion : {a} " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// let outmsg = "o7 Successfully promoted : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::Failed ( a ) = > {
// println!("Failed to promote : {a} ; ");
let outmsg = & format! ( " PoroSad failed to promote : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
// Log::flush();
// let outmsg = "PoroSad failed to promote : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::NoChange ( a ) = > {
// println!("No Changes Made : {a} ; ");
2024-02-18 15:23:58 -05:00
let outmsg = & format! ( " uuh Not making any changes : {a} " ) ;
2024-02-14 01:09:55 -05:00
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// let outmsg = "uuh No Promotion Change : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
}
} else if trgusrroles . contains ( & UserRole ::Mod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) & &
( senderroles . contains ( & UserRole ::Broadcaster ) | |
senderroles . contains ( & UserRole ::BotAdmin ) )
{
botinstance ::botlog ::trace ( & format! ( " Attempting promote... " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
2024-02-18 15:23:58 -05:00
// broadcaster & botadmins can make mods into SupMod
2024-02-14 01:09:55 -05:00
let ta = idlock . promote ( arg1 . to_string ( ) . to_lowercase ( ) ,
Some ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ,
2024-02-18 15:23:58 -05:00
Some ( UserRole ::SupMod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) ) . await ;
2024-02-14 01:09:55 -05:00
match ta {
ChangeResult ::Success ( a ) = > {
// println!("Succesfully promoted : {a} ;");
let outmsg = & format! ( " Successful Promotion : {a} " ) ;
botinstance ::botlog ::debug ( & format! ( " Successful Promotion : {a} " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// let outmsg = "o7 Successfully promoted : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::Failed ( a ) = > {
// println!("Failed to promote : {a} ; ");
let outmsg = & format! ( " PoroSad failed to promote : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
// Log::flush();
// let outmsg = "PoroSad failed to promote : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::NoChange ( a ) = > {
// println!("No Changes Made : {a} ; ");
let outmsg = & format! ( " uuh No Change in Promotion : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// let outmsg = "uuh No Promotion Change : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
}
} else if trgusrroles . contains ( & UserRole ::Broadcaster ) // This should always be NoChange
{
botinstance ::botlog ::trace ( & format! ( " Attempting promote... " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// broadcaster & botadmins can make mods into superadmins
let ta = idlock . promote ( arg1 . to_string ( ) . to_lowercase ( ) ,
Some ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ,
Some ( UserRole ::Mod ( ChType ::Channel ( msg . channel_login . to_lowercase ( ) ) ) ) ) . await ;
match ta {
ChangeResult ::Success ( a ) = > {
// println!("Succesfully promoted : {a} ;");
let outmsg = & format! ( " Successful Promotion : {a} " ) ;
botinstance ::botlog ::debug ( & format! ( " Successful Promotion : {a} " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// let outmsg = "o7 Successfully promoted : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::Failed ( a ) = > {
// println!("Failed to promote : {a} ; ");
let outmsg = & format! ( " PoroSad failed to promote : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
// Log::flush();
// let outmsg = "PoroSad failed to promote : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::NoChange ( a ) = > {
// println!("No Changes Made : {a} ; ");
let outmsg = & format! ( " uuh No Change in Promotion : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , Some ( & msg ) ) ;
Log ::flush ( ) ;
// let outmsg = "uuh No Promotion Change : ".to_string();
bot . read ( ) . await . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
}
}
else {
let s = botlog ::fatal ( " Reached unreachable else " ,
Some ( " identity > cmd_promote() " . to_string ( ) ) , Some ( & msg ) ) ;
panic! ( " {} " , s ) ;
} ;
Log ::flush ( ) ;
2024-02-13 19:49:36 -05:00
}
2024-02-12 05:25:38 -05:00
_ = > ( ) ,
2024-02-01 08:40:09 -05:00
}
let arg2 = argv . next ( ) ;
let targetchnl = arg2 ;
2024-02-18 15:23:58 -05:00
* /
2024-02-01 08:40:09 -05:00
2024-02-14 01:09:55 -05:00
botinstance ::botlog ::trace ( & format! ( " End of cmd_promote() " ) ,
Some ( " identity.rs > cmd_prommote() " . to_string ( ) ) , None ) ;
2024-01-29 11:09:33 -05:00
}
2024-02-12 02:34:32 -05:00
// BotCommand {
// module : BotModule(String::from("identity")),
// command : String::from("demote"), // command call name
// alias : vec![], // String of alternative names
// exec_body : actions_util::asyncbox(cmd_demote) ,
// help : String::from("demote"),
// required_roles : vec![
// UserRole::Mod(ChType::Channel(String::new())),
// UserRole::SupMod(ChType::Channel(String::new())),
// UserRole::Broadcaster,
// UserRole::BotAdmin,
// ],
// }.add_to_modmgr(Arc::clone(&mgr));
let tempb = BotCommand {
2024-01-29 11:09:33 -05:00
module : BotModule ( String ::from ( " identity " ) ) ,
command : String ::from ( " demote " ) , // command call name
alias : vec ! [ ] , // String of alternative names
exec_body : actions_util ::asyncbox ( cmd_demote ) ,
help : String ::from ( " demote " ) ,
2024-01-30 09:13:59 -05:00
required_roles : vec ! [
UserRole ::Mod ( ChType ::Channel ( String ::new ( ) ) ) ,
UserRole ::SupMod ( ChType ::Channel ( String ::new ( ) ) ) ,
UserRole ::Broadcaster ,
UserRole ::BotAdmin ,
] ,
2024-02-12 02:34:32 -05:00
} ;
tempb . add_to_modmgr ( Arc ::clone ( & mgr ) ) . await ;
2024-01-29 11:09:33 -05:00
2024-02-12 01:25:12 -05:00
// async fn cmd_demote(mut _chat:Arc<Mutex<BotInstance>>,_msg:PrivmsgMessage) {
2024-02-18 15:23:58 -05:00
async fn cmd_demote ( mut bot :BotAR , msg :PrivmsgMessage ) {
2024-02-13 10:11:49 -05:00
// println!("Called cmd demote");
botinstance ::botlog ::debug ( " Called cmd demote " ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-14 01:09:55 -05:00
Log ::flush ( ) ;
2024-02-14 09:21:50 -05:00
2024-02-14 01:09:55 -05:00
// -- If the BotCommand.command was called (e.g., demote) & required roles were validated OUTSIDE of this call
// , this is the current function body to execute
/*
- ` promote ` / ` demote `
- [ ] ` SupMod ` & ` Broadcaster ` & ` BotAdmin ` can run
- [ ] ` UserRole ` s that can run , can
- [ ] run ` promote ` on a regular ` Chatter ` to make them a ` Mod `
- [ ] run ` demote ` on a ` Mod ` to make them a ` Chatter `
- [ ] Only ` BotAdmin ` can :
- [ ] target themselves to ` promote ` / ` demote ` , in the case that they want to make themselves either a ` Mod ` or ` SupMod ` for the channel temporarily
- [ ] ` promote admin < Chatter > ` to assign them ` BotAdmin ` role
- ` [ ] Broadcaster ` & ` BotAdmin ` can ` demote ` a ` SupMod ` to make them a ` Mod ` or ` promote ` the other way
* /
2024-01-29 11:09:33 -05:00
2024-02-14 01:09:55 -05:00
/*
Usage :
promote < user >
demote < user >
promote - admin < user >
* /
2024-01-31 21:30:08 -05:00
2024-02-18 15:23:58 -05:00
// [ ] #TODO : Need to define the body that calls demote()
// [x] Unwraps arguments from message
// let mut argv = msg.message_text.split(" ");
// argv.next(); // Skip the command name
// let arg1 = argv.next();
// let arg2 = argv.next();
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 )
} ;
/*
let mut sender_badge :Option < ChatBadge > = 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 ) ;
}
}
* /
// ---
/*
= > 2024.0 2.15 - The business logic seems embeded straight into demote ( ) with the following in mind :
- demote ( ) atm doesn ' t take sender ChatBadge < - - the assumption is canuserrun ( ) was done
for this user , and automatically assigned any roles that should get auto assigned
- demote ( ) returns a ChangeResult
- [ ] So I think all I need to do here is parse out and pass input args to demote ( ) , and output quirky messages based on ChangeResult
- [ x ] 1. Parse out the following
- Sender ( e . g . , Name & Badge )
- Target User ( arg1 )
- Target Channel ( current channel )
- Msg or Msg . Message_Text ( for later )
- [ x ] 2. Run Demote ( )
- within demote ( ) , getspecialuserroles ( ) is called on both the sender and the target
- getspecialuserroles ( ) only sends current db , while canuserrun ( ) may change db depending on the most current state of the sender
- getspecialuserroles also borrows the sender ' s badge to evaluate
- [ ] 3. Take ChangeResult and output response
* /
/*
- [ x ] 1. Parse out the following
- Sender ( e . g . , Name & Badge )
- Target User ( arg1 )
- Target Channel ( current channel )
- ( no need ) Msg or Msg . Message_Text ( for later )
* /
let sendername = msg . clone ( ) . sender . name ;
let mut sender_badge_mut :Option < ChatBadge > = None ;
for b in & msg . badges {
if b . name = = " moderator " {
sender_badge_mut = Some ( ChatBadge ::Mod ) ;
} else if b . name = = " broadcaster " {
sender_badge_mut = Some ( ChatBadge ::Broadcaster ) ;
}
}
let sender_badge = sender_badge_mut ;
let targetusr = arg1 ;
let targetchnl = msg . channel_login . to_lowercase ( ) ;
/*
- [ x ] 2. Run Demote ( )
- within demote ( ) , getspecialuserroles ( ) is called on both the sender and the target
- getspecialuserroles ( ) only sends current db , while canuserrun ( ) may change db depending on the most current state of the sender
- getspecialuserroles also borrows the sender ' s badge to evaluate
* /
// [x] Get a required lock first
let botlock = bot . read ( ) . await ;
let id = botlock . get_identity ( ) ;
let idlock = id . read ( ) . await ;
let rslt = match targetusr {
Some ( targetusr ) = > {
botinstance ::botlog ::debug ( & format! ( " running demote() " ) ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
idlock . demote (
sendername . clone ( ) ,
& sender_badge ,
targetusr . to_string ( ) ,
Some ( ChType ::Channel ( targetchnl . clone ( ) ) ) ) . await
}
None = > {
botinstance ::botlog ::debug ( & format! ( " No Targer User argument " ) ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
ChangeResult ::NoChange ( " No Targer User " . to_string ( ) )
}
} ;
/*
- [ x ] 3. Take ChangeResult and output response
* /
// let senderUserRole = {
// // note : getspecialuserroles will cover :
// // - Internal roles stored at db for Mod & SupMod & BotAdmin
// // - Broadcaster (based on target hchatter & channel)
// // It MAY NOT COVER sutations where Sender has a Mod Badge, but not in DB yet as Mod
// // - So ideally this covers that (at least returns that they're a mod and go ahead and run for now)
// // - [ ] #TODO : This should also go ahead and add that mod to DB if possible as channel mod
// // let evalroles = vec![];
// let evalroles = match sender_badge {
// Some(ChatBadge::Mod) => {
// let mut rslroles = idlock.getspecialuserroles(
// sendername.clone(),
// Some(ChType::Channel(targetchnl.clone()))).await;
// rslroles.push(UserRole::Mod(ChType::Channel(targetchnl)));
// rslroles
// },
// _ => {
// idlock.getspecialuserroles(
// sendername,
// Some(ChType::Channel(targetchnl.clone()))).await
// }
// };
// // => 02.16 - I think better would just migrate over the logic within demote
// // - If there's business reqs to evaluate , better to keep the ChangeResult
// // consistent and also pass ChatBadge
// }; // senderUserRole
match rslt {
ChangeResult ::Success ( a ) = > {
// println!("Succesfully promoted : {a} ;");
let outmsg = & format! ( " o7 Successfully demoted : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , Some ( & msg ) ) ;
// let outmsg = "o7 Successfully promoted : ".to_string();
botlock . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::Failed ( a ) = > {
// println!("Failed to promote : {a} ; ");
let outmsg = & format! ( " PoroSad failed to demote : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , Some ( & msg ) ) ;
// let outmsg = "PoroSad failed to promote : ".to_string();
botlock . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
ChangeResult ::NoChange ( a ) = > {
// println!("No Changes Made : {a} ; ");
let outmsg = & format! ( " uuh No Demotion Change : {a} " ) ;
botinstance ::botlog ::debug ( outmsg ,
Some ( " identity.rs > cmd_demote() " . to_string ( ) ) , Some ( & msg ) ) ;
// let outmsg = "uuh No Promotion Change : ".to_string();
botlock . botmgrs . chat . say_in_reply_to ( & msg , outmsg . to_string ( ) ) . await ;
} ,
}
// println!("tester");
// println!("tester2");
2024-02-12 02:34:32 -05:00
2024-02-14 09:21:50 -05:00
}
2024-02-12 02:34:32 -05:00
let tempcomm = BotCommand {
2024-01-31 21:30:08 -05:00
module : BotModule ( String ::from ( " identity " ) ) ,
command : String ::from ( " getroles " ) , // command call name
alias : vec ! [ ] , // String of alternative names
exec_body : actions_util ::asyncbox ( getroles ) ,
help : String ::from ( " getroles " ) ,
required_roles : vec ! [
UserRole ::Mod ( ChType ::Channel ( String ::new ( ) ) ) ,
UserRole ::SupMod ( ChType ::Channel ( String ::new ( ) ) ) ,
UserRole ::Broadcaster ,
UserRole ::BotAdmin ,
] ,
2024-02-12 02:34:32 -05:00
} ;
tempcomm . add_to_modmgr ( Arc ::clone ( & mgr ) ) . await ;
2024-01-31 21:30:08 -05:00
2024-02-12 05:25:38 -05:00
2024-02-12 01:25:12 -05:00
// async fn getroles(bot:Arc<Mutex<BotInstance>>,msg:PrivmsgMessage) {
async fn getroles ( bot :BotAR , msg :PrivmsgMessage ) {
2024-02-13 10:11:49 -05:00
// println!("Called cmd getroles");
botinstance ::botlog ::debug ( " Called cmd getroles " ,
Some ( " identity.rs > cmd_getroles() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-01-31 21:30:08 -05:00
/*
Usage
getroles < user > < Channel >
- If channel is provided , provide roles for that channel specifically
* /
// IN other code areas , I see this
// ServerMessage::Privmsg(msg) => {
// println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
2024-02-01 08:40:09 -05:00
// println!("{}",msg.message_text);
2024-01-31 21:30:08 -05:00
let mut argv = msg . message_text . split ( " " ) ;
// for v in argv {
// println!("args : {v}");
// }
2024-02-01 08:40:09 -05:00
argv . next ( ) ; // Skip the command name
2024-01-31 21:30:08 -05:00
let arg1 = argv . next ( ) ;
// if arg == None {
// return ; // Do nothing if no arguments
// }
let targetuser = match arg1 {
None = > return , // exit if no arguments
Some ( arg ) = > arg ,
} ;
// match String::from(arg1) {
// a if a == String::from("admin") => (),
// _ => (),
// }
// match argv[1] {
// String::from("admin") => (),
// }
let arg2 = argv . next ( ) ;
let targetchnl = arg2 ;
2024-02-04 14:28:37 -05:00
// // let a = bot.read().ok().unwrap().get_identity();
// let a = bot.lock().await;
// // let a = a.lock().await;
// // let a = a.get_identity().await;
// let a = a.botmgrs;
// // let a = *(*a).lock().await;
// let a = *a.lock().await;
// let a = a.identity;
// let a = *a.lock().await;
// let a = bot.clone();
// let a = a.into_inner();
// let a = a.botmgrs;
// let a = a.into_inner();
// let a = a.identity;
// let a = a.into_inner();
2024-02-12 01:25:12 -05:00
// let a = bot.clone();
2024-02-04 14:28:37 -05:00
// let a = a.lock().await;
2024-02-12 01:25:12 -05:00
// let a = a.get_identity();
// let a = a.lock().await;
// let a = bot.get_identity();
let botlock = bot . read ( ) . await ;
2024-02-13 10:11:49 -05:00
// println!("botlock read");
botinstance ::botlog ::trace ( " botlock read " ,
Some ( " identity.rs > init > getroles() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-12 01:25:12 -05:00
let idlock = botlock . get_identity ( ) ;
2024-02-13 10:11:49 -05:00
// println!("got identity");
botinstance ::botlog ::trace ( " got identity " ,
Some ( " identity.rs > init > getroles() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-12 05:25:38 -05:00
let idlock = idlock . read ( ) . await ; // <-- 02.12 - Latest where it gest stuck - before or at this point
2024-02-13 10:11:49 -05:00
// println!("id lock");
botinstance ::botlog ::trace ( " id lock " ,
Some ( " identity.rs > init > getroles() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-04 14:28:37 -05:00
let sproles = match targetchnl {
2024-01-31 21:30:08 -05:00
None = > {
2024-02-04 14:28:37 -05:00
// let bot = Rc::clone(&bot);
//let bot = Arc::clone(&bot);
// let a = bot.botmgrs.identity.getspecialuserroles(String::from(targetuser),None);
// let a = Arc::try_unwrap(bot).ok().unwrap().into_inner().ok().unwrap();
// let a = Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner();
// let a = a.botmgrs.identity.getspecialuserroles(String::from(targetuser),None);
// let a = a.ok().getspecialuserroles(String::from(targetuser),None);
// let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None);
// println!("Retrieved User Roles >> {:?}",a);
2024-02-12 01:25:12 -05:00
// let a = idlock.read().await;
2024-02-13 19:49:36 -05:00
// 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
2024-01-31 21:30:08 -05:00
} ,
Some ( targetchnl ) = > {
2024-02-04 14:28:37 -05:00
// let bot = Rc::clone(&bot);
// let bot = Arc::clone(&bot);
// let a = bot.botmgrs.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl))));
// Arc::try_unwrap(boxed_bot.clone()).ok().unwrap().into_inner()
// let a = Arc::try_unwrap(bot).ok().unwrap().into_inner().ok().unwrap();
// let a = Arc::try_unwrap(bot.clone()).ok().unwrap().into_inner();
// let a = a.botmgrs.identity.getspecialuserroles(String::from(targetuser), Some(ChType::Channel(String::from(targetchnl))));
// let a = bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None);
// println!("Retrieved User Roles >> {:?}",a);
// bot.read().ok().unwrap().rIdentity().getspecialuserroles(String::from(targetuser),None)
2024-02-12 01:25:12 -05:00
// let a = a.read().await;
2024-02-13 19:49:36 -05:00
// [ ] 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<ChatBadge> = 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
}
2024-02-04 14:28:37 -05:00
2024-01-31 21:30:08 -05:00
} ,
2024-02-04 14:28:37 -05:00
} ;
2024-01-31 21:30:08 -05:00
2024-02-13 19:49:36 -05:00
// let sproles = idlock.getspecialuserroles(String::from(targetuser),).await;
2024-02-04 14:28:37 -05:00
2024-02-13 10:11:49 -05:00
// println!("Retrieved User Roles >> {:?}",sproles);
2024-02-13 19:49:36 -05:00
botinstance ::botlog ::debug ( & format! ( " User roles of Target Chatter >> {:?} " , sproles ) ,
2024-02-13 10:11:49 -05:00
Some ( " identity.rs > init > getroles() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-02-13 19:49:36 -05:00
// # 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();
2024-01-31 21:30:08 -05:00
2024-02-13 19:49:36 -05:00
let outmsg = if ( ( targetuser . to_lowercase ( ) = = msg . channel_login . to_lowercase ( ) ) & & arg2 . is_none ( ) ) | | ( arg2 . is_some ( ) & & arg2 . unwrap ( ) = = targetuser . to_lowercase ( ) )
{
2024-02-14 01:09:55 -05:00
// First evaluates if they're broadcaster
let mut outmsg = format! ( " FeelsWowMan they're the broadcaster. " ) ;
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 ) {
outmsg = outmsg + & format! ( " Target chatter's user roles are : {:?} " , sproles ) ;
}
outmsg
2024-02-13 19:49:36 -05:00
}
2024-02-14 01:09:55 -05:00
2024-02-13 19:49:36 -05:00
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 ")
// }
// }
// };
2024-01-31 21:30:08 -05:00
// let a = bot.identity.getuserroles(String::from("ModulatingForce"), Some(ChType::Channel(String::from("ModulatingForcebot"))));
// println!("{:?}",a);
2024-02-13 19:49:36 -05:00
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
2024-01-31 21:30:08 -05:00
}
2024-02-13 10:11:49 -05:00
// println!("End of Init MOdule add");
botinstance ::botlog ::trace ( " End of Init MOdule add " ,
Some ( " identity.rs > init " . to_string ( ) ) , None ) ;
2024-01-31 21:30:08 -05:00
2024-02-13 19:49:36 -05:00
Log ::flush ( ) ;
2024-01-29 11:09:33 -05:00
}
2024-01-29 22:57:07 -05:00
// #[derive(Debug, PartialEq, Eq, Hash, Clone)]
// pub enum ChType {
// Channel(String),
// }
#[ derive(Debug, PartialEq, Eq , Clone) ]
2024-01-29 11:09:33 -05:00
pub enum UserRole {
2024-01-29 06:18:27 -05:00
Chatter ,
2024-01-29 13:08:35 -05:00
Mod ( ChType ) , // String specifies Channel
SupMod ( ChType ) , // String specifies Channel
2024-01-29 06:18:27 -05:00
Broadcaster ,
BotAdmin ,
2024-01-29 12:41:26 -05:00
2024-01-29 06:18:27 -05:00
}
2024-01-29 22:57:07 -05:00
pub enum Permissible {
2024-01-29 12:41:26 -05:00
Allow ,
Block
}
2024-01-31 18:36:23 -05:00
#[ derive(Clone) ]
2024-01-29 06:18:27 -05:00
pub struct IdentityManager {
2024-02-04 14:28:37 -05:00
// special_roles_users : HashMap<String,Vec<UserRole>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel
2024-02-12 05:25:38 -05:00
// special_roles_users : Arc<Mutex<HashMap<String,Vec<UserRole>>>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel
// special_roles_users : Arc<RwLock<HashMap<String,Vec<UserRole>>>>,
special_roles_users : Arc < RwLock < HashMap < String , Arc < RwLock < Vec < UserRole > > > > > > ,
2024-01-31 09:31:14 -05:00
// parent_mgr : Box<crate::core::botinstance::BotManagers>,
2024-01-31 21:30:08 -05:00
//parent_mgr : Option<Box<crate::core::botinstance::BotManagers>>,
2024-01-29 06:18:27 -05:00
}
2024-02-18 15:23:58 -05:00
/*
HashMap <
String , < - - Chatter / Username
Vec < UserRole > - - < - - Vectors are basically arrays
>
- - [ ]
let a = vec! [ ]
modulatingforce : vec ! [ UserRole ::BotAdmin ,
UserRole ::Mod ( ChType ::Channel ( " modulatingforcebot " ) ) ]
modulatingforce : vec ! [ UserRole ::BotAdmin ,
UserRole ::Mod ( ChType ::Channel ( " modulatingforcebot " ) ) ]
* /
2024-01-29 06:18:27 -05:00
2024-02-18 15:23:58 -05:00
#[ derive(Debug) ]
2024-01-29 22:57:07 -05:00
pub enum ChatBadge {
2024-01-29 12:41:26 -05:00
Broadcaster ,
Mod ,
}
2024-01-29 06:18:27 -05:00
2024-02-13 07:54:35 -05:00
pub enum ChangeResult {
2024-01-31 21:30:08 -05:00
Success ( String ) ,
Failed ( String ) ,
NoChange ( String ) ,
}
2024-01-29 06:18:27 -05:00
impl IdentityManager {
pub fn init ( ) -> IdentityManager {
let mut a = HashMap ::new ( ) ;
for admn in adminvector ( ) {
2024-02-12 05:25:38 -05:00
a . insert ( admn . to_lowercase ( ) , Arc ::new ( RwLock ::new ( vec! [ UserRole ::BotAdmin ] ) ) ) ;
2024-01-29 06:18:27 -05:00
} ;
IdentityManager {
2024-02-12 05:25:38 -05:00
special_roles_users : Arc ::new ( RwLock ::new ( a ) ) ,
2024-01-31 21:30:08 -05:00
//parent_mgr : None,
2024-01-29 06:18:27 -05:00
}
}
2024-01-29 12:41:26 -05:00
2024-01-29 22:57:07 -05:00
// [ ] Maybe I should create a can_user_run version that simply takes PrvMsg, but then calls can_user_run directly
// pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Result<Permissible,Box<dyn Error>>
2024-02-04 14:28:37 -05:00
// pub fn can_user_run_PRVMSG(&self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Permissible
2024-02-12 01:25:12 -05:00
// pub async fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Permissible
2024-02-13 07:54:35 -05:00
pub async fn can_user_run_PRVMSG ( & mut self , msg :& PrivmsgMessage , cmdreqroles :Vec < UserRole > ) -> ( Permissible , ChangeResult )
2024-01-29 22:57:07 -05:00
{
// println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
// [ ] Check what Badges in PrivmsgMessage
2024-02-13 10:11:49 -05:00
// println!{"Checking within PRVMSG"};
botinstance ::botlog ::debug ( " Checking within PRVMSG " ,
Some ( " identity.rs > can_user_run_PRVMSG() " . to_string ( ) ) , Some ( & msg ) ) ;
2024-01-29 22:57:07 -05:00
let mut sender_badge :Option < ChatBadge > = 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 ) ;
}
}
// if &msg.badges.contains(Badge{}) {
// }
2024-02-13 19:49:36 -05:00
// if let Some(sender_badge) = sender_badge {
// match sender_badge {
// Some(sender_badge) => {
2024-01-31 18:36:23 -05:00
// return &self.can_user_run(msg.sender.name.to_owned(),
// ChType::Channel(msg.channel_login.to_owned()),
// sender_badge,
// cmdreqroles
2024-02-04 14:28:37 -05:00
// return self.can_user_run(msg.sender.name.to_owned(),
// let a = Arc::new(Mutex::new(self));
// let mut a = a.lock().await;
// let a = **a;
// let a = a.can_user_run(msg.sender.name.to_owned(),
// ChType::Channel(msg.channel_login.to_owned()),
// sender_badge,
// cmdreqroles
// ) ;
// let a = *self;
// let a = Arc::new(Mutex::new(a));
// let a = a.lock().await.can_user_run(msg.sender.name.to_owned(),
// ChType::Channel(msg.channel_login.to_owned()),
// sender_badge,
// cmdreqroles
// ) ;
// return a;
2024-02-13 07:54:35 -05:00
// return self.can_user_run(msg.sender.name.to_owned(),
// ChType::Channel(msg.channel_login.to_owned()),
// sender_badge,
// cmdreqroles
// ).await
// * NOTE : We're preferring to pass the ChangeResult up , where we have access to Chat via BotInstance
// that have more strained chatting rules
2024-02-13 19:49:36 -05:00
// 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
2024-01-29 22:57:07 -05:00
// [ ] Call can_user_run()
2024-02-12 01:25:12 -05:00
// (self,Permissible::Block)
2024-02-13 19:49:36 -05:00
// (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
2024-01-29 22:57:07 -05:00
}
2024-02-12 01:25:12 -05:00
2024-02-12 05:25:38 -05:00
pub async fn can_user_run ( & mut self ,
2024-01-29 12:41:26 -05:00
usr :String ,
channelname :ChType ,
2024-02-13 19:49:36 -05:00
chat_badge :Option < ChatBadge > ,
2024-01-29 12:41:26 -05:00
cmdreqroles :Vec < UserRole >
2024-01-29 22:57:07 -05:00
// ) -> Result<Permissible,Box<dyn Error>> {
2024-02-13 07:54:35 -05:00
) -> ( Permissible , ChangeResult ) {
2024-02-13 10:11:49 -05:00
// println!{"Checking within can_user_run()"};
2024-02-18 15:23:58 -05:00
botinstance ::botlog ::debug ( & format! ( " Checking within can_user_run() :
usr : { } ; channel : { :? } ; badge : { :? } ; cmdreqroles : { :? } " ,
usr , channelname , chat_badge , cmdreqroles ) ,
2024-02-13 10:11:49 -05:00
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-01-29 12:41:26 -05:00
/*
canUserRun -
Input :
usr :String ,
channelname :ChType ,
2024-01-29 22:57:07 -05:00
chat_badge :ChatBadge ,
2024-01-29 12:41:26 -05:00
cmdreqroles :Vec < UserRole >
Output : Result < Permissible , Box < dyn Error > >
Some Possible outcomes : Ok ( Permissible ::Allow ) , Ok ( Permissible ::Block )
Description
For a Given Chatter ( with any special ChatBadge ) who ran the Command at a Given Channel , check if that user can
run the command based on the given cmdreqroles required by the command
Inputs and business logic determine if the user can run the command based on the command ' s required roles
* /
2024-01-29 13:08:35 -05:00
// Requirements
/*
2024-01-29 22:57:07 -05:00
[ x ] If cmdreqroles is empty vector , automatically assume Ok ( Permissible ::Allow )
[ x ] If chatBadge ::Broadcaster .. .
[ x ] and cmdreqroles includes UserRole ::Broadcaster , Ok ( Permissible ::Allow )
[ x ] and cmdreqroles includes UserRole ::Mod ( " " ) OR UserRole ::SupMod ( " " ) , Ok ( Permissible ::Allow )
[ x ] If chatBadge ::Mod .. .
[ x ] Check if they have either UserRole ::Mod ( channelname ::ChType ) or UserRole ::SupMod ( channelname ::ChType )
[ x ] If not , assign them UserRole ::Mod ( channelname ::ChType )
[ 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 )
[ x ] If cmdreqroles includes UserRole ::SupMod ( " " ) , checks if chatter has UserRole ::SupMod ( channelname ::ChType ) to determine if Ok ( Permissible ::Allow )
[ x ] If cmdreqroles includes UserRole ::BotAdmin and chatter has UserRole ::BotAdmin , Ok ( Permissible ::Allow )
[ x ] Otherwise , Ok ( Permissible ::Block )
2024-01-29 13:08:35 -05:00
* /
2024-01-29 12:41:26 -05:00
2024-01-29 22:57:07 -05:00
// [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow)
2024-01-29 12:41:26 -05:00
2024-02-12 05:25:38 -05:00
// let idar = Arc::new(RwLock::new(self));
2024-02-18 15:23:58 -05:00
let usr = usr . to_lowercase ( ) ;
2024-01-29 22:57:07 -05:00
if cmdreqroles . len ( ) = = 0 {
// return Ok(Permissible::Allow)
2024-02-13 07:54:35 -05:00
return ( Permissible ::Allow , ChangeResult ::NoChange ( " Command has no required cmdreqroles " . to_string ( ) ) )
2024-01-29 22:57:07 -05:00
}
2024-02-13 07:54:35 -05:00
let mut modrolechange = ChangeResult ::NoChange ( " " . to_string ( ) ) ;
2024-01-29 22:57:07 -05:00
match chat_badge {
// [x] If chatBadge::Broadcaster ...
// [x] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow)
// [x] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow)
2024-02-13 19:49:36 -05:00
Some ( ChatBadge ::Broadcaster ) = > {
2024-01-29 22:57:07 -05:00
if cmdreqroles . contains ( & UserRole ::Broadcaster ) | |
cmdreqroles . contains ( & UserRole ::Mod ( ChType ::Channel ( String ::new ( ) ) ) ) | |
cmdreqroles . contains ( & UserRole ::SupMod ( ChType ::Channel ( String ::new ( ) ) ) ) {
// return Ok(Permissible::Allow)
2024-02-13 07:54:35 -05:00
return ( Permissible ::Allow , ChangeResult ::NoChange ( " Broadcaster Role " . to_string ( ) ) )
2024-01-29 22:57:07 -05:00
}
} ,
// [x] If chatBadge::Mod ...
// [x] Check if they have either UserRole::Mod(channelname::ChType) or UserRole::SupMod(channelname::ChType)
// [x] If not, assign them UserRole::Mod(channelname::ChType)
2024-02-13 19:49:36 -05:00
Some ( ChatBadge ::Mod ) = > {
2024-01-29 22:57:07 -05:00
2024-02-13 10:11:49 -05:00
// println!("Mod Chatbadge detected");
botinstance ::botlog ::info ( " Mod Chatbadge detected " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-01-29 22:57:07 -05:00
2024-01-30 09:13:59 -05:00
// println!("debug special roles : {:?}",self.special_roles_users);
// println!("debug usr : {}",&usr.to_lowercase());
2024-01-29 22:57:07 -05:00
// let Some((k,v)) = self.special_roles_users.get_key_value(usr);
2024-01-31 09:31:14 -05:00
// match self.special_roles_users.get_mut(&usr.to_lowercase()) {
2024-02-04 14:28:37 -05:00
// match self.special_roles_users.get(&usr.to_lowercase()) {
2024-02-13 10:11:49 -05:00
// println!("Creating clone");
2024-02-18 15:23:58 -05:00
botinstance ::botlog ::trace ( " Creating arc clone " ,
2024-02-13 10:11:49 -05:00
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-12 05:25:38 -05:00
let roleslock = Arc ::clone ( & ( * self ) . special_roles_users ) ;
2024-02-13 10:11:49 -05:00
// println!("Read lock on : Special_Roles_User"); // <-- after this is slightly different between working and problem
botinstance ::botlog ::trace ( " Read lock on : Special_Roles_User " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-18 15:23:58 -05:00
{
// If target user doesn't exist in special_roles_users , add with blank vector roles
let mut srulock = self . special_roles_users . write ( ) . await ;
srulock . entry ( usr . clone ( ) ) . or_insert ( Arc ::new ( RwLock ::new ( vec! [ ] ) ) ) ;
botinstance ::botlog ::trace ( & format! ( " Ensuring Chatter in Roles {:?} " , srulock . entry ( usr . clone ( ) ) ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
2024-02-12 05:25:38 -05:00
let mut roleslock = roleslock . write ( ) . await ;
match ( * roleslock ) . get ( & usr . to_lowercase ( ) ) {
2024-02-12 15:32:53 -05:00
Some ( usrroles ) if
usrroles . read ( ) . await . contains ( & UserRole ::Mod ( channelname . clone ( ) ) ) | |
usrroles . read ( ) . await . contains ( & UserRole ::SupMod ( channelname . clone ( ) ) ) = > { // <-- working got to this point
// println!("contains mod : {}", usrroles.read().await.contains(&UserRole::Mod(channelname.clone())));
// println!("contains supmod : {}", usrroles.read().await.contains(&UserRole::SupMod(channelname.clone())));
2024-02-13 07:54:35 -05:00
// Do nothing when theh have a mod badge and have either a supmod or mod badge for the channel
2024-02-13 10:11:49 -05:00
// println!("Already a mod in roles");
botinstance ::botlog ::trace ( " Already a mod in roles " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-12 05:25:38 -05:00
2024-02-12 15:32:53 -05:00
}
2024-02-12 15:27:52 -05:00
_ = > {
2024-02-13 07:54:35 -05:00
// In the event they have a mod badge , are running a bot command, but don't have a channel mod role yet...
2024-02-13 10:11:49 -05:00
// println!("lock created > adding with a mod role o7");
botinstance ::botlog ::trace ( " lock created > adding with a mod role o7 " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
// botinstance::botlog::notice("Assigning ModRole to Chatter",
// Some("identity.rs > can_user_run()".to_string()), None);
2024-02-13 07:54:35 -05:00
let mut roleslock = roleslock ;
let mut a = roleslock . get_mut ( & usr . to_lowercase ( ) ) . unwrap ( ) ;
let mut alock = a . write ( ) . await ;
alock . push ( UserRole ::Mod ( channelname . clone ( ) ) ) ;
modrolechange = ChangeResult ::Success ( " Auto Promoted Mod " . to_string ( ) ) ;
// alock.get_mut(&usr.to_lowercase())
// .get_or_insert_with(|| UserRole::Mod(channelname.clone()))
// // .expect("ERROR")
// .unwrap()
// .write().await
// // .get_mut()
// .push(UserRole::Mod(channelname.clone()));
2024-02-12 15:32:53 -05:00
} // <-- I'm assuming problem got to here
2024-01-29 22:57:07 -05:00
}
} ,
2024-02-13 19:49:36 -05:00
_ = > ( ) , // Don't handle other roles here
2024-01-29 22:57:07 -05:00
}
// [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)
2024-02-13 10:11:49 -05:00
// println!("cmd required roles : {:?}",cmdreqroles);
botinstance ::botlog ::trace ( & format! ( " cmd required roles : {:?} " , cmdreqroles ) ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-01-29 22:57:07 -05:00
if cmdreqroles . contains ( & UserRole ::Mod ( ChType ::Channel ( String ::new ( ) ) ) ) {
// match self.special_roles_users.get(&channelname) {
// Some(usrroles) => {},
// None => (),
// }
2024-02-13 10:11:49 -05:00
// println!("Command requires Mod Role");
botinstance ::botlog ::trace ( " Command requires Mod Role " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-01-29 22:57:07 -05:00
2024-02-12 05:25:38 -05:00
if let Some ( a ) = ( & * self ) . special_roles_users . read ( ) . await . get ( & usr . to_lowercase ( ) ) {
2024-02-13 10:11:49 -05:00
// println!("Special roles found for user");
botinstance ::botlog ::trace ( " Special roles found for user " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-12 05:25:38 -05:00
if a . read ( ) . await . contains ( & UserRole ::Mod ( channelname . clone ( ) ) ) | | a . read ( ) . await . contains ( & UserRole ::SupMod ( channelname . clone ( ) ) ) {
2024-01-29 22:57:07 -05:00
// return Ok(Permissible::Allow);
2024-02-13 10:11:49 -05:00
// println!("Special roles found for user : A mod idenfified ");
botinstance ::botlog ::trace ( " > Special Role Identified : Mod " ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-13 07:54:35 -05:00
return ( Permissible ::Allow , modrolechange )
2024-01-29 22:57:07 -05:00
}
}
}
// [x] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow)
if cmdreqroles . contains ( & UserRole ::SupMod ( ChType ::Channel ( String ::new ( ) ) ) ) {
2024-02-12 05:25:38 -05:00
if let Some ( a ) = ( & * self ) . special_roles_users . read ( ) . await . get ( & usr . to_lowercase ( ) ) {
if a . read ( ) . await . contains ( & UserRole ::SupMod ( channelname . clone ( ) ) ) {
2024-01-29 22:57:07 -05:00
// return Ok(Permissible::Allow);
2024-02-13 07:54:35 -05:00
return ( Permissible ::Allow , modrolechange )
2024-01-29 22:57:07 -05:00
}
}
}
// [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow)
2024-02-13 10:11:49 -05:00
// println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin));
botinstance ::botlog ::trace ( & format! ( " Eval cmdreqroles with botadmin : {} " , cmdreqroles . contains ( & UserRole ::BotAdmin ) ) ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-01-29 22:57:07 -05:00
if cmdreqroles . contains ( & UserRole ::BotAdmin ) {
2024-02-13 10:11:49 -05:00
// println!("special roles get : {:?}",(&*self).special_roles_users.read().await.get(&usr.to_lowercase()));
botinstance ::botlog ::trace ( & format! ( " special roles get : {:?} " , ( & * self ) . special_roles_users . read ( ) . await . get ( & usr . to_lowercase ( ) ) ) ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-12 05:25:38 -05:00
if let Some ( a ) = ( & * self ) . special_roles_users . read ( ) . await . get ( & usr . to_lowercase ( ) ) {
println! ( " special roles contains BotAdmin: {} " , a . read ( ) . await . contains ( & UserRole ::BotAdmin ) ) ;
2024-02-13 10:11:49 -05:00
botinstance ::botlog ::trace ( & format! ( " special roles contains BotAdmin: {} " , a . read ( ) . await . contains ( & UserRole ::BotAdmin ) ) ,
Some ( " identity.rs > can_user_run() " . to_string ( ) ) , None ) ;
2024-02-12 05:25:38 -05:00
if a . read ( ) . await . contains ( & UserRole ::BotAdmin ) {
2024-01-29 22:57:07 -05:00
// return Ok(Permissible::Allow);
2024-02-13 07:54:35 -05:00
return ( Permissible ::Allow , modrolechange )
2024-01-29 22:57:07 -05:00
}
}
}
2024-02-13 07:54:35 -05:00
( Permissible ::Block , ChangeResult ::NoChange ( " Not any permissiable condition " . to_string ( ) ) )
2024-01-29 12:41:26 -05:00
}
2024-01-31 21:30:08 -05:00
2024-02-12 01:25:12 -05:00
// pub async fn promote(&mut self,trgchatter:String,channel:Option<ChType>,trg_role:Option<UserRole>) -> ChangeResult {
2024-02-14 09:21:50 -05:00
pub async fn promote ( & self ,
2024-02-18 15:23:58 -05:00
authorizer :String ,
authorizer_badge :& Option < ChatBadge > ,
2024-02-14 09:21:50 -05:00
trgchatter :String ,
channel :Option < ChType > ,
2024-02-18 15:23:58 -05:00
trg_role :Option < UserRole >
) -> ChangeResult
2024-02-14 09:21:50 -05:00
{
2024-02-01 08:40:09 -05:00
2024-02-18 15:23:58 -05:00
botinstance ::botlog ::trace ( & format! (
" IN VARS for promote() : auth : {} ; authbadge : {:?} ; trg : {} ; Channel {:?} ; {:?} " ,
authorizer , authorizer_badge , trgchatter , channel , trg_role ) ,
2024-02-14 01:09:55 -05:00
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
2024-02-01 08:40:09 -05:00
2024-02-18 15:23:58 -05:00
/*
[ x ] 1. Check if Authorizer Mod Badge then Auto Promote to Mod if not Mod
[ x ] 2. Get Authorizer & Target Chatter Roles with a Given Channel
[ x ] 3. If the authorizer & Target Chatters are the same , and the Authorizer is not a Admin , return no change
[ x ] 4 a . If Authorizer is BotAdmin & trg_role is Some ( BotAdmin ) , set Target as BotAdmin and return
[ x ] 4 b . If target is Broadcaster , return NoChange
[ ] 4 c . If Authorizer is a SupMod , Broadcaster , BotAdmin , can Promote Target Chatter > Mod
- NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod
[ ] 4 d . If Authorizer is a Broadcaster , BotAdmin , can Promote a Target Mod > SupMod
- NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod
* /
// [x] 1. Check if Authorizer Mod Badge then Auto Promote to Mod if not Mod
let ( authusrroles , trgusrroles ) = if let Some ( channel ) = channel . clone ( ) {
let mut authusrroles = self . getspecialuserroles (
authorizer . to_lowercase ( ) . clone ( ) ,
Some ( channel . clone ( ) ) )
. await ;
2024-02-01 08:40:09 -05:00
2024-02-18 15:23:58 -05:00
{ // mut block
// let authusrroles_mut = &mut authusrroles;
// [x] Add Mod(channel) to authusrroles
// [x] #TODO also add to DB if possible?
match * authorizer_badge {
Some ( ChatBadge ::Mod ) if ( ! authusrroles . contains ( & UserRole ::Mod ( channel . clone ( ) ) )
& & ! authusrroles . contains ( & UserRole ::SupMod ( channel . clone ( ) ) ) ) = > {
// (*authusrroles_mut).push(UserRole::Mod(channel.clone()));
authusrroles . push ( UserRole ::Mod ( channel . clone ( ) ) ) ;
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 ( channel . clone ( ) ) ) ;
}
_ = > ( ) ,
}
} // mut block
2024-02-04 14:28:37 -05:00
2024-02-18 15:23:58 -05:00
// [x] 2. Get Authorizer & Target Chatter Roles
let trgusrroles = self . getspecialuserroles (
trgchatter . to_lowercase ( ) . clone ( ) ,
Some ( channel . clone ( ) ) )
. await ;
( authusrroles , trgusrroles )
} else {
let mut authusrroles = self . getspecialuserroles (
authorizer . to_lowercase ( ) . clone ( ) ,
None )
. await ;
let trgusrroles = self . getspecialuserroles (
trgchatter . to_lowercase ( ) . clone ( ) ,
None )
. await ;
( authusrroles , trgusrroles )
} ;
// [x] 3. If the authorizer & Target Chatters are the same, and the Authorizer is not a Admin, return no change
if trgchatter = = authorizer & & ! authusrroles . contains ( & UserRole ::BotAdmin ) {
return ChangeResult ::NoChange ( " Can't target yourself " . to_string ( ) ) ;
}
// [x] 4a. If Authorizer is BotAdmin & trg_role is Some(BotAdmin) , set Target as BotAdmin and return
if authusrroles . contains ( & UserRole ::BotAdmin ) & & trg_role = = Some ( UserRole ::BotAdmin ) {
if trgusrroles . contains ( & UserRole ::BotAdmin ) {
return ChangeResult ::NoChange ( " Already has the role " . to_string ( ) ) ;
} else {
2024-02-04 14:28:37 -05:00
2024-02-18 15:23:58 -05:00
{
let mut srulock = self . special_roles_users . write ( ) . await ;
2024-02-04 14:28:37 -05:00
2024-02-18 15:23:58 -05:00
srulock . entry ( trgchatter . clone ( ) ) . or_insert ( Arc ::new ( RwLock ::new ( vec! [ ] ) ) ) ;
botinstance ::botlog ::trace ( & format! ( " Ensuring Target Chatter in Roles > {:?} " , 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 for the user " )
. write ( ) . await
. push ( UserRole ::BotAdmin ) ; // <-- Adds the specific role
botinstance ::botlog ::trace ( & format! ( " Inserting Role > {:?} " , srulock . entry ( trgchatter . clone ( ) ) ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
return ChangeResult ::Success ( " Promotion Successful " . to_string ( ) ) ;
}
}
// [x] 4b. If target is Broadcaster, return NoChange
if trgusrroles . contains ( & UserRole ::Broadcaster ) {
return ChangeResult ::NoChange ( " Can't target broadcaster " . to_string ( ) ) ;
}
/*
[ ] 4 c . If Authorizer is a SupMod , Broadcaster , BotAdmin , can Promote Target Chatter > Mod
- NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod
[ ] 4 d . If Authorizer is a Broadcaster , BotAdmin , can Promote a Target Mod > SupMod
- NOTE : We do not validate trg_role here - app logic requires you to promote 1 to Mod and 1 more to SupMod
* /
// let authhasnsreqroles = match channel.clone() {
// Some(channel) => authusrroles.contains(&UserRole::SupMod(channel.clone())) ||
// authusrroles.contains(&UserRole::BotAdmin) ||
// authusrroles.contains(&UserRole::Broadcaster) ,
// None => authusrroles.contains(&UserRole::BotAdmin),
2024-02-04 14:28:37 -05:00
// };
2024-02-01 08:40:09 -05:00
2024-02-18 15:23:58 -05:00
if let Some ( trg_chnl ) = channel . clone ( ) {
if ! trgusrroles . contains ( & UserRole ::Broadcaster )
& & ! trgusrroles . contains ( & UserRole ::Mod ( trg_chnl . clone ( ) ) )
& & ! trgusrroles . contains ( & UserRole ::SupMod ( trg_chnl . clone ( ) ) ) {
// target user is neither Mod nor SupMod && not broadcaster
// target's Next Role would be Mod
// Authorizer must be SupMod,Broadcaster,BotAdmin
// > Promote target to Mod
if authusrroles . contains ( & UserRole ::SupMod ( trg_chnl . clone ( ) ) )
| | authusrroles . contains ( & UserRole ::Broadcaster )
| | authusrroles . contains ( & UserRole ::BotAdmin )
{
{
// If target user doesn't exist in special_roles_users , add with blank vector roles
let mut srulock = self . special_roles_users . write ( ) . await ;
srulock . entry ( trgchatter . clone ( ) ) . or_insert ( Arc ::new ( RwLock ::new ( vec! [ ] ) ) ) ;
botinstance ::botlog ::trace ( & format! ( " Ensuring Chatter in Roles {:?} " , srulock . entry ( trgchatter . clone ( ) ) ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
{
// promote target after
let mut srulock = self . special_roles_users . write ( ) . await ;
srulock
. get_mut ( & trgchatter )
. expect ( " Error getting roles " )
. write ( ) . await
. push ( UserRole ::Mod ( trg_chnl . clone ( ) ) ) ; // Role to Add
botinstance ::botlog ::trace ( & format! ( " Adding Roles to Chatter {:?} " , srulock . entry ( trgchatter . clone ( ) ) ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
return ChangeResult ::Success ( String ::from ( " Promotion Successful " ) ) ;
}
// Other else conditions would be mostly spcecial responses like ChangeResult::NoChange or ChangeResult::Fail
// related to authusrroles
else {
return ChangeResult ::Failed ( String ::from ( " You're not permitted to do that " ) ) ;
}
} else if ! trgusrroles . contains ( & UserRole ::Broadcaster )
& & trgusrroles . contains ( & UserRole ::Mod ( trg_chnl . clone ( ) ) )
& & ! trgusrroles . contains ( & UserRole ::SupMod ( trg_chnl . clone ( ) ) ) //
{
// target user is a Mod && not broadcaster
// target's Next Role would be SupMod
// [ ] #todo Check first if target have SupMod - Optional but could be done to cleanup first
// Authorizer must be Broadcaster,BotAdmin
// > Promote target to SupMod
if authusrroles . contains ( & UserRole ::Broadcaster )
| | authusrroles . contains ( & UserRole ::BotAdmin )
{
{ // Inserts user if doesn't exist
let mut srulock = self . special_roles_users . write ( ) . await ;
srulock . entry ( trgchatter . clone ( ) ) . or_insert ( Arc ::new ( RwLock ::new ( vec! [ ] ) ) ) ;
botinstance ::botlog ::trace ( & format! ( " Ensuring User in Roles {:?} " , srulock . entry ( trgchatter . clone ( ) ) ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
{ // Adds the requested role for the user
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 ::SupMod ( trg_chnl . clone ( ) ) ) ;
botinstance ::botlog ::trace ( & format! ( " Adding Required Role > {:?} " , srulock . entry ( trgchatter . clone ( ) ) ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
{ // Removes the lower role (mod) from the user
let mut srulock = self . special_roles_users . write ( ) . await ;
let mut uroleslock = srulock
. get_mut ( & trgchatter )
. expect ( " Error getting roles " )
. write ( ) . await ;
if let Some ( indx ) = uroleslock . iter ( ) . position ( | value | * value = = UserRole ::Mod ( trg_chnl . clone ( ) ) ) {
uroleslock . swap_remove ( indx ) ;
}
botinstance ::botlog ::trace ( & format! ( " Removing lower role > {:?} " , uroleslock ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
2024-02-12 05:25:38 -05:00
2024-02-18 15:23:58 -05:00
return ChangeResult ::Success ( String ::from ( " Promotion Successful " ) ) ;
2024-02-12 05:25:38 -05:00
2024-02-18 15:23:58 -05:00
} else {
return ChangeResult ::Failed ( String ::from ( " You're not permitted to do that " ) ) ;
}
2024-02-01 08:40:09 -05:00
2024-02-18 15:23:58 -05:00
} else if ! trgusrroles . contains ( & UserRole ::Broadcaster )
& & trgusrroles . contains ( & UserRole ::SupMod ( trg_chnl . clone ( ) ) ) {
// target user is a SuMod && not broadcaster
// No Change
return ChangeResult ::Failed ( String ::from ( " Already highest available role " ) ) ;
} else {
// since handling for channel is already done, will be handling other trguserroles situations here
// other situations includes :
/*
[ - ] targetuser is broadcaster > > no need - this was done earlier in the function
[ ? ] ?
* /
// At the moment, without any new roles, this should not be reached
botinstance ::botlog ::warn ( & format! ( " Code Warning : add handing for other trgusrroles " ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
return ChangeResult ::Failed ( String ::from ( " Code Warning " ) ) ;
}
// let trghasreqroles =
// {
// // If target user doesn't exist in special_roles_users , add with blank vector roles
// let mut srulock = self.special_roles_users.write().await;
// srulock.entry(trgchatter.clone()).or_insert(Arc::new(RwLock::new(vec![])));
// botinstance::botlog::trace(&format!("Ensuring Chatter in Roles {:?}",srulock.entry(trgchatter.clone())),
// Some("identity.rs > promote()".to_string()), None);
// Log::flush();
// }
// {
// // promote target after
// 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.clone())); // Role to Add
// botinstance::botlog::trace(&format!("Adding Roles to Chatter {:?}",srulock.entry(trgchatter.clone())),
// Some("identity.rs > promote()".to_string()), None);
// Log::flush();
// }
// return ChangeResult::Success(String::from("Promotion Successful"));
} ;
// if authhasnsreqroles {
// {
// // If target user doesn't exist in special_roles_users , add with blank vector roles
// 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();
// }
// {
// // promote target after
// 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"));
// }
// authusrroles.contains(&UserRole::Mod(()))
/*
let chatterroles = self . getspecialuserroles ( trgchatter . clone ( ) , channel . clone ( ) ) . await ;
let rolemap = chatterroles ;
2024-02-01 08:40:09 -05:00
match trg_role {
2024-02-14 01:09:55 -05:00
Some ( UserRole ::Mod ( _ ) ) = > {
2024-02-18 15:23:58 -05:00
2024-02-13 19:49:36 -05:00
if let Some ( trg_chnl ) = channel . clone ( ) {
2024-02-18 15:23:58 -05:00
// [ ] 1. If trg_role & trgchatter is a Mod or SupMod of the target channel, return NoChange
2024-02-13 19:49:36 -05:00
let chatterroles = self . getspecialuserroles ( trgchatter . clone ( ) , channel . clone ( ) ) . await ;
let rolemap = chatterroles ;
2024-02-12 05:25:38 -05:00
// let rolemap = rolemap.unwrap();
if rolemap . contains ( & UserRole ::Mod ( trg_chnl . clone ( ) ) ) {
2024-02-01 08:40:09 -05:00
return ChangeResult ::NoChange ( String ::from ( " Target User already has Target Role " ) ) ;
2024-02-14 01:09:55 -05:00
} else if rolemap . contains ( & UserRole ::Broadcaster ) {
return ChangeResult ::NoChange ( String ::from ( " No need to do that for broadcaster " ) ) ;
2024-02-01 08:40:09 -05:00
}
2024-02-14 01:09:55 -05:00
2024-02-01 08:40:09 -05:00
// # otherwise, trg_role for the given chnl is not assigned to the trgchatter
// chatterroles.push(UserRole::Mod(trg_chnl.clone()));
2024-02-13 19:49:36 -05:00
// let a = self.special_roles_users;
// let b = a.write().await;
// // let c = b.get_mut(&trgchatter);
// let c = (*b).;
2024-02-18 15:23:58 -05:00
// [ ] 2. Ensure an entry in Special_Roles_user for trgchatter, and push Mod(Channel) for the Target User
2024-02-13 19:49:36 -05:00
// [x] (!!) AROUND HERE - check if the user exists first, and at least add the user as we're promoting anyway
{
2024-02-18 15:23:58 -05:00
// If target user doesn't exist in special_roles_users , add with blank vector roles
2024-02-13 19:49:36 -05:00
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 ( ) ;
}
{
2024-02-18 15:23:58 -05:00
// promote target after
2024-02-13 19:49:36 -05:00
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 ( ) ;
}
2024-02-01 08:40:09 -05:00
return ChangeResult ::Success ( String ::from ( " Promotion Successful " ) ) ;
}
} ,
2024-02-14 01:09:55 -05:00
Some ( UserRole ::SupMod ( _ ) ) = >
{
if let Some ( trg_chnl ) = channel . clone ( ) {
2024-02-18 15:23:58 -05:00
// [ ] 1. If trg_role & trgchatter is a Mod or SupMod of the target channel, return NoChange
2024-02-14 01:09:55 -05:00
let chatterroles = self . getspecialuserroles ( trgchatter . clone ( ) , channel . clone ( ) ) . await ;
let rolemap = chatterroles ;
// let rolemap = rolemap.unwrap();
if rolemap . contains ( & UserRole ::SupMod ( trg_chnl . clone ( ) ) ) {
return ChangeResult ::NoChange ( String ::from ( " Target User already has Target Role " ) ) ;
} else if rolemap . contains ( & UserRole ::Broadcaster ) {
return ChangeResult ::NoChange ( String ::from ( " No need to do that for broadcaster " ) ) ;
}
// # otherwise, trg_role for the given chnl is not assigned to the trgchatter
// chatterroles.push(UserRole::Mod(trg_chnl.clone()));
// let a = self.special_roles_users;
// let b = a.write().await;
// // let c = b.get_mut(&trgchatter);
// let c = (*b).;
2024-02-18 15:23:58 -05:00
// [ ] 2. Ensure an entry in Special_Roles_user for trgchatter, and push SupMod(Channel) for the Target User
2024-02-14 01:09:55 -05:00
// [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 ::SupMod ( trg_chnl . clone ( ) ) ) ;
botinstance ::botlog ::trace ( & format! ( " SRLOCK - 2st 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
// .(UserRole::Mod(trg_chnl));
// let indx = srulock.iter().position()
let mut uroleslock = srulock
. get_mut ( & trgchatter )
. expect ( " Error getting roles " )
// !! [ ] Unsure what happens if promoting a chatter that doesn't exist at
. write ( ) . await ;
if let Some ( indx ) = uroleslock . iter ( ) . position ( | value | * value = = UserRole ::Mod ( trg_chnl . clone ( ) ) ) {
uroleslock . swap_remove ( indx ) ;
}
botinstance ::botlog ::trace ( & format! ( " SRLOCK - 2st write > {:?} " , uroleslock ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
}
return ChangeResult ::Success ( String ::from ( " Promotion Successful " ) ) ;
}
} ,
2024-02-13 19:49:36 -05:00
Some ( UserRole ::BotAdmin ) = > {
2024-02-18 15:23:58 -05:00
2024-02-13 19:49:36 -05:00
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 " ) ) ;
} ,
2024-02-14 09:21:50 -05:00
Some ( _ ) = > {
botinstance ::botlog ::warn ( & format! ( " Runtime reached undeveloped code " ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
} ,
None = > {
botinstance ::botlog ::warn ( & format! ( " Runtime reached undeveloped code " ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
} ,
2024-02-01 08:40:09 -05:00
}
2024-02-18 15:23:58 -05:00
* /
2024-02-01 08:40:09 -05:00
// match chatterroles {
// Some(chatterroles) => {
// // [x] chatter already has the target role
// if chatterroles.contains(&trg_role) {
// return ChangeResult::NoChange(String::from("Target User already has Target Role"));
// }
// // By this point, chatteroles does not contain target role
// // match trgRole {
// // Some(trgRole) => {
// // match trgRole {
// // UserRole::Mod(a) => {
// // },
// // UserRole::SupMod(a) => (),
// // UserRole::BotAdmin => (),
// // _ => (), // <-- do nothing with al other options
// // }
// // },
// // None => {
// // /*
// // - If trgRole is None , then promote by implicit rules . For example,
// // - For UserRoles without Mod or SupMod & Caller is SupMod | Broadcaster | BotAdmin > To Mod
// // - For Mod & Caller is SupMod | Broadcaster | BotAdmin > To SupMod
// // - For UserRoles without BotAdmin & Caller is BotAdmin > To BotAdmin
// // */
// // },
// // }
// // let trgRole = match trgRole {
// // Some(UserRole::Mod(a)) => a,
// // Some(UserRole::SupMod(a)) => a,
// // Some(UserRole::BotAdmin) => UserRole::BotAdmin,
// // None => {
// // /*
// // - If trgRole is None , then promote by implicit rules . For example,
// // - For UserRoles without Mod or SupMod & Caller is SupMod | Broadcaster | BotAdmin > To Mod
// // - For Mod & Caller is SupMod | Broadcaster | BotAdmin > To SupMod
// // - For UserRoles without BotAdmin & Caller is BotAdmin > To BotAdmin
// // */
// // },
// // };
// // if let Some(trgRole) = trgRole {
// // // [x] chatter already has the target role
// // if chatterroles.contains(&trgRole) {
// // return ChangeResult::NoChange(String::from("Target User already has Target Role"));
// // }
// // // [ ] trgRole should be assigned based on the input channel
// // let roletoassign = UserRole::
// // }
// },
// _ => (),
// }
2024-02-18 15:23:58 -05:00
botinstance ::botlog ::warn ( & format! ( " Runtime reached undeveloped code " ) ,
Some ( " identity.rs > promote() " . to_string ( ) ) , None ) ;
ChangeResult ::Failed ( String ::from ( " ERROR " ) )
2024-01-31 21:30:08 -05:00
}
2024-02-14 09:21:50 -05:00
pub async fn demote ( & self ,
authorizer :String ,
2024-02-18 15:23:58 -05:00
authorizer_badge :& Option < ChatBadge > ,
2024-02-14 09:21:50 -05:00
trgchatter :String ,
channel :Option < ChType > ,
2024-02-18 15:23:58 -05:00
// trg_role:Option<UserRole>
) -> ChangeResult
2024-02-14 09:21:50 -05:00
{
2024-02-18 15:23:58 -05:00
// botinstance::botlog::trace(&format!("IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?} ; Targer Role {:?}",
// authorizer,trgchatter,channel,trg_role),
botinstance ::botlog ::trace ( & format! ( " IN VARS for demote() : Authorizer : {:?} ; Target Chatter : {} ; Target Channel : {:?} " ,
authorizer , trgchatter , channel ) ,
2024-02-14 09:21:50 -05:00
Some ( " identity.rs > demote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
/*
Check authorizer roles ( if any ) for the target channel
2024-02-18 15:23:58 -05:00
Check Targer User ' s roles ( if any ) for the target channel
2024-02-14 09:21:50 -05:00
Target Channel may be NONE in the case of Non - Channel related roles ( FUTURE ENH )
Use the roles of the above to determine whether the authorizer can demote the target user or not
* /
2024-02-18 15:23:58 -05:00
// [x] 1. If Authorizer's Badge is Mod, ensuring Sender is in DB as Mod(Channel)
2024-02-14 09:21:50 -05:00
if let Some ( channel ) = channel {
2024-02-18 15:23:58 -05:00
let mut authusrroles = self . getspecialuserroles (
2024-02-14 09:21:50 -05:00
authorizer . to_lowercase ( ) . clone ( ) ,
Some ( channel . clone ( ) ) )
. await ;
// let authusrroles = authusrroles;
2024-02-18 15:23:58 -05:00
{
// let authusrroles_mut = &mut authusrroles;
// [x] Add Mod(channel) to authusrroles
// [x] #TODO also add to DB if possible?
match * authorizer_badge {
Some ( ChatBadge ::Mod ) if ( ! authusrroles . contains ( & UserRole ::Mod ( channel . clone ( ) ) )
& & ! authusrroles . contains ( & UserRole ::SupMod ( channel . clone ( ) ) )
) = > {
// (*authusrroles_mut).push(UserRole::Mod(channel.clone()));
authusrroles . push ( UserRole ::Mod ( channel . clone ( ) ) ) ;
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 ( channel . clone ( ) ) ) ;
}
_ = > ( ) ,
}
}
// [x] 2. Targer User's Vec<UserRole>
2024-02-14 09:21:50 -05:00
let trgusrroles = self . getspecialuserroles (
trgchatter . to_lowercase ( ) . clone ( ) ,
Some ( channel . clone ( ) ) )
. await ;
2024-02-18 15:23:58 -05:00
// [x] 3. Return if Authorizer & Target are same chatter and Authorizer is not a BotAdmin
if trgchatter = = authorizer & & ! authusrroles . contains ( & UserRole ::BotAdmin ) {
return ChangeResult ::NoChange ( " Can't target yourself " . to_string ( ) )
}
// [x] 4a. Authorizers who are BotAdmin, Broadcaster or Supermod can demote a Mod
2024-02-14 09:21:50 -05:00
if ( authusrroles . contains ( & UserRole ::BotAdmin ) | |
authusrroles . contains ( & UserRole ::Broadcaster ) | |
authusrroles . contains ( & UserRole ::SupMod ( channel . clone ( ) ) ) ) & &
trgusrroles . contains ( & UserRole ::Mod ( channel . clone ( ) ) )
{
let mut srulock = self . special_roles_users . write ( ) . await ;
let mut usrrolelock = srulock
. get_mut ( & trgchatter )
. expect ( " Error getting roles " )
. write ( ) . await ;
if let Some ( indx ) = usrrolelock . iter ( ) . position ( | value | * value = = UserRole ::Mod ( channel . clone ( ) ) ) {
usrrolelock . swap_remove ( indx ) ;
return ChangeResult ::Success ( " Demoted successfully " . to_string ( ) )
}
}
2024-02-18 15:23:58 -05:00
// [x] 4b. Authorizers who are BotAdmin, Broadcaster can demote a SupMod
2024-02-14 09:21:50 -05:00
else if ( authusrroles . contains ( & UserRole ::BotAdmin ) | |
authusrroles . contains ( & UserRole ::Broadcaster ) ) & &
trgusrroles . contains ( & UserRole ::SupMod ( channel . clone ( ) ) )
{
let mut srulock = self . special_roles_users . write ( ) . await ;
let mut usrrolelock = srulock
. get_mut ( & trgchatter )
. expect ( " Error getting roles " )
. write ( ) . await ;
2024-02-18 15:23:58 -05:00
usrrolelock . push ( UserRole ::Mod ( channel . clone ( ) ) ) ; // pushes Mod , and removes SupMod
2024-02-14 09:21:50 -05:00
if let Some ( indx ) = usrrolelock . iter ( ) . position ( | value | * value = = UserRole ::SupMod ( channel . clone ( ) ) ) {
usrrolelock . swap_remove ( indx ) ;
return ChangeResult ::Success ( " Demoted successfully " . to_string ( ) )
}
}
2024-02-18 15:23:58 -05:00
// [x] 4c. When Target chatter isnt a Mod or SupMod to demote
else if ! trgusrroles . contains ( & UserRole ::Mod ( channel . clone ( ) ) ) & &
! trgusrroles . contains ( & UserRole ::SupMod ( channel . clone ( ) ) ) {
return ChangeResult ::Failed ( " Target chatter does not have a role that can be demoted " . to_string ( ) )
}
// [x] 4d. WHhen they're only a Mod
else if authusrroles . contains ( & UserRole ::Mod ( channel . clone ( ) ) ) {
return ChangeResult ::Failed ( " You're not permitted to do that " . to_string ( ) )
}
2024-02-14 09:21:50 -05:00
}
2024-02-18 15:23:58 -05:00
botinstance ::botlog ::warn ( & format! ( " Potential Unhandled Demotion Condition : Consider explicitely adding in for better handling " ) ,
Some ( " identity.rs > demote() " . to_string ( ) ) , None ) ;
Log ::flush ( ) ;
2024-02-14 09:21:50 -05:00
ChangeResult ::Failed ( String ::from ( " Did not meet criteria to demote succesfully " ) )
2024-02-18 15:23:58 -05:00
2024-01-31 21:30:08 -05:00
}
2024-02-18 15:23:58 -05:00
2024-02-13 19:49:36 -05:00
// pub async fn getspecialuserroles(&self,chattername:String,channel:Option<ChType>) -> Option<Arc<RwLock<Vec<UserRole>>>> {
2024-02-18 15:23:58 -05:00
pub async fn getspecialuserroles (
& self , chattername :String ,
channel :Option < ChType > ) -> Vec < UserRole > {
2024-02-12 05:25:38 -05:00
/*
Note : Ideally this be called for a given chatter name ?
* /
2024-01-31 21:30:08 -05:00
2024-02-13 19:49:36 -05:00
// [ ] !!! 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! [ ] ;
2024-01-31 21:30:08 -05:00
2024-02-12 05:25:38 -05:00
let chattername = chattername . to_lowercase ( ) ;
2024-01-31 21:30:08 -05:00
2024-02-13 19:49:36 -05:00
// 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 ,
} ;
2024-02-12 05:25:38 -05:00
let rolesa = Arc ::clone ( & self . special_roles_users ) ;
let a = rolesa . read ( ) . await ;
// let a = Arc::clone(a)
let a = a ;
2024-02-13 19:49:36 -05:00
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
} ,
2024-02-04 14:28:37 -05:00
2024-02-12 05:25:38 -05:00
}
2024-02-04 14:28:37 -05:00
2024-02-13 19:49:36 -05:00
botinstance ::botlog ::debug ( & format! ( " OUT > evalsproles {:?} " , & evalsproles ) ,
Some ( " IdentityManager > getspecialuserroles() " . to_string ( ) ) , None ) ;
return evalsproles ;
2024-01-31 21:30:08 -05:00
}
2024-01-29 06:18:27 -05:00
}