summaryrefslogtreecommitdiff
path: root/include/modules/nickserv.h
blob: f8d1567ef83a90f45a908771814309d3341c5678 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
 * Anope IRC Services
 *
 * Copyright (C) 2011-2016 Anope Team <team@anope.org>
 *
 * This file is part of Anope. Anope is free software; you can
 * redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software
 * Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "event.h"
#include "service.h"
#include "serialize.h"

#include "nickserv/nick.h"
#include "nickserv/account.h"

namespace NickServ
{
	class Nick;
	class Account;
	class IdentifyRequestListener;

	using nickalias_map = Anope::locale_hash_map<Nick *>;
	using nickcore_map = Anope::locale_hash_map<Account *>;

	class NickServService : public Service
	{
	 public:
		NickServService(Module *m) : Service(m, "NickServService", "NickServ")
		{
		}

		virtual void Validate(User *u) anope_abstract;
		virtual void Collide(User *u, Nick *na) anope_abstract;
		virtual void Release(Nick *na) anope_abstract;

		virtual IdentifyRequest *CreateIdentifyRequest(IdentifyRequestListener *l, Module *owner, const Anope::string &acc, const Anope::string &pass) anope_abstract;
		virtual std::set<IdentifyRequest *>& GetIdentifyRequests() anope_abstract;

		virtual std::vector<Nick *> GetNickList() anope_abstract;
		virtual nickalias_map& GetNickMap() anope_abstract;

		virtual std::vector<Account *> GetAccountList() anope_abstract;
		virtual nickcore_map& GetAccountMap() anope_abstract;

		virtual Nick *FindNick(const Anope::string &nick) anope_abstract;
		virtual Account *FindAccount(const Anope::string &acc) anope_abstract;
	};
	
	extern NickServService *service;

	inline Nick *FindNick(const Anope::string &nick)
	{
		return service ? service->FindNick(nick) : nullptr;
	}

	inline Account *FindAccount(const Anope::string &account)
	{
		return service ? service->FindAccount(account) : nullptr;
	}

	namespace Event
	{
		struct CoreExport PreNickExpire : Events
		{
			static constexpr const char *NAME = "prenickexpire";

			using Events::Events;
			
			/** Called before a nick expires
			 * @param na The nick
			 * @param expire Set to true to allow the nick to expire
			 */
			virtual void OnPreNickExpire(Nick *na, bool &expire) anope_abstract;
		};

		struct CoreExport NickExpire : Events
		{
			static constexpr const char *NAME = "nickexpire";

			using Events::Events;
			
			/** Called when a nick drops
			 * @param na The nick
			 */
			virtual void OnNickExpire(Nick *na) anope_abstract;
		};

		struct CoreExport NickRegister : Events
		{
			static constexpr const char *NAME = "nickregister";

			using Events::Events;
			
			/** Called when a nick is registered
			 * @param user The user registering the nick, of any
			 * @param The nick
			 * @param password The password of the nick
			 */
			virtual void OnNickRegister(User *user, Nick *na, const Anope::string &password) anope_abstract;
		};

		struct CoreExport NickConfirm : Events
		{
			static constexpr const char *NAME = "nickconfirm";

			using Events::Events;
			
			virtual void OnNickConfirm(User *, Account *) anope_abstract;
		};

		struct CoreExport NickValidate : Events
		{
			static constexpr const char *NAME = "nickvalidate";

			using Events::Events;
			
			/** Called when a nick is validated. That is, to determine if a user is permissted
			 * to be on the given nick.
			 * @param u The user
			 * @param na The nick they are on
			 * @return EVENT_STOP to force the user off of the nick
			 */
			virtual EventReturn OnNickValidate(User *u, Nick *na) anope_abstract;
		};
	}

	/* A request to check if an account/password is valid. These can exist for
	 * extended periods due to the time some authentication modules take.
	 */
	class CoreExport IdentifyRequest
	{
	 protected:
		/* Owner of this request, used to cleanup requests if a module is unloaded
		 * while a request us pending */
		Module *owner;
		IdentifyRequestListener *l;
		Anope::string account;
		Anope::string password;

		std::set<Module *> holds;
		bool dispatched = false;
		bool success = false;

		IdentifyRequest(IdentifyRequestListener *li, Module *o, const Anope::string &acc, const Anope::string &pass) : owner(o), l(li), account(acc), password(pass) { }
	 public:
		virtual ~IdentifyRequest() { }

		const Anope::string &GetAccount() const { return account; }
		const Anope::string &GetPassword() const { return password; }
		Module *GetOwner() const { return owner; }

		/* Holds this request. When a request is held it must be Released later
		 * for the request to complete. Multiple modules may hold a request at any time,
		 * but the request is not complete until every module has released it. If you do not
		 * require holding this (eg, your password check is done in this thread and immediately)
		 * then you don't need to hold the request before Successing it.
		 * @param m The module holding this request
		 */
		virtual void Hold(Module *m) anope_abstract;

		/** Releases a held request
		 * @param m The module releaseing the hold
		 */
		virtual void Release(Module *m) anope_abstract;

		/** Called by modules when this IdentifyRequest has successeded successfully.
		 * If this request is behind held it must still be Released after calling this.
		 * @param m The module confirming authentication
		 */
		virtual void Success(Module *m) anope_abstract;

		/** Used to either finalize this request or marks
		 * it as dispatched and begins waiting for the module(s)
		 * that have holds to finish.
		 */
		virtual void Dispatch() anope_abstract;
	};

	class IdentifyRequestListener
	{
	 public:
		virtual ~IdentifyRequestListener() { }
		virtual void OnSuccess(IdentifyRequest *) anope_abstract;
		virtual void OnFail(IdentifyRequest *) anope_abstract;
	};

	class Mode : public Serialize::Object
	{
	 public:
		static constexpr const char *const NAME = "mode";
		 
		using Serialize::Object::Object;

		virtual Account *GetAccount() anope_abstract;
		virtual void SetAccount(Account *) anope_abstract;

		virtual Anope::string GetMode() anope_abstract;
		virtual void SetMode(const Anope::string &) anope_abstract;
	};

}