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 varT & Get() const { return USER_PROPERTY<varT>::ConstData(); }
 
  85     const std::string & GetName() const { return name; }
 
  86     bool Set(const varT & val,
 
  88              const std::string & login,
 
  90              const std::string & msg = "");
 
  92     void WriteAccessDenied(const std::string & login,
 
  94                            const std::string & parameter);
 
  96     void WriteSuccessChange(const std::string & login,
 
  98                             const std::string & parameter,
 
  99                             const std::string & oldValue,
 
 100                             const std::string & newValue,
 
 101                             const std::string & msg,
 
 102                             const STORE * store);
 
 104     void OnChange(const std::string & login,
 
 105                   const std::string & paramName,
 
 106                   const std::string & oldValue,
 
 107                   const std::string & newValue,
 
 108                   const ADMIN  * admin);
 
 110     STG_LOGGER &      stgLogger;
 
 114     const std::string scriptsDir;
 
 116 //-----------------------------------------------------------------------------
 
 117 class USER_PROPERTIES : private NONCOPYABLE {
 
 119  В этом месте важен порядок следования приватной и открытой частей.
 
 120  Это связано с тем, что часть которая находится в публичной секции
 
 121  по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно
 
 122  чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в
 
 123  начале идет закрытая секция
 
 132     USER_PROPERTIES(const std::string & sd);
 
 134     USER_STAT & Stat() { return stat; }
 
 135     USER_CONF & Conf() { return conf; }
 
 136     const USER_STAT & GetStat() const { return stat; }
 
 137     const USER_CONF & GetConf() const { return conf; }
 
 138     void SetStat(const USER_STAT & s) { stat = s; }
 
 139     void SetConf(const USER_CONF & c) { conf = c; }
 
 141     void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; }
 
 143     std::string GetPropertyValue(const std::string & name) const;
 
 144     bool Exists(const std::string & name) const;
 
 146     USER_PROPERTY_LOGGED<double>            cash;
 
 147     USER_PROPERTY_LOGGED<DIR_TRAFF>         up;
 
 148     USER_PROPERTY_LOGGED<DIR_TRAFF>         down;
 
 149     USER_PROPERTY_LOGGED<double>            lastCashAdd;
 
 150     USER_PROPERTY_LOGGED<time_t>            passiveTime;
 
 151     USER_PROPERTY_LOGGED<time_t>            lastCashAddTime;
 
 152     USER_PROPERTY_LOGGED<double>            freeMb;
 
 153     USER_PROPERTY_LOGGED<time_t>            lastActivityTime;
 
 155     USER_PROPERTY_LOGGED<std::string>       password;
 
 156     USER_PROPERTY_LOGGED<int>               passive;
 
 157     USER_PROPERTY_LOGGED<int>               disabled;
 
 158     USER_PROPERTY_LOGGED<int>               disabledDetailStat;
 
 159     USER_PROPERTY_LOGGED<int>               alwaysOnline;
 
 160     USER_PROPERTY_LOGGED<std::string>       tariffName;
 
 161     USER_PROPERTY_LOGGED<std::string>       nextTariff;
 
 162     USER_PROPERTY_LOGGED<std::string>       address;
 
 163     USER_PROPERTY_LOGGED<std::string>       note;
 
 164     USER_PROPERTY_LOGGED<std::string>       group;
 
 165     USER_PROPERTY_LOGGED<std::string>       email;
 
 166     USER_PROPERTY_LOGGED<std::string>       phone;
 
 167     USER_PROPERTY_LOGGED<std::string>       realName;
 
 168     USER_PROPERTY_LOGGED<double>            credit;
 
 169     USER_PROPERTY_LOGGED<time_t>            creditExpire;
 
 170     USER_PROPERTY_LOGGED<USER_IPS>          ips;
 
 171     USER_PROPERTY_LOGGED<std::string>       userdata0;
 
 172     USER_PROPERTY_LOGGED<std::string>       userdata1;
 
 173     USER_PROPERTY_LOGGED<std::string>       userdata2;
 
 174     USER_PROPERTY_LOGGED<std::string>       userdata3;
 
 175     USER_PROPERTY_LOGGED<std::string>       userdata4;
 
 176     USER_PROPERTY_LOGGED<std::string>       userdata5;
 
 177     USER_PROPERTY_LOGGED<std::string>       userdata6;
 
 178     USER_PROPERTY_LOGGED<std::string>       userdata7;
 
 179     USER_PROPERTY_LOGGED<std::string>       userdata8;
 
 180     USER_PROPERTY_LOGGED<std::string>       userdata9;
 
 182 //=============================================================================
 
 184 //-----------------------------------------------------------------------------
 
 185 //-----------------------------------------------------------------------------
 
 186 //-----------------------------------------------------------------------------
 
 187 template <typename varT>
 
 189 USER_PROPERTY<varT>::USER_PROPERTY(varT & val)
 
 191       modificationTime(stgTime),
 
 196 pthread_mutex_init(&mutex, NULL);
 
 198 //-----------------------------------------------------------------------------
 
 199 template <typename varT>
 
 201 USER_PROPERTY<varT>::~USER_PROPERTY()
 
 203 pthread_mutex_destroy(&mutex);
 
 205 //-----------------------------------------------------------------------------
 
 206 template <typename varT>
 
 208 void USER_PROPERTY<varT>::ModifyTime() throw()
 
 210 modificationTime = stgTime;
 
 212 //-----------------------------------------------------------------------------
 
 213 template <typename varT>
 
 215 void USER_PROPERTY<varT>::Set(const varT & rvalue)
 
 217 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
 
 219 typename std::set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni;
 
 223 ni = beforeNotifiers.begin();
 
 224 while (ni != beforeNotifiers.end())
 
 225     (*ni++)->Notify(oldVal, rvalue);
 
 228 modificationTime = stgTime;
 
 230 ni = afterNotifiers.begin();
 
 231 while (ni != afterNotifiers.end())
 
 232     (*ni++)->Notify(oldVal, rvalue);
 
 234 //-----------------------------------------------------------------------------
 
 235 template <typename varT>
 
 237 USER_PROPERTY<varT> & USER_PROPERTY<varT>::operator= (const varT & newValue)
 
 242 //-----------------------------------------------------------------------------
 
 243 template <typename varT>
 
 245 void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
 
 247 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
 
 248 beforeNotifiers.insert(n);
 
 250 //-----------------------------------------------------------------------------
 
 251 template <typename varT>
 
 253 void USER_PROPERTY<varT>::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
 
 255 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
 
 256 beforeNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
 
 258 //-----------------------------------------------------------------------------
 
 259 template <typename varT>
 
 261 void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n)
 
 263 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
 
 264 afterNotifiers.insert(n);
 
 266 //-----------------------------------------------------------------------------
 
 267 template <typename varT>
 
 269 void USER_PROPERTY<varT>::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n)
 
 271 STG_LOCKER locker(&mutex, __FILE__, __LINE__);
 
 272 afterNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n));
 
 274 //-----------------------------------------------------------------------------
 
 275 //-----------------------------------------------------------------------------
 
 276 //-----------------------------------------------------------------------------
 
 277 template <typename varT>
 
 279 USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val,
 
 280                                                  const std::string & n,
 
 284                                                  const std::string & sd,
 
 285                                                  REGISTRY & properties)
 
 287     : USER_PROPERTY<varT>(val),
 
 294 properties.insert(std::make_pair(ToLower(name), this));
 
 296 //-------------------------------------------------------------------------
 
 297 template <typename varT>
 
 298 bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val,
 
 300                                      const std::string & login,
 
 302                                      const std::string & msg)
 
 304 const PRIV * priv = admin->GetPriv();
 
 306 if ((priv->userConf && !isStat) ||
 
 307     (priv->userStat && isStat) ||
 
 308     (priv->userPasswd && isPassword) ||
 
 309     (priv->userCash && name == "cash"))
 
 311     std::stringstream oldVal;
 
 312     std::stringstream newVal;
 
 314     oldVal.flags(oldVal.flags() | std::ios::fixed);
 
 315     newVal.flags(newVal.flags() | std::ios::fixed);
 
 317     oldVal << USER_PROPERTY<varT>::ConstData();
 
 320     OnChange(login, name, oldVal.str(), newVal.str(), admin);
 
 324         WriteSuccessChange(login, admin, name, "******", "******", msg, store);
 
 328         WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store);
 
 330     USER_PROPERTY<varT>::Set(val);
 
 335     WriteAccessDenied(login, admin, name);
 
 340 //-------------------------------------------------------------------------
 
 341 template <typename varT>
 
 343 void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const std::string & login,
 
 345                                                    const std::string & parameter)
 
 347 stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.",
 
 348           admin->GetLogStr().c_str(), login.c_str(), parameter.c_str());
 
 350 //-------------------------------------------------------------------------
 
 351 template <typename varT>
 
 353 void USER_PROPERTY_LOGGED<varT>::WriteSuccessChange(const std::string & login,
 
 355                                                     const std::string & parameter,
 
 356                                                     const std::string & oldValue,
 
 357                                                     const std::string & newValue,
 
 358                                                     const std::string & msg,
 
 361 stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s",
 
 362           admin->GetLogStr().c_str(),
 
 369 store->WriteUserChgLog(login, admin->GetLogin(), admin->GetIP(), parameter, oldValue, newValue, msg);
 
 371 //-------------------------------------------------------------------------
 
 372 template <typename varT>
 
 373 void USER_PROPERTY_LOGGED<varT>::OnChange(const std::string & login,
 
 374                                           const std::string & paramName,
 
 375                                           const std::string & oldValue,
 
 376                                           const std::string & newValue,
 
 379 std::string filePath = scriptsDir + "/OnChange";
 
 381 if (access(filePath.c_str(), X_OK) == 0)
 
 383     std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
 
 384     ScriptExec(execString.c_str());
 
 388     stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str());
 
 391 //-------------------------------------------------------------------------
 
 392 //-------------------------------------------------------------------------
 
 393 //-------------------------------------------------------------------------
 
 395 std::string USER_PROPERTIES::GetPropertyValue(const std::string & name) const
 
 397 REGISTRY::const_iterator it = properties.find(ToLower(name));
 
 398 if (it == properties.end())
 
 400 return it->second->ToString();
 
 402 //-----------------------------------------------------------------------------
 
 404 bool USER_PROPERTIES::Exists(const std::string & name) const
 
 406 return properties.find(ToLower(name)) != properties.end();
 
 408 //-------------------------------------------------------------------------
 
 409 //-------------------------------------------------------------------------
 
 410 //-------------------------------------------------------------------------
 
 411 template<typename varT>
 
 413 std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY<varT> & value)
 
 415 return stream << value.ConstData();
 
 417 //-----------------------------------------------------------------------------
 
 418 template<typename varT>
 
 420 std::string USER_PROPERTY<varT>::ToString() const
 
 422 std::ostringstream stream;
 
 426 #endif // USER_PROPERTY_H