]> git.stg.codes - stg.git/blob - projects/stargazer/user_property.h
3ea1be45509eeff7f96e74394ab57dc8112d2d93
[stg.git] / projects / stargazer / user_property.h
1 /*
2 $Revision: 1.44 $
3 $Date: 2010/09/13 05:54:43 $
4 $Author: faust $
5 */
6
7
8 #ifndef USER_PROPERTY_H
9 #define USER_PROPERTY_H
10
11 #include <ctime>
12 #include <string>
13 #include <set>
14 #include <sstream>
15 #include <iostream>
16 #include <algorithm>
17
18 #include "base_store.h"
19 #include "stg_logger.h"
20 #include "admin.h"
21 #include "settings.h"
22 #include "notifer.h"
23 #include "stg_logger.h"
24 #include "stg_locker.h"
25 #include "script_executer.h"
26
27 using namespace std;
28
29 extern const volatile time_t stgTime;
30
31 //-----------------------------------------------------------------------------
32 template<typename varT>
33 class USER_PROPERTY
34     {
35 public:
36     USER_PROPERTY(varT& val);
37     USER_PROPERTY<varT>& operator= (const varT&);
38     USER_PROPERTY<varT>& operator-= (const varT&);
39     virtual ~USER_PROPERTY();
40
41     const varT * operator&() const throw();
42     const varT& ConstData() const throw();
43
44     operator const varT&() const throw()
45     {
46         return value;
47     }
48
49     //bool    IsEmpty() const throw();
50
51     void    AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
52     void    DelBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
53
54     void    AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
55     void    DelAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
56
57     time_t  ModificationTime() const throw();
58     void    ModifyTime() throw();
59
60 protected:
61     varT  & value;
62     time_t  modificationTime;
63     //typedef set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator notifier_iter_t;
64     mutable set<PROPERTY_NOTIFIER_BASE<varT> *> beforeNotifiers;
65     mutable set<PROPERTY_NOTIFIER_BASE<varT> *> afterNotifiers;
66     mutable pthread_mutex_t mutex;
67     };
68 //-----------------------------------------------------------------------------
69 template<typename varT>
70 class USER_PROPERTY_LOGGED: public USER_PROPERTY<varT>
71     {
72 public:
73     USER_PROPERTY_LOGGED(varT& val,
74                          const string n,
75                          bool isPassword,
76                          bool isStat,
77                          STG_LOGGER & logger,
78                          const SETTINGS * s);
79     virtual ~USER_PROPERTY_LOGGED();
80
81     //operator const varT&() const throw();;
82     USER_PROPERTY_LOGGED<varT> * GetPointer() throw();
83     const varT & Get() const;
84     const string & GetName() const;
85     bool Set(const varT & val,
86              const ADMIN & admin,
87              const string & login,
88              const BASE_STORE * store,
89              const string & msg = "");
90 protected:
91     void WriteAccessDenied(const string & login,
92                            const ADMIN  & admin,
93                            const string & parameter);
94
95     void WriteSuccessChange(const string     & login,
96                             const ADMIN      & admin,
97                             const string     & parameter,
98                             const string     & oldValue,
99                             const string     & newValue,
100                             const string     & msg,
101                             const BASE_STORE * store);
102
103     void OnChange(const string & login,
104                   const string & paramName,
105                   const string & oldValue,
106                   const string & newValue,
107                   const ADMIN  & admin);
108
109     string          name;       // parameter name. needed for logging
110     bool            isPassword; // is parameter password. when true, it will be logged as *******
111     bool            isStat;     // is parameter a stat data or conf data?
112     mutable pthread_mutex_t mutex;
113     STG_LOGGER &    stgLogger;  // server's logger
114     const SETTINGS * settings;
115     };
116 //-----------------------------------------------------------------------------
117 class USER_PROPERTIES
118     {
119     friend class USER;
120 /*
121  В этом месте важен порядок следования приватной и открытой частей.
122  Это связано с тем, что часть которая находится в публичной секции
123  по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
124  чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
125  начале идет закрытая секция
126  * */
127
128 private:
129     USER_STAT stat;
130     USER_CONF conf;
131
132 public:
133     USER_PROPERTIES(const SETTINGS * settings);
134
135     const USER_STAT & GetStat() const { return stat; }
136     const USER_CONF & GetConf() const { return conf; }
137     void SetStat(const USER_STAT & s) { stat = s; }
138     void SetConf(const USER_CONF & c) { conf = c; }
139
140     void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
141
142     USER_PROPERTY_LOGGED<double>            cash;
143     USER_PROPERTY_LOGGED<DIR_TRAFF>         up;
144     USER_PROPERTY_LOGGED<DIR_TRAFF>         down;
145     USER_PROPERTY_LOGGED<double>            lastCashAdd;
146     USER_PROPERTY_LOGGED<time_t>            passiveTime;
147     USER_PROPERTY_LOGGED<time_t>            lastCashAddTime;
148     USER_PROPERTY_LOGGED<double>            freeMb;
149     USER_PROPERTY_LOGGED<time_t>            lastActivityTime;
150
151     USER_PROPERTY_LOGGED<string>            password;
152     USER_PROPERTY_LOGGED<int>               passive;
153     USER_PROPERTY_LOGGED<int>               disabled;
154     USER_PROPERTY_LOGGED<int>               disabledDetailStat;
155     USER_PROPERTY_LOGGED<int>               alwaysOnline;
156     USER_PROPERTY_LOGGED<string>            tariffName;
157     USER_PROPERTY_LOGGED<string>            nextTariff;
158     USER_PROPERTY_LOGGED<string>            address;
159     USER_PROPERTY_LOGGED<string>            note;
160     USER_PROPERTY_LOGGED<string>            group;
161     USER_PROPERTY_LOGGED<string>            email;
162     USER_PROPERTY_LOGGED<string>            phone;
163     USER_PROPERTY_LOGGED<string>            realName;
164     USER_PROPERTY_LOGGED<double>            credit;
165     USER_PROPERTY_LOGGED<time_t>            creditExpire;
166     USER_PROPERTY_LOGGED<USER_IPS>          ips;
167     USER_PROPERTY_LOGGED<string>            userdata0;
168     USER_PROPERTY_LOGGED<string>            userdata1;
169     USER_PROPERTY_LOGGED<string>            userdata2;
170     USER_PROPERTY_LOGGED<string>            userdata3;
171     USER_PROPERTY_LOGGED<string>            userdata4;
172     USER_PROPERTY_LOGGED<string>            userdata5;
173     USER_PROPERTY_LOGGED<string>            userdata6;
174     USER_PROPERTY_LOGGED<string>            userdata7;
175     USER_PROPERTY_LOGGED<string>            userdata8;
176     USER_PROPERTY_LOGGED<string>            userdata9;
177     };
178
179 //=============================================================================
180
181 //-----------------------------------------------------------------------------
182 //-----------------------------------------------------------------------------
183 //-----------------------------------------------------------------------------
184 template <typename varT>
185 USER_PROPERTY<varT>::USER_PROPERTY(varT& val)
186 :
187 value(val)
188 {
189 pthread_mutex_init(&mutex, NULL);
190 modificationTime = stgTime;
191 }
192 //-----------------------------------------------------------------------------
193 template <typename varT>
194 USER_PROPERTY<varT>::~USER_PROPERTY()
195 {
196 }
197 //-----------------------------------------------------------------------------
198 template <typename varT>
199 void USER_PROPERTY<varT>::ModifyTime() throw()
200 {
201     modificationTime = stgTime;
202 }
203 //-----------------------------------------------------------------------------
204 template <typename varT>
205 USER_PROPERTY<varT>& USER_PROPERTY<varT>::operator= (const varT& newValue)
206 {
207 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
208
209 /*
210 TODO
211 if (value == newValue)
212     return *this;*/
213
214 typename set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
215
216 varT oldVal = value;
217
218 ni = beforeNotifiers.begin();
219 while (ni != beforeNotifiers.end())
220     (*ni++)->Notify(oldVal, newValue);
221
222 value = newValue;
223 modificationTime = stgTime;
224
225 ni = afterNotifiers.begin();
226 while (ni != afterNotifiers.end())
227     (*ni++)->Notify(oldVal, newValue);
228
229 return *this;
230 }
231 //-----------------------------------------------------------------------------
232 template <typename varT>
233 USER_PROPERTY<varT>& USER_PROPERTY<varT>::operator-= (const varT& delta)
234 {
235 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
236
237 typename set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
238
239 varT oldVal = value;
240
241 ni = beforeNotifiers.begin();
242 while (ni != beforeNotifiers.end())
243     (*ni++)->Notify(oldVal, oldVal - delta);
244
245 value -= delta;
246 modificationTime = stgTime;
247
248 ni = afterNotifiers.begin();
249 while (ni != afterNotifiers.end())
250     (*ni++)->Notify(oldVal, value);
251
252 return *this;
253 }
254 //-----------------------------------------------------------------------------
255 template <typename varT>
256 const varT * USER_PROPERTY<varT>::operator&() const throw()
257 {
258 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
259 return &value;
260 }
261 //-----------------------------------------------------------------------------
262 template <typename varT>
263 const varT& USER_PROPERTY<varT>::ConstData() const throw()
264 {
265 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
266 return value;
267 }
268 //-----------------------------------------------------------------------------
269 /*template <typename varT>
270 bool USER_PROPERTY<varT>::IsEmpty() const throw()
271 {
272 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
273 return !is_set;
274 }*/
275 //-----------------------------------------------------------------------------
276 template <typename varT>
277 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
278 {
279 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
280 beforeNotifiers.insert(n);
281 }
282 //-----------------------------------------------------------------------------
283 template <typename varT>
284 void USER_PROPERTY<varT>::DelBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
285 {
286 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
287 beforeNotifiers.erase(n);
288 }
289 //-----------------------------------------------------------------------------
290 template <typename varT>
291 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
292 {
293 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
294 afterNotifiers.insert(n);
295 }
296 //-----------------------------------------------------------------------------
297 template <typename varT>
298 void USER_PROPERTY<varT>::DelAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
299 {
300 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
301 afterNotifiers.erase(n);
302 }
303 //-----------------------------------------------------------------------------
304 template <typename varT>
305 time_t USER_PROPERTY<varT>::ModificationTime() const throw()
306 {
307 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
308 return modificationTime;
309 }
310 //-----------------------------------------------------------------------------
311 //-----------------------------------------------------------------------------
312 //-----------------------------------------------------------------------------
313 template <typename varT>
314 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(
315                                                 varT& val,
316                                                 string n,
317                                                 bool isPass,
318                                                 bool isSt,
319                                                 STG_LOGGER & logger,
320                                                 const SETTINGS * s)
321
322 :USER_PROPERTY<varT>(val),
323 stgLogger(logger)
324 {
325 pthread_mutex_init(&mutex, NULL);
326 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
327 USER_PROPERTY<varT>::value = val;
328 isPassword = isPass;
329 isStat = isSt;
330 name = n;
331 settings = s;
332 }
333 //-----------------------------------------------------------------------------
334 template <typename varT>
335 USER_PROPERTY_LOGGED<varT>::~USER_PROPERTY_LOGGED()
336 {
337 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
338 }
339 //-----------------------------------------------------------------------------
340 template <typename varT>
341 USER_PROPERTY_LOGGED<varT> * USER_PROPERTY_LOGGED<varT>::GetPointer() throw()
342 {
343 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
344 return this;
345 }
346 //-----------------------------------------------------------------------------
347 template <typename varT>
348 const varT & USER_PROPERTY_LOGGED<varT>::Get() const
349 {
350 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
351 return USER_PROPERTY<varT>::value;
352 };
353 //-------------------------------------------------------------------------
354 template <typename varT>
355 const string & USER_PROPERTY_LOGGED<varT>::GetName() const
356 {
357 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
358 return name;
359 };
360 //-------------------------------------------------------------------------
361 template <typename varT>
362 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
363                                      const ADMIN & admin,
364                                      const string & login,
365                                      const BASE_STORE * store,
366                                      const string & msg)
367 {
368 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
369
370 //cout << "USER_PROPERTY_LOGGED " << val << endl;
371 //value = val;
372 //modificationTime = stgTime;
373
374 const PRIV * priv = admin.GetPriv();
375 string adm_login = admin.GetLogin();
376 string adm_ip = admin.GetAdminIPStr();
377
378 if ((priv->userConf && !isStat) || (priv->userStat && isStat) || (priv->userPasswd && isPassword) || (priv->userCash && name == "cash"))
379     {
380     stringstream oldVal;
381     stringstream newVal;
382
383     oldVal.flags(oldVal.flags() | ios::fixed);
384     newVal.flags(newVal.flags() | ios::fixed);
385
386     oldVal << USER_PROPERTY<varT>::value;
387     newVal << val;
388
389     OnChange(login, name, oldVal.str(), newVal.str(), admin);
390
391     if (isPassword)
392         {
393         WriteSuccessChange(login, admin, name, "******", "******", msg, store);
394         }
395     else
396         {
397         WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
398         }
399     USER_PROPERTY<varT>::operator =(val);
400     return true;
401     }
402 else
403     {
404     WriteAccessDenied(login, admin, name);
405     return false;
406     }
407 return true;
408 }
409 //-------------------------------------------------------------------------
410 template <typename varT>
411 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const string & login,
412                                                    const ADMIN  & admin,
413                                                    const string & parameter)
414 {
415 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
416           admin.GetLogStr().c_str(), login.c_str(), parameter.c_str());
417 }
418 //-------------------------------------------------------------------------
419 template <typename varT>
420 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const string & login,
421                                                     const ADMIN      & admin,
422                                                     const string     & parameter,
423                                                     const string     & oldValue,
424                                                     const string     & newValue,
425                                                     const string     & msg,
426                                                     const BASE_STORE * store)
427 {
428 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
429           admin.GetLogStr().c_str(),
430           login.c_str(),
431           parameter.c_str(),
432           oldValue.c_str(),
433           newValue.c_str(),
434           msg.c_str());
435
436 store->WriteUserChgLog(login, admin.GetLogin(), admin.GetAdminIP(), parameter, oldValue, newValue, msg);
437 }
438 //-------------------------------------------------------------------------
439 template <typename varT>
440 void USER_PROPERTY_LOGGED<varT>::OnChange(const string & login,
441                                           const string & paramName,
442                                           const string & oldValue,
443                                           const string & newValue,
444                                           const ADMIN  & admin)
445 {
446 string str1;
447
448 str1 = settings->GetConfDir() + "/OnChange";
449
450 if (access(str1.c_str(), X_OK) == 0)
451     {
452     string str2("\"" + str1 + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.GetLogin() + "\" \"" + admin.GetAdminIPStr() + "\"");
453     ScriptExec(str2);
454     }
455 else
456     {
457     stgLogger("Script OnChange cannot be executed. File %s not found.", str1.c_str());
458     }
459 }
460 //-------------------------------------------------------------------------
461 //-------------------------------------------------------------------------
462 //-------------------------------------------------------------------------
463 template<typename varT>
464 stringstream & operator<< (stringstream & s, const USER_PROPERTY<varT> & v)
465 {
466 s << v.ConstData();
467 return s;
468 }
469 //-----------------------------------------------------------------------------
470 template<typename varT>
471 ostream & operator<< (ostream & o, const USER_PROPERTY<varT> & v)
472 {
473 return o << v.ConstData();
474 }
475 //-----------------------------------------------------------------------------
476
477
478 #endif // USER_PROPERTY_H
479