working identity > can_user_run()

This commit is contained in:
ModulatingForce 2024-01-29 22:57:07 -05:00
parent 5f7ea5d2a7
commit e63133aee6
4 changed files with 224 additions and 39 deletions

View file

@ -22,7 +22,7 @@ use crate::core::ratelimiter;
use crate::core::botmodules;
use crate::core::botmodules::ModulesManager;
use crate::core::identity::IdentityManager;
use crate::core::identity::{IdentityManager,Permissible};
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
@ -222,7 +222,7 @@ impl BotInstance
while let Some(message) = self.incoming_messages.recv().await {
// Below can be used to debug if I want to capture all messages
println!("Received message: {:?}", message);
// println!("Received message: {:?}", message);
match message {
ServerMessage::Notice(msg) => {
@ -271,7 +271,8 @@ impl BotInstance
// PRIVATE FUNCTIONS
async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () {
// async fn listener_main_prvmsg(&mut self,msg:PrivmsgMessage) -> () {
async fn listener_main_prvmsg(&self,msg:PrivmsgMessage) -> () {
// println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
@ -286,6 +287,11 @@ impl BotInstance
/*
BotCommand handling -
- [x] Checks if the input message is a prefix with command name or alias
- [ ] Validate User can run based on identityModule(From_Bot)::can_user_run(
_usr:String,
_channelname:ChType,
_chat_badge:ChatBadge,
_cmdreqroles:Vec<UserRole>)
*/
let inpt = msg.message_text.split("\n").next().expect("ERROR during BotCommand");
@ -293,20 +299,40 @@ impl BotInstance
// [x] Check if a bot command based on ...
// [x] prefix + command
let mut exec_bot_command = false;
let mut confirmed_bot_command = false;
if inpt == self.prefix.to_string() + c.command.as_str() {
exec_bot_command = true;
confirmed_bot_command = true;
}
// [x] prefix + alias
for alias in &c.alias {
if inpt == self.prefix.to_string() + alias.as_str() {
exec_bot_command = true;
confirmed_bot_command = true;
}
}
if exec_bot_command {
c.execute(self.chat.clone(), msg.clone()).await;
if confirmed_bot_command {
// self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone());
// [ ] Around here, validate if permissable before executing
// match self.identity.clone().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
// Ok(Permissible::Allow) => c.execute(self.chat.clone(), msg.clone()).await,
// Ok(Permissible::Block) => println!("User Not allowed to run command"),
// _ => (),
// }
match self.identity.to_owned().can_user_run_PRVMSG(&msg, c.required_roles.clone()) {
// Ok(Permissible::Allow) => (),
Permissible::Allow => {
println!("Executed as permissible");
c.execute(self.chat.clone(), msg.clone()).await;
}
Permissible::Block => println!("User Not allowed to run command"),
// _ => (),
}
// c.execute(self.chat.clone(), msg.clone()).await;
}
},

View file

@ -34,7 +34,7 @@ pub enum ModType {
pub use ModType::BotModule;
#[derive(Debug, PartialEq, Eq, Hash)]
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum ChType {
Channel(String),
}

View file

@ -6,7 +6,7 @@ use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait,
use crate::core::botmodules::bot_actions::actions_util;
use crate::core::botinstance::{self};
use twitch_irc::message::PrivmsgMessage;
use twitch_irc::message::{Badge, PrivmsgMessage};
use crate::core::botmodules::ChType;
@ -29,7 +29,7 @@ pub fn init(mgr:&mut ModulesManager)
async fn cmd_promote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) {
//println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
println!("Called cmd promote");
}
@ -44,13 +44,19 @@ pub fn init(mgr:&mut ModulesManager)
async fn cmd_demote(mut _chat:botinstance::Chat,_msg:PrivmsgMessage) {
println!("Called cmd demote");
}
}
// #[derive(Debug, PartialEq, Eq, Hash, Clone)]
// pub enum ChType {
// Channel(String),
// }
#[derive(Debug, PartialEq, Eq , Clone)]
pub enum UserRole {
Chatter,
Mod(ChType), // String specifies Channel
@ -61,16 +67,17 @@ pub enum UserRole {
}
enum Permissible {
pub enum Permissible {
Allow,
Block
}
#[derive(Clone)]
pub struct IdentityManager {
special_roles_users : HashMap<String,Vec<UserRole>>,
special_roles_users : HashMap<String,Vec<UserRole>>, // # <-- (!) This must be String instead of ChType because we're checking a User not a Channel
}
enum ChatBadge {
pub enum ChatBadge {
Broadcaster,
Mod,
}
@ -89,19 +96,57 @@ impl IdentityManager {
}
}
pub fn canUserRun(self,
// [ ] 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>>
pub fn can_user_run_PRVMSG(self,msg:&PrivmsgMessage,cmdreqroles:Vec<UserRole>) -> Permissible
{
// println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
// [ ] Check what Badges in PrivmsgMessage
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{}) {
// }
if let Some(sender_badge) = sender_badge {
return self.can_user_run(msg.sender.name.to_owned(),
ChType::Channel(msg.channel_login.to_owned()),
sender_badge,
cmdreqroles
) ;
}
// [ ] Call can_user_run()
Permissible::Block
}
pub fn can_user_run(mut self,
usr:String,
channelname:ChType,
chatBadge:ChatBadge,
chat_badge:ChatBadge,
cmdreqroles:Vec<UserRole>
) -> Result<Permissible,Box<dyn Error>> {
// ) -> Result<Permissible,Box<dyn Error>> {
) -> Permissible {
/*
canUserRun -
Input :
usr:String,
channelname:ChType,
chatBadge:ChatBadge,
chat_badge:ChatBadge,
cmdreqroles:Vec<UserRole>
Output : Result<Permissible,Box<dyn Error>>
@ -118,18 +163,125 @@ impl IdentityManager {
// Requirements
/*
[ ] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow)
[ ] If chatBadge::Broadcaster ...
[ ] and cmdreqroles includes UserRole::Broadcaster , Ok(Permissible::Allow)
[ ] and cmdreqroles includes UserRole::Mod("") OR UserRole::SupMod("") , Ok(Permissible::Allow)
[ ] If cmdreqroles includes UserRole::Mod("") , checks if chatter has UserRole::Mod(channelname::ChType) to determine if Ok(Permissible::Allow)
[ ] If cmdreqroles includes UserRole::SupMod("") , checks if chatter has UserRole::SupMod(channelname::ChType) to determine if Ok(Permissible::Allow)
[ ] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow)
[ ] Otherwise, Ok(Permissible::Block)
[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)
*/
// [x] If cmdreqroles is empty vector , automatically assume Ok(Permissible::Allow)
Ok(Permissible::Allow)
if cmdreqroles.len() == 0 {
// return Ok(Permissible::Allow)
return Permissible::Allow
}
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)
ChatBadge::Broadcaster => {
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)
return 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)
ChatBadge::Mod => {
println!("Mod Chatbadge detected");
println!("debug special roles : {:?}",self.special_roles_users);
println!("debug usr : {}",&usr.to_lowercase());
// let Some((k,v)) = self.special_roles_users.get_key_value(usr);
match self.special_roles_users.get_mut(&usr.to_lowercase()) {
Some(usrroles) => {
println!("contains mod : {}", usrroles.contains(&UserRole::Mod(channelname.clone())));
println!("contains supmod : {}", usrroles.contains(&UserRole::SupMod(channelname.clone())));
if usrroles.contains(&UserRole::Mod(channelname.clone())) ||
usrroles.contains(&UserRole::SupMod(channelname.clone())) {
// Do nothing - this is expected
} else {
// in this case, they have a ChatBadge::Mod but should have this for the channel
usrroles.push(UserRole::Mod(channelname.clone()));
println!("debug special roles : {:?}",self.special_roles_users);
}
},
_ => ()
}
},
// _ => (),
}
// [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)
println!("cmd required roles : {:?}",cmdreqroles);
if cmdreqroles.contains(&UserRole::Mod(ChType::Channel(String::new()))) {
// match self.special_roles_users.get(&channelname) {
// Some(usrroles) => {},
// None => (),
// }
println!("Mod Role required");
if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) {
if a.contains(&UserRole::Mod(channelname.clone())) || a.contains(&UserRole::SupMod(channelname.clone())){
// return Ok(Permissible::Allow);
return Permissible::Allow
}
}
}
// [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()))) {
if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) {
if a.contains(&UserRole::SupMod(channelname.clone())) {
// return Ok(Permissible::Allow);
return Permissible::Allow
}
}
}
// [x] If cmdreqroles includes UserRole::BotAdmin and chatter has UserRole::BotAdmin , Ok(Permissible::Allow)
println!("Eval cmdreqroles with botadmin : {}",cmdreqroles.contains(&UserRole::BotAdmin));
if cmdreqroles.contains(&UserRole::BotAdmin) {
println!("special roles get : {:?}",self.special_roles_users.get(&usr.to_lowercase()));
if let Some(a) = self.special_roles_users.get(&usr.to_lowercase()) {
println!("special roles contains BotAdmin: {}",a.contains(&UserRole::BotAdmin));
if a.contains(&UserRole::BotAdmin) {
// return Ok(Permissible::Allow);
return Permissible::Allow
}
}
}
Permissible::Block
}
}

