X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/fe9860ffc1555d5bf5a3f2132d9d073b5da85226..b2b89723a2427bba8290bd6967a1ab39cbb630be:/include/stg/user_property.h diff --git a/include/stg/user_property.h b/include/stg/user_property.h index fbd6aa46..d73a636b 100644 --- a/include/stg/user_property.h +++ b/include/stg/user_property.h @@ -1,386 +1,374 @@ -/* -$Revision: 1.44 $ -$Date: 2010/09/13 05:54:43 $ -$Author: faust $ -*/ - -#ifndef USER_PROPERTY_H -#define USER_PROPERTY_H - -#include // access +#pragma once + +#include "stg/user_conf.h" +#include "stg/user_ips.h" +#include "stg/store.h" +#include "stg/admin.h" +#include "stg/subscriptions.h" +#include "stg/admin_conf.h" +#include "stg/logger.h" +#include "stg/locker.h" +#include "stg/settings.h" +#include "stg/scriptexecuter.h" +#include "stg/common.h" #include #include #include +#include #include #include +#include -#include "stg/logger.h" -#include "stg/locker.h" -#include "stg/scriptexecuter.h" - -#include "store.h" -#include "admin.h" -#include "notifer.h" -#include "noncopyable.h" - -extern const volatile time_t stgTime; +#include // access +namespace STG +{ //----------------------------------------------------------------------------- -template -class USER_PROPERTY { -public: - USER_PROPERTY(varT & val); - virtual ~USER_PROPERTY(); - - void Set(const varT & rvalue); +struct UserPropertyBase +{ + virtual ~UserPropertyBase() = default; + virtual std::string ToString() const = 0; +}; +//----------------------------------------------------------------------------- +using Registry = std::map; +//----------------------------------------------------------------------------- +template +class UserProperty : public UserPropertyBase +{ + public: + explicit UserProperty(T& val); - USER_PROPERTY & operator= (const varT & rvalue); + void Set(const T& rhs); + T get() const { return value; } - const varT * operator&() const throw() { return &value; } - const varT & ConstData() const throw() { return value; } + UserProperty& operator=(const T& rhs); - operator const varT&() const throw() { return value; } + const T* operator&() const noexcept { return &value; } + const T& ConstData() const noexcept { return value; } - void AddBeforeNotifier(PROPERTY_NOTIFIER_BASE * n); - void DelBeforeNotifier(PROPERTY_NOTIFIER_BASE * n); + operator const T&() const noexcept { return value; } - void AddAfterNotifier(PROPERTY_NOTIFIER_BASE * n); - void DelAfterNotifier(PROPERTY_NOTIFIER_BASE * n); + template + auto beforeChange(F&& f) { return m_beforeCallbacks.add(std::forward(f)); } + template + auto afterChange(F&& f) { return m_afterCallbacks.add(std::forward(f)); } - time_t ModificationTime() const throw() { return modificationTime; } - void ModifyTime() throw(); + time_t ModificationTime() const noexcept { return modificationTime; } + void ModifyTime() noexcept; -private: - varT & value; - time_t modificationTime; - std::set *> beforeNotifiers; - std::set *> afterNotifiers; - pthread_mutex_t mutex; + std::string ToString() const override; + private: + T& value; + time_t modificationTime; + Subscriptions m_beforeCallbacks; + Subscriptions m_afterCallbacks; + std::mutex mutex; }; //----------------------------------------------------------------------------- -template -class USER_PROPERTY_LOGGED: public USER_PROPERTY { -public: - USER_PROPERTY_LOGGED(varT & val, - const std::string & n, - bool isPassword, - bool isStat, - STG_LOGGER & logger, - const std::string & sd); - virtual ~USER_PROPERTY_LOGGED() {} - - USER_PROPERTY_LOGGED * GetPointer() throw() { return this; } - const varT & Get() const { return USER_PROPERTY::ConstData(); } - const std::string & GetName() const { return name; } - bool Set(const varT & val, - const ADMIN * admin, - const std::string & login, - const STORE * store, - const std::string & msg = ""); -private: - void WriteAccessDenied(const std::string & login, - const ADMIN * admin, - const std::string & parameter); - - void WriteSuccessChange(const std::string & login, - const ADMIN * admin, - const std::string & parameter, - const std::string & oldValue, - const std::string & newValue, - const std::string & msg, - const STORE * store); - - void OnChange(const std::string & login, - const std::string & paramName, - const std::string & oldValue, - const std::string & newValue, - const ADMIN * admin); - - STG_LOGGER & stgLogger; - bool isPassword; - bool isStat; - std::string name; - const std::string scriptsDir; +template +class UserPropertyLogged: public UserProperty +{ + public: + UserPropertyLogged(T& val, + const std::string& n, + bool isPassword, + bool isStat, + const Settings& s, + Registry& properties); + + UserPropertyLogged* GetPointer() noexcept { return this; } + const UserPropertyLogged* GetPointer() const noexcept { return this; } + const T& Get() const { return UserProperty::ConstData(); } + const std::string& GetName() const { return name; } + bool Set(const T& val, + const Admin& admin, + const std::string& login, + const Store& store, + const std::string& msg = ""); + private: + void WriteAccessDenied(const std::string& login, + const Admin& admin, + const std::string& parameter); + + void WriteSuccessChange(const std::string& login, + const Admin& admin, + const std::string& parameter, + const std::string& oldValue, + const std::string& newValue, + const std::string& msg, + const Store& store); + + void OnChange(const std::string& login, + const std::string& paramName, + const std::string& oldValue, + const std::string& newValue, + const Admin& admin); + + Logger& stgLogger; + bool isPassword; + bool isStat; + std::string name; + const Settings& settings; }; //----------------------------------------------------------------------------- -class USER_PROPERTIES : private NONCOPYABLE { -/* - В этом месте важен порядок следования приватной и открытой частей. - Это связано с тем, что часть которая находится в публичной секции - по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно - чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в - начале идет закрытая секция - * */ - -private: - USER_STAT stat; - USER_CONF conf; - -public: - USER_PROPERTIES(const std::string & sd); - - 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; +class UserProperties +{ + /* + В этом месте важен порядок следования приватной и открытой частей. + Это связано с тем, что часть которая находится в публичной секции + по сути является завуалированной ссылкой на закрытую часть. Т.о. нам нужно + чтобы конструкторы из закрытой части вызвались раньше открытой. Поэтомому в + начале идет закрытая секция + * */ + + private: + UserStat stat; + UserConf conf; + + Registry properties; + public: + explicit UserProperties(const Settings& s); + + UserStat& Stat() { return stat; } + UserConf& Conf() { return conf; } + const UserStat& GetStat() const { return stat; } + const UserConf& GetConf() const { return conf; } + void SetStat(const UserStat& s) { stat = s; } + void SetConf(const UserConf& c) { conf = c; } + + void SetProperties(const UserProperties& p) { stat = p.stat; conf = p.conf; } + + std::string GetPropertyValue(const std::string & name) const; + bool Exists(const std::string & name) const; + + UserPropertyLogged cash; + UserPropertyLogged up; + UserPropertyLogged down; + UserPropertyLogged lastCashAdd; + UserPropertyLogged passiveTime; + UserPropertyLogged lastCashAddTime; + UserPropertyLogged freeMb; + UserPropertyLogged lastActivityTime; + + UserPropertyLogged password; + UserPropertyLogged passive; + UserPropertyLogged disabled; + UserPropertyLogged disabledDetailStat; + UserPropertyLogged alwaysOnline; + UserPropertyLogged tariffName; + UserPropertyLogged nextTariff; + UserPropertyLogged address; + UserPropertyLogged note; + UserPropertyLogged group; + UserPropertyLogged email; + UserPropertyLogged phone; + UserPropertyLogged realName; + UserPropertyLogged credit; + UserPropertyLogged creditExpire; + UserPropertyLogged ips; + UserPropertyLogged userdata0; + UserPropertyLogged userdata1; + UserPropertyLogged userdata2; + UserPropertyLogged userdata3; + UserPropertyLogged userdata4; + UserPropertyLogged userdata5; + UserPropertyLogged userdata6; + UserPropertyLogged userdata7; + UserPropertyLogged userdata8; + UserPropertyLogged userdata9; }; //============================================================================= //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -template +template inline -USER_PROPERTY::USER_PROPERTY(varT & val) +UserProperty::UserProperty(T& val) : value(val), - modificationTime(stgTime), - beforeNotifiers(), - afterNotifiers(), - mutex() + modificationTime(time(NULL)) { -pthread_mutex_init(&mutex, NULL); } //----------------------------------------------------------------------------- -template +template inline -USER_PROPERTY::~USER_PROPERTY() +void UserProperty::ModifyTime() noexcept { -pthread_mutex_destroy(&mutex); + modificationTime = time(NULL); } //----------------------------------------------------------------------------- -template +template inline -void USER_PROPERTY::ModifyTime() throw() +void UserProperty::Set(const T& rhs) { -modificationTime = stgTime; -} -//----------------------------------------------------------------------------- -template -inline -void USER_PROPERTY::Set(const varT & rvalue) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); + std::lock_guard lock(mutex); -typename std::set *>::iterator ni; + T oldVal = value; -varT oldVal = value; + m_beforeCallbacks.notify(oldVal, rhs); -ni = beforeNotifiers.begin(); -while (ni != beforeNotifiers.end()) - (*ni++)->Notify(oldVal, rvalue); + value = rhs; + modificationTime = time(NULL); -value = rvalue; -modificationTime = stgTime; - -ni = afterNotifiers.begin(); -while (ni != afterNotifiers.end()) - (*ni++)->Notify(oldVal, rvalue); -} -//----------------------------------------------------------------------------- -template -inline -USER_PROPERTY & USER_PROPERTY::operator= (const varT & newValue) -{ -Set(newValue); -return *this; + m_afterCallbacks.notify(oldVal, rhs); } //----------------------------------------------------------------------------- -template +template inline -void USER_PROPERTY::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +UserProperty& UserProperty::operator=(const T& newValue) { -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -beforeNotifiers.insert(n); + Set(newValue); + return *this; } //----------------------------------------------------------------------------- -template -inline -void USER_PROPERTY::DelBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -beforeNotifiers.erase(n); -} //----------------------------------------------------------------------------- -template -inline -void USER_PROPERTY::AddAfterNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -afterNotifiers.insert(n); -} //----------------------------------------------------------------------------- -template +template inline -void USER_PROPERTY::DelAfterNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -afterNotifiers.erase(n); -} -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template -inline -USER_PROPERTY_LOGGED::USER_PROPERTY_LOGGED(varT & val, - const std::string & n, - bool isPass, - bool isSt, - STG_LOGGER & logger, - const std::string & sd) - - : USER_PROPERTY(val), - stgLogger(logger), +UserPropertyLogged::UserPropertyLogged(T& val, + const std::string& n, + bool isPass, + bool isSt, + const Settings& s, + Registry& properties) + + : UserProperty(val), + stgLogger(Logger::get()), isPassword(isPass), isStat(isSt), name(n), - scriptsDir(sd) + settings(s) { + properties.insert(std::make_pair(ToLower(name), this)); } //------------------------------------------------------------------------- -template -bool USER_PROPERTY_LOGGED::Set(const varT & val, - const ADMIN * admin, - const std::string & login, - const STORE * store, - const std::string & msg) +template +inline +bool UserPropertyLogged::Set(const T& val, + const Admin& admin, + const std::string& login, + const Store& store, + const std::string& msg) { -const PRIV * priv = admin->GetPriv(); + const auto& priv = admin.priv(); -if ((priv->userConf && !isStat) || - (priv->userStat && isStat) || - (priv->userPasswd && isPassword) || - (priv->userCash && name == "cash")) + if ((priv.userConf && !isStat) || + (priv.userStat && isStat) || + (priv.userPasswd && isPassword) || + (priv.userCash && name == "cash")) { - std::stringstream oldVal; - std::stringstream newVal; + std::stringstream oldVal; + std::stringstream newVal; - oldVal.flags(oldVal.flags() | ios::fixed); - newVal.flags(newVal.flags() | ios::fixed); + oldVal.flags(oldVal.flags() | std::ios::fixed); + newVal.flags(newVal.flags() | std::ios::fixed); - oldVal << USER_PROPERTY::ConstData(); - newVal << val; + oldVal << UserProperty::ConstData(); + newVal << val; - OnChange(login, name, oldVal.str(), newVal.str(), admin); + 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; + if (isPassword) + WriteSuccessChange(login, admin, name, "******", "******", msg, store); + else + WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store); + + UserProperty::Set(val); + return true; } -else - { + WriteAccessDenied(login, admin, name); return false; - } -return true; } //------------------------------------------------------------------------- -template +template inline -void USER_PROPERTY_LOGGED::WriteAccessDenied(const std::string & login, - const ADMIN * admin, - const std::string & parameter) +void UserPropertyLogged::WriteAccessDenied(const std::string& login, + const Admin& admin, + const std::string& parameter) { -stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.", - admin->GetLogStr().c_str(), login.c_str(), parameter.c_str()); + stgLogger("%s Change user \'%s.\' Parameter \'%s\'. Access denied.", + admin.logStr().c_str(), login.c_str(), parameter.c_str()); } //------------------------------------------------------------------------- -template +template inline -void USER_PROPERTY_LOGGED::WriteSuccessChange(const std::string & login, - const ADMIN * admin, - const std::string & parameter, - const std::string & oldValue, - const std::string & newValue, - const std::string & msg, - const STORE * store) +void UserPropertyLogged::WriteSuccessChange(const std::string& login, + const Admin& admin, + const std::string& parameter, + const std::string& oldValue, + const std::string& newValue, + const std::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); + stgLogger("%s User \'%s\': \'%s\' parameter changed from \'%s\' to \'%s\'. %s", + admin.logStr().c_str(), + login.c_str(), + parameter.c_str(), + oldValue.c_str(), + newValue.c_str(), + msg.c_str()); + + for (size_t i = 0; i < settings.GetFilterParamsLog().size(); ++i) + if (settings.GetFilterParamsLog()[i] == "*" || strcasecmp(settings.GetFilterParamsLog()[i].c_str(), parameter.c_str()) == 0) + { + store.WriteUserChgLog(login, admin.login(), admin.IP(), parameter, oldValue, newValue, msg); + return; + } } //------------------------------------------------------------------------- -template -void USER_PROPERTY_LOGGED::OnChange(const std::string & login, - const std::string & paramName, - const std::string & oldValue, - const std::string & newValue, - const ADMIN * admin) +template +void UserPropertyLogged::OnChange(const std::string& login, + const std::string& paramName, + const std::string& oldValue, + const std::string& newValue, + const Admin& admin) { -std::string filePath = scriptsDir + "/OnChange"; + const auto filePath = settings.GetScriptsDir() + "/OnChange"; -if (access(filePath.c_str(), X_OK) == 0) + if (access(filePath.c_str(), X_OK) == 0) { - std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\""); - ScriptExec(execString.c_str()); - } -else - { - stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str()); + const auto execString = "\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin.login() + "\" \"" + admin.IPStr() + "\""; + ScriptExec(execString.c_str()); } + else + stgLogger("Script OnChange cannot be executed. File %s not found.", filePath.c_str()); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- -template inline -ostream & operator<< (ostream & stream, const USER_PROPERTY & value) +std::string UserProperties::GetPropertyValue(const std::string& name) const { -return stream << value.ConstData(); + const auto it = properties.find(ToLower(name)); + if (it == properties.end()) + return ""; + return it->second->ToString(); } //----------------------------------------------------------------------------- +inline +bool UserProperties::Exists(const std::string& name) const +{ + return properties.find(ToLower(name)) != properties.end(); +} +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +template +inline +std::ostream& operator<<(std::ostream& stream, const UserProperty& value) +{ + return stream << value.ConstData(); +} +//----------------------------------------------------------------------------- +template +inline +std::string UserProperty::ToString() const +{ + std::ostringstream stream; + stream << value; + return stream.str(); +} -#endif // USER_PROPERTY_H +}