anope

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

ns_resetpass.cpp (4149B)

      1 /* NickServ core functions
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #include "module.h"
     13 
     14 static bool SendResetEmail(User *u, const NickAlias *na, BotInfo *bi);
     15 
     16 class CommandNSResetPass : public Command
     17 {
     18  public:
     19 	CommandNSResetPass(Module *creator) : Command(creator, "nickserv/resetpass", 2, 2)
     20 	{
     21 		this->SetDesc(_("Helps you reset lost passwords"));
     22 		this->SetSyntax(_("\037nickname\037 \037email\037"));
     23 		this->AllowUnregistered(true);
     24 	}
     25 
     26 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
     27 	{
     28 		const NickAlias *na;
     29 
     30 		if (!(na = NickAlias::Find(params[0])))
     31 			source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
     32 		else if (!na->nc->email.equals_ci(params[1]))
     33 			source.Reply(_("Incorrect email address."));
     34 		else
     35 		{
     36 			if (SendResetEmail(source.GetUser(), na, source.service))
     37 			{
     38 				Log(LOG_COMMAND, source, this) << "for " << na->nick << " (group: " << na->nc->display << ")";
     39 				source.Reply(_("Password reset email for \002%s\002 has been sent."), na->nick.c_str());
     40 			}
     41 		}
     42 
     43 		return;
     44 	}
     45 
     46 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
     47 	{
     48 		this->SendSyntax(source);
     49 		source.Reply(" ");
     50 		source.Reply(_("Sends a passcode to the nickname with instructions on how to\n"
     51 				"reset their password.  Email must be the email address associated\n"
     52 				"to the nickname."));
     53 		return true;
     54 	}
     55 };
     56 
     57 struct ResetInfo
     58 {
     59 	Anope::string code;
     60 	time_t time;
     61 };
     62 
     63 class NSResetPass : public Module
     64 {
     65 	CommandNSResetPass commandnsresetpass;
     66 	PrimitiveExtensibleItem<ResetInfo> reset;
     67 
     68  public:
     69 	NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
     70 		commandnsresetpass(this), reset(this, "reset")
     71 	{
     72 		if (!Config->GetBlock("mail")->Get<bool>("usemail"))
     73 			throw ModuleException("Not using mail.");
     74 	}
     75 
     76 	EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
     77 	{
     78 		if (command->name == "nickserv/confirm" && params.size() > 1)
     79 		{
     80 			if (Anope::ReadOnly)
     81 			{
     82 				source.Reply(READ_ONLY_MODE);
     83 				return EVENT_STOP;
     84 			}
     85 
     86 			NickAlias *na = NickAlias::Find(params[0]);
     87 
     88 			ResetInfo *ri = na ? reset.Get(na->nc) : NULL;
     89 			if (na && ri)
     90 			{
     91 				NickCore *nc = na->nc;
     92 				const Anope::string &passcode = params[1];
     93 				if (ri->time < Anope::CurTime - 3600)
     94 				{
     95 					reset.Unset(nc);
     96 					source.Reply(_("Your password reset request has expired."));
     97 				}
     98 				else if (passcode.equals_cs(ri->code))
     99 				{
    100 					reset.Unset(nc);
    101 					nc->Shrink<bool>("UNCONFIRMED");
    102 
    103 					Log(LOG_COMMAND, source, &commandnsresetpass) << "to confirm RESETPASS and forcefully identify as " << na->nick;
    104 
    105 					if (source.GetUser())
    106 					{
    107 						source.GetUser()->Identify(na);
    108 					}
    109 					
    110 					source.Reply(_("You are now identified for your nick. Change your password now."));
    111 				}
    112 				else
    113 					return EVENT_CONTINUE;
    114 
    115 				return EVENT_STOP;
    116 			}
    117 		}
    118 
    119 		return EVENT_CONTINUE;
    120 	}
    121 };
    122 
    123 static bool SendResetEmail(User *u, const NickAlias *na, BotInfo *bi)
    124 {
    125 	Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_subject").c_str()),
    126 		message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_message").c_str()),
    127 		passcode = Anope::Random(20);
    128 
    129 	subject = subject.replace_all_cs("%n", na->nick);
    130 	subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
    131 	subject = subject.replace_all_cs("%c", passcode);
    132 
    133 	message = message.replace_all_cs("%n", na->nick);
    134 	message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
    135 	message = message.replace_all_cs("%c", passcode);
    136 
    137 	ResetInfo *ri = na->nc->Extend<ResetInfo>("reset");
    138 	ri->code = passcode;
    139 	ri->time = Anope::CurTime;
    140 
    141 	return Mail::Send(u, na->nc, bi, subject, message);
    142 }
    143 
    144 MODULE_INIT(NSResetPass)