]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
Use std::lock_guard instead of STG_LOCKER.
[stg.git] / projects / stargazer / plugins / configuration / rpcconfig / users_methods.cpp
1 #include "users_methods.h"
2 #include "rpcconfig.h"
3 #include "user_helper.h"
4
5 #include "stg/users.h"
6 #include "stg/admins.h"
7 #include "stg/tariffs.h"
8 #include "stg/tariff.h"
9 #include "stg/user.h"
10 #include "stg/user_property.h"
11 #include "stg/common.h"
12
13 #include <cerrno>
14
15 using UserPtr = STG::User*;
16
17 //------------------------------------------------------------------------------
18
19 void METHOD_USER_GET::execute(xmlrpc_c::paramList const & paramList,
20                               xmlrpc_c::value *   const   retvalPtr)
21 {
22 std::string cookie = paramList.getString(0);
23 std::string login = paramList.getString(1);
24 paramList.verifyEnd(2);
25
26 std::map<std::string, xmlrpc_c::value> structVal;
27 ADMIN_INFO adminInfo;
28
29 if (config->GetAdminInfo(cookie, &adminInfo))
30     {
31     structVal["result"] = xmlrpc_c::value_boolean(false);
32     *retvalPtr = xmlrpc_c::value_struct(structVal);
33     return;
34     }
35
36 UserPtr u;
37
38 if (users->FindByName(login, &u))
39     {
40     structVal["result"] = xmlrpc_c::value_boolean(false);
41     *retvalPtr = xmlrpc_c::value_struct(structVal);
42     return;
43     }
44
45 USER_HELPER uhelper(u, *users);
46
47 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
48     {
49     uhelper.GetUserInfo(retvalPtr, true);
50     return;
51     }
52
53 uhelper.GetUserInfo(retvalPtr);
54 }
55
56 //------------------------------------------------------------------------------
57
58 void METHOD_USER_ADD::execute(xmlrpc_c::paramList const & paramList,
59                               xmlrpc_c::value *   const   retvalPtr)
60 {
61 std::string cookie = paramList.getString(0);
62 std::string login = paramList.getString(1);
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 STG::Admin * admin = NULL;
74
75 if (admins->find(adminInfo.admin, &admin))
76     {
77     *retvalPtr = xmlrpc_c::value_boolean(false);
78     return;
79     }
80
81 UserPtr 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 paramList.verifyEnd(2);
107
108 ADMIN_INFO adminInfo;
109
110 if (config->GetAdminInfo(cookie, &adminInfo))
111     {
112     *retvalPtr = xmlrpc_c::value_boolean(false);
113     return;
114     }
115
116 STG::Admin * admin;
117
118 if (admins->find(adminInfo.admin, &admin))
119     {
120     *retvalPtr = xmlrpc_c::value_boolean(false);
121     return;
122     }
123
124 UserPtr u;
125
126 if (!users->FindByName(login, &u))
127     {
128     users->Del(login, admin);
129     *retvalPtr = xmlrpc_c::value_boolean(true);
130     return;
131     }
132
133 *retvalPtr = xmlrpc_c::value_boolean(false);
134 return;
135 }
136
137 //------------------------------------------------------------------------------
138
139 void METHOD_USERS_GET::execute(xmlrpc_c::paramList const & paramList,
140                                xmlrpc_c::value *   const   retvalPtr)
141 {
142 std::string cookie = paramList.getString(0);
143 paramList.verifyEnd(1);
144
145 std::map<std::string, xmlrpc_c::value> structVal;
146 std::vector<xmlrpc_c::value> retval;
147 ADMIN_INFO adminInfo;
148
149 if (config->GetAdminInfo(cookie, &adminInfo))
150     {
151     structVal["result"] = xmlrpc_c::value_boolean(false);
152     *retvalPtr = xmlrpc_c::value_struct(structVal);
153     return;
154     }
155
156 bool hidePassword = !adminInfo.priviledges.userConf ||
157                     !adminInfo.priviledges.userPasswd;
158
159 UserPtr u;
160
161 int h = users->OpenSearch();
162 if (!h)
163     {
164     printfd(__FILE__, "users->OpenSearch() error\n");
165     users->CloseSearch(h);
166     return;
167     }
168
169 while (1)
170     {
171     if (users->SearchNext(h, &u))
172         {
173         break;
174         }
175
176     xmlrpc_c::value info;
177
178     USER_HELPER uhelper(u, *users);
179
180     uhelper.GetUserInfo(&info, hidePassword);
181
182     retval.push_back(info);
183     }
184
185 *retvalPtr = xmlrpc_c::value_array(retval);
186 }
187
188 //------------------------------------------------------------------------------
189
190 void METHOD_USER_CHG::execute(xmlrpc_c::paramList const & paramList,
191                               xmlrpc_c::value *   const   retvalPtr)
192 {
193 std::string cookie = paramList.getString(0);
194 std::string login = paramList.getString(1);
195 xmlrpc_c::value_struct info(paramList.getStruct(2));
196 paramList.verifyEnd(3);
197
198 ADMIN_INFO adminInfo;
199
200 if (config->GetAdminInfo(cookie, &adminInfo))
201     {
202     *retvalPtr = xmlrpc_c::value_boolean(false);
203     return;
204     }
205
206 STG::Admin * admin;
207
208 if (admins->find(adminInfo.admin, &admin))
209     {
210     *retvalPtr = xmlrpc_c::value_boolean(false);
211     return;
212     }
213
214 UserPtr u;
215
216 if (users->FindByName(login, &u))
217     {
218     *retvalPtr = xmlrpc_c::value_boolean(false);
219     return;
220     }
221
222 USER_HELPER uhelper(u, *users);
223
224 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
225     {
226     uhelper.SetUserInfo(info, *admin, login, *store, tariffs);
227     }
228 else
229     {
230     uhelper.SetUserInfo(info, *admin, login, *store, tariffs);
231     }
232
233 u->WriteConf();
234 u->WriteStat();
235
236 *retvalPtr = xmlrpc_c::value_boolean(true);
237 }
238
239 //------------------------------------------------------------------------------
240
241 void METHOD_USER_CASH_ADD::execute(xmlrpc_c::paramList const & paramList,
242                                    xmlrpc_c::value *   const   retvalPtr)
243 {
244 std::string cookie = paramList.getString(0);
245 std::string login = paramList.getString(1);
246 double amount = paramList.getDouble(2);
247 std::string comment = IconvString(paramList.getString(3), "UTF-8", "KOI8-R");
248 paramList.verifyEnd(4);
249
250 ADMIN_INFO adminInfo;
251
252 if (config->GetAdminInfo(cookie, &adminInfo))
253     {
254     *retvalPtr = xmlrpc_c::value_boolean(false);
255     return;
256     }
257
258 STG::Admin * admin;
259
260 if (admins->find(adminInfo.admin, &admin))
261     {
262     *retvalPtr = xmlrpc_c::value_boolean(false);
263     return;
264     }
265
266 UserPtr u;
267
268 if (users->FindByName(login, &u))
269     {
270     *retvalPtr = xmlrpc_c::value_boolean(false);
271     return;
272     }
273
274 double cash = u->GetProperties().cash.Get();
275 cash += amount;
276
277 if (!u->GetProperties().cash.Set(cash, *admin, login, *store, comment))
278     {
279     *retvalPtr = xmlrpc_c::value_boolean(false);
280     return;
281     }
282
283 u->WriteStat();
284
285 *retvalPtr = xmlrpc_c::value_boolean(true);
286 }
287
288 //------------------------------------------------------------------------------
289
290 void METHOD_USER_CASH_SET::execute(xmlrpc_c::paramList const & paramList,
291                                    xmlrpc_c::value *   const   retvalPtr)
292 {
293 std::string cookie = paramList.getString(0);
294 std::string login = paramList.getString(1);
295 double cash = paramList.getDouble(2);
296 std::string comment = IconvString(paramList.getString(3), "UTF-8", "KOI8-R");
297 paramList.verifyEnd(4);
298
299 ADMIN_INFO adminInfo;
300
301 if (config->GetAdminInfo(cookie, &adminInfo))
302     {
303     *retvalPtr = xmlrpc_c::value_boolean(false);
304     return;
305     }
306
307 STG::Admin * admin;
308
309 if (admins->find(adminInfo.admin, &admin))
310     {
311     *retvalPtr = xmlrpc_c::value_boolean(false);
312     return;
313     }
314
315 UserPtr u;
316
317 if (users->FindByName(login, &u))
318     {
319     *retvalPtr = xmlrpc_c::value_boolean(false);
320     return;
321     }
322
323 if (!u->GetProperties().cash.Set(cash, *admin, login, *store, comment))
324     {
325     *retvalPtr = xmlrpc_c::value_boolean(false);
326     return;
327     }
328
329 u->WriteStat();
330
331 *retvalPtr = xmlrpc_c::value_boolean(true);
332 }
333
334 //------------------------------------------------------------------------------
335
336 void METHOD_USER_TARIFF_CHANGE::execute(xmlrpc_c::paramList const & paramList,
337                                         xmlrpc_c::value *   const   retvalPtr)
338 {
339 std::string cookie = paramList.getString(0);
340 std::string login = paramList.getString(1);
341 std::string tariff = paramList.getString(2);
342 bool delayed = paramList.getBoolean(3);
343 std::string comment = IconvString(paramList.getString(4), "UTF-8", "KOI8-R");
344 paramList.verifyEnd(5);
345
346 ADMIN_INFO adminInfo;
347
348 if (config->GetAdminInfo(cookie, &adminInfo))
349     {
350     *retvalPtr = xmlrpc_c::value_boolean(false);
351     return;
352     }
353
354 STG::Admin * admin;
355
356 if (admins->find(adminInfo.admin, &admin))
357     {
358     *retvalPtr = xmlrpc_c::value_boolean(false);
359     return;
360     }
361
362 UserPtr u;
363
364 if (users->FindByName(login, &u))
365     {
366     *retvalPtr = xmlrpc_c::value_boolean(false);
367     return;
368     }
369
370 if (tariffs->FindByName(tariff))
371     {
372     if (delayed)
373         {
374         if (u->GetProperties().nextTariff.Set(tariff, *admin, login, *store, comment))
375             {
376             u->WriteConf();
377             *retvalPtr = xmlrpc_c::value_boolean(true);
378             return;
379             }
380         }
381     else
382         {
383         const auto newTariff = tariffs->FindByName(tariff);
384         if (newTariff)
385             {
386             const auto currentTariff = u->GetTariff();
387             std::string message = currentTariff->TariffChangeIsAllowed(*newTariff, time(NULL));
388             if (message.empty())
389                 {
390                 if (u->GetProperties().tariffName.Set(tariff, *admin, login, *store, comment))
391                     {
392                     u->ResetNextTariff();
393                     u->WriteConf();
394                     *retvalPtr = xmlrpc_c::value_boolean(true);
395                     return;
396                     }
397                 }
398             else
399                 {
400                     STG::PluginLogger::get("conf_rpc")("Tariff change is prohibited for user %s. %s", u->GetLogin().c_str(), message.c_str());
401                 }
402             }
403         }
404     }
405
406 *retvalPtr = xmlrpc_c::value_boolean(false);
407 }
408
409 //------------------------------------------------------------------------------
410
411 void METHOD_GET_ONLINE_IPS::execute(xmlrpc_c::paramList const & paramList,
412                                     xmlrpc_c::value *   const   retvalPtr)
413 {
414 std::string cookie = paramList.getString(0);
415 typedef std::vector<xmlrpc_c::value> ValueVector;
416 ValueVector subnetsStr = paramList.getArray(1);
417 paramList.verifyEnd(2);
418
419 std::vector<STG::IPMask> subnets;
420
421 for (ValueVector::const_iterator it(subnetsStr.begin()); it != subnetsStr.end(); ++it)
422     {
423     STG::IPMask 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 ValueVector ips;
445
446 UserPtr 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         for (std::vector<STG::IPMask>::const_iterator it(subnets.begin()); it != subnets.end(); ++it)
468             {
469             if ((it->ip & it->mask) == (ip & it->mask))
470                 {
471                 ips.push_back(xmlrpc_c::value_string(inet_ntostring(u->GetCurrIP())));
472                 break;
473                 }
474             }
475         }
476     }
477
478 structVal["ips"] = xmlrpc_c::value_array(ips);
479
480 *retvalPtr = xmlrpc_c::value_struct(structVal);
481 }
482
483 bool METHOD_GET_ONLINE_IPS::ParseNet(const std::string & net, STG::IPMask & ipm) const
484 {
485 size_t pos = net.find_first_of('/');
486
487 if (pos == std::string::npos)
488     {
489     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Network address is not in CIDR-notation\n");
490     return true;
491     }
492
493 int res = inet_pton(AF_INET, net.substr(0, pos).c_str(), &ipm.ip);
494
495 if (res < 0)
496     {
497     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): '%s'\n", strerror(errno));
498     return true;
499     }
500 else if (res == 0)
501     {
502     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Invalid network address\n", strerror(errno));
503     return true;
504     }
505
506 if (str2x(net.substr(pos + 1, net.length() - pos - 1), ipm.mask))
507     {
508     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Invalid network mask\n");
509     return true;
510     }
511 if (ipm.mask > 32)
512     {
513     printfd(__FILE__, "METHOD_GET_ONLINE_IPS::ParseNet(): Network mask is out of range\n");
514     return true;
515     }
516 ipm.mask = htonl(0xffFFffFF << (32 - ipm.mask));
517
518 return false;
519 }
520
521 void METHOD_GET_USER_AUTH_BY::execute(xmlrpc_c::paramList const & paramList,
522                                       xmlrpc_c::value *   const   retvalPtr)
523 {
524 std::string cookie = paramList.getString(0);
525 std::string login = paramList.getString(1);
526 paramList.verifyEnd(2);
527
528 std::map<std::string, xmlrpc_c::value> structVal;
529 ADMIN_INFO adminInfo;
530
531 if (config->GetAdminInfo(cookie, &adminInfo))
532     {
533     structVal["result"] = xmlrpc_c::value_boolean(false);
534     *retvalPtr = xmlrpc_c::value_struct(structVal);
535     return;
536     }
537
538 UserPtr u;
539
540 if (users->FindByName(login, &u))
541     {
542     structVal["result"] = xmlrpc_c::value_boolean(false);
543     *retvalPtr = xmlrpc_c::value_struct(structVal);
544     return;
545     }
546
547 std::vector<std::string> list(u->GetAuthorizers());
548 std::vector<xmlrpc_c::value> authList;
549 for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
550     authList.push_back(xmlrpc_c::value_string(*it));
551 *retvalPtr = xmlrpc_c::value_array(authList);
552 }