X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/b4e3971acd4927a3409a5a5433a326e6462ceeae..ebd170a764ab9660adee464588cda1801c7986b4:/include/stg/user_property.h?ds=inline diff --git a/include/stg/user_property.h b/include/stg/user_property.h index 474eba6a..3400abd0 100644 --- a/include/stg/user_property.h +++ b/include/stg/user_property.h @@ -1,416 +1,373 @@ -/* -$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/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" +#include // access -extern volatile time_t stgTime; +namespace STG +{ //----------------------------------------------------------------------------- -//template -class USER_PROPERTY_BASE { -public: +struct UserPropertyBase +{ + virtual ~UserPropertyBase() = default; virtual std::string ToString() const = 0; }; //----------------------------------------------------------------------------- -template -class USER_PROPERTY : USER_PROPERTY_BASE { -public: - USER_PROPERTY(varT & val); - virtual ~USER_PROPERTY(); - - void Set(const varT & rvalue); +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(const PROPERTY_NOTIFIER_BASE * n); + operator const T&() const noexcept { return value; } - void AddAfterNotifier(PROPERTY_NOTIFIER_BASE * n); - void DelAfterNotifier(const 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; - std::string ToString() const; -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, - std::map & properties); - 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; - - std::map & properties; -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; } - - std::string GetPropertyValue(const std::string & name) const; - - 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__); - -typename std::set *>::iterator ni; + std::lock_guard lock(mutex); -varT oldVal = value; + T oldVal = value; -ni = beforeNotifiers.begin(); -while (ni != beforeNotifiers.end()) - (*ni++)->Notify(oldVal, rvalue); + m_beforeCallbacks.notify(oldVal, rhs); -value = rvalue; -modificationTime = stgTime; + value = rhs; + modificationTime = time(NULL); -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; -} -//----------------------------------------------------------------------------- -template -inline -void USER_PROPERTY::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -beforeNotifiers.insert(n); + m_afterCallbacks.notify(oldVal, rhs); } //----------------------------------------------------------------------------- -template +template inline -void USER_PROPERTY::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE * n) +UserProperty& UserProperty::operator=(const T& newValue) { -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -beforeNotifiers.erase(const_cast *>(n)); -} -//----------------------------------------------------------------------------- -template -inline -void USER_PROPERTY::AddAfterNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -afterNotifiers.insert(n); -} -//----------------------------------------------------------------------------- -template -inline -void USER_PROPERTY::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -afterNotifiers.erase(const_cast *>(n)); + Set(newValue); + return *this; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -template +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, - std::map & properties) - - : 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(name, this)); + 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() | std::ios::fixed); - newVal.flags(newVal.flags() | std::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) - { - std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\""); - ScriptExec(execString.c_str()); - } -else + if (access(filePath.c_str(), X_OK) == 0) { - 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()); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- inline -std::string USER_PROPERTIES::GetPropertyValue(const std::string & name) const +std::string UserProperties::GetPropertyValue(const std::string& name) const { -std::map::iterator it = properties.find(name); -if (it == properties.end()) - return ""; -return it->second->ToString(); + 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 +template inline -std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY & value) +std::ostream& operator<<(std::ostream& stream, const UserProperty& value) { -return stream << value.ConstData(); + return stream << value.ConstData(); } //----------------------------------------------------------------------------- -template +template inline -std::string USER_PROPERTY::ToString() const +std::string UserProperty::ToString() const { -std::stringstream stream; -stream << value; -return stream.str(); + std::ostringstream stream; + stream << value; + return stream.str(); +} + } -#endif // USER_PROPERTY_H