3 $Date: 2010/09/13 05:54:43 $
7 #ifndef USER_PROPERTY_H
8 #define USER_PROPERTY_H
10 #include <unistd.h> // access
19 #include "stg/logger.h"
20 #include "stg/locker.h"
21 #include "stg/scriptexecuter.h"
26 #include "noncopyable.h"
28 extern volatile time_t stgTime;
29 //-----------------------------------------------------------------------------
30 class USER_PROPERTY_BASE {
32 virtual std::string ToString() const = 0;
34 //-----------------------------------------------------------------------------
35 template<typename varT>
36 class USER_PROPERTY : public USER_PROPERTY_BASE {
38 USER_PROPERTY(varT & val);
39 virtual ~USER_PROPERTY();
41 void Set(const varT & rvalue);
43 USER_PROPERTY<varT> & operator= (const varT & rvalue);
45 const varT * operator&() const throw() { return &value; }
46 const varT & ConstData() const throw() { return value; }
48 operator const varT&() const throw() { return value; }
50 void AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
51 void DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
53 void AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
54 void DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
56 time_t ModificationTime() const throw() { return modificationTime; }
57 void ModifyTime() throw();
59 std::string ToString() const;
62 time_t modificationTime;
63 std::set<PROPERTY_NOTIFIER_BASE<varT> *> beforeNotifiers;
64 std::set<PROPERTY_NOTIFIER_BASE<varT> *> afterNotifiers;
65 pthread_mutex_t mutex;
67 //-----------------------------------------------------------------------------
68 template<typename varT>
69 class USER_PROPERTY_LOGGED: public USER_PROPERTY<varT> {
71 USER_PROPERTY_LOGGED(varT & val,
72 const std::string & n,
76 const std::string & sd,
77 std::map<std::string, USER_PROPERTY_BASE*> & properties);
78 virtual ~USER_PROPERTY_LOGGED() {}
80 USER_PROPERTY_LOGGED<varT> * GetPointer() throw() { return this; }
81 const varT & Get() const { return USER_PROPERTY<varT>::ConstData(); }
82 const std::string & GetName() const { return name; }
83 bool Set(const varT & val,
85 const std::string & login,
87 const std::string & msg = "");
89 void WriteAccessDenied(const std::string & login,
91 const std::string & parameter);
93 void WriteSuccessChange(const std::string & login,
95 const std::string & parameter,
96 const std::string & oldValue,
97 const std::string & newValue,
98 const std::string & msg,
101 void OnChange(const std::string & login,
102 const std::string & paramName,
103 const std::string & oldValue,
104 const std::string & newValue,
105 const ADMIN * admin);
107 STG_LOGGER & stgLogger;
111 const std::string scriptsDir;
113 //-----------------------------------------------------------------------------
114 class USER_PROPERTIES : private NONCOPYABLE {
116 В этом месте важен порядок следования приватной и открытой частей.
117 Это связано с тем, что часть которая находится в публичной секции
118 по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
119 чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
120 начале идет закрытая секция
127 std::map<std::string, USER_PROPERTY_BASE *> properties;
129 USER_PROPERTIES(const std::string & sd);
131 USER_STAT & Stat() { return stat; }
132 USER_CONF & Conf() { return conf; }
133 const USER_STAT & GetStat() const { return stat; }
134 const USER_CONF & GetConf() const { return conf; }
135 void SetStat(const USER_STAT & s) { stat = s; }
136 void SetConf(const USER_CONF & c) { conf = c; }
138 void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
140 std::string GetPropertyValue(const std::string & name) const;
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;
151 USER_PROPERTY_LOGGED<std::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<std::string> tariffName;
157 USER_PROPERTY_LOGGED<std::string> nextTariff;
158 USER_PROPERTY_LOGGED<std::string> address;
159 USER_PROPERTY_LOGGED<std::string> note;
160 USER_PROPERTY_LOGGED<std::string> group;
161 USER_PROPERTY_LOGGED<std::string> email;
162 USER_PROPERTY_LOGGED<std::string> phone;
163 USER_PROPERTY_LOGGED<std::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<std::string> userdata0;
168 USER_PROPERTY_LOGGED<std::string> userdata1;
169 USER_PROPERTY_LOGGED<std::string> userdata2;
170 USER_PROPERTY_LOGGED<std::string> userdata3;
171 USER_PROPERTY_LOGGED<std::string> userdata4;
172 USER_PROPERTY_LOGGED<std::string> userdata5;
173 USER_PROPERTY_LOGGED<std::string> userdata6;
174 USER_PROPERTY_LOGGED<std::string> userdata7;
175 USER_PROPERTY_LOGGED<std::string> userdata8;
176 USER_PROPERTY_LOGGED<std::string> userdata9;
178 //=============================================================================
180 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
182 //-----------------------------------------------------------------------------
183 template <typename varT>
185 USER_PROPERTY<varT>::USER_PROPERTY(varT & val)
187 modificationTime(stgTime),
192 pthread_mutex_init(&mutex, NULL);
194 //-----------------------------------------------------------------------------
195 template <typename varT>
197 USER_PROPERTY<varT>::~USER_PROPERTY()
199 pthread_mutex_destroy(&mutex);
201 //-----------------------------------------------------------------------------
202 template <typename varT>
204 void USER_PROPERTY<varT>::ModifyTime() throw()
206 modificationTime = stgTime;
208 //-----------------------------------------------------------------------------
209 template <typename varT>
211 void USER_PROPERTY<varT>::Set(const varT & rvalue)
213 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
215 typename std::set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
219 ni = beforeNotifiers.begin();
220 while (ni != beforeNotifiers.end())
221 (*ni++)->Notify(oldVal, rvalue);
224 modificationTime = stgTime;
226 ni = afterNotifiers.begin();
227 while (ni != afterNotifiers.end())
228 (*ni++)->Notify(oldVal, rvalue);
230 //-----------------------------------------------------------------------------
231 template <typename varT>
233 USER_PROPERTY<varT> & USER_PROPERTY<varT>::operator= (const varT & newValue)
238 //-----------------------------------------------------------------------------
239 template <typename varT>
241 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
243 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
244 beforeNotifiers.insert(n);
246 //-----------------------------------------------------------------------------
247 template <typename varT>
249 void USER_PROPERTY<varT>::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
251 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
252 beforeNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
254 //-----------------------------------------------------------------------------
255 template <typename varT>
257 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
259 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
260 afterNotifiers.insert(n);
262 //-----------------------------------------------------------------------------
263 template <typename varT>
265 void USER_PROPERTY<varT>::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
267 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
268 afterNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
270 //-----------------------------------------------------------------------------
271 //-----------------------------------------------------------------------------
272 //-----------------------------------------------------------------------------
273 template <typename varT>
275 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val,
276 const std::string & n,
280 const std::string & sd,
281 std::map<std::string, USER_PROPERTY_BASE*> & properties)
283 : USER_PROPERTY<varT>(val),
290 properties.insert(std::make_pair(name, this));
292 //-------------------------------------------------------------------------
293 template <typename varT>
294 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
296 const std::string & login,
298 const std::string & msg)
300 const PRIV * priv = admin->GetPriv();
302 if ((priv->userConf && !isStat) ||
303 (priv->userStat && isStat) ||
304 (priv->userPasswd && isPassword) ||
305 (priv->userCash && name == "cash"))
307 std::stringstream oldVal;
308 std::stringstream newVal;
310 oldVal.flags(oldVal.flags() | std::ios::fixed);
311 newVal.flags(newVal.flags() | std::ios::fixed);
313 oldVal << USER_PROPERTY<varT>::ConstData();
316 OnChange(login, name, oldVal.str(), newVal.str(), admin);
320 WriteSuccessChange(login, admin, name, "******", "******", msg, store);
324 WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
326 USER_PROPERTY<varT>::Set(val);
331 WriteAccessDenied(login, admin, name);
336 //-------------------------------------------------------------------------
337 template <typename varT>
339 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const std::string & login,
341 const std::string & parameter)
343 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
344 admin->GetLogStr().c_str(), login.c_str(), parameter.c_str());
346 //-------------------------------------------------------------------------
347 template <typename varT>
349 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const std::string & login,
351 const std::string & parameter,
352 const std::string & oldValue,
353 const std::string & newValue,
354 const std::string & msg,
357 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
358 admin->GetLogStr().c_str(),
365 store->WriteUserChgLog(login, admin->GetLogin(), admin->GetIP(), parameter, oldValue, newValue, msg);
367 //-------------------------------------------------------------------------
368 template <typename varT>
369 void USER_PROPERTY_LOGGED<varT>::OnChange(const std::string & login,
370 const std::string & paramName,
371 const std::string & oldValue,
372 const std::string & newValue,
375 std::string filePath = scriptsDir + "/OnChange";
377 if (access(filePath.c_str(), X_OK) == 0)
379 std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
380 ScriptExec(execString.c_str());
384 stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
387 //-------------------------------------------------------------------------
388 //-------------------------------------------------------------------------
389 //-------------------------------------------------------------------------
391 std::string USER_PROPERTIES::GetPropertyValue(const std::string & name) const
393 std::map<std::string, USER_PROPERTY_BASE*>::const_iterator it = properties.find(name);
394 if (it == properties.end())
396 return it->second->ToString();
398 //-------------------------------------------------------------------------
399 //-------------------------------------------------------------------------
400 //-------------------------------------------------------------------------
401 template<typename varT>
403 std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY<varT> & value)
405 return stream << value.ConstData();
407 //-----------------------------------------------------------------------------
408 template<typename varT>
410 std::string USER_PROPERTY<varT>::ToString() const
412 std::ostringstream stream;
416 #endif // USER_PROPERTY_H