ns_set_email.cpp

Go to the documentation of this file.
00001 /* NickServ core functions
00002  *
00003  * (C) 2003-2012 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  */
00011 
00012 /*************************************************************************/
00013 
00014 #include "module.h"
00015 
00016 static bool SendConfirmMail(User *u, const BotInfo *bi)
00017 {
00018         int chars[] = {
00019                 ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
00020                 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
00021                 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
00022                 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
00023                 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
00024         };
00025         int idx, min = 1, max = 62;
00026         Anope::string code;
00027         for (idx = 0; idx < 9; ++idx)
00028                 code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min];
00029         
00030         u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code));
00031 
00032         Anope::string subject = Config->MailEmailchangeSubject;
00033         Anope::string message = Config->MailEmailchangeMessage;
00034 
00035         subject = subject.replace_all_cs("%e", u->Account()->email);
00036         subject = subject.replace_all_cs("%N", Config->NetworkName);
00037         subject = subject.replace_all_cs("%c", code);
00038 
00039         message = message.replace_all_cs("%e", u->Account()->email);
00040         message = message.replace_all_cs("%N", Config->NetworkName);
00041         message = message.replace_all_cs("%c", code);
00042 
00043         return Mail::Send(u, u->Account(), bi, subject, message);
00044 }
00045 
00046 class CommandNSSetEmail : public Command
00047 {
00048  public:
00049         CommandNSSetEmail(Module *creator, const Anope::string &cname = "nickserv/set/email", size_t min = 0) : Command(creator, cname, min, min + 1)
00050         {
00051                 this->SetDesc(_("Associate an E-mail address with your nickname"));
00052                 this->SetSyntax(_("\037address\037"));
00053         }
00054 
00055         void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
00056         {
00057                 const NickAlias *na = NickAlias::Find(user);
00058                 if (!na)
00059                 {
00060                         source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
00061                         return;
00062                 }
00063                 NickCore *nc = na->nc;
00064 
00065                 if (param.empty() && Config->NSForceEmail)
00066                 {
00067                         source.Reply(_("You cannot unset the e-mail on this network."));
00068                         return;
00069                 }
00070                 else if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper())
00071                 {
00072                         source.Reply(_("You may not change the email of other services operators."));
00073                         return;
00074                 }
00075                 else if (!param.empty() && !Mail::Validate(param))
00076                 {
00077                         source.Reply(MAIL_X_INVALID, param.c_str());
00078                         return;
00079                 }
00080 
00081                 EventReturn MOD_RESULT;
00082                 FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param));
00083                 if (MOD_RESULT == EVENT_STOP)
00084                         return;
00085 
00086                 if (!param.empty() && Config->NSConfirmEmailChanges && !source.IsServicesOper())
00087                 {
00088                         source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param));
00089                         Anope::string old = source.nc->email;
00090                         source.nc->email = param;
00091                         if (SendConfirmMail(source.GetUser(), source.service))
00092                                 source.Reply(_("A confirmation email has been sent to \002%s\002. Follow the instructions in it to change your email address."), param.c_str());
00093                         source.nc->email = old;
00094                 }
00095                 else
00096                 {
00097                         if (!param.empty())
00098                         {
00099                                 nc->email = param;
00100                                 source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str());
00101                         }
00102                         else
00103                         {
00104                                 nc->email.clear();
00105                                 source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str());
00106                         }
00107                 }
00108 
00109                 return;
00110         }
00111 
00112         void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
00113         {
00114                 this->Run(source, source.nc->display, params.size() ? params[0] : "");
00115         }
00116 
00117         bool OnHelp(CommandSource &source, const Anope::string &) anope_override
00118         {
00119                 this->SendSyntax(source);
00120                 source.Reply(" ");
00121                 source.Reply(_("Associates the given E-mail address with your nickname.\n"
00122                                 "This address will be displayed whenever someone requests\n"
00123                                 "information on the nickname with the \002INFO\002 command."));
00124                 return true;
00125         }
00126 };
00127 
00128 class CommandNSSASetEmail : public CommandNSSetEmail
00129 {
00130  public:
00131         CommandNSSASetEmail(Module *creator) : CommandNSSetEmail(creator, "nickserv/saset/email", 2)
00132         {
00133                 this->ClearSyntax();
00134                 this->SetSyntax(_("\037nickname\037 \037address\037"));
00135         }
00136 
00137         void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
00138         {
00139                 this->Run(source, params[0], params.size() > 1 ? params[1] : "");
00140         }
00141 
00142         bool OnHelp(CommandSource &source, const Anope::string &) anope_override
00143         {
00144                 this->SendSyntax(source);
00145                 source.Reply(" ");
00146                 source.Reply(_("Associates the given E-mail address with the nickname."));
00147                 return true;
00148         }
00149 };
00150 
00151 class NSSetEmail : public Module
00152 {
00153         CommandNSSetEmail commandnssetemail;
00154         CommandNSSASetEmail commandnssasetemail;
00155 
00156  public:
00157         NSSetEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
00158                 commandnssetemail(this), commandnssasetemail(this)
00159         {
00160                 this->SetAuthor("Anope");
00161 
00162                 ModuleManager::Attach(I_OnPreCommand, this);
00163 
00164         }
00165 
00166         EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
00167         {
00168                 NickCore *uac = source.nc;
00169                 if (command->name == "nickserv/confirm" && !params.empty() && uac)
00170                 {
00171                         Anope::string *new_email = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email"), *passcode = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email_passcode");
00172                         if (new_email && passcode)
00173                         {
00174                                 if (params[0] == *passcode)
00175                                 {
00176                                         uac->email = *new_email;
00177                                         Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->email;
00178                                         source.Reply(_("Your email address has been changed to \002%s\002."), uac->email.c_str());
00179                                         uac->Shrink("ns_set_email");
00180                                         uac->Shrink("ns_set_email_passcode");
00181                                         return EVENT_STOP;
00182                                 }
00183                         }
00184                 }
00185 
00186                 return EVENT_CONTINUE;
00187         }
00188 };
00189 
00190 MODULE_INIT(NSSetEmail)