]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp
Hide or add proper copy ctor and assignement operator, initialize
[stg.git] / projects / stargazer / plugins / configuration / rpcconfig / rpcconfig.cpp
1 #include <unistd.h> // TODO: usleep
2
3 #include <cstdlib>
4 #include <csignal>
5
6 #include <vector>
7 #include <algorithm>
8
9 #include "stg/common.h"
10 #include "stg/admin.h"
11 #include "stg/module_settings.h"
12 #include "stg/settings.h"
13 #include "stg/plugin_creator.h"
14
15 #include "rpcconfig.h"
16 #include "info_methods.h"
17 #include "users_methods.h"
18 #include "tariffs_methods.h"
19 #include "admins_methods.h"
20 #include "messages_methods.h"
21
22 PLUGIN_CREATOR<RPC_CONFIG> rpcc;
23
24 RPC_CONFIG_SETTINGS::RPC_CONFIG_SETTINGS()
25     : errorStr(),
26       port(0),
27       cookieTimeout(0)
28 {
29 }
30
31 int RPC_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
32 {
33 int p;
34 PARAM_VALUE pv;
35 std::vector<PARAM_VALUE>::const_iterator pvi;
36
37 pv.param = "Port";
38 pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
39 if (pvi == s.moduleParams.end())
40     {
41     errorStr = "Parameter \'Port\' not found.";
42     printfd(__FILE__, "Parameter 'Port' not found\n");
43     return -1;
44     }
45 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
46     {
47     errorStr = "Cannot parse parameter \'Port\': " + errorStr;
48     printfd(__FILE__, "Cannot parse parameter 'Port'\n");
49     return -1;
50     }
51 port = p;
52
53 pv.param = "CookieTimeout";
54 pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
55 if (pvi == s.moduleParams.end())
56     {
57     cookieTimeout = 1800; // 30 * 60
58     }
59 else
60     {
61     if (str2x(pvi->value[0], cookieTimeout))
62         {
63         errorStr = "Incorrect value of CookieTimeout: \'" + pvi->value[0] + "\'";
64         printfd(__FILE__, "Incorrect value of 'CookieTimeout'\n");
65         return -1;
66         }
67     }
68
69 return 0;
70 }
71
72 PLUGIN * GetPlugin()
73 {
74 return rpcc.GetPlugin();
75 }
76
77 RPC_CONFIG::RPC_CONFIG()
78     : errorStr(),
79       rpcConfigSettings(),
80       users(NULL),
81       admins(NULL),
82       tariffs(NULL),
83       store(NULL),
84       settings(),
85       rpcRegistry(),
86       rpcServer(NULL),
87       running(false),
88       stopped(true),
89       tid(),
90       cookies(),
91       dayFee(0),
92       dirNames()
93 {
94 }
95
96 RPC_CONFIG::~RPC_CONFIG()
97 {
98 // delete server
99 delete rpcServer;
100 }
101
102 int RPC_CONFIG::ParseSettings()
103 {
104 int ret = rpcConfigSettings.ParseSettings(settings);
105
106 if (ret)
107     errorStr = rpcConfigSettings.GetStrError();
108
109 return ret;
110 }
111
112 void RPC_CONFIG::SetStgSettings(const SETTINGS * settings)
113 {
114     dayFee = settings->GetDayFee();
115     dirNames.erase(dirNames.begin(), dirNames.end());
116     for (size_t i = 0; i < DIR_NUM; ++i) {
117         dirNames.push_back(settings->GetDirName(i));
118     }
119 }
120
121 int RPC_CONFIG::Start()
122 {
123 InitiateRegistry();
124 running = true;
125 rpcServer = new xmlrpc_c::serverAbyss(
126         rpcRegistry,
127         rpcConfigSettings.GetPort(),
128         "/var/log/stargazer_rpc.log"
129         );
130 if (pthread_create(&tid, NULL, Run, this))
131     {
132     errorStr = "Failed to create RPC thread";
133     printfd(__FILE__, "Failed to crate RPC thread\n");
134     return -1;
135     }
136 return 0;
137 }
138
139 int RPC_CONFIG::Stop()
140 {
141 running = false;
142 for (int i = 0; i < 5 && !stopped; ++i)
143     usleep(200000);
144 //rpcServer->terminate();
145 if (!stopped)
146     {
147     if (pthread_kill(tid, SIGTERM))
148         {
149         errorStr = "Failed to kill thread";
150         printfd(__FILE__, "Failed to kill thread\n");
151         }
152     for (int i = 0; i < 25 && !stopped; ++i)
153         usleep(200000);
154     if (!stopped)
155         {
156         printfd(__FILE__, "Failed to stop RPC thread\n");
157         errorStr = "Failed to stop RPC thread";
158         return -1;
159         }
160     else
161         {
162         pthread_join(tid, NULL);
163         }
164     }
165 return 0;
166 }
167
168 void * RPC_CONFIG::Run(void * rc)
169 {
170 RPC_CONFIG * config = static_cast<RPC_CONFIG *>(rc);
171
172 config->stopped = false;
173 while (config->running)
174     {
175     config->rpcServer->runOnce();
176     }
177 config->stopped = true;
178
179 return NULL;
180 }
181
182 bool RPC_CONFIG::GetAdminInfo(const std::string & cookie,
183                               ADMIN_INFO * info)
184 {
185 std::map<std::string,
186          ADMIN_INFO>::iterator it;
187
188 it = cookies.find(cookie);
189
190 if (it == cookies.end())
191     {
192     return true;
193     }
194
195 if (difftime(it->second.accessTime, time(NULL)) >
196     rpcConfigSettings.GetCookieTimeout())
197     {
198     cookies.erase(it);
199     return true;
200     }
201
202 // Update access time
203 time(&it->second.accessTime);
204 *info = it->second;
205 return false;
206 }
207
208 bool RPC_CONFIG::CheckAdmin(const std::string & login,
209                             const std::string & password,
210                             std::string * cookie)
211 {
212 ADMIN * admin = NULL;
213
214 if (!admins->Correct(login, password, &admin))
215     {
216     return true;
217     }
218
219 ADMIN_INFO info;
220 time(&info.accessTime);
221 info.admin = login;
222 info.priviledges = *admin->GetPriv();
223 *cookie = GetCookie();
224 cookies[*cookie] = info;
225
226 return false;
227 }
228
229 bool RPC_CONFIG::LogoutAdmin(const std::string & cookie)
230 {
231 std::map<std::string,
232          ADMIN_INFO>::iterator it;
233
234 it = cookies.find(cookie);
235
236 if (it == cookies.end())
237     {
238     return true;
239     }
240
241 cookies.erase(it);
242
243 return false;
244 }
245
246 std::string RPC_CONFIG::GetCookie() const
247 {
248 std::string charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
249 std::string cookie;
250
251 for (int i = 0; i < 64; ++i)
252     {
253     cookie += charset[rand() % charset.length()];
254     };
255
256 return cookie;
257 }
258
259 void RPC_CONFIG::InitiateRegistry()
260 {
261 // manage registry
262 xmlrpc_c::methodPtr const methodInfoPtr(new METHOD_INFO(
263             tariffs,
264             users,
265             dayFee,
266             dirNames
267             ));
268 rpcRegistry.addMethod("stargazer.info", methodInfoPtr);
269
270 xmlrpc_c::methodPtr const methodLoginPtr(new METHOD_LOGIN(
271             this
272             ));
273 rpcRegistry.addMethod("stargazer.login", methodLoginPtr);
274
275 xmlrpc_c::methodPtr const methodLogoutPtr(new METHOD_LOGOUT(
276             this
277             ));
278 rpcRegistry.addMethod("stargazer.logout", methodLogoutPtr);
279
280 xmlrpc_c::methodPtr const methodGetUserPtr(new METHOD_USER_GET(
281             this,
282             users
283             ));
284 rpcRegistry.addMethod("stargazer.get_user", methodGetUserPtr);
285
286 xmlrpc_c::methodPtr const methodAddUserPtr(new METHOD_USER_ADD(
287             this,
288             admins,
289             users
290             ));
291 rpcRegistry.addMethod("stargazer.add_user", methodAddUserPtr);
292
293 xmlrpc_c::methodPtr const methodDelUserPtr(new METHOD_USER_DEL(
294             this,
295             admins,
296             users
297             ));
298 rpcRegistry.addMethod("stargazer.del_user", methodDelUserPtr);
299
300 xmlrpc_c::methodPtr const methodGetUsersPtr(new METHOD_USERS_GET(
301             this,
302             users
303             ));
304 rpcRegistry.addMethod("stargazer.get_users", methodGetUsersPtr);
305
306 xmlrpc_c::methodPtr const methodChgUserPtr(new METHOD_USER_CHG(
307             this,
308             admins,
309             tariffs,
310             store,
311             users
312             ));
313 rpcRegistry.addMethod("stargazer.chg_user", methodChgUserPtr);
314
315 xmlrpc_c::methodPtr const methodAddCashPtr(new METHOD_USER_CASH_ADD(
316             this,
317             admins,
318             store,
319             users
320             ));
321 rpcRegistry.addMethod("stargazer.add_user_cash", methodAddCashPtr);
322
323 xmlrpc_c::methodPtr const methodSetCashPtr(new METHOD_USER_CASH_SET(
324             this,
325             admins,
326             store,
327             users
328             ));
329 rpcRegistry.addMethod("stargazer.set_user_cash", methodSetCashPtr);
330
331 xmlrpc_c::methodPtr const methodTariffChangePtr(new METHOD_USER_TARIFF_CHANGE(
332             this,
333             admins,
334             tariffs,
335             store,
336             users
337             ));
338 rpcRegistry.addMethod("stargazer.chg_user_tariff", methodTariffChangePtr);
339
340 xmlrpc_c::methodPtr const methodGetTariffPtr(new METHOD_TARIFF_GET(
341             this,
342             tariffs
343             ));
344 rpcRegistry.addMethod("stargazer.get_tariff", methodGetTariffPtr);
345
346 xmlrpc_c::methodPtr const methodChgTariffPtr(new METHOD_TARIFF_CHG(
347             this,
348             admins,
349             tariffs
350             ));
351 rpcRegistry.addMethod("stargazer.chg_tariff", methodChgTariffPtr);
352
353 xmlrpc_c::methodPtr const methodGetTariffsPtr(new METHOD_TARIFFS_GET(
354             this,
355             tariffs
356             ));
357 rpcRegistry.addMethod("stargazer.get_tariffs", methodGetTariffsPtr);
358
359 xmlrpc_c::methodPtr const methodAddTariffPtr(new METHOD_TARIFF_ADD(
360             this,
361             admins,
362             tariffs
363             ));
364 rpcRegistry.addMethod("stargazer.add_tariff", methodAddTariffPtr);
365
366 xmlrpc_c::methodPtr const methodDelTariffPtr(new METHOD_TARIFF_DEL(
367             this,
368             admins,
369             tariffs,
370             users
371             ));
372 rpcRegistry.addMethod("stargazer.del_tariff", methodDelTariffPtr);
373
374 xmlrpc_c::methodPtr const methodGetAdminPtr(new METHOD_ADMIN_GET(
375             this,
376             admins
377             ));
378 rpcRegistry.addMethod("stargazer.get_admin", methodGetAdminPtr);
379
380 xmlrpc_c::methodPtr const methodAddAdminPtr(new METHOD_ADMIN_ADD(
381             this,
382             admins
383             ));
384 rpcRegistry.addMethod("stargazer.add_admin", methodAddAdminPtr);
385
386 xmlrpc_c::methodPtr const methodDelAdminPtr(new METHOD_ADMIN_DEL(
387             this,
388             admins
389             ));
390 rpcRegistry.addMethod("stargazer.del_admin", methodDelAdminPtr);
391
392 xmlrpc_c::methodPtr const methodChgAdminPtr(new METHOD_ADMIN_CHG(
393             this,
394             admins
395             ));
396 rpcRegistry.addMethod("stargazer.chg_admin", methodChgAdminPtr);
397
398 xmlrpc_c::methodPtr const methodGetAdminsPtr(new METHOD_ADMINS_GET(
399             this,
400             admins
401             ));
402 rpcRegistry.addMethod("stargazer.get_admins", methodGetAdminsPtr);
403
404 xmlrpc_c::methodPtr const methodSendMessagePtr(new METHOD_MESSAGE_SEND(
405             this,
406             users
407             ));
408 rpcRegistry.addMethod("stargazer.send_user_message", methodSendMessagePtr);
409
410 xmlrpc_c::methodPtr const methodGetOnlinIPsPtr(new METHOD_GET_ONLINE_IPS(
411             this,
412             users
413             ));
414 rpcRegistry.addMethod("stargazer.get_online_ips", methodGetOnlinIPsPtr);
415 }
416