summaryrefslogtreecommitdiff
path: root/src/coremods
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2017-07-27 13:13:16 +0100
committerGitHub <noreply@github.com>2017-07-27 13:13:16 +0100
commitff3b706b2506d7614bce5e54bc88657bd62ebd4d (patch)
treedbfbe3df3df3668f0e1ac531229b4e15ff240754 /src/coremods
parentbb4aa10ed82612624da45d0c9592ddf7f2f51ab5 (diff)
parent81027f3a0888ac4c8e3fb6ea90081492defce946 (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.cpp12
-rw-r--r--src/coremods/core_channel/core_channel.cpp45
-rw-r--r--src/coremods/core_channel/core_channel.h2
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;