Anope IRC Services  Version 2.0
ns_suspend.cpp
Go to the documentation of this file.
1 /* NickServ core functions
2  *
3  * (C) 2003-2014 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 #include "modules/suspend.h"
14 
15 static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
16 
18 {
19  NSSuspendInfo(Extensible *) : Serializable("NSSuspendInfo") { }
20 
22  {
23  data["nick"] << what;
24  data["by"] << by;
25  data["reason"] << reason;
26  data["time"] << when;
27  data["expires"] << expires;
28  }
29 
31  {
32  Anope::string snick;
33  data["nick"] >> snick;
34 
35  NSSuspendInfo *si;
36  if (obj)
38  else
39  {
40  NickAlias *na = NickAlias::Find(snick);
41  if (!na)
42  return NULL;
43  si = na->nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
44  data["nick"] >> si->what;
45  }
46 
47  data["by"] >> si->by;
48  data["reason"] >> si->reason;
49  data["time"] >> si->when;
50  data["expires"] >> si->expires;
51  return si;
52  }
53 };
54 
55 class CommandNSSuspend : public Command
56 {
57  public:
58  CommandNSSuspend(Module *creator) : Command(creator, "nickserv/suspend", 2, 3)
59  {
60  this->SetDesc(_("Suspend a given nick"));
61  this->SetSyntax(_("\037nickname\037 [+\037expiry\037] [\037reason\037]"));
62  }
63 
64  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
65  {
66 
67  const Anope::string &nick = params[0];
68  Anope::string expiry = params[1];
69  Anope::string reason = params.size() > 2 ? params[2] : "";
70  time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire");
71 
72  if (Anope::ReadOnly)
73  source.Reply(READ_ONLY_MODE);
74 
75  if (expiry[0] != '+')
76  {
77  reason = expiry + " " + reason;
78  reason.trim();
79  expiry.clear();
80  }
81  else
82  {
83  expiry_secs = Anope::DoTime(expiry);
84  if (expiry_secs == -1)
85  {
86  source.Reply(BAD_EXPIRY_TIME);
87  return;
88  }
89  }
90 
91  NickAlias *na = NickAlias::Find(nick);
92  if (!na)
93  {
94  source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
95  return;
96  }
97 
98  if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
99  {
100  source.Reply(_("You may not suspend other Services Operators' nicknames."));
101  return;
102  }
103 
104  if (na->nc->HasExt("NS_SUSPENDED"))
105  {
106  source.Reply(_("\002%s\002 is already suspended."), na->nc->display.c_str());
107  return;
108  }
109 
110  NickCore *nc = na->nc;
111 
112  NSSuspendInfo *si = nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
113  si->what = nc->display;
114  si->by = source.GetNick();
115  si->reason = reason;
116  si->when = Anope::CurTime;
117  si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
118 
119  for (unsigned i = 0; i < nc->aliases->size(); ++i)
120  {
121  NickAlias *na2 = nc->aliases->at(i);
122 
123  if (na2 && *na2->nc == *na->nc)
124  {
125  na2->last_quit = reason;
126 
127  User *u2 = User::Find(na2->nick, true);
128  if (u2)
129  {
130  u2->Logout();
131  if (nickserv)
132  nickserv->Collide(u2, na2);
133  }
134  }
135  }
136 
137  Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
138  source.Reply(_("Nick %s is now suspended."), nick.c_str());
139 
140  FOREACH_MOD(OnNickSuspend, (na));
141  }
142 
143  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
144  {
145  this->SendSyntax(source);
146  source.Reply(" ");
147  source.Reply(_("Suspends a registered nickname, which prevents it from being used\n"
148  "while keeping all the data for that nick. If an expiry is given\n"
149  "the nick will be unsuspended after that period of time, else the\n"
150  "default expiry from the configuration is used."));
151  return true;
152  }
153 };
154 
156 {
157  public:
158  CommandNSUnSuspend(Module *creator) : Command(creator, "nickserv/unsuspend", 1, 1)
159  {
160  this->SetDesc(_("Unsuspend a given nick"));
161  this->SetSyntax(_("\037nickname\037"));
162  }
163 
164  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
165  {
166  const Anope::string &nick = params[0];
167 
168  if (Anope::ReadOnly)
169  source.Reply(READ_ONLY_MODE);
170 
171  NickAlias *na = NickAlias::Find(nick);
172  if (!na)
173  {
174  source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
175  return;
176  }
177 
178  if (!na->nc->HasExt("NS_SUSPENDED"))
179  {
180  source.Reply(_("Nick %s is not suspended."), na->nick.c_str());
181  return;
182  }
183 
184  NSSuspendInfo *si = na->nc->GetExt<NSSuspendInfo>("NS_SUSPENDED");
185 
186  Log(LOG_ADMIN, source, this) << "for " << na->nick << " which was suspended by " << (!si->by.empty() ? si->by : "(none)") << " for: " << (!si->reason.empty() ? si->reason : "No reason");
187 
188  na->nc->Shrink<NSSuspendInfo>("NS_SUSPENDED");
189 
190  source.Reply(_("Nick %s is now released."), nick.c_str());
191 
192  FOREACH_MOD(OnNickUnsuspended, (na));
193  }
194 
195  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
196  {
197  this->SendSyntax(source);
198  source.Reply(" ");
199  source.Reply(_("Unsuspends a nickname which allows it to be used again."));
200  return true;
201  }
202 };
203 
204 class NSSuspend : public Module
205 {
210  std::vector<Anope::string> show;
211 
212  struct trim
213  {
215  {
216  return s.trim();
217  }
218  };
219 
220  bool Show(CommandSource &source, const Anope::string &what) const
221  {
222  return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
223  }
224 
225  public:
226  NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
227  commandnssuspend(this), commandnsunsuspend(this), suspend(this, "NS_SUSPENDED"),
228  suspend_type("NSSuspendInfo", NSSuspendInfo::Unserialize)
229  {
230  }
231 
233  {
234  Anope::string s = conf->GetModule(this)->Get<Anope::string>("show");
235  commasepstream(s).GetTokens(show);
236  std::transform(show.begin(), show.end(), show.begin(), trim());
237  }
238 
239  void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
240  {
241  NSSuspendInfo *s = suspend.Get(na->nc);
242  if (!s)
243  return;
244 
245  if (show_hidden || Show(source, "suspended"))
246  info[_("Suspended")] = _("This nickname is \002suspended\002.");
247  if (!s->by.empty() && (show_hidden || Show(source, "by")))
248  info[_("Suspended by")] = s->by;
249  if (!s->reason.empty() && (show_hidden || Show(source, "reason")))
250  info[_("Suspend reason")] = s->reason;
251  if (s->when && (show_hidden || Show(source, "on")))
252  info[_("Suspended on")] = Anope::strftime(s->when, source.GetAccount(), true);
253  if (s->expires && (show_hidden || Show(source, "expires")))
254  info[_("Suspension expires")] = Anope::strftime(s->expires, source.GetAccount(), true);
255  }
256 
257  void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
258  {
259  NSSuspendInfo *s = suspend.Get(na->nc);
260  if (!s)
261  return;
262 
263  expire = false;
264 
265  if (!s->expires)
266  return;
267 
268  if (s->expires < Anope::CurTime)
269  {
270  na->last_seen = Anope::CurTime;
271  suspend.Unset(na->nc);
272 
273  Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
274  }
275  }
276 
278  {
279  NSSuspendInfo *s = suspend.Get(na->nc);
280  if (!s)
281  return EVENT_CONTINUE;
282 
283  u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str());
284  return EVENT_STOP;
285  }
286 };
287 
Serialize::Reference< NickCore > nc
Definition: account.h:47
CoreExport bool ReadOnly
Definition: main.cpp:28
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
void OnReload(Configuration::Conf *conf) anope_override
Definition: ns_suspend.cpp:232
void clear()
Definition: anope.h:187
Serialize::Checker< std::vector< NickAlias * > > aliases
Definition: account.h:128
Anope::string nick
Definition: account.h:37
time_t expires
Definition: suspend.h:14
Anope::string reason
Definition: suspend.h:13
void GetTokens(T &token)
Definition: anope.h:587
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
Definition: ns_suspend.cpp:257
Anope::string what
Definition: suspend.h:13
Definition: users.h:34
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
#define NICK_X_NOT_REGISTERED
Definition: language.h:79
Anope::string operator()(Anope::string s) const
Definition: ns_suspend.cpp:214
Serialize::Type suspend_type
Definition: ns_suspend.cpp:209
#define READ_ONLY_MODE
Definition: language.h:71
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
void Unset(Extensible *obj) anope_override
Definition: extensible.h:95
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: ns_suspend.cpp:143
static ServiceReference< NickServService > nickserv("NickServService","NickServ")
CoreExport time_t CurTime
Definition: main.cpp:41
NSSuspend(const Anope::string &modname, const Anope::string &creator)
Definition: ns_suspend.cpp:226
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
bool Show(CommandSource &source, const Anope::string &what) const
Definition: ns_suspend.cpp:220
Definition: Config.cs:26
EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
Definition: ns_suspend.cpp:277
CoreExport time_t DoTime(const Anope::string &s)
Definition: misc.cpp:275
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: ns_suspend.cpp:195
time_t when
Definition: suspend.h:14
void Serialize(Serialize::Data &data) const anope_override
Definition: ns_suspend.cpp:21
static Serializable * Unserialize(Serializable *obj, Serialize::Data &data)
Definition: ns_suspend.cpp:30
Anope::string display
Definition: account.h:113
string & trim(const Anope::string &what=" \t\r\n")
Definition: anope.h:177
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
void Logout()
Definition: users.cpp:408
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
ExtensibleItem< NSSuspendInfo > suspend
Definition: ns_suspend.cpp:208
CommandNSSuspend commandnssuspend
Definition: ns_suspend.cpp:206
bool IsOper()
Definition: command.cpp:87
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
CommandNSUnSuspend commandnsunsuspend
Definition: ns_suspend.cpp:207
static User * Find(const Anope::string &name, bool nick_only=false)
Definition: users.cpp:815
CommandNSUnSuspend(Module *creator)
Definition: ns_suspend.cpp:158
std::vector< Anope::string > show
Definition: ns_suspend.cpp:210
T * Get(const Extensible *obj) const
Definition: extensible.h:103
T anope_dynamic_static_cast(O ptr)
Definition: anope.h:774
CommandNSSuspend(Module *creator)
Definition: ns_suspend.cpp:58
void SendSyntax(CommandSource &)
Definition: command.cpp:145
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: ns_suspend.cpp:164
Anope::string last_quit
Definition: account.h:38
#define BAD_EXPIRY_TIME
Definition: language.h:69
NSSuspendInfo(Extensible *)
Definition: ns_suspend.cpp:19
CoreExport Anope::string strftime(time_t t, const NickCore *nc=NULL, bool short_output=false)
Definition: misc.cpp:356
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
Definition: ns_suspend.cpp:239
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: ns_suspend.cpp:64
#define _(x)
Definition: services.h:50
Type(const Anope::string &n, unserialize_func f, Module *owner=NULL)
Anope::string by
Definition: suspend.h:13
#define NICK_X_SUSPENDED
Definition: language.h:82
Module * owner
Definition: service.h:84