]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_services_account.cpp
m_chanfilter: Apply filters to part messages (#1702)
[user/henk/code/inspircd.git] / src / modules / m_services_account.cpp
index c3f7155a6ff239e3e632676cee1ccd349b31060f..78d20a6e91150c017f765582a67f3ae149f6e468 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "inspircd.h"
 #include "modules/account.h"
+#include "modules/callerid.h"
+#include "modules/ctctags.h"
 #include "modules/exemption.h"
 #include "modules/whois.h"
 
@@ -52,7 +54,7 @@ class Channel_r : public ModeHandler
 
        ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
        {
-               // only a u-lined server may add or remove the +r mode.
+               // Only a U-lined server may add or remove the +r mode.
                if (!IS_LOCAL(source))
                {
                        // Only change the mode if it's not redundant
@@ -64,7 +66,7 @@ class Channel_r : public ModeHandler
                }
                else
                {
-                       source->WriteNumeric(500, "Only a server may modify the +r channel mode");
+                       source->WriteNumeric(ERR_NOPRIVILEGES, "Only a server may modify the +r channel mode");
                }
                return MODEACTION_DENY;
        }
@@ -90,7 +92,7 @@ class User_r : public ModeHandler
                }
                else
                {
-                       source->WriteNumeric(500, "Only a server may modify the +r user mode");
+                       source->WriteNumeric(ERR_NOPRIVILEGES, "Only a server may modify the +r user mode");
                }
                return MODEACTION_DENY;
        }
@@ -107,16 +109,16 @@ class AccountExtItemImpl : public AccountExtItem
        {
        }
 
-       void unserialize(SerializeFormat format, Extensible* container, const std::string& value) CXX11_OVERRIDE
+       void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE
        {
-               User* user = static_cast<User*>(container);
-
-               StringExtItem::unserialize(format, container, value);
+               StringExtItem::FromInternal(container, value);
+       }
 
-               // If we are being reloaded then don't send the numeric or run the event
-               if (format == FORMAT_INTERNAL)
-                       return;
+       void FromNetwork(Extensible* container, const std::string& value) CXX11_OVERRIDE
+       {
+               StringExtItem::FromNetwork(container, value);
 
+               User* user = static_cast<User*>(container);
                if (IS_LOCAL(user))
                {
                        if (value.empty())
@@ -135,8 +137,13 @@ class AccountExtItemImpl : public AccountExtItem
        }
 };
 
-class ModuleServicesAccount : public Module, public Whois::EventListener
+class ModuleServicesAccount
+       : public Module
+       , public Whois::EventListener
+       , public CTCTags::EventListener
 {
+ private:
+       CallerID::API calleridapi;
        CheckExemption::EventProvider exemptionprov;
        SimpleChannelModeHandler m1;
        SimpleChannelModeHandler m2;
@@ -145,9 +152,12 @@ class ModuleServicesAccount : public Module, public Whois::EventListener
        User_r m5;
        AccountExtItemImpl accountname;
        bool checking_ban;
+
  public:
        ModuleServicesAccount()
                : Whois::EventListener(this)
+               , CTCTags::EventListener(this)
+               , calleridapi(this)
                , exemptionprov(this)
                , m1(this, "reginvite", 'R')
                , m2(this, "regmoderated", 'M')
@@ -189,7 +199,7 @@ class ModuleServicesAccount : public Module, public Whois::EventListener
                        m5.RemoveMode(user);
        }
 
-       ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE
+       ModResult HandleMessage(User* user, const MessageTarget& target)
        {
                if (!IS_LOCAL(user))
                        return MOD_RES_PASSTHRU;
@@ -197,32 +207,53 @@ class ModuleServicesAccount : public Module, public Whois::EventListener
                std::string *account = accountname.get(user);
                bool is_registered = account && !account->empty();
 
-               if (target.type == MessageTarget::TYPE_CHANNEL)
+               switch (target.type)
                {
-                       Channel* c = target.Get<Channel>();
-                       ModResult res = CheckExemption::Call(exemptionprov, user, c, "regmoderated");
-
-                       if (c->IsModeSet(m2) && !is_registered && res != MOD_RES_ALLOW)
+                       case MessageTarget::TYPE_CHANNEL:
                        {
-                               // user messaging a +M channel and is not registered
-                               user->WriteNumeric(ERR_NEEDREGGEDNICK, c->name, "You need to be identified to a registered account to message this channel");
+                               Channel* targchan = target.Get<Channel>();
+
+                               if (!targchan->IsModeSet(m2) || is_registered)
+                                       return MOD_RES_PASSTHRU;
+
+                               if (CheckExemption::Call(exemptionprov, user, targchan, "regmoderated") == MOD_RES_ALLOW)
+                                       return MOD_RES_PASSTHRU;
+
+                               // User is messaging a +M channel and is not registered or exempt.
+                               user->WriteNumeric(ERR_NEEDREGGEDNICK, targchan->name, "You need to be identified to a registered account to message this channel");
                                return MOD_RES_DENY;
+                               break;
                        }
-               }
-               else if (target.type == MessageTarget::TYPE_USER)
-               {
-                       User* u = target.Get<User>();
-
-                       if (u->IsModeSet(m3) && !is_registered)
+                       case MessageTarget::TYPE_USER:
                        {
-                               // user messaging a +R user and is not registered
-                               user->WriteNumeric(ERR_NEEDREGGEDNICK, u->nick, "You need to be identified to a registered account to message this user");
+                               User* targuser = target.Get<User>();
+                               if (!targuser->IsModeSet(m3)  || is_registered)
+                                       return MOD_RES_PASSTHRU;
+
+                               if (calleridapi && calleridapi->IsOnAcceptList(user, targuser))
+                                       return MOD_RES_PASSTHRU;
+
+                               // User is messaging a +R user and is not registered or on an accept list.
+                               user->WriteNumeric(ERR_NEEDREGGEDNICK, targuser->nick, "You need to be identified to a registered account to message this user");
                                return MOD_RES_DENY;
+                               break;
                        }
+                       case MessageTarget::TYPE_SERVER:
+                               break;
                }
                return MOD_RES_PASSTHRU;
        }
 
+       ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE
+       {
+               return HandleMessage(user, target);
+       }
+
+       ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, CTCTags::TagMessageDetails& details) CXX11_OVERRIDE
+       {
+               return HandleMessage(user, target);
+       }
+
        ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask) CXX11_OVERRIDE
        {
                if (checking_ban)
@@ -288,7 +319,7 @@ class ModuleServicesAccount : public Module, public Whois::EventListener
 
        Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Provides support for ircu-style services accounts, including chmode +R, etc.",VF_OPTCOMMON|VF_VENDOR);
+               return Version("Provides support for ircu-style services accounts, including channel mode +R, etc", VF_OPTCOMMON|VF_VENDOR);
        }
 };