diff options
author | Peter Powell <petpow@saberuk.com> | 2017-07-27 13:13:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-27 13:13:16 +0100 |
commit | ff3b706b2506d7614bce5e54bc88657bd62ebd4d (patch) | |
tree | dbfbe3df3df3668f0e1ac531229b4e15ff240754 /src/coremods | |
parent | bb4aa10ed82612624da45d0c9592ddf7f2f51ab5 (diff) | |
parent | 81027f3a0888ac4c8e3fb6ea90081492defce946 (diff) |
Merge pull request #1271 from SaberUK/master+exemption
Move the OnCheckExemption hook out of the core.
Diffstat (limited to 'src/coremods')
-rw-r--r-- | src/coremods/core_channel/cmd_topic.cpp | 12 | ||||
-rw-r--r-- | src/coremods/core_channel/core_channel.cpp | 45 | ||||
-rw-r--r-- | src/coremods/core_channel/core_channel.h | 2 |
3 files changed, 53 insertions, 6 deletions
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<std::string>& 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 6fe6199db..3af809645 100644 --- a/src/coremods/core_channel/core_channel.cpp +++ b/src/coremods/core_channel/core_channel.cpp @@ -22,7 +22,7 @@ #include "invite.h" #include "listmode.h" -class CoreModChannel : public Module +class CoreModChannel : public Module, public CheckExemption::EventListener { Invite::APIImpl invapi; CommandInvite cmdinvite; @@ -30,6 +30,7 @@ class CoreModChannel : public Module CommandKick cmdkick; CommandNames cmdnames; CommandTopic cmdtopic; + insp::flat_map<std::string, char> exemptions; ModResult IsInvited(User* user, Channel* chan) { @@ -41,8 +42,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) { } @@ -57,6 +63,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<std::string, char> 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 On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE @@ -135,6 +158,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; |