00001
00002
00003
00004
00005
00006
00007
00008
00009
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 ¶m)
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> ¶ms) 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> ¶ms) 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> ¶ms) 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)