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
25 extern volatile time_t stgTime;
29 //-----------------------------------------------------------------------------
30 struct UserPropertyBase {
31 virtual ~UserPropertyBase() = default;
32 virtual std::string ToString() const = 0;
34 //-----------------------------------------------------------------------------
35 using Registry = std::map<std::string, UserPropertyBase*>;
36 //-----------------------------------------------------------------------------
38 class UserProperty : public UserPropertyBase {
40 explicit UserProperty(T& val);
42 void Set(const T& rhs);
43 T get() const { return value; }
45 UserProperty<T>& operator=(const T& rhs);
47 const T* operator&() const noexcept { return &value; }
48 const T& ConstData() const noexcept { return value; }
50 operator const T&() const noexcept { return value; }
52 void AddBeforeNotifier(PropertyNotifierBase<T>* n);
53 void DelBeforeNotifier(const PropertyNotifierBase<T>* n);
55 void AddAfterNotifier(PropertyNotifierBase<T>* n);
56 void DelAfterNotifier(const PropertyNotifierBase<T>* n);
58 time_t ModificationTime() const noexcept { return modificationTime; }
59 void ModifyTime() noexcept;
61 std::string ToString() const override;
64 time_t modificationTime;
65 std::set<PropertyNotifierBase<T>*> beforeNotifiers;
66 std::set<PropertyNotifierBase<T>*> afterNotifiers;
69 //-----------------------------------------------------------------------------
71 class UserPropertyLogged: public UserProperty<T> {
73 UserPropertyLogged(T& val,
78 Registry& properties);
80 UserPropertyLogged<T>* GetPointer() noexcept { return this; }
81 const UserPropertyLogged<T>* GetPointer() const noexcept { return this; }
82 const T& Get() const { return UserProperty<T>::ConstData(); }
83 const std::string& GetName() const { return name; }
84 bool Set(const T& val,
86 const std::string& login,
88 const std::string& msg = "");
90 void WriteAccessDenied(const std::string& login,
92 const std::string& parameter);
94 void WriteSuccessChange(const std::string& login,
96 const std::string& parameter,
97 const std::string& oldValue,
98 const std::string& newValue,
99 const std::string& msg,
102 void OnChange(const std::string& login,
103 const std::string& paramName,
104 const std::string& oldValue,
105 const std::string& newValue,
112 const Settings& settings;
114 //-----------------------------------------------------------------------------
115 class UserProperties {
117 В этом месте важен порядок следования приватной и открытой частей.
118 Это связано с тем, что часть которая находится в публичной секции
119 по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
120 чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
121 начале идет закрытая секция
130 explicit UserProperties(const Settings& s);
132 UserStat& Stat() { return stat; }
133 UserConf& Conf() { return conf; }
134 const UserStat& GetStat() const { return stat; }
135 const UserConf& GetConf() const { return conf; }
136 void SetStat(const UserStat& s) { stat = s; }
137 void SetConf(const UserConf& c) { conf = c; }
139 void SetProperties(const UserProperties& p) { stat = p.stat; conf = p.conf; }
141 std::string GetPropertyValue(const std::string & name) const;
142 bool Exists(const std::string & name) const;
144 UserPropertyLogged<double> cash;
145 UserPropertyLogged<DirTraff> up;
146 UserPropertyLogged<DirTraff> down;
147 UserPropertyLogged<double> lastCashAdd;
148 UserPropertyLogged<time_t> passiveTime;
149 UserPropertyLogged<time_t> lastCashAddTime;
150 UserPropertyLogged<double> freeMb;
151 UserPropertyLogged<time_t> lastActivityTime;
153 UserPropertyLogged<std::string> password;
154 UserPropertyLogged<int> passive;
155 UserPropertyLogged<int> disabled;
156 UserPropertyLogged<int> disabledDetailStat;
157 UserPropertyLogged<int> alwaysOnline;
158 UserPropertyLogged<std::string> tariffName;
159 UserPropertyLogged<std::string> nextTariff;
160 UserPropertyLogged<std::string> address;
161 UserPropertyLogged<std::string> note;
162 UserPropertyLogged<std::string> group;
163 UserPropertyLogged<std::string> email;
164 UserPropertyLogged<std::string> phone;
165 UserPropertyLogged<std::string> realName;
166 UserPropertyLogged<double> credit;
167 UserPropertyLogged<time_t> creditExpire;
168 UserPropertyLogged<UserIPs> ips;
169 UserPropertyLogged<std::string> userdata0;
170 UserPropertyLogged<std::string> userdata1;
171 UserPropertyLogged<std::string> userdata2;
172 UserPropertyLogged<std::string> userdata3;
173 UserPropertyLogged<std::string> userdata4;
174 UserPropertyLogged<std::string> userdata5;
175 UserPropertyLogged<std::string> userdata6;
176 UserPropertyLogged<std::string> userdata7;
177 UserPropertyLogged<std::string> userdata8;
178 UserPropertyLogged<std::string> userdata9;
180 //=============================================================================
182 //-----------------------------------------------------------------------------
183 //-----------------------------------------------------------------------------
184 //-----------------------------------------------------------------------------
185 template <typename T>
187 UserProperty<T>::UserProperty(T& val)
189 modificationTime(stgTime),
194 //-----------------------------------------------------------------------------
195 template <typename T>
197 void UserProperty<T>::ModifyTime() noexcept
199 modificationTime = stgTime;
201 //-----------------------------------------------------------------------------
202 template <typename T>
204 void UserProperty<T>::Set(const T& rvalue)
206 std::lock_guard<std::mutex> lock(mutex);
210 auto ni = beforeNotifiers.begin();
211 while (ni != beforeNotifiers.end())
212 (*ni++)->Notify(oldVal, rvalue);
215 modificationTime = stgTime;
217 ni = afterNotifiers.begin();
218 while (ni != afterNotifiers.end())
219 (*ni++)->Notify(oldVal, rvalue);
221 //-----------------------------------------------------------------------------
222 template <typename T>
224 UserProperty<T>& UserProperty<T>::operator=(const T& newValue)
229 //-----------------------------------------------------------------------------
230 template <typename T>
232 void UserProperty<T>::AddBeforeNotifier(PropertyNotifierBase<T>* n)
234 std::lock_guard<std::mutex> lock(mutex);
235 beforeNotifiers.insert(n);
237 //-----------------------------------------------------------------------------
238 template <typename T>
240 void UserProperty<T>::DelBeforeNotifier(const PropertyNotifierBase<T>* n)
242 std::lock_guard<std::mutex> lock(mutex);
243 beforeNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
245 //-----------------------------------------------------------------------------
246 template <typename T>
248 void UserProperty<T>::AddAfterNotifier(PropertyNotifierBase<T>* n)
250 std::lock_guard<std::mutex> lock(mutex);
251 afterNotifiers.insert(n);
253 //-----------------------------------------------------------------------------
254 template <typename T>
256 void UserProperty<T>::DelAfterNotifier(const PropertyNotifierBase<T>* n)
258 std::lock_guard<std::mutex> lock(mutex);
259 afterNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
261 //-----------------------------------------------------------------------------
262 //-----------------------------------------------------------------------------
263 //-----------------------------------------------------------------------------
264 template <typename T>
266 UserPropertyLogged<T>::UserPropertyLogged(T& val,
267 const std::string& n,
271 Registry& properties)
273 : UserProperty<T>(val),
274 stgLogger(Logger::get()),
280 properties.insert(std::make_pair(ToLower(name), this));
282 //-------------------------------------------------------------------------
283 template <typename T>
285 bool UserPropertyLogged<T>::Set(const T& val,
287 const std::string& login,
289 const std::string& msg)
291 const auto& priv = admin.priv();
293 if ((priv.userConf && !isStat) ||
294 (priv.userStat && isStat) ||
295 (priv.userPasswd && isPassword) ||
296 (priv.userCash && name == "cash"))
298 std::stringstream oldVal;
299 std::stringstream newVal;
301 oldVal.flags(oldVal.flags() | std::ios::fixed);
302 newVal.flags(newVal.flags() | std::ios::fixed);
304 oldVal << UserProperty<T>::ConstData();
307 OnChange(login, name, oldVal.str(), newVal.str(), admin);
310 WriteSuccessChange(login, admin, name, "******", "******", msg, store);
312 WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
314 UserProperty<T>::Set(val);
318 WriteAccessDenied(login, admin, name);
321 //-------------------------------------------------------------------------
322 template <typename T>
324 void UserPropertyLogged<T>::WriteAccessDenied(const std::string& login,
326 const std::string& parameter)
328 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
329 admin.logStr().c_str(), login.c_str(), parameter.c_str());
331 //-------------------------------------------------------------------------
332 template <typename T>
334 void UserPropertyLogged<T>::WriteSuccessChange(const std::string& login,
336 const std::string& parameter,
337 const std::string& oldValue,
338 const std::string& newValue,
339 const std::string& msg,
342 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
343 admin.logStr().c_str(),
350 for (size_t i = 0; i < settings.GetFilterParamsLog().size(); ++i)
351 if (settings.GetFilterParamsLog()[i] == "*" || strcasecmp(settings.GetFilterParamsLog()[i].c_str(), parameter.c_str()) == 0)
353 store.WriteUserChgLog(login, admin.login(), admin.IP(), parameter, oldValue, newValue, msg);
357 //-------------------------------------------------------------------------
358 template <typename T>
359 void UserPropertyLogged<T>::OnChange(const std::string& login,
360 const std::string& paramName,
361 const std::string& oldValue,
362 const std::string& newValue,
365 const auto filePath = settings.GetScriptsDir() + "/OnChange";
367 if (access(filePath.c_str(), X_OK) == 0)
369 const auto execString = "\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.login() + "\" \"" + admin.IPStr() + "\"";
370 ScriptExec(execString.c_str());
373 stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
375 //-------------------------------------------------------------------------
376 //-------------------------------------------------------------------------
377 //-------------------------------------------------------------------------
379 std::string UserProperties::GetPropertyValue(const std::string& name) const
381 const auto it = properties.find(ToLower(name));
382 if (it == properties.end())
384 return it->second->ToString();
386 //-----------------------------------------------------------------------------
388 bool UserProperties::Exists(const std::string& name) const
390 return properties.find(ToLower(name)) != properties.end();
392 //-------------------------------------------------------------------------
393 //-------------------------------------------------------------------------
394 //-------------------------------------------------------------------------
397 std::ostream& operator<<(std::ostream& stream, const UserProperty<T>& value)
399 return stream << value.ConstData();
401 //-----------------------------------------------------------------------------
404 std::string UserProperty<T>::ToString() const
406 std::ostringstream stream;