]> git.stg.codes - stg.git/blob - projects/stargazer/user_property.h
41a0cfb544633fa1c29f3284cbd88fb095247807
[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 std::string & sd);
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     STG_LOGGER &    stgLogger;  // server's logger
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     string          name;       // parameter name. needed for logging
107     const std::string scriptsDir;
108 };
109 //-----------------------------------------------------------------------------
110 class USER_PROPERTIES {
111 /*
112  В этом месте важен порядок следования приватной и открытой частей.
113  Это связано с тем, что часть которая находится в публичной секции
114  по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
115  чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
116  начале идет закрытая секция
117  * */
118
119 private:
120     USER_STAT stat;
121     USER_CONF conf;
122
123 public:
124     USER_PROPERTIES(const std::string & sd);
125
126     USER_STAT & Stat() { return stat; }
127     USER_CONF & Conf() { return conf; }
128     const USER_STAT & GetStat() const { return stat; }
129     const USER_CONF & GetConf() const { return conf; }
130     void SetStat(const USER_STAT & s) { stat = s; }
131     void SetConf(const USER_CONF & c) { conf = c; }
132
133     void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
134
135     USER_PROPERTY_LOGGED<double>            cash;
136     USER_PROPERTY_LOGGED<DIR_TRAFF>         up;
137     USER_PROPERTY_LOGGED<DIR_TRAFF>         down;
138     USER_PROPERTY_LOGGED<double>            lastCashAdd;
139     USER_PROPERTY_LOGGED<time_t>            passiveTime;
140     USER_PROPERTY_LOGGED<time_t>            lastCashAddTime;
141     USER_PROPERTY_LOGGED<double>            freeMb;
142     USER_PROPERTY_LOGGED<time_t>            lastActivityTime;
143
144     USER_PROPERTY_LOGGED<string>            password;
145     USER_PROPERTY_LOGGED<int>               passive;
146     USER_PROPERTY_LOGGED<int>               disabled;
147     USER_PROPERTY_LOGGED<int>               disabledDetailStat;
148     USER_PROPERTY_LOGGED<int>               alwaysOnline;
149     USER_PROPERTY_LOGGED<string>            tariffName;
150     USER_PROPERTY_LOGGED<string>            nextTariff;
151     USER_PROPERTY_LOGGED<string>            address;
152     USER_PROPERTY_LOGGED<string>            note;
153     USER_PROPERTY_LOGGED<string>            group;
154     USER_PROPERTY_LOGGED<string>            email;
155     USER_PROPERTY_LOGGED<string>            phone;
156     USER_PROPERTY_LOGGED<string>            realName;
157     USER_PROPERTY_LOGGED<double>            credit;
158     USER_PROPERTY_LOGGED<time_t>            creditExpire;
159     USER_PROPERTY_LOGGED<USER_IPS>          ips;
160     USER_PROPERTY_LOGGED<string>            userdata0;
161     USER_PROPERTY_LOGGED<string>            userdata1;
162     USER_PROPERTY_LOGGED<string>            userdata2;
163     USER_PROPERTY_LOGGED<string>            userdata3;
164     USER_PROPERTY_LOGGED<string>            userdata4;
165     USER_PROPERTY_LOGGED<string>            userdata5;
166     USER_PROPERTY_LOGGED<string>            userdata6;
167     USER_PROPERTY_LOGGED<string>            userdata7;
168     USER_PROPERTY_LOGGED<string>            userdata8;
169     USER_PROPERTY_LOGGED<string>            userdata9;
170 };
171 //=============================================================================
172
173 //-----------------------------------------------------------------------------
174 //-----------------------------------------------------------------------------
175 //-----------------------------------------------------------------------------
176 template <typename varT>
177 USER_PROPERTY<varT>::USER_PROPERTY(varT& val)
178     : value(val)
179 {
180 pthread_mutex_init(&mutex, NULL);
181 modificationTime = stgTime;
182 }
183 //-----------------------------------------------------------------------------
184 template <typename varT>
185 USER_PROPERTY<varT>::~USER_PROPERTY()
186 {
187 }
188 //-----------------------------------------------------------------------------
189 template <typename varT>
190 void USER_PROPERTY<varT>::ModifyTime() throw()
191 {
192     modificationTime = stgTime;
193 }
194 //-----------------------------------------------------------------------------
195 template <typename varT>
196 void USER_PROPERTY<varT>::Set(const varT & rvalue)
197 {
198 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
199
200 typename set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
201
202 varT oldVal = value;
203
204 ni = beforeNotifiers.begin();
205 while (ni != beforeNotifiers.end())
206     (*ni++)->Notify(oldVal, rvalue);
207
208 value = rvalue;
209 modificationTime = stgTime;
210
211 ni = afterNotifiers.begin();
212 while (ni != afterNotifiers.end())
213     (*ni++)->Notify(oldVal, rvalue);
214 }
215 //-----------------------------------------------------------------------------
216 template <typename varT>
217 USER_PROPERTY<varT>& USER_PROPERTY<varT>::operator= (const varT & newValue)
218 {
219 Set(newValue);
220 return *this;
221 }
222 //-----------------------------------------------------------------------------
223 template <typename varT>
224 USER_PROPERTY<varT>& USER_PROPERTY<varT>::operator-= (const varT & delta)
225 {
226 varT newValue = ConstData() - delta;
227 Set(newValue);
228 return *this;
229 }
230 //-----------------------------------------------------------------------------
231 template <typename varT>
232 const varT * USER_PROPERTY<varT>::operator&() const throw()
233 {
234 return &value;
235 }
236 //-----------------------------------------------------------------------------
237 template <typename varT>
238 const varT& USER_PROPERTY<varT>::ConstData() const throw()
239 {
240 return value;
241 }
242 //-----------------------------------------------------------------------------
243 template <typename varT>
244 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
245 {
246 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
247 beforeNotifiers.insert(n);
248 }
249 //-----------------------------------------------------------------------------
250 template <typename varT>
251 void USER_PROPERTY<varT>::DelBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
252 {
253 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
254 beforeNotifiers.erase(n);
255 }
256 //-----------------------------------------------------------------------------
257 template <typename varT>
258 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
259 {
260 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
261 afterNotifiers.insert(n);
262 }
263 //-----------------------------------------------------------------------------
264 template <typename varT>
265 void USER_PROPERTY<varT>::DelAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
266 {
267 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
268 afterNotifiers.erase(n);
269 }
270 //-----------------------------------------------------------------------------
271 template <typename varT>
272 time_t USER_PROPERTY<varT>::ModificationTime() const throw()
273 {
274 return modificationTime;
275 }
276 //-----------------------------------------------------------------------------
277 //-----------------------------------------------------------------------------
278 //-----------------------------------------------------------------------------
279 template <typename varT>
280 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT& val,
281                                                  string n,
282                                                  bool isPass,
283                                                  bool isSt,
284                                                  STG_LOGGER & logger,
285                                                  const std::string & sd)
286
287     : USER_PROPERTY<varT>(val),
288       stgLogger(logger),
289       isPassword(isPass),
290       isStat(isSt),
291       name(n),
292       scriptsDir(sd)
293 {
294 }
295 //-----------------------------------------------------------------------------
296 template <typename varT>
297 USER_PROPERTY_LOGGED<varT>::~USER_PROPERTY_LOGGED()
298 {
299 }
300 //-----------------------------------------------------------------------------
301 template <typename varT>
302 USER_PROPERTY_LOGGED<varT> * USER_PROPERTY_LOGGED<varT>::GetPointer() throw()
303 {
304 return this;
305 }
306 //-----------------------------------------------------------------------------
307 template <typename varT>
308 const varT & USER_PROPERTY_LOGGED<varT>::Get() const
309 {
310 return USER_PROPERTY<varT>::ConstData();
311 };
312 //-------------------------------------------------------------------------
313 template <typename varT>
314 const string & USER_PROPERTY_LOGGED<varT>::GetName() const
315 {
316 return name;
317 };
318 //-------------------------------------------------------------------------
319 template <typename varT>
320 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
321                                      const ADMIN * admin,
322                                      const string & login,
323                                      const STORE * store,
324                                      const string & msg)
325 {
326 const PRIV * priv = admin->GetPriv();
327 string adm_login = admin->GetLogin();
328 string adm_ip = admin->GetIPStr();
329
330 if ((priv->userConf && !isStat) || (priv->userStat && isStat) || (priv->userPasswd && isPassword) || (priv->userCash && name == "cash"))
331     {
332     stringstream oldVal;
333     stringstream newVal;
334
335     oldVal.flags(oldVal.flags() | ios::fixed);
336     newVal.flags(newVal.flags() | ios::fixed);
337
338     oldVal << USER_PROPERTY<varT>::ConstData();
339     newVal << val;
340
341     OnChange(login, name, oldVal.str(), newVal.str(), admin);
342
343     if (isPassword)
344         {
345         WriteSuccessChange(login, admin, name, "******", "******", msg, store);
346         }
347     else
348         {
349         WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
350         }
351     USER_PROPERTY<varT>::Set(val);
352     return true;
353     }
354 else
355     {
356     WriteAccessDenied(login, admin, name);
357     return false;
358     }
359 return true;
360 }
361 //-------------------------------------------------------------------------
362 template <typename varT>
363 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const string & login,
364                                                    const ADMIN  * admin,
365                                                    const string & parameter)
366 {
367 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
368           admin->GetLogStr().c_str(), login.c_str(), parameter.c_str());
369 }
370 //-------------------------------------------------------------------------
371 template <typename varT>
372 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const string & login,
373                                                     const ADMIN * admin,
374                                                     const string & parameter,
375                                                     const string & oldValue,
376                                                     const string & newValue,
377                                                     const string & msg,
378                                                     const STORE * store)
379 {
380 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
381           admin->GetLogStr().c_str(),
382           login.c_str(),
383           parameter.c_str(),
384           oldValue.c_str(),
385           newValue.c_str(),
386           msg.c_str());
387
388 store->WriteUserChgLog(login, admin->GetLogin(), admin->GetIP(), parameter, oldValue, newValue, msg);
389 }
390 //-------------------------------------------------------------------------
391 template <typename varT>
392 void USER_PROPERTY_LOGGED<varT>::OnChange(const string & login,
393                                           const string & paramName,
394                                           const string & oldValue,
395                                           const string & newValue,
396                                           const ADMIN * admin)
397 {
398 string str1;
399
400 str1 = scriptsDir + "/OnChange";
401
402 if (access(str1.c_str(), X_OK) == 0)
403     {
404     string str2("\"" + str1 + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
405     ScriptExec(str2);
406     }
407 else
408     {
409     stgLogger("Script OnChange cannot be executed. File %s not found.", str1.c_str());
410     }
411 }
412 //-------------------------------------------------------------------------
413 //-------------------------------------------------------------------------
414 //-------------------------------------------------------------------------
415 template<typename varT>
416 ostream & operator<< (ostream & stream, const USER_PROPERTY<varT> & value)
417 {
418 return stream << value.ConstData();
419 }
420 //-----------------------------------------------------------------------------
421
422 #endif // USER_PROPERTY_H