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/settings.h"
 
  22 #include "stg/scriptexecuter.h"
 
  23 #include "stg/common.h"
 
  28 #include "noncopyable.h"
 
  30 extern volatile time_t stgTime;
 
  31 //-----------------------------------------------------------------------------
 
  32 class USER_PROPERTY_BASE {
 
  34     virtual std::string ToString() const = 0;
 
  36 //-----------------------------------------------------------------------------
 
  37 typedef std::map<std::string, USER_PROPERTY_BASE *> REGISTRY;
 
  38 //-----------------------------------------------------------------------------
 
  39 template<typename varT>
 
  40 class USER_PROPERTY : public USER_PROPERTY_BASE {
 
  42     USER_PROPERTY(varT & val);
 
  43     virtual ~USER_PROPERTY();
 
  45     void Set(const varT & rvalue);
 
  47     USER_PROPERTY<varT> & operator= (const varT & rvalue);
 
  49     const varT * operator&() const throw() { return &value; }
 
  50     const varT & ConstData() const throw() { return value; }
 
  52     operator const varT&() const throw() { return value; }
 
  54     void    AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
 
  55     void    DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
 
  57     void    AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
 
  58     void    DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
 
  60     time_t  ModificationTime() const throw() { return modificationTime; }
 
  61     void    ModifyTime() throw();
 
  63     std::string ToString() const;
 
  66     time_t modificationTime;
 
  67     std::set<PROPERTY_NOTIFIER_BASE<varT> *> beforeNotifiers;
 
  68     std::set<PROPERTY_NOTIFIER_BASE<varT> *> afterNotifiers;
 
  69     pthread_mutex_t mutex;
 
  71 //-----------------------------------------------------------------------------
 
  72 template<typename varT>
 
  73 class USER_PROPERTY_LOGGED: public USER_PROPERTY<varT> {
 
  75     USER_PROPERTY_LOGGED(varT & val,
 
  76                          const std::string & n,
 
  81                          REGISTRY & properties);
 
  82     virtual ~USER_PROPERTY_LOGGED() {}
 
  84     USER_PROPERTY_LOGGED<varT> * GetPointer() throw() { return this; }
 
  85     const USER_PROPERTY_LOGGED<varT> * GetPointer() const throw() { return this; }
 
  86     const varT & Get() const { return USER_PROPERTY<varT>::ConstData(); }
 
  87     const std::string & GetName() const { return name; }
 
  88     bool Set(const varT & val,
 
  90              const std::string & login,
 
  92              const std::string & msg = "");
 
  94     void WriteAccessDenied(const std::string & login,
 
  96                            const std::string & parameter);
 
  98     void WriteSuccessChange(const std::string & login,
 
 100                             const std::string & parameter,
 
 101                             const std::string & oldValue,
 
 102                             const std::string & newValue,
 
 103                             const std::string & msg,
 
 104                             const STORE * store);
 
 106     void OnChange(const std::string & login,
 
 107                   const std::string & paramName,
 
 108                   const std::string & oldValue,
 
 109                   const std::string & newValue,
 
 110                   const ADMIN  * admin);
 
 112     STG_LOGGER &      stgLogger;
 
 116     const SETTINGS&   settings;
 
 118 //-----------------------------------------------------------------------------
 
 119 class USER_PROPERTIES : private NONCOPYABLE {
 
 121  В этом месте важен порядок следования приватной и открытой частей.
 
 122  Это связано с тем, что часть которая находится в публичной секции
 
 123  по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
 
 124  чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
 
 125  начале идет закрытая секция
 
 134     USER_PROPERTIES(const SETTINGS& s);
 
 136     USER_STAT & Stat() { return stat; }
 
 137     USER_CONF & Conf() { return conf; }
 
 138     const USER_STAT & GetStat() const { return stat; }
 
 139     const USER_CONF & GetConf() const { return conf; }
 
 140     void SetStat(const USER_STAT & s) { stat = s; }
 
 141     void SetConf(const USER_CONF & c) { conf = c; }
 
 143     void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
 
 145     std::string GetPropertyValue(const std::string & name) const;
 
 146     bool Exists(const std::string & name) const;
 
 148     USER_PROPERTY_LOGGED<double>            cash;
 
 149     USER_PROPERTY_LOGGED<DIR_TRAFF>         up;
 
 150     USER_PROPERTY_LOGGED<DIR_TRAFF>         down;
 
 151     USER_PROPERTY_LOGGED<double>            lastCashAdd;
 
 152     USER_PROPERTY_LOGGED<time_t>            passiveTime;
 
 153     USER_PROPERTY_LOGGED<time_t>            lastCashAddTime;
 
 154     USER_PROPERTY_LOGGED<double>            freeMb;
 
 155     USER_PROPERTY_LOGGED<time_t>            lastActivityTime;
 
 157     USER_PROPERTY_LOGGED<std::string>       password;
 
 158     USER_PROPERTY_LOGGED<int>               passive;
 
 159     USER_PROPERTY_LOGGED<int>               disabled;
 
 160     USER_PROPERTY_LOGGED<int>               disabledDetailStat;
 
 161     USER_PROPERTY_LOGGED<int>               alwaysOnline;
 
 162     USER_PROPERTY_LOGGED<std::string>       tariffName;
 
 163     USER_PROPERTY_LOGGED<std::string>       nextTariff;
 
 164     USER_PROPERTY_LOGGED<std::string>       address;
 
 165     USER_PROPERTY_LOGGED<std::string>       note;
 
 166     USER_PROPERTY_LOGGED<std::string>       group;
 
 167     USER_PROPERTY_LOGGED<std::string>       email;
 
 168     USER_PROPERTY_LOGGED<std::string>       phone;
 
 169     USER_PROPERTY_LOGGED<std::string>       realName;
 
 170     USER_PROPERTY_LOGGED<double>            credit;
 
 171     USER_PROPERTY_LOGGED<time_t>            creditExpire;
 
 172     USER_PROPERTY_LOGGED<USER_IPS>          ips;
 
 173     USER_PROPERTY_LOGGED<std::string>       userdata0;
 
 174     USER_PROPERTY_LOGGED<std::string>       userdata1;
 
 175     USER_PROPERTY_LOGGED<std::string>       userdata2;
 
 176     USER_PROPERTY_LOGGED<std::string>       userdata3;
 
 177     USER_PROPERTY_LOGGED<std::string>       userdata4;
 
 178     USER_PROPERTY_LOGGED<std::string>       userdata5;
 
 179     USER_PROPERTY_LOGGED<std::string>       userdata6;
 
 180     USER_PROPERTY_LOGGED<std::string>       userdata7;
 
 181     USER_PROPERTY_LOGGED<std::string>       userdata8;
 
 182     USER_PROPERTY_LOGGED<std::string>       userdata9;
 
 184 //=============================================================================
 
 186 //-----------------------------------------------------------------------------
 
 187 //-----------------------------------------------------------------------------
 
 188 //-----------------------------------------------------------------------------
 
 189 template <typename varT>
 
 191 USER_PROPERTY<varT>::USER_PROPERTY(varT & val)
 
 193       modificationTime(stgTime),
 
 198 pthread_mutex_init(&mutex, NULL);
 
 200 //-----------------------------------------------------------------------------
 
 201 template <typename varT>
 
 203 USER_PROPERTY<varT>::~USER_PROPERTY()
 
 205 pthread_mutex_destroy(&mutex);
 
 207 //-----------------------------------------------------------------------------
 
 208 template <typename varT>
 
 210 void USER_PROPERTY<varT>::ModifyTime() throw()
 
 212 modificationTime = stgTime;
 
 214 //-----------------------------------------------------------------------------
 
 215 template <typename varT>
 
 217 void USER_PROPERTY<varT>::Set(const varT & rvalue)
 
 219 STG_LOCKER locker(&mutex);
 
 221 typename std::set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
 
 225 ni = beforeNotifiers.begin();
 
 226 while (ni != beforeNotifiers.end())
 
 227     (*ni++)->Notify(oldVal, rvalue);
 
 230 modificationTime = stgTime;
 
 232 ni = afterNotifiers.begin();
 
 233 while (ni != afterNotifiers.end())
 
 234     (*ni++)->Notify(oldVal, rvalue);
 
 236 //-----------------------------------------------------------------------------
 
 237 template <typename varT>
 
 239 USER_PROPERTY<varT> & USER_PROPERTY<varT>::operator= (const varT & newValue)
 
 244 //-----------------------------------------------------------------------------
 
 245 template <typename varT>
 
 247 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
 
 249 STG_LOCKER locker(&mutex);
 
 250 beforeNotifiers.insert(n);
 
 252 //-----------------------------------------------------------------------------
 
 253 template <typename varT>
 
 255 void USER_PROPERTY<varT>::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
 
 257 STG_LOCKER locker(&mutex);
 
 258 beforeNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
 
 260 //-----------------------------------------------------------------------------
 
 261 template <typename varT>
 
 263 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
 
 265 STG_LOCKER locker(&mutex);
 
 266 afterNotifiers.insert(n);
 
 268 //-----------------------------------------------------------------------------
 
 269 template <typename varT>
 
 271 void USER_PROPERTY<varT>::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
 
 273 STG_LOCKER locker(&mutex);
 
 274 afterNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
 
 276 //-----------------------------------------------------------------------------
 
 277 //-----------------------------------------------------------------------------
 
 278 //-----------------------------------------------------------------------------
 
 279 template <typename varT>
 
 281 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val,
 
 282                                                  const std::string & n,
 
 287                                                  REGISTRY & properties)
 
 289     : USER_PROPERTY<varT>(val),
 
 296 properties.insert(std::make_pair(ToLower(name), this));
 
 298 //-------------------------------------------------------------------------
 
 299 template <typename varT>
 
 300 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
 
 302                                      const std::string & login,
 
 304                                      const std::string & msg)
 
 306 const PRIV * priv = admin->GetPriv();
 
 308 if ((priv->userConf && !isStat) ||
 
 309     (priv->userStat && isStat) ||
 
 310     (priv->userPasswd && isPassword) ||
 
 311     (priv->userCash && name == "cash"))
 
 313     std::stringstream oldVal;
 
 314     std::stringstream newVal;
 
 316     oldVal.flags(oldVal.flags() | std::ios::fixed);
 
 317     newVal.flags(newVal.flags() | std::ios::fixed);
 
 319     oldVal << USER_PROPERTY<varT>::ConstData();
 
 322     OnChange(login, name, oldVal.str(), newVal.str(), admin);
 
 326         WriteSuccessChange(login, admin, name, "******", "******", msg, store);
 
 330         WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
 
 332     USER_PROPERTY<varT>::Set(val);
 
 337     WriteAccessDenied(login, admin, name);
 
 342 //-------------------------------------------------------------------------
 
 343 template <typename varT>
 
 345 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const std::string & login,
 
 347                                                    const std::string & parameter)
 
 349 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
 
 350           admin->GetLogStr().c_str(), login.c_str(), parameter.c_str());
 
 352 //-------------------------------------------------------------------------
 
 353 template <typename varT>
 
 355 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const std::string & login,
 
 357                                                     const std::string & parameter,
 
 358                                                     const std::string & oldValue,
 
 359                                                     const std::string & newValue,
 
 360                                                     const std::string & msg,
 
 363 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
 
 364           admin->GetLogStr().c_str(),
 
 371 for (size_t i = 0; i < settings.GetFilterParamsLog().size(); ++i)
 
 372     if (settings.GetFilterParamsLog()[i] == "*" || strcasecmp(settings.GetFilterParamsLog()[i].c_str(), parameter.c_str()) == 0)
 
 374         store->WriteUserChgLog(login, admin->GetLogin(), admin->GetIP(), parameter, oldValue, newValue, msg);
 
 378 //-------------------------------------------------------------------------
 
 379 template <typename varT>
 
 380 void USER_PROPERTY_LOGGED<varT>::OnChange(const std::string & login,
 
 381                                           const std::string & paramName,
 
 382                                           const std::string & oldValue,
 
 383                                           const std::string & newValue,
 
 386 static std::string filePath = settings.GetScriptsDir() + "/OnChange";
 
 388 if (access(filePath.c_str(), X_OK) == 0)
 
 390     std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
 
 391     ScriptExec(execString.c_str());
 
 395     stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
 
 398 //-------------------------------------------------------------------------
 
 399 //-------------------------------------------------------------------------
 
 400 //-------------------------------------------------------------------------
 
 402 std::string USER_PROPERTIES::GetPropertyValue(const std::string & name) const
 
 404 REGISTRY::const_iterator it = properties.find(ToLower(name));
 
 405 if (it == properties.end())
 
 407 return it->second->ToString();
 
 409 //-----------------------------------------------------------------------------
 
 411 bool USER_PROPERTIES::Exists(const std::string & name) const
 
 413 return properties.find(ToLower(name)) != properties.end();
 
 415 //-------------------------------------------------------------------------
 
 416 //-------------------------------------------------------------------------
 
 417 //-------------------------------------------------------------------------
 
 418 template<typename varT>
 
 420 std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY<varT> & value)
 
 422 return stream << value.ConstData();
 
 424 //-----------------------------------------------------------------------------
 
 425 template<typename varT>
 
 427 std::string USER_PROPERTY<varT>::ToString() const
 
 429 std::ostringstream stream;
 
 433 #endif // USER_PROPERTY_H