]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
Merge branch 'master' into full-month-stats
[stg.git] / projects / stargazer / plugins / configuration / rpcconfig / users_methods.cpp
1 #include <cerrno>
2
3 #include "stg/users.h"
4 #include "stg/admins.h"
5 #include "stg/tariffs.h"
6 #include "stg/user_ips.h"
7 #include "stg/common.h"
8 #include "stg/user_property.h"
9
10 #include "users_methods.h"
11 #include "rpcconfig.h"
12 #include "user_helper.h"
13 #include "utils.h"
14
15 //------------------------------------------------------------------------------
16
17 void METHOD_USER_GET::execute(xmlrpc_c::paramList const & paramList,
18                               xmlrpc_c::value *   const   retvalPtr)
19 {
20 std::string cookie = paramList.getString(0);
21 std::string login = paramList.getString(1);
22 std::string enc;
23 paramList.verifyEnd(2);
24
25 std::map<std::string, xmlrpc_c::value> structVal;
26 ADMIN_INFO adminInfo;
27
28 if (config->GetAdminInfo(cookie, &adminInfo))
29     {
30     structVal["result"] = xmlrpc_c::value_boolean(false);
31     *retvalPtr = xmlrpc_c::value_struct(structVal);
32     return;
33     }
34
35 USER_PTR u;
36
37 if (users->FindByName(login, &u))
38     {
39     structVal["result"] = xmlrpc_c::value_boolean(false);
40     *retvalPtr = xmlrpc_c::value_struct(structVal);
41     return;
42     }
43
44 USER_HELPER uhelper(u);
45
46 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
47     {
48     uhelper.GetUserInfo(retvalPtr, true);
49     return;
50     }
51
52 uhelper.GetUserInfo(retvalPtr);
53 }
54
55 //------------------------------------------------------------------------------
56
57 void METHOD_USER_ADD::execute(xmlrpc_c::paramList const & paramList,
58                               xmlrpc_c::value *   const   retvalPtr)
59 {
60 std::string cookie = paramList.getString(0);
61 std::string login = paramList.getString(1);
62 std::string enc;
63 paramList.verifyEnd(2);
64
65 ADMIN_INFO adminInfo;
66
67 if (config->GetAdminInfo(cookie, &adminInfo))
68     {
69     *retvalPtr = xmlrpc_c::value_boolean(false);
70     return;
71     }
72
73 ADMIN * admin = NULL;
74
75 if (admins->Find(adminInfo.admin, &admin))
76     {
77     *retvalPtr = xmlrpc_c::value_boolean(false);
78     return;
79     }
80
81 USER_PTR u;
82
83 if (users->FindByName(login, &u))
84     {
85     if (users->Add(login, admin))
86         {
87         *retvalPtr = xmlrpc_c::value_boolean(false);
88         return;
89         }
90
91     *retvalPtr = xmlrpc_c::value_boolean(true);
92     return;
93     }
94     
95 *retvalPtr = xmlrpc_c::value_boolean(false);
96 return;
97 }
98
99 //------------------------------------------------------------------------------
100
101 void METHOD_USER_DEL::execute(xmlrpc_c::paramList const & paramList,
102                               xmlrpc_c::value *   const   retvalPtr)
103 {
104 std::string cookie = paramList.getString(0);
105 std::string login = paramList.getString(1);
106 std::string enc;
107 paramList.verifyEnd(2);
108
109 ADMIN_INFO adminInfo;
110
111 if (config->GetAdminInfo(cookie, &adminInfo))
112     {
113     *retvalPtr = xmlrpc_c::value_boolean(false);
114     return;
115     }
116
117 ADMIN * admin;
118
119 if (admins->Find(adminInfo.admin, &admin))
120     {
121     *retvalPtr = xmlrpc_c::value_boolean(false);
122     return;
123     }
124
125 USER_PTR u;
126
127 if (!users->FindByName(login, &u))
128     {
129     users->Del(login, admin);
130     *retvalPtr = xmlrpc_c::value_boolean(true);
131     return;
132     }
133
134 *retvalPtr = xmlrpc_c::value_boolean(false);
135 return;
136 }
137
138 //------------------------------------------------------------------------------
139
140 void METHOD_USERS_GET::execute(xmlrpc_c::paramList const & paramList,
141                                xmlrpc_c::value *   const   retvalPtr)
142 {
143 std::string cookie = paramList.getString(0);
144 std::string enc;
145 paramList.verifyEnd(1);
146
147 std::map<std::string, xmlrpc_c::value> structVal;
148 std::vector<xmlrpc_c::value> retval;
149 ADMIN_INFO adminInfo;
150
151 if (config->GetAdminInfo(cookie, &adminInfo))
152     {
153     structVal["result"] = xmlrpc_c::value_boolean(false);
154     *retvalPtr = xmlrpc_c::value_struct(structVal);
155     return;
156     }
157
158 bool hidePassword = !adminInfo.priviledges.userConf ||
159                     !adminInfo.priviledges.userPasswd;
160
161 USER_PTR u;
162
163 int h = users->OpenSearch();
164 if (!h)
165     {
166     printfd(__FILE__, "users->OpenSearch() error\n");
167     users->CloseSearch(h);
168     return;
169     }
170
171 while (1)
172     {
173     if (users->SearchNext(h, &u))
174         {
175         break;
176         }
177
178     xmlrpc_c::value info;
179
180     USER_HELPER uhelper(u);
181
182     uhelper.GetUserInfo(&info, hidePassword);
183
184     retval.push_back(info);
185     }
186
187 *retvalPtr = xmlrpc_c::value_array(retval);
188 }
189
190 //------------------------------------------------------------------------------
191
192 void METHOD_USER_CHG::execute(xmlrpc_c::paramList const & paramList,
193                               xmlrpc_c::value *   const   retvalPtr)
194 {
195 std::string cookie = paramList.getString(0);
196 std::string login = paramList.getString(1);
197 xmlrpc_c::value_struct info(paramList.getStruct(2));
198 std::string enc;
199 paramList.verifyEnd(3);
200
201 ADMIN_INFO adminInfo;
202
203 if (config->GetAdminInfo(cookie, &adminInfo))
204     {
205     *retvalPtr = xmlrpc_c::value_boolean(false);
206     return;
207     }
208
209 ADMIN * admin;
210
211 if (admins->Find(adminInfo.admin, &admin))
212     {
213     *retvalPtr = xmlrpc_c::value_boolean(false);
214     return;
215     }
216
217 USER_PTR u;
218
219 if (users->FindByName(login, &u))
220     {
221     *retvalPtr = xmlrpc_c::value_boolean(false);
222     return;
223     }
224
225 USER_HELPER uhelper(u);
226
227 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
228     {
229     uhelper.SetUserInfo(info, admin, login, *store, tariffs);
230     }
231 else
232     {
233     uhelper.SetUserInfo(info, admin, login, *store, tariffs);
234     }
235
236 u->WriteConf();
237 u->WriteStat();
238
239 *retvalPtr = xmlrpc_c::value_boolean(true);
240 }
241
242 //------------------------------------------------------------------------------
243
244 void METHOD_USER_CASH_ADD::execute(xmlrpc_c::paramList const & paramList,
245                                    xmlrpc_c::value *   const   retvalPtr)
246 {
247 std::string cookie = paramList.getString(0);
248 std::string login = paramList.getString(1);
249 double amount = paramList.getDouble(2);
250 std::string comment = IconvString(paramList.getString(3), "UTF-8", "KOI8-R");
251 std::string enc;
252 paramList.verifyEnd(4);
253
254 ADMIN_INFO adminInfo;
255
256 if (config->GetAdminInfo(cookie, &adminInfo))
257     {
258     *retvalPtr = xmlrpc_c::value_boolean(false);
259     return;
260     }
261
262 ADMIN * admin;
263
264 if (admins->Find(adminInfo.admin, &admin))
265     {
266     *retvalPtr = xmlrpc_c::value_boolean(false);
267     return;
268     }
269
270 USER_PTR u;
271
272 if (users->FindByName(login, &u))
273     {
274     *retvalPtr = xmlrpc_c::value_boolean(false);
275     return;
276     }
277
278 double cash = u->GetProperty().cash.Get();
279 cash += amount;
280
281 if (!u->GetProperty().cash.Set(cash, admin, login, store, comment))
282     {
283     *retvalPtr = xmlrpc_c::value_boolean(false);
284     return;
285     }
286
287 u->WriteStat();
288
289 *retvalPtr = xmlrpc_c::value_boolean(true);
290 }
291
292 //------------------------------------------------------------------------------
293
294 void METHOD_USER_CASH_SET::execute(xmlrpc_c::paramList const & paramList,
295                                    xmlrpc_c::value *   const   retvalPtr)
296 {
297 std::string cookie = paramList.getString(0);
298 std::string login = paramList.getString(1);
299 double cash = paramList.getDouble(2);
300 std::string comment = IconvString(paramList.getString(3), "UTF-8", "KOI8-R");
301 std::string enc;
302 paramList.verifyEnd(4);
303
304 ADMIN_INFO adminInfo;
305
306 if (config->GetAdminInfo(cookie, &adminInfo))
307     {
308     *retvalPtr = xmlrpc_c::value_boolean(false);
309     return;
310     }
311
312 ADMIN * admin;
313
314 if (admins->Find(adminInfo.admin, &admin))
315     {
316     *retvalPtr = xmlrpc_c::value_boolean(false);
317     return;
318     }
319
320 USER_PTR u;
321
322 if (users->FindByName(login, &u))
323     {
324     *retvalPtr = xmlrpc_c::value_boolean(false);
325     return;
326     }
327
328 if (!u->GetProperty().cash.Set(cash, admin, login, store, comment))
329     {
330     *retvalPtr = xmlrpc_c::value_boolean(false);
331     return;
332     }
333
334 u->WriteStat();
335
336 *retvalPtr = xmlrpc_c::value_boolean(true);
337 }
338
339 //------------------------------------------------------------------------------
340
341 void METHOD_USER_TARIFF_CHANGE::execute(xmlrpc_c::paramList const & paramList,
342                                         xmlrpc_c::value *   const   retvalPtr)
343 {
344 std::string cookie = paramList.getString(0);
345 std::string login = paramList.getString(1);
346 std::string tariff = paramList.getString(2);
347 bool delayed = paramList.getBoolean(3);
348 std::string comment = IconvString(paramList.getString(4), "UTF-8", "KOI8-R");
349 std::string enc;
350 paramList.verifyEnd(5);
351
352 ADMIN_INFO adminInfo;
353
354 if (config->GetAdminInfo(cookie, &adminInfo))
355     {
356     *retvalPtr = xmlrpc_c::value_boolean(false);
357     return;
358     }
359
360 ADMIN * admin;
361
362 if (admins->Find(adminInfo.admin, &admin))
363     {
364     *retvalPtr = xmlrpc_c::value_boolean(false);
365     return;
366     }
367
368 USER_PTR u;
369
370 if (users->FindByName(login, &u))
371     {
372     *retvalPtr = xmlrpc_c::value_boolean(false);
373     return;
374     }
375
376 if (tariffs->FindByName(tariff))
377     {
378     if (delayed)
379         {
380         if (u->GetProperty().nextTariff.Set(tariff,
381                                             admin,
382                                             login,
383                                             store))
384             {
385             u->WriteConf();
386             *retvalPtr = xmlrpc_c::value_boolean(true);
387             return;
388             }
389         }
390     else
391         {
392         if (u->GetProperty().tariffName.Set(tariff,
393                                             admin,
394                                             login,
395                                             store))
396             {
397             u->ResetNextTariff();
398             u->WriteConf();
399             *retvalPtr = xmlrpc_c::value_boolean(true);
400             return;
401             }
402         }
403     }
404
405 *retvalPtr = xmlrpc_c::value_boolean(false);
406 }
407
408 //------------------------------------------------------------------------------
409
410 void METHOD_GET_ONLINE_IPS::execute(xmlrpc_c::paramList const & paramList,
411                                     xmlrpc_c::value *   const   retvalPtr)
412 {
413 std::string cookie = paramList.getString(0);
414 std::vector<xmlrpc_c::value> subnetsStr = paramList.getArray(1);
415 paramList.verifyEnd(2);
416
417 std::vector<IP_MASK> subnets;
418
419 std::vector<xmlrpc_c::value>::iterator it;
420
421 for (it = subnetsStr.begin(); it != subnetsStr.end(); ++it)
422     {
423     IP_MASK ipm;
424     if (ParseNet(xmlrpc_c::value_string(*it), ipm))
425         {
426         printfd(__FILE__, "METHOD_GET_ONLINE_IPS::execute(): Failed to parse subnet ('%s')\n", std::string(xmlrpc_c::value_string(*it)).c_str());
427         }
428     else
429         {
430         subnets.push_back(ipm);
431         }
432     }
433
434 std::map<std::string, xmlrpc_c::value> structVal;
435 ADMIN_INFO adminInfo;
436
437 if (config->GetAdminInfo(cookie, &adminInfo))
438     {
439     structVal["result"] = xmlrpc_c::value_boolean(false);
440     *retvalPtr = xmlrpc_c::value_struct(structVal);
441     return;
442     }
443
444 std::vector<xmlrpc_c::value> ips;
445
446 USER_PTR u;
447
448 int handle = users->OpenSearch();
449 if (!handle)
450     {
451     printfd(__FILE__, "users->OpenSearch() error\n");
452     users->CloseSearch(handle);
453     return;
454     }
455
456 while (1)
457     {
458     if (users->SearchNext(handle, &u))
459         {
460         break;
461         }
462
463     if (u->GetAuthorized())
464         {
465         uint32_t ip = u->GetCurrIP();
466
467         std::vector<IP_MASK>::iterator it;
468         for (it = subnets.begin(); it != subnets.end(); ++it)
469             {
470             if ((it->ip & it->mask) == (ip & it->mask))
471                 {
472                 ips.push_back(xmlrpc_c::value_string(inet_ntostring(u->GetCurrIP())));
473                 break;
474                 }
475             }
476         }
477     }
478
479 structVal["ips"] = xmlrpc_c::value_array(ips);
480
481 *retvalPtr = xmlrpc_c::value_struct(structVal);
482 }
483
484 bool METHOD_GET_ONLINE_IPS::ParseNet(const std::string & net, IP_MASK & ipm) const
485 {
486 size_t pos = net.find_first_of('/');
487
488 if (pos == std::string::npos)
489     {
490     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Network address is not in CIDR-notation\n");
491     return true;
492     }
493
494 int res = inet_pton(AF_INET, net.substr(0, pos).c_str(), &ipm.ip);
495
496 if (res < 0)
497     {
498     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): '%s'\n", strerror(errno));
499     return true;
500     }
501 else if (res == 0)
502     {
503     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Invalid network address\n", strerror(errno));
504     return true;
505     }
506
507 if (str2x(net.substr(pos + 1, net.length() - pos - 1), ipm.mask))
508     {
509     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Invalid network mask\n");
510     return true;
511     }
512 if (ipm.mask > 32)
513     {
514     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Network mask is out of range\n");
515     return true;
516     }
517 ipm.mask = htonl(0xffFFffFF << (32 - ipm.mask));
518
519 return false;
520 }