From 6830169ef13d4599916496b149c72577e6fb297d Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 11 Apr 2022 23:49:10 +0100 Subject: Add a method for finding the next prefix mode above a rank. --- src/mode.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src/mode.cpp') diff --git a/src/mode.cpp b/src/mode.cpp index 4ab91fc6b..8fdbcdea0 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -286,18 +286,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode unsigned int ourrank = chan->GetPrefixValue(user); if (ourrank < neededrank) { - const PrefixMode* neededmh = NULL; - const PrefixModeList& prefixmodes = GetPrefixModes(); - for (PrefixModeList::const_iterator i = prefixmodes.begin(); i != prefixmodes.end(); ++i) - { - const PrefixMode* const privmh = *i; - if (privmh->GetPrefixRank() >= neededrank) - { - // this mode is sufficient to allow this action - if (!neededmh || privmh->GetPrefixRank() < neededmh->GetPrefixRank()) - neededmh = privmh; - } - } + const PrefixMode* neededmh = FindNearestPrefixMode(neededrank); if (neededmh) user->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, InspIRCd::Format("You must have channel %s access or above to %sset channel mode %c", neededmh->name.c_str(), adding ? "" : "un", modechar)); @@ -732,6 +721,24 @@ PrefixMode* ModeParser::FindPrefixMode(unsigned char modeletter) return mh->IsPrefixMode(); } +PrefixMode* ModeParser::FindNearestPrefixMode(unsigned int rank) +{ + PrefixMode* pm = NULL; + const PrefixModeList& prefixmodes = GetPrefixModes(); + for (PrefixModeList::const_iterator i = prefixmodes.begin(); i != prefixmodes.end(); ++i) + { + PrefixMode* thispm = *i; + if (thispm->GetPrefixRank() < rank) + continue; // Not ranked high enough. + + // Is it lower than the last checked mode? + if (!pm || thispm->GetPrefixRank() < pm->GetPrefixRank()) + pm = thispm; + + } + return pm; +} + PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter) { const PrefixModeList& list = GetPrefixModes(); -- cgit v1.3.1-10-gc9f91 From 7266f8681d603c58e1281f3e7e2934d61f910ea4 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 12 Apr 2022 12:48:54 +0100 Subject: Add a numeric builder for the ERR_CHANOPRIVSNEEDED numeric. This should make privilege errors more consistent. --- include/numericbuilder.h | 18 ++++++++++++++++++ src/coremods/core_channel/cmd_invite.cpp | 5 +---- src/coremods/core_channel/cmd_kick.cpp | 3 +-- src/coremods/core_channel/cmd_topic.cpp | 2 +- src/mode.cpp | 8 ++------ src/modules/m_hidelist.cpp | 2 +- src/modules/m_rmode.cpp | 7 ++----- src/modules/m_sslinfo.cpp | 2 +- src/modules/m_timedbans.cpp | 2 +- src/modules/m_uninvite.cpp | 2 +- 10 files changed, 29 insertions(+), 22 deletions(-) (limited to 'src/mode.cpp') diff --git a/include/numericbuilder.h b/include/numericbuilder.h index a077c666d..658b9ddbf 100644 --- a/include/numericbuilder.h +++ b/include/numericbuilder.h @@ -201,6 +201,7 @@ class Numeric::ParamBuilder : public GenericParamBuildername); + + const PrefixMode* pm = ServerInstance->Modes.FindNearestPrefixMode(rank); + if (pm) + push(InspIRCd::Format("You must be a channel %s or higher to %s.", pm->name.c_str(), message.c_str())); + else + push(InspIRCd::Format("You do not have the required channel privileges to %s.", message.c_str())); + } +}; + /* Builder for the ERR_INVALIDMODEPARAM numeric. */ class Numerics::InvalidModeParameter : public Numeric::Numeric { diff --git a/src/coremods/core_channel/cmd_invite.cpp b/src/coremods/core_channel/cmd_invite.cpp index 258c8c643..81b56f949 100644 --- a/src/coremods/core_channel/cmd_invite.cpp +++ b/src/coremods/core_channel/cmd_invite.cpp @@ -127,10 +127,7 @@ CmdResult CommandInvite::Handle(User* user, const Params& parameters) unsigned int rank = c->GetPrefixValue(user); if (rank < HALFOP_VALUE) { - // Check whether halfop mode is available and phrase error message accordingly - ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL); - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, InspIRCd::Format("You must be a channel %soperator", - (mh && mh->name == "halfop" ? "half-" : ""))); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(c, HALFOP_VALUE, "send an invite")); return CMD_FAILURE; } } diff --git a/src/coremods/core_channel/cmd_kick.cpp b/src/coremods/core_channel/cmd_kick.cpp index 477c6fe25..0440f9cfb 100644 --- a/src/coremods/core_channel/cmd_kick.cpp +++ b/src/coremods/core_channel/cmd_kick.cpp @@ -123,8 +123,7 @@ CmdResult CommandKick::Handle(User* user, const Params& parameters) if (them < req) { - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, InspIRCd::Format("You must be a channel %soperator", - req > HALFOP_VALUE ? "" : "half-")); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(memb->chan, req, "kick a more privileged user")); return CMD_FAILURE; } } diff --git a/src/coremods/core_channel/cmd_topic.cpp b/src/coremods/core_channel/cmd_topic.cpp index ab60f54f5..020d0c66e 100644 --- a/src/coremods/core_channel/cmd_topic.cpp +++ b/src/coremods/core_channel/cmd_topic.cpp @@ -84,7 +84,7 @@ CmdResult CommandTopic::HandleLocal(LocalUser* user, const Params& parameters) ModResult MOD_RESULT = CheckExemption::Call(exemptionprov, 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"); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(c, HALFOP_VALUE, "change the topic")); return CMD_FAILURE; } } diff --git a/src/mode.cpp b/src/mode.cpp index 8fdbcdea0..7ac165bf4 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -286,12 +286,8 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode unsigned int ourrank = chan->GetPrefixValue(user); if (ourrank < neededrank) { - const PrefixMode* neededmh = FindNearestPrefixMode(neededrank); - if (neededmh) - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, InspIRCd::Format("You must have channel %s access or above to %sset channel mode %c", - neededmh->name.c_str(), adding ? "" : "un", modechar)); - else - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, InspIRCd::Format("You cannot %sset channel mode %c", (adding ? "" : "un"), modechar)); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(chan, neededrank, InspIRCd::Format("%s channel mode %c (%s)", + adding ? "set" : "unset", mh->GetModeChar(), mh->name.c_str()))); return MODEACTION_DENY; } } diff --git a/src/modules/m_hidelist.cpp b/src/modules/m_hidelist.cpp index d076e2e63..e495c148b 100644 --- a/src/modules/m_hidelist.cpp +++ b/src/modules/m_hidelist.cpp @@ -48,7 +48,7 @@ class ListWatcher : public ModeWatcher if (user->HasPrivPermission("channels/auspex")) return true; - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, InspIRCd::Format("You do not have access to view the %s list", GetModeName().c_str())); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(chan, minrank, InspIRCd::Format("view the channel %s list", GetModeName().c_str()))); return false; } }; diff --git a/src/modules/m_rmode.cpp b/src/modules/m_rmode.cpp index eb7a018c4..ff5097c40 100644 --- a/src/modules/m_rmode.cpp +++ b/src/modules/m_rmode.cpp @@ -53,11 +53,8 @@ class CommandRMode : public Command if (chan->GetPrefixValue(user) < mh->GetLevelRequired(false)) { - const PrefixMode* neededmh = ServerInstance->Modes.FindNearestPrefixMode(mh->GetLevelRequired(false)); - if (neededmh) - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, InspIRCd::Format("You must have channel %s access or above to unset channel mode %c", neededmh->name.c_str(), mh->GetModeChar())); - else - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, InspIRCd::Format("You cannot unset channel mode %c", mh->GetModeChar())); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(chan, mh->GetLevelRequired(false), InspIRCd::Format("unset channel mode %c (%s)", + mh->GetModeChar(), mh->name.c_str()))); return CMD_FAILURE; } diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp index 5f19e8610..bc5ffea7a 100644 --- a/src/modules/m_sslinfo.cpp +++ b/src/modules/m_sslinfo.cpp @@ -201,7 +201,7 @@ class CommandSSLInfo : public SplitCommand if (!source->IsOper() && chan->GetPrefixValue(source) < OP_VALUE) { - source->WriteNumeric(ERR_CHANOPRIVSNEEDED, chan->name, "You must be a channel operator."); + source->WriteNumeric(Numerics::ChannelPrivilegesNeeded(chan, OP_VALUE, "view TLS (SSL) client certificate information")); return CMD_FAILURE; } diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index b1432270c..20ce1615a 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -93,7 +93,7 @@ class CommandTban : public Command unsigned int cm = channel->GetPrefixValue(user); if (cm < HALFOP_VALUE) { - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, channel->name, "You do not have permission to set bans on this channel"); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(channel, HALFOP_VALUE, "set timed bans")); return CMD_FAILURE; } diff --git a/src/modules/m_uninvite.cpp b/src/modules/m_uninvite.cpp index d6b42c242..a03205013 100644 --- a/src/modules/m_uninvite.cpp +++ b/src/modules/m_uninvite.cpp @@ -77,7 +77,7 @@ class CommandUninvite : public Command { if (c->GetPrefixValue(user) < HALFOP_VALUE) { - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, InspIRCd::Format("You must be a channel %soperator", c->GetPrefixValue(u) == HALFOP_VALUE ? "" : "half-")); + user->WriteNumeric(Numerics::ChannelPrivilegesNeeded(c, HALFOP_VALUE, "remove an invite")); return CMD_FAILURE; } } -- cgit v1.3.1-10-gc9f91