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