diff --git a/sopel_modules/SpiceBot/Events.py b/sopel_modules/SpiceBot/Events.py index a795e92..8024bef 100644 --- a/sopel_modules/SpiceBot/Events.py +++ b/sopel_modules/SpiceBot/Events.py @@ -39,6 +39,7 @@ class BotEvents(object): self.RPL_ISUPPORT = '005' # This is a defined IRC event self.RPL_WHOREPLY = '352' # This is a defined IRC event self.RPL_NAMREPLY = '353' # This is a defined IRC event + self.RPL_WHOISREGNICK = '307' # this is an unrealircd event self.BOT_UPTIME = time.time() self.BOT_WELCOME = '1001' self.BOT_READY = '1002' diff --git a/sopel_modules/SpiceBot/Prerun.py b/sopel_modules/SpiceBot/Prerun.py index 51521e4..5598c35 100644 --- a/sopel_modules/SpiceBot/Prerun.py +++ b/sopel_modules/SpiceBot/Prerun.py @@ -36,7 +36,7 @@ def prerun(t_command_type='module', t_command_subtype=None): # Verify channel and user exist verify_channel(trigger) - verify_user(trigger) + verify_user(bot, trigger) botcom = class_create('botcom') @@ -130,7 +130,7 @@ def prerun_query(t_command_type='module', t_command_subtype=None): # Verify channel and user exist verify_channel(trigger) - verify_user(trigger) + verify_user(bot, trigger) botcom = class_create('botcom') @@ -189,9 +189,11 @@ def prerun_query(t_command_type='module', t_command_subtype=None): return actual_decorator -def verify_user(trigger): +def verify_user(bot, trigger): # Identify nick_id = botusers.whois_ident(trigger.nick) + # check if nick is registered + botusers.whois_send(bot, trigger.nick) # Verify nick is in the all list botusers.add_to_all(trigger.nick, nick_id) # Verify nick is in the all list @@ -283,6 +285,12 @@ def trigger_runstatus_query(bot, trigger, botcom): botmessagelog.messagelog_error(botcom.dict["log_id"], "The admin switch (-a) is for use by authorized nicks ONLY.") return False + # Stop here if not registered + if bot.config.SpiceBot_regnick.regnick: + if str(trigger.nick).lower() not in [x.lower() for x in botusers.dict["registered"]]: + message = "The query command requires you to be registerd with IRC services. Registering may take a few minutes to process with the bot." + return trigger_cant_run(bot, trigger, botcom, message) + # don't run commands that are disabled in channels if not trigger.is_privmsg: channel_disabled_list = botcommands.get_commands_disabled(str(trigger.sender)) @@ -334,6 +342,12 @@ def trigger_runstatus(bot, trigger, botcom): botmessagelog.messagelog_error(botcom.dict["log_id"], "The admin switch (-a) is for use by authorized nicks ONLY.") return False + # Stop here if not registered + if bot.config.SpiceBot_regnick.regnick: + if str(trigger.nick).lower() not in [x.lower() for x in botusers.dict["registered"]]: + message = "The " + str(botcom.dict["comtext"]) + " command requires you to be registerd with IRC services. Registering may take a few minutes to process with the bot." + return trigger_cant_run(bot, trigger, botcom, message) + # if botcom.dict["hyphen_arg"]: # return False diff --git a/sopel_modules/SpiceBot/RegNicks.py b/sopel_modules/SpiceBot/RegNicks.py new file mode 100644 index 0000000..e174cb4 --- /dev/null +++ b/sopel_modules/SpiceBot/RegNicks.py @@ -0,0 +1,11 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot regnick system. +""" + +from sopel.config.types import StaticSection, ValidatedAttribute + + +class SpiceBot_RegNicks_MainSection(StaticSection): + regnick = ValidatedAttribute('regnick', default=False) diff --git a/sopel_modules/SpiceBot/Users.py b/sopel_modules/SpiceBot/Users.py index e944b4f..0fc51ea 100644 --- a/sopel_modules/SpiceBot/Users.py +++ b/sopel_modules/SpiceBot/Users.py @@ -12,6 +12,7 @@ from sopel_modules.spicemanip import spicemanip import threading import re +import time # TODO timestamp for new .seen @@ -28,6 +29,8 @@ class BotUsers(): "offline": [], "away": [], "current": {}, + "registered": botdb.get_bot_value('regged_users') or [], + "notregistered": {}, } """during setup, all users from database are offline until marked online""" for user_id in list(self.dict["all"].keys()): @@ -72,6 +75,7 @@ class BotUsers(): def save_user_db(self): botdb.set_bot_value('users', self.dict["all"]) + botdb.set_bot_value('regged_users', self.dict["registered"]) def add_to_all(self, nick, nick_id=None): self.lock.acquire() @@ -101,6 +105,8 @@ class BotUsers(): for user in list(bot.channels[channel].privileges.keys()): # Identify nick_id = self.whois_ident(user) + # check if nick is registered + self.whois_send(bot, user) # Verify nick is in the all list self.add_to_all(user, nick_id) # Verify nick is in the all list @@ -150,6 +156,8 @@ class BotUsers(): for user in list(bot.channels[trigger.sender].privileges.keys()): # Identify nick_id = self.whois_ident(user) + # check if nick is registered + self.whois_send(bot, user) # Verify nick is in the all list self.add_to_all(user, nick_id) # Verify nick is in the all list @@ -163,6 +171,8 @@ class BotUsers(): return # Identify nick_id = self.whois_ident(trigger.nick) + # check if nick is registered + self.whois_send(bot, trigger.nick) # Verify nick is in the all list self.add_to_all(trigger.nick, nick_id) # Verify nick is in the all list @@ -179,6 +189,8 @@ class BotUsers(): return # Identify nick_id = self.whois_ident(trigger.nick) + # check if nick is registered + self.whois_send(bot, trigger.nick) # Verify nick is in the all list self.add_to_all(trigger.nick, nick_id) # Verify nick is in the all list @@ -195,6 +207,8 @@ class BotUsers(): return # Identify nick_id = self.whois_ident(trigger.nick) + # check if nick is registered + self.whois_send(bot, trigger.nick) # Verify nick is in the all list self.add_to_all(trigger.nick, nick_id) # Verify nick is in the all list @@ -213,6 +227,8 @@ class BotUsers(): return # Identify nick_id = self.whois_ident(trigger.nick) + # check if nick is registered + self.whois_send(bot, trigger.nick) # Verify nick is in the all list self.add_to_all(trigger.nick, nick_id) # Verify nick is in the all list @@ -232,6 +248,8 @@ class BotUsers(): return # Identify nick_id = self.whois_ident(targetnick) + # check if nick is registered + self.whois_send(bot, targetnick) # Verify nick is in the all list self.add_to_all(targetnick, nick_id) # Verify nick is in the all list @@ -247,6 +265,8 @@ class BotUsers(): newnick = Identifier(trigger) if oldnick == bot.nick or newnick == bot.nick: return + # check if nick is registered + self.whois_send(bot, newnick) # Verify nick is in the all list self.add_to_all(oldnick, old_nick_id) # Verify nick is in the all list @@ -297,6 +317,8 @@ class BotUsers(): self.add_channel(channel, nick_id) # mark user as online self.mark_user_online(nick_id) + # check if nick is registered + self.whois_send(bot, nick) def rpl_who(self, bot, trigger): if len(trigger.args) < 2 or trigger.args[1] not in self.who_reqs: @@ -319,6 +341,34 @@ class BotUsers(): self.add_channel(channel, nick_id) # mark user as online self.mark_user_online(nick_id) + # check if nick is registered + self.whois_send(bot, nick) + + def rpl_whois(self, bot, trigger): + if not bot.config.SpiceBot_regnick.regnick: + return + nick = trigger.args[1] + if str(nick).lower() in [x.lower() for x in self.dict["registered"]]: + return + self.whois_handle(nick) + + def whois_handle(self, nick): + self.lock.acquire() + if str(nick).lower() not in [x.lower() for x in self.dict["registered"]]: + self.dict["registered"].append(str(nick)) + else: + self.dict["notregistered"][str(nick).lower()] = time.time() + self.lock.release() + + def whois_send(self, bot, nick): + if not bot.config.SpiceBot_regnick.regnick: + return + if str(nick).lower() in [x.lower() for x in list(self.dict["notregistered"].keys())]: + timestamp = self.dict["notregistered"][str(nick).lower()] + if time.time() - timestamp < 240: + return + if str(nick).lower() not in [x.lower() for x in self.dict["registered"]]: + bot.write(['WHOIS', str(nick)]) def account(self, bot, trigger): # Identify @@ -423,6 +473,12 @@ class BotUsers(): if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]: return {"targetgood": False, "error": "It looks like " + self.nick_actual(target) + " is online right now, but in a different channel.", "reason": "diffchannel"} + # not a registered nick + if "unregged" not in targetbypass: + if bot.config.SpiceBot_regnick.regnick: + if str(nick).lower() not in [x.lower() for x in self.dict["registered"]]: + return {"targetgood": False, "error": "It looks like " + self.nick_actual(target) + " is not a registered nick.", "reason": "unregged"} + return targetgood def random_valid_target(self, bot, trigger, outputtype): diff --git a/sopel_modules/SpiceBot/__init__.py b/sopel_modules/SpiceBot/__init__.py index e5c42bc..13a8f1f 100644 --- a/sopel_modules/SpiceBot/__init__.py +++ b/sopel_modules/SpiceBot/__init__.py @@ -38,6 +38,7 @@ from .DictComs import * from .Read import * from .Translate import * from .Version import * +from .RegNicks import * __author__ = 'Sam Zick' diff --git a/sopel_modules/SpiceBot/configure.py b/sopel_modules/SpiceBot/configure.py index 9e59a47..1358c01 100644 --- a/sopel_modules/SpiceBot/configure.py +++ b/sopel_modules/SpiceBot/configure.py @@ -13,6 +13,7 @@ from .Reddit import SpiceBot_Reddit_MainSection from .Sherlock import SpiceBot_Sherlock_MainSection from .Kick import SpiceBot_Kick from .osd import SpiceBot_OSD +from .RegNicks import SpiceBot_RegNicks_MainSection def configure(config): @@ -62,3 +63,6 @@ def configure(config): config.define_section("SpiceBot_Sherlock", SpiceBot_Sherlock_MainSection, validate=False) config.SpiceBot_Sherlock.configure_setting('extra', 'SpiceBot_Sherlock API Extra directory') + + config.define_section("SpiceBot_regnick", SpiceBot_RegNicks_MainSection, validate=False) + config.SpiceBot_Channels.configure_setting('regnick', 'SpiceBot_regnick Only allow regged nicks') diff --git a/sopel_modules/SpiceBot/setup.py b/sopel_modules/SpiceBot/setup.py index f67bbcc..d0f5896 100644 --- a/sopel_modules/SpiceBot/setup.py +++ b/sopel_modules/SpiceBot/setup.py @@ -22,6 +22,7 @@ from .Gif import SpiceBot_Gif_MainSection from .DictComs import SpiceBot_DictComs_MainSection from .Sherlock import SpiceBot_Sherlock_MainSection from .AI import SpiceBot_AI_MainSection +from .RegNicks import SpiceBot_RegNicks_MainSection def setup(bot): @@ -64,6 +65,8 @@ def setup(bot): setup_sherlock(bot) + setup_regnicks(bot) + def setup_config(bot): logs.log('SpiceBot_Config', "Setting Up Configuration") @@ -167,3 +170,8 @@ def setup_dictcoms(bot): def setup_sherlock(bot): bot.config.define_section("SpiceBot_Sherlock", SpiceBot_Sherlock_MainSection, validate=False) + + +def setup_regnicks(bot): + bot.config.define_section("SpiceBot_regnick", SpiceBot_RegNicks_MainSection, validate=False) + botconfig.define_section("SpiceBot_regnick", SpiceBot_RegNicks_MainSection, validate=False) diff --git a/sopel_modules/SpiceBot_Core_Commands/RegNicks.py b/sopel_modules/SpiceBot_Core_Commands/RegNicks.py new file mode 100644 index 0000000..61bd66a --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/RegNicks.py @@ -0,0 +1,23 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot regnicks system. +""" +import sopel + +import sopel_modules.SpiceBot as SpiceBot +from sopel_modules.spicemanip import spicemanip + + +@SpiceBot.prerun('nickname') +@sopel.module.nickname_commands('regnicks', 'regnick') +def nickname_comand_regnicks(bot, trigger, botcom): + reggedusers = SpiceBot.users.dict["registered"] + bot.osd("These users are registered " + spicemanip(reggedusers, 'andlist') + ".", trigger.sender, 'notice') + notregged = [] + for user in SpiceBot.users.dict["online"]: + usernick = SpiceBot.users.ID(user) + if str(usernick).lower() not in [x.lower() for x in SpiceBot.users.dict["registered"]]: + if usernick != bot.nick: + notregged.append(usernick) + bot.osd("These online users are not registered " + spicemanip(notregged, 'andlist') + ".", trigger.sender, 'notice') diff --git a/sopel_modules/SpiceBot_Core_Commands/__init__.py b/sopel_modules/SpiceBot_Core_Commands/__init__.py index 009efa8..fbf890c 100644 --- a/sopel_modules/SpiceBot_Core_Commands/__init__.py +++ b/sopel_modules/SpiceBot_Core_Commands/__init__.py @@ -23,6 +23,7 @@ from .AI import * from .DictComs import * from .TODO import * from .Version import * +from .RegNicks import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_Core_Processing/Users.py b/sopel_modules/SpiceBot_Core_Processing/Users.py index 07a7009..eee2e70 100644 --- a/sopel_modules/SpiceBot_Core_Processing/Users.py +++ b/sopel_modules/SpiceBot_Core_Processing/Users.py @@ -80,3 +80,9 @@ def account_notify_users(bot, trigger): @sopel.module.rule('.*') def track_notify_users(bot, trigger): SpiceBot.users.track_notify(bot, trigger) + + +@sopel.module.event(SpiceBot.events.RPL_WHOISREGNICK) +@sopel.module.rule('.*') +def bot_whois_user(bot, trigger): + SpiceBot.users.rpl_whois(bot, trigger)