anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

ns_maxemail.cpp (3006B)

      1 /* ns_maxemail.cpp - Limit the amount of times an email address
      2  *                   can be used for a NickServ account.
      3  *
      4  * (C) 2003-2022 Anope Team
      5  * Contact us at team@anope.org
      6  *
      7  * Included in the Anope module pack since Anope 1.7.9
      8  * Anope Coder: GeniusDex <geniusdex@anope.org>
      9  *
     10  * Please read COPYING and README for further details.
     11  */
     12 
     13 #include "module.h"
     14 
     15 class NSMaxEmail : public Module
     16 {
     17 	bool clean;
     18 
     19 	/* strip dots from username, and remove anything after the first + */
     20 	Anope::string CleanMail(const Anope::string &email)
     21 	{
     22 		size_t host = email.find('@');
     23 		if (host == Anope::string::npos)
     24 			return email;
     25 
     26 		Anope::string username = email.substr(0, host);
     27 		username = username.replace_all_cs(".", "");
     28 
     29 		size_t sz = username.find('+');
     30 		if (sz != Anope::string::npos)
     31 			username = username.substr(0, sz);
     32 
     33 		Anope::string cleaned = username + email.substr(host);
     34 		Log(LOG_DEBUG) << "cleaned " << email << " to " << cleaned;
     35 		return cleaned;
     36 	}
     37 
     38 	bool CheckLimitReached(CommandSource &source, const Anope::string &email)
     39 	{
     40 		int NSEmailMax = Config->GetModule(this)->Get<int>("maxemails");
     41 
     42 		if (NSEmailMax < 1 || email.empty())
     43 			return false;
     44 
     45 		if (this->CountEmail(email, source.nc) < NSEmailMax)
     46 			return false;
     47 
     48 		if (NSEmailMax == 1)
     49 			source.Reply(_("The email address \002%s\002 has reached its usage limit of 1 user."), email.c_str());
     50 		else
     51 			source.Reply(_("The email address \002%s\002 has reached its usage limit of %d users."), email.c_str(), NSEmailMax);
     52 
     53 		return true;
     54 	}
     55 
     56 	int CountEmail(const Anope::string &email, NickCore *unc)
     57 	{
     58 		int count = 0;
     59 
     60 		if (email.empty())
     61 			return 0;
     62 
     63 		Anope::string cleanemail = clean ? CleanMail(email) : email;
     64 
     65 		for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
     66 		{
     67 			const NickCore *nc = it->second;
     68 
     69 			Anope::string cleannc = clean ? CleanMail(nc->email) : nc->email;
     70 
     71 			if (unc != nc && cleanemail.equals_ci(cleannc))
     72 				++count;
     73 		}
     74 
     75 		return count;
     76 	}
     77 
     78  public:
     79 	NSMaxEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
     80 		, clean(false)
     81 	{
     82 	}
     83 
     84 	void OnReload(Configuration::Conf *conf) anope_override
     85 	{
     86 		clean = conf->GetModule(this)->Get<bool>("remove_aliases", "true");
     87 	}
     88 
     89 	EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
     90 	{
     91 		if (source.IsOper())
     92 			return EVENT_CONTINUE;
     93 
     94 		if (command->name == "nickserv/register")
     95 		{
     96 			if (this->CheckLimitReached(source, params.size() > 1 ? params[1] : ""))
     97 				return EVENT_STOP;
     98 		}
     99 		else if (command->name == "nickserv/set/email")
    100 		{
    101 			if (this->CheckLimitReached(source, params.size() > 0 ? params[0] : ""))
    102 				return EVENT_STOP;
    103 		}
    104 		else if (command->name == "nickserv/ungroup" && source.GetAccount())
    105 		{
    106 			if (this->CheckLimitReached(source, source.GetAccount()->email))
    107 				return EVENT_STOP;
    108 		}
    109 
    110 		return EVENT_CONTINUE;
    111 	}
    112 };
    113 
    114 MODULE_INIT(NSMaxEmail)