View file

@ -14,12 +14,14 @@
use std::future::Future;
use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand};
use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait, BotCommand,ChType};
use crate::core::botmodules::bot_actions::actions_util;
use crate::core::botinstance::{self};
use twitch_irc::message::PrivmsgMessage;
use crate::core::identity;
pub fn init(mgr:&mut ModulesManager)
{
@ -30,7 +32,10 @@ pub fn init(mgr:&mut ModulesManager)
alias : vec![String::from("tester1"),String::from("testy1")], // String of alternative names
exec_body : actions_util::asyncbox(testy) ,
help : String::from("DUPCMD4 tester"),
required_roles : vec![],
required_roles : vec![
//identity::UserRole::Mod(ChType::Channel(String::new())),
identity::UserRole::SupMod(ChType::Channel(String::new()))
],
}.add_to_modmgr(mgr);
@ -40,19 +45,21 @@ pub fn init(mgr:&mut ModulesManager)
alias : vec![String::from("tester2"),String::from("testy2")], // String of alternative names
exec_body : actions_util::asyncbox(testy) ,
help : String::from("DUPCMD4 tester"),
required_roles : vec![],
required_roles : vec![
identity::UserRole::BotAdmin
],
}.add_to_modmgr(mgr);
let list1 = Listener {
module : BotModule(String::from("experiments 004")),
name : String::from("GoodGirl Listener"),
exec_body : actions_util::asyncbox(good_girl) ,
help : String::from("")
};
// let list1 = Listener {
// module : BotModule(String::from("experiments 004")),
// name : String::from("GoodGirl Listener"),
// exec_body : actions_util::asyncbox(good_girl) ,
// help : String::from("")
// };
list1.add_to_modmgr(mgr);
// list1.add_to_modmgr(mgr);
}