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;