]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp
Code deduplication (plugin creation via template PLUGIN_CREATOR)
[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     : users(NULL),
79       admins(NULL),
80       tariffs(NULL),
81       store(NULL),
82       rpcServer(NULL),
83       running(false),
84       stopped(true),
85       dayFee(0)
86 {
87 }
88
89 RPC_CONFIG::~RPC_CONFIG()
90 {
91 // delete server
92 delete rpcServer;
93 }
94
95 int RPC_CONFIG::ParseSettings()
96 {
97 int ret = rpcConfigSettings.ParseSettings(settings);
98
99 if (ret)
100     errorStr = rpcConfigSettings.GetStrError();
101
102 return ret;
103 }
104
105 void RPC_CONFIG::SetStgSettings(const SETTINGS * settings)
106 {
107     dayFee = settings->GetDayFee();
108     dirNames.erase(dirNames.begin(), dirNames.end());
109     for (size_t i = 0; i < DIR_NUM; ++i) {
110         dirNames.push_back(settings->GetDirName(i));
111     }
112 }
113
114 int RPC_CONFIG::Start()
115 {
116 InitiateRegistry();
117 running = true;
118 rpcServer = new xmlrpc_c::serverAbyss(
119         rpcRegistry,
120         rpcConfigSettings.GetPort(),
121         "/var/log/stargazer_rpc.log"
122         );
123 if (pthread_create(&tid, NULL, Run, this))
124     {
125     errorStr = "Failed to create RPC thread";
126     printfd(__FILE__, "Failed to crate RPC thread\n");
127     return -1;
128     }
129 return 0;
130 }
131
132 int RPC_CONFIG::Stop()
133 {
134 running = false;
135 for (int i = 0; i < 5 && !stopped; ++i)
136     usleep(200000);
137 //rpcServer->terminate();
138 if (!stopped)
139     {
140     if (pthread_kill(tid, SIGTERM))
141         {
142         errorStr = "Failed to kill thread";
143         printfd(__FILE__, "Failed to kill thread\n");
144         }
145     for (int i = 0; i < 25 && !stopped; ++i)
146         usleep(200000);
147     if (!stopped)
148         {
149         printfd(__FILE__, "Failed to stop RPC thread\n");
150         errorStr = "Failed to stop RPC thread";
151         return -1;
152         }
153     else
154         {
155         pthread_join(tid, NULL);
156         }
157     }
158 return 0;
159 }
160
161 void * RPC_CONFIG::Run(void * rc)
162 {
163 RPC_CONFIG * config = static_cast<RPC_CONFIG *>(rc);
164
165 config->stopped = false;
166 while (config->running)
167     {
168     config->rpcServer->runOnce();
169     }
170 config->stopped = true;
171
172 return NULL;
173 }
174
175 bool RPC_CONFIG::GetAdminInfo(const std::string & cookie,
176                               ADMIN_INFO * info)
177 {
178 std::map<std::string,
179          ADMIN_INFO>::iterator it;
180
181 it = cookies.find(cookie);
182
183 if (it == cookies.end())
184     {
185     return true;
186     }
187
188 if (difftime(it->second.accessTime, time(NULL)) >
189     rpcConfigSettings.GetCookieTimeout())
190     {
191     cookies.erase(it);
192     return true;
193     }
194
195 // Update access time
196 time(&it->second.accessTime);
197 *info = it->second;
198 return false;
199 }
200
201 bool RPC_CONFIG::CheckAdmin(const std::string & login,
202                             const std::string & password,
203                             std::string * cookie)
204 {
205 ADMIN * admin = NULL;
206
207 if (!admins->AdminCorrect(login, password, &admin))
208     {
209     return true;
210     }
211
212 ADMIN_INFO info;
213 time(&info.accessTime);
214 info.admin = login;
215 info.priviledges = *admin->GetPriv();
216 *cookie = GetCookie();
217 cookies[*cookie] = info;
218
219 return false;
220 }
221
222 bool RPC_CONFIG::LogoutAdmin(const std::string & cookie)
223 {
224 std::map<std::string,
225          ADMIN_INFO>::iterator it;
226
227 it = cookies.find(cookie);
228
229 if (it == cookies.end())
230     {
231     return true;
232     }
233
234 cookies.erase(it);
235
236 return false;
237 }
238
239 std::string RPC_CONFIG::GetCookie() const
240 {
241 std::string charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
242 std::string cookie;
243
244 for (int i = 0; i < 64; ++i)
245     {
246     cookie += charset[rand() % charset.length()];
247     };
248
249 return cookie;
250 }
251
252 void RPC_CONFIG::InitiateRegistry()
253 {
254 // manage registry
255 xmlrpc_c::methodPtr const methodInfoPtr(new METHOD_INFO(
256             tariffs,
257             users,
258             dayFee,
259             dirNames
260             ));
261 rpcRegistry.addMethod("stargazer.info", methodInfoPtr);
262
263 xmlrpc_c::methodPtr const methodLoginPtr(new METHOD_LOGIN(
264             this
265             ));
266 rpcRegistry.addMethod("stargazer.login", methodLoginPtr);
267
268 xmlrpc_c::methodPtr const methodLogoutPtr(new METHOD_LOGOUT(
269             this
270             ));
271 rpcRegistry.addMethod("stargazer.logout", methodLogoutPtr);
272
273 xmlrpc_c::methodPtr const methodGetUserPtr(new METHOD_USER_GET(
274             this,
275             users
276             ));
277 rpcRegistry.addMethod("stargazer.get_user", methodGetUserPtr);
278
279 xmlrpc_c::methodPtr const methodAddUserPtr(new METHOD_USER_ADD(
280             this,
281             admins,
282             users
283             ));
284 rpcRegistry.addMethod("stargazer.add_user", methodAddUserPtr);
285
286 xmlrpc_c::methodPtr const methodDelUserPtr(new METHOD_USER_DEL(
287             this,
288             admins,
289             users
290             ));
291 rpcRegistry.addMethod("stargazer.del_user", methodDelUserPtr);
292
293 xmlrpc_c::methodPtr const methodGetUsersPtr(new METHOD_USERS_GET(
294             this,
295             users
296             ));
297 rpcRegistry.addMethod("stargazer.get_users", methodGetUsersPtr);
298
299 xmlrpc_c::methodPtr const methodChgUserPtr(new METHOD_USER_CHG(
300             this,
301             admins,
302             tariffs,
303             store,
304             users
305             ));
306 rpcRegistry.addMethod("stargazer.chg_user", methodChgUserPtr);
307
308 xmlrpc_c::methodPtr const methodAddCashPtr(new METHOD_USER_CASH_ADD(
309             this,
310             admins,
311             store,
312             users
313             ));
314 rpcRegistry.addMethod("stargazer.add_user_cash", methodAddCashPtr);
315
316 xmlrpc_c::methodPtr const methodSetCashPtr(new METHOD_USER_CASH_SET(
317             this,
318             admins,
319             store,
320             users
321             ));
322 rpcRegistry.addMethod("stargazer.set_user_cash", methodSetCashPtr);
323
324 xmlrpc_c::methodPtr const methodTariffChangePtr(new METHOD_USER_TARIFF_CHANGE(
325             this,
326             admins,
327             tariffs,
328             store,
329             users
330             ));
331 rpcRegistry.addMethod("stargazer.chg_user_tariff", methodTariffChangePtr);
332
333 xmlrpc_c::methodPtr const methodGetTariffPtr(new METHOD_TARIFF_GET(
334             this,
335             tariffs
336             ));
337 rpcRegistry.addMethod("stargazer.get_tariff", methodGetTariffPtr);
338
339 xmlrpc_c::methodPtr const methodChgTariffPtr(new METHOD_TARIFF_CHG(
340             this,
341             admins,
342             tariffs
343             ));
344 rpcRegistry.addMethod("stargazer.chg_tariff", methodChgTariffPtr);
345
346 xmlrpc_c::methodPtr const methodGetTariffsPtr(new METHOD_TARIFFS_GET(
347             this,
348             tariffs
349             ));
350 rpcRegistry.addMethod("stargazer.get_tariffs", methodGetTariffsPtr);
351
352 xmlrpc_c::methodPtr const methodAddTariffPtr(new METHOD_TARIFF_ADD(
353             this,
354             admins,
355             tariffs
356             ));
357 rpcRegistry.addMethod("stargazer.add_tariff", methodAddTariffPtr);
358
359 xmlrpc_c::methodPtr const methodDelTariffPtr(new METHOD_TARIFF_DEL(
360             this,
361             admins,
362             tariffs,
363             users
364             ));
365 rpcRegistry.addMethod("stargazer.del_tariff", methodDelTariffPtr);
366
367 xmlrpc_c::methodPtr const methodGetAdminPtr(new METHOD_ADMIN_GET(
368             this,
369             admins
370             ));
371 rpcRegistry.addMethod("stargazer.get_admin", methodGetAdminPtr);
372
373 xmlrpc_c::methodPtr const methodAddAdminPtr(new METHOD_ADMIN_ADD(
374             this,
375             admins
376             ));
377 rpcRegistry.addMethod("stargazer.add_admin", methodAddAdminPtr);
378
379 xmlrpc_c::methodPtr const methodDelAdminPtr(new METHOD_ADMIN_DEL(
380             this,
381             admins
382             ));
383 rpcRegistry.addMethod("stargazer.del_admin", methodDelAdminPtr);
384
385 xmlrpc_c::methodPtr const methodChgAdminPtr(new METHOD_ADMIN_CHG(
386             this,
387             admins
388             ));
389 rpcRegistry.addMethod("stargazer.chg_admin", methodChgAdminPtr);
390
391 xmlrpc_c::methodPtr const methodGetAdminsPtr(new METHOD_ADMINS_GET(
392             this,
393             admins
394             ));
395 rpcRegistry.addMethod("stargazer.get_admins", methodGetAdminsPtr);
396
397 xmlrpc_c::methodPtr const methodSendMessagePtr(new METHOD_MESSAGE_SEND(
398             this,
399             users
400             ));
401 rpcRegistry.addMethod("stargazer.send_user_message", methodSendMessagePtr);
402
403 xmlrpc_c::methodPtr const methodGetOnlinIPsPtr(new METHOD_GET_ONLINE_IPS(
404             this,
405             users
406             ));
407 rpcRegistry.addMethod("stargazer.get_online_ips", methodGetOnlinIPsPtr);
408 }
409