From 81027f3a0888ac4c8e3fb6ea90081492defce946 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 20 Mar 2017 11:43:24 +0000 Subject: Move the OnCheckExemption hook out of the core. --- src/coremods/core_channel/cmd_topic.cpp | 12 ++++++-- src/coremods/core_channel/core_channel.cpp | 45 ++++++++++++++++++++++++++++-- src/coremods/core_channel/core_channel.h | 2 ++ 3 files changed, 53 insertions(+), 6 deletions(-) (limited to 'src/coremods/core_channel') diff --git a/src/coremods/core_channel/cmd_topic.cpp b/src/coremods/core_channel/cmd_topic.cpp index 6d99edcc6..ec6ed9744 100644 --- a/src/coremods/core_channel/cmd_topic.cpp +++ b/src/coremods/core_channel/cmd_topic.cpp @@ -25,6 +25,7 @@ CommandTopic::CommandTopic(Module* parent) : SplitCommand(parent, "TOPIC", 1, 2) + , exemptionprov(parent) , secretmode(parent, "secret") , topiclockmode(parent, "topiclock") { @@ -73,10 +74,15 @@ CmdResult CommandTopic::HandleLocal(const std::vector& parameters, user->WriteNumeric(ERR_NOTONCHANNEL, c->name, "You're not on that channel!"); return CMD_FAILURE; } - if (c->IsModeSet(topiclockmode) && !ServerInstance->OnCheckExemption(user, c, "topiclock").check(c->GetPrefixValue(user) >= HALFOP_VALUE)) + if (c->IsModeSet(topiclockmode)) { - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, "You do not have access to change the topic on this channel"); - return CMD_FAILURE; + ModResult MOD_RESULT; + FIRST_MOD_RESULT_CUSTOM(exemptionprov, CheckExemption::EventListener, OnCheckExemption, MOD_RESULT, (user, c, "topiclock")); + if (!MOD_RESULT.check(c->GetPrefixValue(user) >= HALFOP_VALUE)) + { + user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, "You do not have access to change the topic on this channel"); + return CMD_FAILURE; + } } } diff --git a/src/coremods/core_channel/core_channel.cpp b/src/coremods/core_channel/core_channel.cpp index aba4d9769..b77aac7e2 100644 --- a/src/coremods/core_channel/core_channel.cpp +++ b/src/coremods/core_channel/core_channel.cpp @@ -21,7 +21,7 @@ #include "core_channel.h" #include "invite.h" -class CoreModChannel : public Module +class CoreModChannel : public Module, public CheckExemption::EventListener { Invite::APIImpl invapi; CommandInvite cmdinvite; @@ -29,6 +29,7 @@ class CoreModChannel : public Module CommandKick cmdkick; CommandNames cmdnames; CommandTopic cmdtopic; + insp::flat_map exemptions; ModResult IsInvited(User* user, Channel* chan) { @@ -40,8 +41,13 @@ class CoreModChannel : public Module public: CoreModChannel() - : invapi(this) - , cmdinvite(this, invapi), cmdjoin(this), cmdkick(this), cmdnames(this), cmdtopic(this) + : CheckExemption::EventListener(this) + , invapi(this) + , cmdinvite(this, invapi) + , cmdjoin(this) + , cmdkick(this) + , cmdnames(this) + , cmdtopic(this) { } @@ -56,6 +62,23 @@ class CoreModChannel : public Module for (unsigned int i = 0; i < sizeof(events)/sizeof(Implementation); i++) ServerInstance->Modules.Detach(events[i], this); } + + std::string current; + irc::spacesepstream defaultstream(optionstag->getString("exemptchanops")); + insp::flat_map exempts; + while (defaultstream.GetToken(current)) + { + std::string::size_type pos = current.find(':'); + if (pos == std::string::npos || (pos + 2) > current.size()) + throw ModuleException("Invalid exemptchanops value '" + current + "' at " + optionstag->getTagLocation()); + + const std::string restriction = current.substr(0, pos); + const char prefix = current[pos + 1]; + + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Exempting prefix %c from %s", prefix, restriction.c_str()); + exempts[restriction] = prefix; + } + exemptions.swap(exempts); } void OnPostJoin(Membership* memb) CXX11_OVERRIDE @@ -110,6 +133,22 @@ class CoreModChannel : public Module invapi.RemoveAll(chan); } + ModResult OnCheckExemption(User* user, Channel* chan, const std::string& restriction) CXX11_OVERRIDE + { + if (!exemptions.count(restriction)) + return MOD_RES_PASSTHRU; + + unsigned int mypfx = chan->GetPrefixValue(user); + char minmode = exemptions[restriction]; + + PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(minmode); + if (mh && mypfx >= mh->GetPrefixRank()) + return MOD_RES_ALLOW; + if (mh || minmode == '*') + return MOD_RES_DENY; + return MOD_RES_PASSTHRU; + } + void Prioritize() CXX11_OVERRIDE { ServerInstance->Modules.SetPriority(this, I_OnPostJoin, PRIORITY_FIRST); diff --git a/src/coremods/core_channel/core_channel.h b/src/coremods/core_channel/core_channel.h index 0dafde8cb..19a984827 100644 --- a/src/coremods/core_channel/core_channel.h +++ b/src/coremods/core_channel/core_channel.h @@ -20,6 +20,7 @@ #pragma once #include "inspircd.h" +#include "modules/exemption.h" namespace Topic { @@ -72,6 +73,7 @@ class CommandJoin : public SplitCommand */ class CommandTopic : public SplitCommand { + CheckExemption::EventProvider exemptionprov; ChanModeReference secretmode; ChanModeReference topiclockmode; -- cgit v1.2.3