1
0
mirror of https://github.com/anope/anope.git synced 2026-06-29 19:56:37 +02:00

Improve the usability of adding hostmasks to access lists.

* When adding a user by their nickname check for their account
  instead of just adding their hostmask.

* Allow opting out of cleaning up of malformed hostmasks.
This commit is contained in:
Sadie Powell
2026-01-28 19:44:49 +00:00
parent 48bb6089fa
commit c3e62d3772
6 changed files with 73 additions and 17 deletions
+6
View File
@@ -179,6 +179,12 @@ module
*/
disallow_channel_access = no
/*
* If set, prevents malformed hostmasks from being added to access lists
* instead of attempting to fix their format.
*/
#disallow_malformed_hostmask = yes
/*
* If set, ChanServ will always lower the timestamp of registered channels to their registration date.
* This prevents several race conditions where unauthorized users can join empty registered channels and set
+1
View File
@@ -140,6 +140,7 @@ namespace Language
#define CHAN_ACCESS_LIMIT N_("You can only have %u access entry on a channel.", "You can only have %u access entries on a channel.")
#define CHAN_ACCESS_LIMIT_DEEP N_("You can only have %u access entry on a channel, including access entries from other channels.", "You can only have %u access entries on a channel, including access entries from other channels.")
#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.")
#define CHAN_ACCESS_MALFORMED _("You cannot add a malformed mask to an access list. Did you mean to add %s instead?")
#define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except has been removed.")
#define CHAN_INFO_HEADER _("Information about channel \002%s\002:")
#define CHAN_LIMIT_EXCEEDED _("You have already exceeded your limit of \002%d\002 channels.")
+6 -2
View File
@@ -16,8 +16,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-19 11:28+0000\n"
"PO-Revision-Date: 2026-01-19 11:28+0000\n"
"POT-Creation-Date: 2026-01-28 19:44+0000\n"
"PO-Revision-Date: 2026-01-28 19:44+0000\n"
"Last-Translator: Sadie Powell <sadie@witchery.services>\n"
"Language-Team: English\n"
"Language: en_US\n"
@@ -6220,6 +6220,10 @@ msgstr ""
msgid "You can't logout %s, they are a Services Operator."
msgstr ""
#, c-format
msgid "You cannot add a malformed mask to an access list. Did you mean to add %s instead?"
msgstr ""
#, c-format
msgid "You cannot set the %c flag."
msgstr ""
+20 -5
View File
@@ -167,9 +167,10 @@ private:
}
}
const auto &csconf = Config->GetModule("chanserv");
if (IRCD->IsChannelValid(mask))
{
if (Config->GetModule("chanserv").Get<bool>("disallow_channel_access"))
if (csconf.Get<bool>("disallow_channel_access"))
{
source.Reply(_("Channels may not be on access lists."));
return;
@@ -204,7 +205,7 @@ private:
}
else
{
if (Config->GetModule("chanserv").Get<bool>("disallow_hostmask_access"))
if (csconf.Get<bool>("disallow_hostmask_access"))
{
source.Reply(_("Masks and unregistered users may not be on access lists."));
return;
@@ -215,18 +216,32 @@ private:
auto *targ = User::Find(mask, true);
if (!targ)
{
source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
source.Reply(NICK_X_NOT_IN_USE, mask.c_str());
return;
}
mask = "*!*@" + targ->GetDisplayedHost();
auto *targnc = targ->Account();
if (!targnc)
{
source.Reply(NICK_X_NOT_REGISTERED, targ->nick.c_str());
return;
}
mask = targnc->display;
if (description.empty())
description = targ->nick;
}
else
{
// Normalize the entry mask.
mask = Entry(mask).GetCleanMask();
const auto cleanmask = Entry(mask).GetCleanMask();
if (csconf.Get<bool>("disallow_malformed_hostmask") && cleanmask != mask)
{
source.Reply(CHAN_ACCESS_MALFORMED, cleanmask.c_str());
return;
}
mask = cleanmask;
}
}
}
+20 -5
View File
@@ -94,9 +94,10 @@ class CommandCSFlags final
const ChanAccess *highest = u_access.Highest();
const NickAlias *na = NULL;
const auto &csconf = Config->GetModule("chanserv");
if (IRCD->IsChannelValid(mask))
{
if (Config->GetModule("chanserv").Get<bool>("disallow_channel_access"))
if (csconf.Get<bool>("disallow_channel_access"))
{
source.Reply(_("Channels may not be on access lists."));
return;
@@ -131,7 +132,7 @@ class CommandCSFlags final
}
else
{
if (Config->GetModule("chanserv").Get<bool>("disallow_hostmask_access"))
if (csconf.Get<bool>("disallow_hostmask_access"))
{
source.Reply(_("Masks and unregistered users may not be on access lists."));
return;
@@ -142,18 +143,32 @@ class CommandCSFlags final
auto *targ = User::Find(mask, true);
if (!targ)
{
source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
source.Reply(NICK_X_NOT_IN_USE, mask.c_str());
return;
}
mask = "*!*@" + targ->GetDisplayedHost();
auto *targnc = targ->Account();
if (!targnc)
{
source.Reply(NICK_X_NOT_REGISTERED, targ->nick.c_str());
return;
}
mask = targnc->display;
if (description.empty())
description = targ->nick;
}
else
{
// Normalize the entry mask.
mask = Entry(mask).GetCleanMask();
const auto cleanmask = Entry(mask).GetCleanMask();
if (csconf.Get<bool>("disallow_malformed_hostmask") && cleanmask != mask)
{
source.Reply(CHAN_ACCESS_MALFORMED, cleanmask.c_str());
return;
}
mask = cleanmask;
}
}
}
+20 -5
View File
@@ -142,9 +142,10 @@ private:
}
}
const auto &csconf = Config->GetModule("chanserv");
if (IRCD->IsChannelValid(mask))
{
if (Config->GetModule("chanserv").Get<bool>("disallow_channel_access"))
if (csconf.Get<bool>("disallow_channel_access"))
{
source.Reply(_("Channels may not be on access lists."));
return;
@@ -179,7 +180,7 @@ private:
}
else
{
if (Config->GetModule("chanserv").Get<bool>("disallow_hostmask_access"))
if (csconf.Get<bool>("disallow_hostmask_access"))
{
source.Reply(_("Masks and unregistered users may not be on access lists."));
return;
@@ -190,18 +191,32 @@ private:
auto *targ = User::Find(mask, true);
if (!targ)
{
source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
source.Reply(NICK_X_NOT_IN_USE, mask.c_str());
return;
}
mask = "*!*@" + targ->GetDisplayedHost();
auto *targnc = targ->Account();
if (!targnc)
{
source.Reply(NICK_X_NOT_REGISTERED, targ->nick.c_str());
return;
}
mask = targnc->display;
if (description.empty())
description = targ->nick;
}
else
{
// Normalize the entry mask.
mask = Entry(mask).GetCleanMask();
const auto cleanmask = Entry(mask).GetCleanMask();
if (csconf.Get<bool>("disallow_malformed_hostmask") && cleanmask != mask)
{
source.Reply(CHAN_ACCESS_MALFORMED, cleanmask.c_str());
return;
}
mask = cleanmask;
}
}
}