3 $Date: 2010/09/13 05:54:43 $
7 #ifndef USER_PROPERTY_H
8 #define USER_PROPERTY_H
10 #include <unistd.h> // access
18 #include "stg/logger.h"
19 #include "stg/locker.h"
20 #include "stg/scriptexecuter.h"
25 #include "noncopyable.h"
27 extern volatile time_t stgTime;
28 //-----------------------------------------------------------------------------
29 class USER_PROPERTY_BASE {
31 virtual std::string ToString() const = 0;
33 //-----------------------------------------------------------------------------
34 template<typename varT>
35 class USER_PROPERTY : USER_PROPERTY_BASE {
37 USER_PROPERTY(varT & val);
38 virtual ~USER_PROPERTY();
40 void Set(const varT & rvalue);
42 USER_PROPERTY<varT> & operator= (const varT & rvalue);
44 const varT * operator&() const throw() { return &value; }
45 const varT & ConstData() const throw() { return value; }
47 operator const varT&() const throw() { return value; }
49 void AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
50 void DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
52 void AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
53 void DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
55 time_t ModificationTime() const throw() { return modificationTime; }
56 void ModifyTime() throw();
58 std::string ToString() const;
61 time_t modificationTime;
62 std::set<PROPERTY_NOTIFIER_BASE<varT> *> beforeNotifiers;
63 std::set<PROPERTY_NOTIFIER_BASE<varT> *> afterNotifiers;
64 pthread_mutex_t mutex;
66 //-----------------------------------------------------------------------------
67 template<typename varT>
68 class USER_PROPERTY_LOGGED: public USER_PROPERTY<varT> {
70 USER_PROPERTY_LOGGED(varT & val,
71 const std::string & n,
75 const std::string & sd,
76 std::map<std::string, USER_PROPERTY_BASE*> & properties);
77 virtual ~USER_PROPERTY_LOGGED() {}
79 USER_PROPERTY_LOGGED<varT> * GetPointer() throw() { return this; }
80 const varT & Get() const { return USER_PROPERTY<varT>::ConstData(); }
81 const std::string & GetName() const { return name; }
82 bool Set(const varT & val,
84 const std::string & login,
86 const std::string & msg = "");
88 void WriteAccessDenied(const std::string & login,
90 const std::string & parameter);
92 void WriteSuccessChange(const std::string & login,
94 const std::string & parameter,
95 const std::string & oldValue,
96 const std::string & newValue,
97 const std::string & msg,
100 void OnChange(const std::string & login,
101 const std::string & paramName,
102 const std::string & oldValue,
103 const std::string & newValue,
104 const ADMIN * admin);
106 STG_LOGGER & stgLogger;
110 const std::string scriptsDir;
112 //-----------------------------------------------------------------------------
113 class USER_PROPERTIES : private NONCOPYABLE {
115 В этом месте важен порядок следования приватной и открытой частей.
116 Это связано с тем, что часть которая находится в публичной секции
117 по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
118 чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
119 начале идет закрытая секция
126 std::map<std::string, USER_PROPERTY_BASE *> & properties;
128 USER_PROPERTIES(const std::string & sd);
130 USER_STAT & Stat() { return stat; }
131 USER_CONF & Conf() { return conf; }
132 const USER_STAT & GetStat() const { return stat; }
133 const USER_CONF & GetConf() const { return conf; }
134 void SetStat(const USER_STAT & s) { stat = s; }
135 void SetConf(const USER_CONF & c) { conf = c; }
137 void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
139 std::string GetPropertyValue(const std::string & name) const;
141 USER_PROPERTY_LOGGED<double> cash;
142 USER_PROPERTY_LOGGED<DIR_TRAFF> up;
143 USER_PROPERTY_LOGGED<DIR_TRAFF> down;
144 USER_PROPERTY_LOGGED<double> lastCashAdd;
145 USER_PROPERTY_LOGGED<time_t> passiveTime;
146 USER_PROPERTY_LOGGED<time_t> lastCashAddTime;
147 USER_PROPERTY_LOGGED<double> freeMb;
148 USER_PROPERTY_LOGGED<time_t> lastActivityTime;
150 USER_PROPERTY_LOGGED<std::string> password;
151 USER_PROPERTY_LOGGED<int> passive;
152 USER_PROPERTY_LOGGED<int> disabled;
153 USER_PROPERTY_LOGGED<int> disabledDetailStat;
154 USER_PROPERTY_LOGGED<int> alwaysOnline;
155 USER_PROPERTY_LOGGED<std::string> tariffName;
156 USER_PROPERTY_LOGGED<std::string> nextTariff;
157 USER_PROPERTY_LOGGED<std::string> address;
158 USER_PROPERTY_LOGGED<std::string> note;
159 USER_PROPERTY_LOGGED<std::string> group;
160 USER_PROPERTY_LOGGED<std::string> email;
161 USER_PROPERTY_LOGGED<std::string> phone;
162 USER_PROPERTY_LOGGED<std::string> realName;
163 USER_PROPERTY_LOGGED<double> credit;
164 USER_PROPERTY_LOGGED<time_t> creditExpire;
165 USER_PROPERTY_LOGGED<USER_IPS> ips;
166 USER_PROPERTY_LOGGED<std::string> userdata0;
167 USER_PROPERTY_LOGGED<std::string> userdata1;
168 USER_PROPERTY_LOGGED<std::string> userdata2;
169 USER_PROPERTY_LOGGED<std::string> userdata3;
170 USER_PROPERTY_LOGGED<std::string> userdata4;
171 USER_PROPERTY_LOGGED<std::string> userdata5;
172 USER_PROPERTY_LOGGED<std::string> userdata6;
173 USER_PROPERTY_LOGGED<std::string> userdata7;
174 USER_PROPERTY_LOGGED<std::string> userdata8;
175 USER_PROPERTY_LOGGED<std::string> userdata9;
177 //=============================================================================
179 //-----------------------------------------------------------------------------
180 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
182 template <typename varT>
184 USER_PROPERTY<varT>::USER_PROPERTY(varT & val)
186 modificationTime(stgTime),
191 pthread_mutex_init(&mutex, NULL);
193 //-----------------------------------------------------------------------------
194 template <typename varT>
196 USER_PROPERTY<varT>::~USER_PROPERTY()
198 pthread_mutex_destroy(&mutex);
200 //-----------------------------------------------------------------------------
201 template <typename varT>
203 void USER_PROPERTY<varT>::ModifyTime() throw()
205 modificationTime = stgTime;
207 //-----------------------------------------------------------------------------
208 template <typename varT>
210 void USER_PROPERTY<varT>::Set(const varT & rvalue)
212 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
214 typename std::set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
218 ni = beforeNotifiers.begin();
219 while (ni != beforeNotifiers.end())
220 (*ni++)->Notify(oldVal, rvalue);
223 modificationTime = stgTime;
225 ni = afterNotifiers.begin();
226 while (ni != afterNotifiers.end())
227 (*ni++)->Notify(oldVal, rvalue);
229 //-----------------------------------------------------------------------------
230 template <typename varT>
232 USER_PROPERTY<varT> & USER_PROPERTY<varT>::operator= (const varT & newValue)
237 //-----------------------------------------------------------------------------
238 template <typename varT>
240 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
242 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
243 beforeNotifiers.insert(n);
245 //-----------------------------------------------------------------------------
246 template <typename varT>
248 void USER_PROPERTY<varT>::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
250 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
251 beforeNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
253 //-----------------------------------------------------------------------------
254 template <typename varT>
256 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
258 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
259 afterNotifiers.insert(n);
261 //-----------------------------------------------------------------------------
262 template <typename varT>
264 void USER_PROPERTY<varT>::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
266 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
267 afterNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
269 //-----------------------------------------------------------------------------
270 //-----------------------------------------------------------------------------
271 //-----------------------------------------------------------------------------
272 template <typename varT>
274 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val,
275 const std::string & n,
279 const std::string & sd,
280 std::map<std::string, USER_PROPERTY_BASE*> & properties)
282 : USER_PROPERTY<varT>(val),
289 properties.insert(std::make_pair(name, this));
291 //-------------------------------------------------------------------------
292 template <typename varT>
293 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
295 const std::string & login,
297 const std::string & msg)
299 const PRIV * priv = admin->GetPriv();
301 if ((priv->userConf && !isStat) ||
302 (priv->userStat && isStat) ||
303 (priv->userPasswd && isPassword) ||
304 (priv->userCash && name == "cash"))
306 std::stringstream oldVal;
307 std::stringstream newVal;
309 oldVal.flags(oldVal.flags() | std::ios::fixed);
310 newVal.flags(newVal.flags() | std::ios::fixed);
312 oldVal << USER_PROPERTY<varT>::ConstData();
315 OnChange(login, name, oldVal.str(), newVal.str(), admin);
319 WriteSuccessChange(login, admin, name, "******", "******", msg, store);
323 WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
325 USER_PROPERTY<varT>::Set(val);
330 WriteAccessDenied(login, admin, name);
335 //-------------------------------------------------------------------------
336 template <typename varT>
338 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const std::string & login,
340 const std::string & parameter)
342 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
343 admin->GetLogStr().c_str(), login.c_str(), parameter.c_str());
345 //-------------------------------------------------------------------------
346 template <typename varT>
348 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const std::string & login,
350 const std::string & parameter,
351 const std::string & oldValue,
352 const std::string & newValue,
353 const std::string & msg,
356 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
357 admin->GetLogStr().c_str(),
364 store->WriteUserChgLog(login, admin->GetLogin(), admin->GetIP(), parameter, oldValue, newValue, msg);
366 //-------------------------------------------------------------------------
367 template <typename varT>
368 void USER_PROPERTY_LOGGED<varT>::OnChange(const std::string & login,
369 const std::string & paramName,
370 const std::string & oldValue,
371 const std::string & newValue,
374 std::string filePath = scriptsDir + "/OnChange";
376 if (access(filePath.c_str(), X_OK) == 0)
378 std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
379 ScriptExec(execString.c_str());
383 stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
386 //-------------------------------------------------------------------------
387 //-------------------------------------------------------------------------
388 //-------------------------------------------------------------------------
389 std::string USER_PROPERTIES::GetPropertyValue(const std::string & name) const
391 std::map<std::string, USER_PROPERTY_BASE*>::iterator it = properties.find(name);
392 if (it == properties.end())
394 return it->second.ToString();
396 //-------------------------------------------------------------------------
397 //-------------------------------------------------------------------------
398 //-------------------------------------------------------------------------
399 template<typename varT>
401 std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY<varT> & value)
403 return stream << value.ConstData();
405 //-----------------------------------------------------------------------------
406 template<typename varT>
408 std::string USER_PROPERTY<varT>::ToString() const
410 std::stringstream stream;
414 #endif // USER_PROPERTY_H