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