diff options
| author | 2022-10-16 22:47:24 +0100 | |
|---|---|---|
| committer | 2022-10-18 10:58:14 +0100 | |
| commit | 4dfb70a9364c6a337b4dd7d222f5375b58220763 (patch) | |
| tree | e4948f48f105d6b4e9ce653dc00b4e5e91ee357f /src/modules/m_services_account.cpp | |
| parent | Remove is_registered in services_account. (diff) | |
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.
Diffstat (limited to 'src/modules/m_services_account.cpp')
| -rw-r--r-- | src/modules/m_services_account.cpp | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp index f9e36d556..291f9f798 100644 --- a/src/modules/m_services_account.cpp +++ b/src/modules/m_services_account.cpp @@ -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 |
