/* $Revision: 1.44 $ $Date: 2010/09/13 05:54:43 $ $Author: faust $ */ #ifndef USER_PROPERTY_H #define USER_PROPERTY_H #include #include #include #include #include #include #include "store.h" #include "stg_logger.h" #include "admin.h" #include "settings.h" #include "notifer.h" #include "stg_logger.h" #include "stg_locker.h" #include "script_executer.h" extern const volatile time_t stgTime; //----------------------------------------------------------------------------- template class USER_PROPERTY { public: USER_PROPERTY(varT& val); virtual ~USER_PROPERTY(); void Set(const varT & rvalue); USER_PROPERTY& operator= (const varT & rvalue); USER_PROPERTY& operator-= (const varT & rvalue); const varT * operator&() const throw(); const varT& ConstData() const throw(); operator const varT&() const throw() { return value; } void AddBeforeNotifier(PROPERTY_NOTIFIER_BASE * n); void DelBeforeNotifier(PROPERTY_NOTIFIER_BASE * n); void AddAfterNotifier(PROPERTY_NOTIFIER_BASE * n); void DelAfterNotifier(PROPERTY_NOTIFIER_BASE * n); time_t ModificationTime() const throw(); void ModifyTime() throw(); private: varT & value; time_t modificationTime; set *> beforeNotifiers; set *> afterNotifiers; mutable pthread_mutex_t mutex; }; //----------------------------------------------------------------------------- template class USER_PROPERTY_LOGGED: public USER_PROPERTY { public: USER_PROPERTY_LOGGED(varT & val, const string n, bool isPassword, bool isStat, STG_LOGGER & logger, const SETTINGS * s); virtual ~USER_PROPERTY_LOGGED(); USER_PROPERTY_LOGGED * GetPointer() throw(); const varT & Get() const; const string & GetName() const; bool Set(const varT & val, const ADMIN & admin, const string & login, const STORE * store, const string & msg = ""); private: void WriteAccessDenied(const string & login, const ADMIN & admin, const string & parameter); void WriteSuccessChange(const string & login, const ADMIN & admin, const string & parameter, const string & oldValue, const string & newValue, const string & msg, const STORE * store); void OnChange(const string & login, const string & paramName, const string & oldValue, const string & newValue, const ADMIN & admin); string name; // parameter name. needed for logging bool isPassword; // is parameter password. when true, it will be logged as ******* bool isStat; // is parameter a stat data or conf data? mutable pthread_mutex_t mutex; STG_LOGGER & stgLogger; // server's logger const SETTINGS * settings; }; //----------------------------------------------------------------------------- class USER_PROPERTIES { /* В этом месте важен порядок следования приватной и открытой частей. Это связано с тем, что часть которая находится в публичной секции по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в начале идет закрытая секция * */ private: USER_STAT stat; USER_CONF conf; public: USER_PROPERTIES(const SETTINGS * settings); USER_STAT & Stat() { return stat; } USER_CONF & Conf() { return conf; } const USER_STAT & GetStat() const { return stat; } const USER_CONF & GetConf() const { return conf; } void SetStat(const USER_STAT & s) { stat = s; } void SetConf(const USER_CONF & c) { conf = c; } void SetProperties(const USER_PROPERTIES & p) { stat = p.stat; conf = p.conf; } USER_PROPERTY_LOGGED cash; USER_PROPERTY_LOGGED up; USER_PROPERTY_LOGGED down; USER_PROPERTY_LOGGED lastCashAdd; USER_PROPERTY_LOGGED passiveTime; USER_PROPERTY_LOGGED lastCashAddTime; USER_PROPERTY_LOGGED freeMb; USER_PROPERTY_LOGGED lastActivityTime; USER_PROPERTY_LOGGED password; USER_PROPERTY_LOGGED passive; USER_PROPERTY_LOGGED disabled; USER_PROPERTY_LOGGED disabledDetailStat; USER_PROPERTY_LOGGED alwaysOnline; USER_PROPERTY_LOGGED tariffName; USER_PROPERTY_LOGGED nextTariff; USER_PROPERTY_LOGGED address; USER_PROPERTY_LOGGED note; USER_PROPERTY_LOGGED group; USER_PROPERTY_LOGGED email; USER_PROPERTY_LOGGED phone; USER_PROPERTY_LOGGED realName; USER_PROPERTY_LOGGED credit; USER_PROPERTY_LOGGED creditExpire; USER_PROPERTY_LOGGED ips; USER_PROPERTY_LOGGED userdata0; USER_PROPERTY_LOGGED userdata1; USER_PROPERTY_LOGGED userdata2; USER_PROPERTY_LOGGED userdata3; USER_PROPERTY_LOGGED userdata4; USER_PROPERTY_LOGGED userdata5; USER_PROPERTY_LOGGED userdata6; USER_PROPERTY_LOGGED userdata7; USER_PROPERTY_LOGGED userdata8; USER_PROPERTY_LOGGED userdata9; }; //============================================================================= //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template USER_PROPERTY::USER_PROPERTY(varT& val) : value(val) { pthread_mutex_init(&mutex, NULL); modificationTime = stgTime; } //----------------------------------------------------------------------------- template USER_PROPERTY::~USER_PROPERTY() { } //----------------------------------------------------------------------------- template void USER_PROPERTY::ModifyTime() throw() { modificationTime = stgTime; } //----------------------------------------------------------------------------- template void USER_PROPERTY::Set(const varT & rvalue) { STG_LOCKER locker(&mutex, __FILE__, __LINE__); typename set *>::iterator ni; varT oldVal = value; ni = beforeNotifiers.begin(); while (ni != beforeNotifiers.end()) (*ni++)->Notify(oldVal, rvalue); value = rvalue; modificationTime = stgTime; ni = afterNotifiers.begin(); while (ni != afterNotifiers.end()) (*ni++)->Notify(oldVal, rvalue); } //----------------------------------------------------------------------------- template USER_PROPERTY& USER_PROPERTY::operator= (const varT & newValue) { Set(newValue); return *this; } //----------------------------------------------------------------------------- template USER_PROPERTY& USER_PROPERTY::operator-= (const varT & delta) { varT newValue = ConstData() - delta; Set(newValue); return *this; } //----------------------------------------------------------------------------- template const varT * USER_PROPERTY::operator&() const throw() { return &value; } //----------------------------------------------------------------------------- template const varT& USER_PROPERTY::ConstData() const throw() { return value; } //----------------------------------------------------------------------------- template void USER_PROPERTY::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) { STG_LOCKER locker(&mutex, __FILE__, __LINE__); beforeNotifiers.insert(n); } //----------------------------------------------------------------------------- template void USER_PROPERTY::DelBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) { STG_LOCKER locker(&mutex, __FILE__, __LINE__); beforeNotifiers.erase(n); } //----------------------------------------------------------------------------- template void USER_PROPERTY::AddAfterNotifier(PROPERTY_NOTIFIER_BASE * n) { STG_LOCKER locker(&mutex, __FILE__, __LINE__); afterNotifiers.insert(n); } //----------------------------------------------------------------------------- template void USER_PROPERTY::DelAfterNotifier(PROPERTY_NOTIFIER_BASE * n) { STG_LOCKER locker(&mutex, __FILE__, __LINE__); afterNotifiers.erase(n); } //----------------------------------------------------------------------------- template time_t USER_PROPERTY::ModificationTime() const throw() { return modificationTime; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template USER_PROPERTY_LOGGED::USER_PROPERTY_LOGGED(varT& val, string n, bool isPass, bool isSt, STG_LOGGER & logger, const SETTINGS * s) : USER_PROPERTY(val), stgLogger(logger) { pthread_mutex_init(&mutex, NULL); STG_LOCKER locker(&mutex, __FILE__, __LINE__); isPassword = isPass; isStat = isSt; name = n; settings = s; } //----------------------------------------------------------------------------- template USER_PROPERTY_LOGGED::~USER_PROPERTY_LOGGED() { } //----------------------------------------------------------------------------- template USER_PROPERTY_LOGGED * USER_PROPERTY_LOGGED::GetPointer() throw() { return this; } //----------------------------------------------------------------------------- template const varT & USER_PROPERTY_LOGGED::Get() const { return USER_PROPERTY::ConstData(); }; //------------------------------------------------------------------------- template const string & USER_PROPERTY_LOGGED::GetName() const { return name; }; //------------------------------------------------------------------------- template bool USER_PROPERTY_LOGGED::Set(const varT & val, const ADMIN & admin, const string & login, const STORE * store, const string & msg) { STG_LOCKER locker(&mutex, __FILE__, __LINE__); //cout << "USER_PROPERTY_LOGGED " << val << endl; //value = val; //modificationTime = stgTime; const PRIV * priv = admin.GetPriv(); string adm_login = admin.GetLogin(); string adm_ip = admin.GetIPStr(); if ((priv->userConf && !isStat) || (priv->userStat && isStat) || (priv->userPasswd && isPassword) || (priv->userCash && name == "cash")) { stringstream oldVal; stringstream newVal; oldVal.flags(oldVal.flags() | ios::fixed); newVal.flags(newVal.flags() | ios::fixed); oldVal << USER_PROPERTY::ConstData(); newVal << val; OnChange(login, name, oldVal.str(), newVal.str(), admin); if (isPassword) { WriteSuccessChange(login, admin, name, "******", "******", msg, store); } else { WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store); } USER_PROPERTY::Set(val); return true; } else { WriteAccessDenied(login, admin, name); return false; } return true; } //------------------------------------------------------------------------- template void USER_PROPERTY_LOGGED::WriteAccessDenied(const string & login, const ADMIN & admin, const string & parameter) { stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.", admin.GetLogStr().c_str(), login.c_str(), parameter.c_str()); } //------------------------------------------------------------------------- template void USER_PROPERTY_LOGGED::WriteSuccessChange(const string & login, const ADMIN & admin, const string & parameter, const string & oldValue, const string & newValue, const string & msg, const STORE * store) { stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s", admin.GetLogStr().c_str(), login.c_str(), parameter.c_str(), oldValue.c_str(), newValue.c_str(), msg.c_str()); store->WriteUserChgLog(login, admin.GetLogin(), admin.GetIP(), parameter, oldValue, newValue, msg); } //------------------------------------------------------------------------- template void USER_PROPERTY_LOGGED::OnChange(const string & login, const string & paramName, const string & oldValue, const string & newValue, const ADMIN & admin) { string str1; str1 = settings->GetConfDir() + "/OnChange"; if (access(str1.c_str(), X_OK) == 0) { string str2("\"" + str1 + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.GetLogin() + "\" \"" + admin.GetIPStr() + "\""); ScriptExec(str2); } else { stgLogger("Script OnChange cannot be executed. File %s not found.", str1.c_str()); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- /*template stringstream & operator<< (stringstream & s, const USER_PROPERTY & v) { s << v.ConstData(); return s; }*/ //----------------------------------------------------------------------------- template ostream & operator<< (ostream & stream, const USER_PROPERTY & value) { return stream << value.ConstData(); } //----------------------------------------------------------------------------- #endif // USER_PROPERTY_H