anope

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

m_sql_authentication.cpp (3652B)

      1 /*
      2  *
      3  * (C) 2012-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  */
      8 
      9 #include "module.h"
     10 #include "modules/sql.h"
     11 
     12 static Module *me;
     13 
     14 class SQLAuthenticationResult : public SQL::Interface
     15 {
     16 	Reference<User> user;
     17 	IdentifyRequest *req;
     18 
     19  public:
     20 	SQLAuthenticationResult(User *u, IdentifyRequest *r) : SQL::Interface(me), user(u), req(r)
     21 	{
     22 		req->Hold(me);
     23 	}
     24 
     25 	~SQLAuthenticationResult()
     26 	{
     27 		req->Release(me);
     28 	}
     29 
     30 	void OnResult(const SQL::Result &r) anope_override
     31 	{
     32 		if (r.Rows() == 0)
     33 		{
     34 			Log(LOG_DEBUG) << "m_sql_authentication: Unsuccessful authentication for " << req->GetAccount();
     35 			delete this;
     36 			return;
     37 		}
     38 
     39 		Log(LOG_DEBUG) << "m_sql_authentication: Successful authentication for " << req->GetAccount();
     40 
     41 		Anope::string email;
     42 		try
     43 		{
     44 			email = r.Get(0, "email");
     45 		}
     46 		catch (const SQL::Exception &) { }
     47 
     48 		NickAlias *na = NickAlias::Find(req->GetAccount());
     49 		BotInfo *NickServ = Config->GetClient("NickServ");
     50 		if (na == NULL)
     51 		{
     52 			na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount()));
     53 			FOREACH_MOD(OnNickRegister, (user, na, ""));
     54 			if (user && NickServ)
     55 				user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
     56 		}
     57 
     58 		if (!email.empty() && email != na->nc->email)
     59 		{
     60 			na->nc->email = email;
     61 			if (user && NickServ)
     62 				user->SendMessage(NickServ, _("Your email has been updated to \002%s\002."), email.c_str());
     63 		}
     64 
     65 		req->Success(me);
     66 		delete this;
     67 	}
     68 
     69 	void OnError(const SQL::Result &r) anope_override
     70 	{
     71 		Log(this->owner) << "m_sql_authentication: Error executing query " << r.GetQuery().query << ": " << r.GetError();
     72 		delete this;
     73 	}
     74 };
     75 
     76 class ModuleSQLAuthentication : public Module
     77 {
     78 	Anope::string engine;
     79 	Anope::string query;
     80 	Anope::string disable_reason, disable_email_reason;
     81 
     82 	ServiceReference<SQL::Provider> SQL;
     83 
     84  public:
     85 	ModuleSQLAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
     86 	{
     87 		me = this;
     88 
     89 	}
     90 
     91 	void OnReload(Configuration::Conf *conf) anope_override
     92 	{
     93 		Configuration::Block *config = conf->GetModule(this);
     94 		this->engine = config->Get<const Anope::string>("engine");
     95 		this->query =  config->Get<const Anope::string>("query");
     96 		this->disable_reason = config->Get<const Anope::string>("disable_reason");
     97 		this->disable_email_reason = config->Get<Anope::string>("disable_email_reason");
     98 
     99 		this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine);
    100 	}
    101 
    102 	EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
    103 	{
    104 		if (!this->disable_reason.empty() && (command->name == "nickserv/register" || command->name == "nickserv/group"))
    105 		{
    106 			source.Reply(this->disable_reason);
    107 			return EVENT_STOP;
    108 		}
    109 
    110 		if (!this->disable_email_reason.empty() && command->name == "nickserv/set/email")
    111 		{
    112 			source.Reply(this->disable_email_reason);
    113 			return EVENT_STOP;
    114 		}
    115 
    116 		return EVENT_CONTINUE;
    117 	}
    118 
    119 	void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override
    120 	{
    121 		if (!this->SQL)
    122 		{
    123 			Log(this) << "Unable to find SQL engine";
    124 			return;
    125 		}
    126 
    127 		SQL::Query q(this->query);
    128 		q.SetValue("a", req->GetAccount());
    129 		q.SetValue("p", req->GetPassword());
    130 		if (u)
    131 		{
    132 			q.SetValue("n", u->nick);
    133 			q.SetValue("i", u->ip.addr());
    134 		}
    135 		else
    136 		{
    137 			q.SetValue("n", "");
    138 			q.SetValue("i", "");
    139 		}
    140 
    141 
    142 		this->SQL->Run(new SQLAuthenticationResult(u, req), q);
    143 
    144 		Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount();
    145 	}
    146 };
    147 
    148 MODULE_INIT(ModuleSQLAuthentication)