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"
 
  22 #include "stg/common.h"
 
  27 #include "noncopyable.h"
 
  29 extern volatile time_t stgTime;
 
  30 //-----------------------------------------------------------------------------
 
  31 class USER_PROPERTY_BASE {
 
  33     virtual std::string ToString() const = 0;
 
  35 //-----------------------------------------------------------------------------
 
  36 typedef std::map<std::string, USER_PROPERTY_BASE *> REGISTRY;
 
  37 //-----------------------------------------------------------------------------
 
  38 template<typename varT>
 
  39 class USER_PROPERTY : public USER_PROPERTY_BASE {
 
  41     USER_PROPERTY(varT & val);
 
  42     virtual ~USER_PROPERTY();
 
  44     void Set(const varT & rvalue);
 
  46     USER_PROPERTY<varT> & operator= (const varT & rvalue);
 
  48     const varT * operator&() const throw() { return &value; }
 
  49     const varT & ConstData() const throw() { return value; }
 
  51     operator const varT&() const throw() { return value; }
 
  53     void    AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
 
  54     void    DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
 
  56     void    AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n);
 
  57     void    DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n);
 
  59     time_t  ModificationTime() const throw() { return modificationTime; }
 
  60     void    ModifyTime() throw();
 
  62     std::string ToString() const;
 
  65     time_t modificationTime;
 
  66     std::set<PROPERTY_NOTIFIER_BASE<varT> *> beforeNotifiers;
 
  67     std::set<PROPERTY_NOTIFIER_BASE<varT> *> afterNotifiers;
 
  68     pthread_mutex_t mutex;
 
  70 //-----------------------------------------------------------------------------
 
  71 template<typename varT>
 
  72 class USER_PROPERTY_LOGGED: public USER_PROPERTY<varT> {
 
  74     USER_PROPERTY_LOGGED(varT & val,
 
  75                          const std::string & n,
 
  79                          const std::string & sd,
 
  80                          REGISTRY & properties);
 
  81     virtual ~USER_PROPERTY_LOGGED() {}
 
  83     USER_PROPERTY_LOGGED<varT> * GetPointer() throw() { return this; }
 
  84     const USER_PROPERTY_LOGGED<varT> * GetPointer() const throw() { return this; }
 
  85     const varT & Get() const { return USER_PROPERTY<varT>::ConstData(); }
 
  86     const std::string & GetName() const { return name; }
 
  87     bool Set(const varT & val,
 
  89              const std::string & login,
 
  91              const std::string & msg = "");
 
  93     void WriteAccessDenied(const std::string & login,
 
  95                            const std::string & parameter);
 
  97     void WriteSuccessChange(const std::string & login,
 
  99                             const std::string & parameter,
 
 100                             const std::string & oldValue,
 
 101                             const std::string & newValue,
 
 102                             const std::string & msg,
 
 103                             const STORE * store);
 
 105     void OnChange(const std::string & login,
 
 106                   const std::string & paramName,
 
 107                   const std::string & oldValue,
 
 108                   const std::string & newValue,
 
 109                   const ADMIN  * admin);
 
 111     STG_LOGGER &      stgLogger;
 
 115     const std::string scriptsDir;
 
 117 //-----------------------------------------------------------------------------
 
 118 class USER_PROPERTIES : private NONCOPYABLE {
 
 120  В этом месте важен порядок следования приватной и открытой частей.
 
 121  Это связано с тем, что часть которая находится в публичной секции
 
 122  по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
 
 123  чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
 
 124  начале идет закрытая секция
 
 133     USER_PROPERTIES(const std::string & sd);
 
 135     USER_STAT & Stat() { return stat; }
 
 136     USER_CONF & Conf() { return conf; }
 
 137     const USER_STAT & GetStat() const { return stat; }
 
 138     const USER_CONF & GetConf() const { return conf; }
 
 139     void SetStat(const USER_STAT & s) { stat = s; }
 
 140     void SetConf(const USER_CONF & c) { conf = c; }
 
 142     void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
 
 144     std::string GetPropertyValue(const std::string & name) const;
 
 145     bool Exists(const std::string & name) const;
 
 147     USER_PROPERTY_LOGGED<double>            cash;
 
 148     USER_PROPERTY_LOGGED<DIR_TRAFF>         up;
 
 149     USER_PROPERTY_LOGGED<DIR_TRAFF>         down;
 
 150     USER_PROPERTY_LOGGED<double>            lastCashAdd;
 
 151     USER_PROPERTY_LOGGED<time_t>            passiveTime;
 
 152     USER_PROPERTY_LOGGED<time_t>            lastCashAddTime;
 
 153     USER_PROPERTY_LOGGED<double>            freeMb;
 
 154     USER_PROPERTY_LOGGED<time_t>            lastActivityTime;
 
 156     USER_PROPERTY_LOGGED<std::string>       password;
 
 157     USER_PROPERTY_LOGGED<int>               passive;
 
 158     USER_PROPERTY_LOGGED<int>               disabled;
 
 159     USER_PROPERTY_LOGGED<int>               disabledDetailStat;
 
 160     USER_PROPERTY_LOGGED<int>               alwaysOnline;
 
 161     USER_PROPERTY_LOGGED<std::string>       tariffName;
 
 162     USER_PROPERTY_LOGGED<std::string>       nextTariff;
 
 163     USER_PROPERTY_LOGGED<std::string>       address;
 
 164     USER_PROPERTY_LOGGED<std::string>       note;
 
 165     USER_PROPERTY_LOGGED<std::string>       group;
 
 166     USER_PROPERTY_LOGGED<std::string>       email;
 
 167     USER_PROPERTY_LOGGED<std::string>       phone;
 
 168     USER_PROPERTY_LOGGED<std::string>       realName;
 
 169     USER_PROPERTY_LOGGED<double>            credit;
 
 170     USER_PROPERTY_LOGGED<time_t>            creditExpire;
 
 171     USER_PROPERTY_LOGGED<USER_IPS>          ips;
 
 172     USER_PROPERTY_LOGGED<std::string>       userdata0;
 
 173     USER_PROPERTY_LOGGED<std::string>       userdata1;
 
 174     USER_PROPERTY_LOGGED<std::string>       userdata2;
 
 175     USER_PROPERTY_LOGGED<std::string>       userdata3;
 
 176     USER_PROPERTY_LOGGED<std::string>       userdata4;
 
 177     USER_PROPERTY_LOGGED<std::string>       userdata5;
 
 178     USER_PROPERTY_LOGGED<std::string>       userdata6;
 
 179     USER_PROPERTY_LOGGED<std::string>       userdata7;
 
 180     USER_PROPERTY_LOGGED<std::string>       userdata8;
 
 181     USER_PROPERTY_LOGGED<std::string>       userdata9;
 
 183 //=============================================================================
 
 185 //-----------------------------------------------------------------------------
 
 186 //-----------------------------------------------------------------------------
 
 187 //-----------------------------------------------------------------------------
 
 188 template <typename varT>
 
 190 USER_PROPERTY<varT>::USER_PROPERTY(varT & val)
 
 192       modificationTime(stgTime),
 
 197 pthread_mutex_init(&mutex, NULL);
 
 199 //-----------------------------------------------------------------------------
 
 200 template <typename varT>
 
 202 USER_PROPERTY<varT>::~USER_PROPERTY()
 
 204 pthread_mutex_destroy(&mutex);
 
 206 //-----------------------------------------------------------------------------
 
 207 template <typename varT>
 
 209 void USER_PROPERTY<varT>::ModifyTime() throw()
 
 211 modificationTime = stgTime;
 
 213 //-----------------------------------------------------------------------------
 
 214 template <typename varT>
 
 216 void USER_PROPERTY<varT>::Set(const varT & rvalue)
 
 218 STG_LOCKER locker(&mutex);
 
 220 typename std::set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
 
 224 ni = beforeNotifiers.begin();
 
 225 while (ni != beforeNotifiers.end())
 
 226     (*ni++)->Notify(oldVal, rvalue);
 
 229 modificationTime = stgTime;
 
 231 ni = afterNotifiers.begin();
 
 232 while (ni != afterNotifiers.end())
 
 233     (*ni++)->Notify(oldVal, rvalue);
 
 235 //-----------------------------------------------------------------------------
 
 236 template <typename varT>
 
 238 USER_PROPERTY<varT> & USER_PROPERTY<varT>::operator= (const varT & newValue)
 
 243 //-----------------------------------------------------------------------------
 
 244 template <typename varT>
 
 246 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
 
 248 STG_LOCKER locker(&mutex);
 
 249 beforeNotifiers.insert(n);
 
 251 //-----------------------------------------------------------------------------
 
 252 template <typename varT>
 
 254 void USER_PROPERTY<varT>::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
 
 256 STG_LOCKER locker(&mutex);
 
 257 beforeNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
 
 259 //-----------------------------------------------------------------------------
 
 260 template <typename varT>
 
 262 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
 
 264 STG_LOCKER locker(&mutex);
 
 265 afterNotifiers.insert(n);
 
 267 //-----------------------------------------------------------------------------
 
 268 template <typename varT>
 
 270 void USER_PROPERTY<varT>::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
 
 272 STG_LOCKER locker(&mutex);
 
 273 afterNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
 
 275 //-----------------------------------------------------------------------------
 
 276 //-----------------------------------------------------------------------------
 
 277 //-----------------------------------------------------------------------------
 
 278 template <typename varT>
 
 280 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val,
 
 281                                                  const std::string & n,
 
 285                                                  const std::string & sd,
 
 286                                                  REGISTRY & properties)
 
 288     : USER_PROPERTY<varT>(val),
 
 295 properties.insert(std::make_pair(ToLower(name), this));
 
 297 //-------------------------------------------------------------------------
 
 298 template <typename varT>
 
 299 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
 
 301                                      const std::string & login,
 
 303                                      const std::string & msg)
 
 305 const PRIV * priv = admin->GetPriv();
 
 307 if ((priv->userConf && !isStat) ||
 
 308     (priv->userStat && isStat) ||
 
 309     (priv->userPasswd && isPassword) ||
 
 310     (priv->userCash && name == "cash"))
 
 312     std::stringstream oldVal;
 
 313     std::stringstream newVal;
 
 315     oldVal.flags(oldVal.flags() | std::ios::fixed);
 
 316     newVal.flags(newVal.flags() | std::ios::fixed);
 
 318     oldVal << USER_PROPERTY<varT>::ConstData();
 
 321     OnChange(login, name, oldVal.str(), newVal.str(), admin);
 
 325         WriteSuccessChange(login, admin, name, "******", "******", msg, store);
 
 329         WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
 
 331     USER_PROPERTY<varT>::Set(val);
 
 336     WriteAccessDenied(login, admin, name);
 
 341 //-------------------------------------------------------------------------
 
 342 template <typename varT>
 
 344 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const std::string & login,
 
 346                                                    const std::string & parameter)
 
 348 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
 
 349           admin->GetLogStr().c_str(), login.c_str(), parameter.c_str());
 
 351 //-------------------------------------------------------------------------
 
 352 template <typename varT>
 
 354 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const std::string & login,
 
 356                                                     const std::string & parameter,
 
 357                                                     const std::string & oldValue,
 
 358                                                     const std::string & newValue,
 
 359                                                     const std::string & msg,
 
 362 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
 
 363           admin->GetLogStr().c_str(),
 
 370 store->WriteUserChgLog(login, admin->GetLogin(), admin->GetIP(), parameter, oldValue, newValue, msg);
 
 372 //-------------------------------------------------------------------------
 
 373 template <typename varT>
 
 374 void USER_PROPERTY_LOGGED<varT>::OnChange(const std::string & login,
 
 375                                           const std::string & paramName,
 
 376                                           const std::string & oldValue,
 
 377                                           const std::string & newValue,
 
 380 std::string filePath = scriptsDir + "/OnChange";
 
 382 if (access(filePath.c_str(), X_OK) == 0)
 
 384     std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
 
 385     ScriptExec(execString.c_str());
 
 389     stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
 
 392 //-------------------------------------------------------------------------
 
 393 //-------------------------------------------------------------------------
 
 394 //-------------------------------------------------------------------------
 
 396 std::string USER_PROPERTIES::GetPropertyValue(const std::string & name) const
 
 398 REGISTRY::const_iterator it = properties.find(ToLower(name));
 
 399 if (it == properties.end())
 
 401 return it->second->ToString();
 
 403 //-----------------------------------------------------------------------------
 
 405 bool USER_PROPERTIES::Exists(const std::string & name) const
 
 407 return properties.find(ToLower(name)) != properties.end();
 
 409 //-------------------------------------------------------------------------
 
 410 //-------------------------------------------------------------------------
 
 411 //-------------------------------------------------------------------------
 
 412 template<typename varT>
 
 414 std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY<varT> & value)
 
 416 return stream << value.ConstData();
 
 418 //-----------------------------------------------------------------------------
 
 419 template<typename varT>
 
 421 std::string USER_PROPERTY<varT>::ToString() const
 
 423 std::ostringstream stream;
 
 427 #endif // USER_PROPERTY_H