3 #include "stg/user_conf.h"
4 #include "stg/user_ips.h"
7 #include "stg/notifer.h"
8 #include "stg/admin_conf.h"
9 #include "stg/logger.h"
10 #include "stg/locker.h"
11 #include "stg/settings.h"
12 #include "stg/scriptexecuter.h"
13 #include "stg/common.h"
23 #include <unistd.h> // access
27 //-----------------------------------------------------------------------------
28 struct UserPropertyBase {
29 virtual ~UserPropertyBase() = default;
30 virtual std::string ToString() const = 0;
32 //-----------------------------------------------------------------------------
33 using Registry = std::map<std::string, UserPropertyBase*>;
34 //-----------------------------------------------------------------------------
36 class UserProperty : public UserPropertyBase {
38 explicit UserProperty(T& val);
40 void Set(const T& rhs);
41 T get() const { return value; }
43 UserProperty<T>& operator=(const T& rhs);
45 const T* operator&() const noexcept { return &value; }
46 const T& ConstData() const noexcept { return value; }
48 operator const T&() const noexcept { return value; }
50 void AddBeforeNotifier(PropertyNotifierBase<T>* n);
51 void DelBeforeNotifier(const PropertyNotifierBase<T>* n);
53 void AddAfterNotifier(PropertyNotifierBase<T>* n);
54 void DelAfterNotifier(const PropertyNotifierBase<T>* n);
56 time_t ModificationTime() const noexcept { return modificationTime; }
57 void ModifyTime() noexcept;
59 std::string ToString() const override;
62 time_t modificationTime;
63 std::set<PropertyNotifierBase<T>*> beforeNotifiers;
64 std::set<PropertyNotifierBase<T>*> afterNotifiers;
67 //-----------------------------------------------------------------------------
69 class UserPropertyLogged: public UserProperty<T> {
71 UserPropertyLogged(T& val,
76 Registry& properties);
78 UserPropertyLogged<T>* GetPointer() noexcept { return this; }
79 const UserPropertyLogged<T>* GetPointer() const noexcept { return this; }
80 const T& Get() const { return UserProperty<T>::ConstData(); }
81 const std::string& GetName() const { return name; }
82 bool Set(const T& 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,
110 const Settings& settings;
112 //-----------------------------------------------------------------------------
113 class UserProperties {
115 В этом месте важен порядок следования приватной и открытой частей.
116 Это связано с тем, что часть которая находится в публичной секции
117 по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
118 чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
119 начале идет закрытая секция
128 explicit UserProperties(const Settings& s);
130 UserStat& Stat() { return stat; }
131 UserConf& Conf() { return conf; }
132 const UserStat& GetStat() const { return stat; }
133 const UserConf& GetConf() const { return conf; }
134 void SetStat(const UserStat& s) { stat = s; }
135 void SetConf(const UserConf& c) { conf = c; }
137 void SetProperties(const UserProperties& p) { stat = p.stat; conf = p.conf; }
139 std::string GetPropertyValue(const std::string & name) const;
140 bool Exists(const std::string & name) const;
142 UserPropertyLogged<double> cash;
143 UserPropertyLogged<DirTraff> up;
144 UserPropertyLogged<DirTraff> down;
145 UserPropertyLogged<double> lastCashAdd;
146 UserPropertyLogged<time_t> passiveTime;
147 UserPropertyLogged<time_t> lastCashAddTime;
148 UserPropertyLogged<double> freeMb;
149 UserPropertyLogged<time_t> lastActivityTime;
151 UserPropertyLogged<std::string> password;
152 UserPropertyLogged<int> passive;
153 UserPropertyLogged<int> disabled;
154 UserPropertyLogged<int> disabledDetailStat;
155 UserPropertyLogged<int> alwaysOnline;
156 UserPropertyLogged<std::string> tariffName;
157 UserPropertyLogged<std::string> nextTariff;
158 UserPropertyLogged<std::string> address;
159 UserPropertyLogged<std::string> note;
160 UserPropertyLogged<std::string> group;
161 UserPropertyLogged<std::string> email;
162 UserPropertyLogged<std::string> phone;
163 UserPropertyLogged<std::string> realName;
164 UserPropertyLogged<double> credit;
165 UserPropertyLogged<time_t> creditExpire;
166 UserPropertyLogged<UserIPs> ips;
167 UserPropertyLogged<std::string> userdata0;
168 UserPropertyLogged<std::string> userdata1;
169 UserPropertyLogged<std::string> userdata2;
170 UserPropertyLogged<std::string> userdata3;
171 UserPropertyLogged<std::string> userdata4;
172 UserPropertyLogged<std::string> userdata5;
173 UserPropertyLogged<std::string> userdata6;
174 UserPropertyLogged<std::string> userdata7;
175 UserPropertyLogged<std::string> userdata8;
176 UserPropertyLogged<std::string> userdata9;
178 //=============================================================================
180 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
182 //-----------------------------------------------------------------------------
183 template <typename T>
185 UserProperty<T>::UserProperty(T& val)
187 modificationTime(time(NULL)),
192 //-----------------------------------------------------------------------------
193 template <typename T>
195 void UserProperty<T>::ModifyTime() noexcept
197 modificationTime = time(NULL);
199 //-----------------------------------------------------------------------------
200 template <typename T>
202 void UserProperty<T>::Set(const T& rvalue)
204 std::lock_guard<std::mutex> lock(mutex);
208 auto ni = beforeNotifiers.begin();
209 while (ni != beforeNotifiers.end())
210 (*ni++)->notify(oldVal, rvalue);
213 modificationTime = time(NULL);
215 ni = afterNotifiers.begin();
216 while (ni != afterNotifiers.end())
217 (*ni++)->notify(oldVal, rvalue);
219 //-----------------------------------------------------------------------------
220 template <typename T>
222 UserProperty<T>& UserProperty<T>::operator=(const T& newValue)
227 //-----------------------------------------------------------------------------
228 template <typename T>
230 void UserProperty<T>::AddBeforeNotifier(PropertyNotifierBase<T>* n)
232 std::lock_guard<std::mutex> lock(mutex);
233 beforeNotifiers.insert(n);
235 //-----------------------------------------------------------------------------
236 template <typename T>
238 void UserProperty<T>::DelBeforeNotifier(const PropertyNotifierBase<T>* n)
240 std::lock_guard<std::mutex> lock(mutex);
241 beforeNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
243 //-----------------------------------------------------------------------------
244 template <typename T>
246 void UserProperty<T>::AddAfterNotifier(PropertyNotifierBase<T>* n)
248 std::lock_guard<std::mutex> lock(mutex);
249 afterNotifiers.insert(n);
251 //-----------------------------------------------------------------------------
252 template <typename T>
254 void UserProperty<T>::DelAfterNotifier(const PropertyNotifierBase<T>* n)
256 std::lock_guard<std::mutex> lock(mutex);
257 afterNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
259 //-----------------------------------------------------------------------------
260 //-----------------------------------------------------------------------------
261 //-----------------------------------------------------------------------------
262 template <typename T>
264 UserPropertyLogged<T>::UserPropertyLogged(T& val,
265 const std::string& n,
269 Registry& properties)
271 : UserProperty<T>(val),
272 stgLogger(Logger::get()),
278 properties.insert(std::make_pair(ToLower(name), this));
280 //-------------------------------------------------------------------------
281 template <typename T>
283 bool UserPropertyLogged<T>::Set(const T& val,
285 const std::string& login,
287 const std::string& msg)
289 const auto& priv = admin.priv();
291 if ((priv.userConf && !isStat) ||
292 (priv.userStat && isStat) ||
293 (priv.userPasswd && isPassword) ||
294 (priv.userCash && name == "cash"))
296 std::stringstream oldVal;
297 std::stringstream newVal;
299 oldVal.flags(oldVal.flags() | std::ios::fixed);
300 newVal.flags(newVal.flags() | std::ios::fixed);
302 oldVal << UserProperty<T>::ConstData();
305 OnChange(login, name, oldVal.str(), newVal.str(), admin);
308 WriteSuccessChange(login, admin, name, "******", "******", msg, store);
310 WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
312 UserProperty<T>::Set(val);
316 WriteAccessDenied(login, admin, name);
319 //-------------------------------------------------------------------------
320 template <typename T>
322 void UserPropertyLogged<T>::WriteAccessDenied(const std::string& login,
324 const std::string& parameter)
326 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
327 admin.logStr().c_str(), login.c_str(), parameter.c_str());
329 //-------------------------------------------------------------------------
330 template <typename T>
332 void UserPropertyLogged<T>::WriteSuccessChange(const std::string& login,
334 const std::string& parameter,
335 const std::string& oldValue,
336 const std::string& newValue,
337 const std::string& msg,
340 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
341 admin.logStr().c_str(),
348 for (size_t i = 0; i < settings.GetFilterParamsLog().size(); ++i)
349 if (settings.GetFilterParamsLog()[i] == "*" || strcasecmp(settings.GetFilterParamsLog()[i].c_str(), parameter.c_str()) == 0)
351 store.WriteUserChgLog(login, admin.login(), admin.IP(), parameter, oldValue, newValue, msg);
355 //-------------------------------------------------------------------------
356 template <typename T>
357 void UserPropertyLogged<T>::OnChange(const std::string& login,
358 const std::string& paramName,
359 const std::string& oldValue,
360 const std::string& newValue,
363 const auto filePath = settings.GetScriptsDir() + "/OnChange";
365 if (access(filePath.c_str(), X_OK) == 0)
367 const auto execString = "\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.login() + "\" \"" + admin.IPStr() + "\"";
368 ScriptExec(execString.c_str());
371 stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
373 //-------------------------------------------------------------------------
374 //-------------------------------------------------------------------------
375 //-------------------------------------------------------------------------
377 std::string UserProperties::GetPropertyValue(const std::string& name) const
379 const auto it = properties.find(ToLower(name));
380 if (it == properties.end())
382 return it->second->ToString();
384 //-----------------------------------------------------------------------------
386 bool UserProperties::Exists(const std::string& name) const
388 return properties.find(ToLower(name)) != properties.end();
390 //-------------------------------------------------------------------------
391 //-------------------------------------------------------------------------
392 //-------------------------------------------------------------------------
395 std::ostream& operator<<(std::ostream& stream, const UserProperty<T>& value)
397 return stream << value.ConstData();
399 //-----------------------------------------------------------------------------
402 std::string UserProperty<T>::ToString() const
404 std::ostringstream stream;