X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/64b687f8ec36a103865044613cb0f42f98aeda3a..9e321f1d39023f4ba86cd354eda0c347ac15fca2:/include/stg/user_property.h?ds=inline diff --git a/include/stg/user_property.h b/include/stg/user_property.h index 1716296a..3400abd0 100644 --- a/include/stg/user_property.h +++ b/include/stg/user_property.h @@ -1,393 +1,373 @@ -/* -$Revision: 1.44 $ -$Date: 2010/09/13 05:54:43 $ -$Author: faust $ -*/ - -#ifndef USER_PROPERTY_H -#define USER_PROPERTY_H - -#include <unistd.h> // 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 <ctime> #include <string> #include <set> +#include <map> #include <sstream> #include <iostream> +#include <mutex> -#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 volatile time_t stgTime; +#include <unistd.h> // access +namespace STG +{ //----------------------------------------------------------------------------- -template<typename varT> -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<std::string, UserPropertyBase*>; +//----------------------------------------------------------------------------- +template<typename T> +class UserProperty : public UserPropertyBase +{ + public: + explicit UserProperty(T& val); - USER_PROPERTY<varT> & 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<T>& 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<varT> * n); - void DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n); + operator const T&() const noexcept { return value; } - void AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n); - void DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n); + template <typename F> + auto beforeChange(F&& f) { return m_beforeCallbacks.add(std::forward<F>(f)); } + template <typename F> + auto afterChange(F&& f) { return m_afterCallbacks.add(std::forward<F>(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<PROPERTY_NOTIFIER_BASE<varT> *> beforeNotifiers; - std::set<PROPERTY_NOTIFIER_BASE<varT> *> afterNotifiers; - pthread_mutex_t mutex; + std::string ToString() const override; + private: + T& value; + time_t modificationTime; + Subscriptions<T, T> m_beforeCallbacks; + Subscriptions<T, T> m_afterCallbacks; + std::mutex mutex; }; //----------------------------------------------------------------------------- -template<typename varT> -class USER_PROPERTY_LOGGED: public USER_PROPERTY<varT> { -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<varT> * GetPointer() throw() { return this; } - const varT & Get() const { return USER_PROPERTY<varT>::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<typename T> +class UserPropertyLogged: public UserProperty<T> +{ + public: + UserPropertyLogged(T& val, + const std::string& n, + bool isPassword, + bool isStat, + const Settings& s, + Registry& properties); + + UserPropertyLogged<T>* GetPointer() noexcept { return this; } + const UserPropertyLogged<T>* GetPointer() const noexcept { return this; } + const T& Get() const { return UserProperty<T>::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<double> cash; - USER_PROPERTY_LOGGED<DIR_TRAFF> up; - USER_PROPERTY_LOGGED<DIR_TRAFF> down; - USER_PROPERTY_LOGGED<double> lastCashAdd; - USER_PROPERTY_LOGGED<time_t> passiveTime; - USER_PROPERTY_LOGGED<time_t> lastCashAddTime; - USER_PROPERTY_LOGGED<double> freeMb; - USER_PROPERTY_LOGGED<time_t> lastActivityTime; - - USER_PROPERTY_LOGGED<std::string> password; - USER_PROPERTY_LOGGED<int> passive; - USER_PROPERTY_LOGGED<int> disabled; - USER_PROPERTY_LOGGED<int> disabledDetailStat; - USER_PROPERTY_LOGGED<int> alwaysOnline; - USER_PROPERTY_LOGGED<std::string> tariffName; - USER_PROPERTY_LOGGED<std::string> nextTariff; - USER_PROPERTY_LOGGED<std::string> address; - USER_PROPERTY_LOGGED<std::string> note; - USER_PROPERTY_LOGGED<std::string> group; - USER_PROPERTY_LOGGED<std::string> email; - USER_PROPERTY_LOGGED<std::string> phone; - USER_PROPERTY_LOGGED<std::string> realName; - USER_PROPERTY_LOGGED<double> credit; - USER_PROPERTY_LOGGED<time_t> creditExpire; - USER_PROPERTY_LOGGED<USER_IPS> ips; - USER_PROPERTY_LOGGED<std::string> userdata0; - USER_PROPERTY_LOGGED<std::string> userdata1; - USER_PROPERTY_LOGGED<std::string> userdata2; - USER_PROPERTY_LOGGED<std::string> userdata3; - USER_PROPERTY_LOGGED<std::string> userdata4; - USER_PROPERTY_LOGGED<std::string> userdata5; - USER_PROPERTY_LOGGED<std::string> userdata6; - USER_PROPERTY_LOGGED<std::string> userdata7; - USER_PROPERTY_LOGGED<std::string> userdata8; - USER_PROPERTY_LOGGED<std::string> 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<double> cash; + UserPropertyLogged<DirTraff> up; + UserPropertyLogged<DirTraff> down; + UserPropertyLogged<double> lastCashAdd; + UserPropertyLogged<time_t> passiveTime; + UserPropertyLogged<time_t> lastCashAddTime; + UserPropertyLogged<double> freeMb; + UserPropertyLogged<time_t> lastActivityTime; + + UserPropertyLogged<std::string> password; + UserPropertyLogged<int> passive; + UserPropertyLogged<int> disabled; + UserPropertyLogged<int> disabledDetailStat; + UserPropertyLogged<int> alwaysOnline; + UserPropertyLogged<std::string> tariffName; + UserPropertyLogged<std::string> nextTariff; + UserPropertyLogged<std::string> address; + UserPropertyLogged<std::string> note; + UserPropertyLogged<std::string> group; + UserPropertyLogged<std::string> email; + UserPropertyLogged<std::string> phone; + UserPropertyLogged<std::string> realName; + UserPropertyLogged<double> credit; + UserPropertyLogged<time_t> creditExpire; + UserPropertyLogged<UserIPs> ips; + UserPropertyLogged<std::string> userdata0; + UserPropertyLogged<std::string> userdata1; + UserPropertyLogged<std::string> userdata2; + UserPropertyLogged<std::string> userdata3; + UserPropertyLogged<std::string> userdata4; + UserPropertyLogged<std::string> userdata5; + UserPropertyLogged<std::string> userdata6; + UserPropertyLogged<std::string> userdata7; + UserPropertyLogged<std::string> userdata8; + UserPropertyLogged<std::string> userdata9; }; //============================================================================= //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -template <typename varT> +template <typename T> inline -USER_PROPERTY<varT>::USER_PROPERTY(varT & val) +UserProperty<T>::UserProperty(T& val) : value(val), - modificationTime(stgTime), - beforeNotifiers(), - afterNotifiers(), - mutex() + modificationTime(time(NULL)) { -pthread_mutex_init(&mutex, NULL); } //----------------------------------------------------------------------------- -template <typename varT> +template <typename T> inline -USER_PROPERTY<varT>::~USER_PROPERTY() +void UserProperty<T>::ModifyTime() noexcept { -pthread_mutex_destroy(&mutex); + modificationTime = time(NULL); } //----------------------------------------------------------------------------- -template <typename varT> +template <typename T> inline -void USER_PROPERTY<varT>::ModifyTime() throw() +void UserProperty<T>::Set(const T& rhs) { -modificationTime = stgTime; -} -//----------------------------------------------------------------------------- -template <typename varT> -inline -void USER_PROPERTY<varT>::Set(const varT & rvalue) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); - -typename std::set<PROPERTY_NOTIFIER_BASE<varT> *>::iterator ni; + std::lock_guard<std::mutex> 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 <typename varT> -inline -USER_PROPERTY<varT> & USER_PROPERTY<varT>::operator= (const varT & newValue) -{ -Set(newValue); -return *this; -} -//----------------------------------------------------------------------------- -template <typename varT> -inline -void USER_PROPERTY<varT>::AddBeforeNotifier(PROPERTY_NOTIFIER_BASE<varT> * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -beforeNotifiers.insert(n); -} -//----------------------------------------------------------------------------- -template <typename varT> -inline -void USER_PROPERTY<varT>::DelBeforeNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -beforeNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n)); + m_afterCallbacks.notify(oldVal, rhs); } //----------------------------------------------------------------------------- -template <typename varT> +template <typename T> inline -void USER_PROPERTY<varT>::AddAfterNotifier(PROPERTY_NOTIFIER_BASE<varT> * n) +UserProperty<T>& UserProperty<T>::operator=(const T& newValue) { -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -afterNotifiers.insert(n); + Set(newValue); + return *this; } //----------------------------------------------------------------------------- -template <typename varT> -inline -void USER_PROPERTY<varT>::DelAfterNotifier(const PROPERTY_NOTIFIER_BASE<varT> * n) -{ -STG_LOCKER locker(&mutex, __FILE__, __LINE__); -afterNotifiers.erase(const_cast<PROPERTY_NOTIFIER_BASE<varT> *>(n)); -} //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -template <typename varT> +template <typename T> inline -USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val, - const std::string & n, - bool isPass, - bool isSt, - STG_LOGGER & logger, - const std::string & sd) - - : USER_PROPERTY<varT>(val), - stgLogger(logger), +UserPropertyLogged<T>::UserPropertyLogged(T& val, + const std::string& n, + bool isPass, + bool isSt, + const Settings& s, + Registry& properties) + + : UserProperty<T>(val), + stgLogger(Logger::get()), isPassword(isPass), isStat(isSt), name(n), - scriptsDir(sd) + settings(s) { + properties.insert(std::make_pair(ToLower(name), this)); } //------------------------------------------------------------------------- -template <typename varT> -bool USER_PROPERTY_LOGGED<varT>::Set(const varT & val, - const ADMIN * admin, - const std::string & login, - const STORE * store, - const std::string & msg) +template <typename T> +inline +bool UserPropertyLogged<T>::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<varT>::ConstData(); - newVal << val; + oldVal << UserProperty<T>::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<varT>::Set(val); - return true; + if (isPassword) + WriteSuccessChange(login, admin, name, "******", "******", msg, store); + else + WriteSuccessChange(login, admin, name, oldVal.str(), newVal.str(), msg, store); + + UserProperty<T>::Set(val); + return true; } -else - { + WriteAccessDenied(login, admin, name); return false; - } -return true; } //------------------------------------------------------------------------- -template <typename varT> +template <typename T> inline -void USER_PROPERTY_LOGGED<varT>::WriteAccessDenied(const std::string & login, - const ADMIN * admin, - const std::string & parameter) +void UserPropertyLogged<T>::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 <typename varT> +template <typename T> inline -void USER_PROPERTY_LOGGED<varT>::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<T>::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 <typename varT> -void USER_PROPERTY_LOGGED<varT>::OnChange(const std::string & login, - const std::string & paramName, - const std::string & oldValue, - const std::string & newValue, - const ADMIN * admin) +template <typename T> +void UserPropertyLogged<T>::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()); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- -template<typename varT> inline -std::ostream & operator<< (std::ostream & stream, const USER_PROPERTY<varT> & 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(); } //----------------------------------------------------------------------------- -template<typename varT> -std::string USER_PROPERTY<varT>::ToString() const +inline +bool UserProperties::Exists(const std::string& name) const { -std::stringstream stream; -stream << value; -return stream.str(); + return properties.find(ToLower(name)) != properties.end(); +} +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +template<typename T> +inline +std::ostream& operator<<(std::ostream& stream, const UserProperty<T>& value) +{ + return stream << value.ConstData(); +} +//----------------------------------------------------------------------------- +template<typename T> +inline +std::string UserProperty<T>::ToString() const +{ + std::ostringstream stream; + stream << value; + return stream.str(); +} + } -#endif // USER_PROPERTY_H