mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Add the accountnicks metadata as a replacement for user mode +r.
This isn't used much currently but in the future will allow doing a lot of behaviour which is currently implemented in services in the IRCd instead e.g. killing ghost clients, nickname enforcement.
This commit is contained in:
parent
65fe0fc67d
commit
4dfb70a936
@ -26,6 +26,9 @@ namespace Account
|
||||
class API;
|
||||
class APIBase;
|
||||
class EventListener;
|
||||
|
||||
/** Encapsulates a list of nicknames associated with an account. */
|
||||
typedef insp::flat_set<std::string, irc::insensitive_swo> NickList;
|
||||
}
|
||||
|
||||
/** Defines the interface for the account API. */
|
||||
@ -49,6 +52,18 @@ public:
|
||||
* @return If the user is logged in to an account then the account name; otherwise, nullptr.
|
||||
*/
|
||||
virtual std::string* GetAccountName(const User* user) const = 0;
|
||||
|
||||
/** Retrieves the account nicks of the specified user.
|
||||
* @param user The user to retrieve the account nicks of.
|
||||
* @return If the user is logged in to an account then the account nicks; otherwise, nullptr.
|
||||
*/
|
||||
virtual NickList* GetAccountNicks(const User* user) const = 0;
|
||||
|
||||
/** Determines whether a user is identified to their nickname.
|
||||
* @param user The user to check the identification status of.
|
||||
* @return If the user is identified to their nickname then true; otherwise, false.
|
||||
*/
|
||||
virtual bool IsIdentifiedToNick(const User* user) = 0;
|
||||
};
|
||||
|
||||
/** Allows modules to access information regarding user accounts. */
|
||||
|
@ -130,18 +130,63 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AccountNicksExtItem final
|
||||
: public SimpleExtItem<Account::NickList>
|
||||
{
|
||||
public:
|
||||
AccountNicksExtItem(Module* mod)
|
||||
: SimpleExtItem<Account::NickList>(mod, "accountnicks", ExtensionType::USER, true)
|
||||
{
|
||||
}
|
||||
|
||||
void FromInternal(Extensible* container, const std::string& value) noexcept override
|
||||
{
|
||||
if (container->extype != this->extype)
|
||||
return;
|
||||
|
||||
auto list = new Account::NickList();
|
||||
irc::spacesepstream nickstream(value);
|
||||
for (std::string nick; nickstream.GetToken(nick); )
|
||||
list->insert(nick);
|
||||
|
||||
if (list->empty())
|
||||
{
|
||||
// The remote sent an empty list of nicknames for some reason.
|
||||
delete list;
|
||||
Unset(container);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The remote sent a non-zero list of nicks; set it.
|
||||
Set(container, list);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToInternal(const Extensible* container, void* item) const noexcept override
|
||||
{
|
||||
auto list = static_cast<Account::NickList*>(item);
|
||||
return stdalgo::string::join(*list);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AccountAPIImpl final
|
||||
: public Account::APIBase
|
||||
{
|
||||
private:
|
||||
AccountExtItemImpl accountext;
|
||||
StringExtItem accountidext;
|
||||
AccountNicksExtItem accountnicksext;
|
||||
UserModeReference identifiedmode;
|
||||
|
||||
public:
|
||||
AccountAPIImpl(Module* mod)
|
||||
: Account::APIBase(mod)
|
||||
, accountext(mod)
|
||||
, accountidext(mod, "accountid", ExtensionType::USER, true)
|
||||
, accountnicksext(mod)
|
||||
, identifiedmode(mod, "u_registered")
|
||||
{
|
||||
}
|
||||
|
||||
@ -154,6 +199,21 @@ public:
|
||||
{
|
||||
return accountext.Get(user);
|
||||
}
|
||||
|
||||
Account::NickList* GetAccountNicks(const User* user) const override
|
||||
{
|
||||
return accountnicksext.Get(user);
|
||||
}
|
||||
|
||||
bool IsIdentifiedToNick(const User* user) override
|
||||
{
|
||||
if (user->IsModeSet(identifiedmode))
|
||||
return true; // User has +r set.
|
||||
|
||||
// Check whether their current nick is in their nick list.
|
||||
Account::NickList* nicks = accountnicksext.Get(user);
|
||||
return nicks && stdalgo::isin(*nicks, user->nick);
|
||||
}
|
||||
};
|
||||
|
||||
class AccountExtBan final
|
||||
@ -240,26 +300,20 @@ public:
|
||||
if (!request.GetFieldIndex('f', flag_index))
|
||||
return MOD_RES_PASSTHRU;
|
||||
|
||||
if (user->IsModeSet(userregmode))
|
||||
if (accountapi.IsIdentifiedToNick(user))
|
||||
numeric.GetParams()[flag_index].push_back('r');
|
||||
|
||||
return MOD_RES_PASSTHRU;
|
||||
}
|
||||
|
||||
/* <- :twisted.oscnet.org 330 w00t2 w00t2 w00t :is logged in as */
|
||||
void OnWhois(Whois::Context& whois) override
|
||||
{
|
||||
const std::string* account = accountapi.GetAccountName(whois.GetTarget());
|
||||
if (account)
|
||||
{
|
||||
whois.SendLine(RPL_WHOISACCOUNT, *account, "is logged in as");
|
||||
}
|
||||
|
||||
if (whois.GetTarget()->IsModeSet(userregmode))
|
||||
{
|
||||
/* user is registered */
|
||||
if (accountapi.IsIdentifiedToNick(whois.GetTarget()))
|
||||
whois.SendLine(RPL_WHOISREGNICK, "is a registered nick");
|
||||
}
|
||||
}
|
||||
|
||||
void OnUserPostNick(User* user, const std::string& oldnick) override
|
||||
|
Loading…
x
Reference in New Issue
Block a user