X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/6f7160dd027c8ce7e2760aa369768ba39ab80181..a622b081808494796d3679acaebbf5ee364fe9de:/projects/stargazer/user_impl.cpp?ds=sidebyside diff --git a/projects/stargazer/user_impl.cpp b/projects/stargazer/user_impl.cpp index f18dd76e..1278afa2 100644 --- a/projects/stargazer/user_impl.cpp +++ b/projects/stargazer/user_impl.cpp @@ -36,28 +36,34 @@ #include // access #include - +#include + +#include "stg/users.h" +#include "stg/common.h" +#include "stg/scriptexecuter.h" +#include "stg/tariff.h" +#include "stg/tariffs.h" +#include "stg/admin.h" #include "user_impl.h" -#include "users.h" -#include "common.h" -#include "settings.h" -#include "script_executer.h" -#include "tariff.h" -#include "tariffs.h" -#include "admin.h" +#include "settings_impl.h" +#include "stg_timer.h" +#ifdef USE_ABSTRACT_SETTINGS USER_IMPL::USER_IMPL(const SETTINGS * s, - const BASE_STORE * st, + const STORE * st, const TARIFFS * t, - const ADMIN & a, + const ADMIN * a, const USERS * u) - : users(u), - property(s), + : USER(), + users(u), + property(s->GetScriptsDir()), WriteServLog(GetStgLogger()), + lastScanMessages(0), login(), id(0), __connected(0), connected(__connected), + enabledDirs(), userIDGenerator(), __currIP(0), currIP(__currIP), @@ -66,7 +72,15 @@ USER_IMPL::USER_IMPL(const SETTINGS * s, sysAdmin(a), store(st), tariffs(t), - tariff(tariffs->GetNoTariff()), + tariff(NULL), + traffStat(), + traffStatSaved(), + settings(s), + authorizedBy(), + messages(), + deleted(false), + lastWriteStat(0), + lastWriteDetailedStat(0), cash(property.cash), up(property.up), down(property.down), @@ -101,43 +115,137 @@ USER_IMPL::USER_IMPL(const SETTINGS * s, userdata7(property.userdata7), userdata8(property.userdata8), userdata9(property.userdata9), + sessionUpload(), + sessionDownload(), passiveNotifier(this), tariffNotifier(this), cashNotifier(this), - ipNotifier(this) + ipNotifier(this), + mutex(), + errorStr() { -settings = s; - password = "*_EMPTY_PASSWORD_*"; tariffName = NO_TARIFF_NAME; -connected = 0; -tariff = tariffs->GetNoTariff(); ips = StrToIPS("*"); -deleted = false; lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); -lastWriteDeatiledStat = stgTime; +lastWriteDetailedStat = stgTime; property.tariffName.AddBeforeNotifier(&tariffNotifier); property.passive.AddBeforeNotifier(&passiveNotifier); property.cash.AddBeforeNotifier(&cashNotifier); -currIP.AddAfterNotifier(&ipNotifier); +ips.AddAfterNotifier(&ipNotifier); + +pthread_mutexattr_t attr; +pthread_mutexattr_init(&attr); +pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +pthread_mutex_init(&mutex, &attr); +} +#else +USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s, + const STORE * st, + const TARIFFS * t, + const ADMIN * a, + const USERS * u) + : USER(), + users(u), + property(s->GetScriptsDir()), + WriteServLog(GetStgLogger()), + lastScanMessages(0), + login(), + id(0), + __connected(0), + connected(__connected), + enabledDirs(), + userIDGenerator(), + __currIP(0), + currIP(__currIP), + lastIPForDisconnect(0), + pingTime(0), + sysAdmin(a), + store(st), + tariffs(t), + tariff(NULL), + traffStat(), + traffStatSaved(), + settings(s), + authorizedBy(), + messages(), + deleted(false), + lastWriteStat(0), + lastWriteDetailedStat(0), + cash(property.cash), + up(property.up), + down(property.down), + lastCashAdd(property.lastCashAdd), + passiveTime(property.passiveTime), + lastCashAddTime(property.lastCashAddTime), + freeMb(property.freeMb), + lastActivityTime(property.lastActivityTime), + password(property.password), + passive(property.passive), + disabled(property.disabled), + disabledDetailStat(property.disabledDetailStat), + alwaysOnline(property.alwaysOnline), + tariffName(property.tariffName), + nextTariff(property.nextTariff), + address(property.address), + note(property.note), + group(property.group), + email(property.email), + phone(property.phone), + realName(property.realName), + credit(property.credit), + creditExpire(property.creditExpire), + ips(property.ips), + userdata0(property.userdata0), + userdata1(property.userdata1), + userdata2(property.userdata2), + userdata3(property.userdata3), + userdata4(property.userdata4), + userdata5(property.userdata5), + userdata6(property.userdata6), + userdata7(property.userdata7), + userdata8(property.userdata8), + userdata9(property.userdata9), + sessionUpload(), + sessionDownload(), + passiveNotifier(this), + tariffNotifier(this), + cashNotifier(this), + ipNotifier(this), + mutex(), + errorStr() +{ +password = "*_EMPTY_PASSWORD_*"; +tariffName = NO_TARIFF_NAME; +ips = StrToIPS("*"); +lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); +lastWriteDetailedStat = stgTime; -lastScanMessages = 0; +property.tariffName.AddBeforeNotifier(&tariffNotifier); +property.passive.AddBeforeNotifier(&passiveNotifier); +property.cash.AddBeforeNotifier(&cashNotifier); +ips.AddAfterNotifier(&ipNotifier); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex, &attr); } +#endif //----------------------------------------------------------------------------- USER_IMPL::USER_IMPL(const USER_IMPL & u) - : users(u.users), - property(u.settings), + : USER(), + users(u.users), + property(u.settings->GetScriptsDir()), WriteServLog(GetStgLogger()), + lastScanMessages(0), login(u.login), id(u.id), - __connected(u.__connected), + __connected(0), connected(__connected), + enabledDirs(), + userIDGenerator(u.userIDGenerator), __currIP(u.__currIP), currIP(__currIP), lastIPForDisconnect(0), @@ -146,6 +254,14 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u) store(u.store), tariffs(u.tariffs), tariff(u.tariff), + traffStat(u.traffStat), + traffStatSaved(u.traffStatSaved), + settings(u.settings), + authorizedBy(), + messages(u.messages), + deleted(u.deleted), + lastWriteStat(u.lastWriteStat), + lastWriteDetailedStat(u.lastWriteDetailedStat), cash(property.cash), up(property.up), down(property.down), @@ -180,29 +296,22 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u) userdata7(property.userdata7), userdata8(property.userdata8), userdata9(property.userdata9), + sessionUpload(), + sessionDownload(), passiveNotifier(this), tariffNotifier(this), cashNotifier(this), - ipNotifier(this) + ipNotifier(this), + mutex(), + errorStr() { if (&u == this) return; -connected = 0; - -deleted = u.deleted; - -lastWriteStat = u.lastWriteStat; -lastWriteDeatiledStat = u.lastWriteDeatiledStat; - -settings = u.settings; - property.tariffName.AddBeforeNotifier(&tariffNotifier); property.passive.AddBeforeNotifier(&passiveNotifier); property.cash.AddBeforeNotifier(&cashNotifier); -currIP.AddAfterNotifier(&ipNotifier); - -lastScanMessages = 0; +ips.AddAfterNotifier(&ipNotifier); property.SetProperties(u.property); @@ -256,6 +365,9 @@ std::vector hdrsList; if (store->GetMessageHdrs(&hdrsList, login)) { printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str()); + WriteServLog("Cannot read user %s. Error reading message headers: %s.", + login.c_str(), + store->GetStrError().c_str()); return -1; } @@ -315,8 +427,6 @@ int USER_IMPL::WriteStat() STG_LOCKER lock(&mutex, __FILE__, __LINE__); USER_STAT stat(property.GetStat()); -printfd(__FILE__, "USER::WriteStat()\n"); - if (store->SaveUserStat(stat, login)) { WriteServLog("Cannot write stat for user %s.", login.c_str()); @@ -351,7 +461,7 @@ if (store->SaveMonthStat(stat, t1.tm_mon, t1.tm_year, login)) return 0; } //----------------------------------------------------------------------------- -int USER_IMPL::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth) +int USER_IMPL::Authorize(uint32_t ip, uint32_t dirs, const AUTH * auth) { STG_LOCKER lock(&mutex, __FILE__, __LINE__); /* @@ -374,12 +484,12 @@ for (int i = 0; i < DIR_NUM; i++) enabledDirs[i] = dirs & (1 << i); } -if (authorizedBy.size()) +if (!authorizedBy.empty()) { if (currIP != ip) { // We are already authorized, but with different IP address - errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip); + errorStr = "User " + login + " already authorized with IP address " + inet_ntostring(ip); return -1; } @@ -390,7 +500,7 @@ if (authorizedBy.size()) // If it's not our IP - throw an error if (u != this) { - errorStr = "IP address " + inet_ntostring(ip) + " alredy in use"; + errorStr = "IP address " + inet_ntostring(ip) + " already in use"; return -1; } } @@ -400,7 +510,7 @@ else if (users->IsIPInIndex(ip)) { // Address is already present in IP-index - errorStr = "IP address " + inet_ntostring(ip) + " alredy in use"; + errorStr = "IP address " + inet_ntostring(ip) + " already in use"; return -1; } @@ -424,7 +534,7 @@ ScanMessage(); return 0; } //----------------------------------------------------------------------------- -void USER_IMPL::Unauthorize(const BASE_AUTH * auth) +void USER_IMPL::Unauthorize(const AUTH * auth) { STG_LOCKER lock(&mutex, __FILE__, __LINE__); /* @@ -441,7 +551,7 @@ if (authorizedBy.empty()) } } //----------------------------------------------------------------------------- -bool USER_IMPL::IsAuthorizedBy(const BASE_AUTH * auth) const +bool USER_IMPL::IsAuthorizedBy(const AUTH * auth) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); // Is this user authorized by specified authorizer? @@ -458,7 +568,7 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__); if (!fakeConnect) { - string scriptOnConnect = settings->GetScriptDir() + "/OnConnect"; + string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect"; if (access(scriptOnConnect.c_str(), X_OK) == 0) { @@ -479,7 +589,7 @@ if (!fakeConnect) id, dirsStr); - ScriptExec(scriptOnConnectParams); + ScriptExec(scriptOnConnectParams.c_str()); } else { @@ -515,7 +625,7 @@ if (!lastIPForDisconnect) if (!fakeDisconnect) { - string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect"; + string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect"; if (access(scriptOnDisonnect.c_str(), X_OK) == 0) { @@ -536,7 +646,7 @@ if (!fakeDisconnect) id, dirsStr); - ScriptExec(scriptOnDisonnectParams); + ScriptExec(scriptOnDisonnectParams.c_str()); } else { @@ -627,7 +737,7 @@ if (!authorizedBy.empty()) { if (connected) { - lastActivityTime = *const_cast(&stgTime); + property.Stat().lastActivityTime = stgTime; } if (!connected && IsInetable()) { @@ -682,7 +792,7 @@ if (settings->GetFreeMbAllowInet()) return true; } -if (settings->GetShowFeeInCash()) +if (settings->GetShowFeeInCash() || tariff == NULL) { return (cash >= -credit); } @@ -708,7 +818,7 @@ void USER_IMPL::AddTraffStatU(int dir, uint32_t ip, uint32_t len) { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (!connected) +if (!connected || tariff == NULL) return; double cost = 0; @@ -800,7 +910,7 @@ void USER_IMPL::AddTraffStatD(int dir, uint32_t ip, uint32_t len) { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (!connected) +if (!connected || tariff == NULL) return; double cost = 0; @@ -907,11 +1017,35 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__); currIP.DelAfterNotifier(n); } //----------------------------------------------------------------------------- +void USER_IMPL::AddConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +connected.AddBeforeNotifier(n); +} +//----------------------------------------------------------------------------- +void USER_IMPL::DelConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +connected.DelBeforeNotifier(n); +} +//----------------------------------------------------------------------------- +void USER_IMPL::AddConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +connected.AddAfterNotifier(n); +} +//----------------------------------------------------------------------------- +void USER_IMPL::DelConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +connected.DelAfterNotifier(n); +} +//----------------------------------------------------------------------------- void USER_IMPL::OnAdd() { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd"; +string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd"; if (access(scriptOnAdd.c_str(), X_OK) == 0) { @@ -921,7 +1055,7 @@ if (access(scriptOnAdd.c_str(), X_OK) == 0) scriptOnAdd.c_str(), login.c_str()); - ScriptExec(scriptOnAddParams); + ScriptExec(scriptOnAddParams.c_str()); } else { @@ -933,7 +1067,7 @@ void USER_IMPL::OnDelete() { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -string scriptOnDel = settings->GetScriptDir() + "/OnUserDel"; +string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel"; if (access(scriptOnDel.c_str(), X_OK) == 0) { @@ -943,7 +1077,7 @@ if (access(scriptOnDel.c_str(), X_OK) == 0) scriptOnDel.c_str(), login.c_str()); - ScriptExec(scriptOnDelParams); + ScriptExec(scriptOnDelParams.c_str()); } else { @@ -980,7 +1114,7 @@ printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size()); if (ts.size() && !disabledDetailStat) { - if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login)) + if (store->WriteDetailedStat(ts, lastWriteDetailedStat, login)) { printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n"); WriteServLog("Cannot write detail stat for user %s.", login.c_str()); @@ -990,12 +1124,12 @@ if (ts.size() && !disabledDetailStat) printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n"); STG_LOCKER lock(&mutex, __FILE__, __LINE__); traffStatSaved.second.swap(ts); - traffStatSaved.first = lastWriteDeatiledStat; + traffStatSaved.first = lastWriteDetailedStat; } return -1; } } -lastWriteDeatiledStat = stgTime; +lastWriteDetailedStat = stgTime; return 0; } //----------------------------------------------------------------------------- @@ -1083,7 +1217,7 @@ if (nextTariff.ConstData() != "") else { property.tariffName.Set(nextTariff, sysAdmin, login, store); - tariff = nt; + //tariff = nt; } ResetNextTariff(); WriteConf(); @@ -1094,16 +1228,29 @@ void USER_IMPL::ProcessDayFeeSpread() { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (passive.ConstData()) +if (passive.ConstData() || tariff == NULL) return; -double f = tariff->GetFee() / DaysInCurrentMonth(); +double fee = tariff->GetFee() / DaysInCurrentMonth(); -if (f == 0.0) +if (fee == 0.0) return; double c = cash; -property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 1: + if (c > 0) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 2: + if (c > fee) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + } ResetPassiveTime(); } //----------------------------------------------------------------------------- @@ -1111,6 +1258,9 @@ void USER_IMPL::ProcessDayFee() { STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (tariff == NULL) + return; + double passiveTimePart = 1.0; if (!settings->GetFullFee()) { @@ -1124,27 +1274,49 @@ else return; } } -double f = tariff->GetFee() * passiveTimePart; +double fee = tariff->GetFee() * passiveTimePart; ResetPassiveTime(); -if (f == 0.0) +if (fee == 0.0) + { + SetPrepaidTraff(); return; + } double c = cash; printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n", login.c_str(), tariff->GetFee(), passiveTimePart, - f); -property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); + fee); +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + break; + case 1: + if (c > 0) + { + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + } + break; + case 2: + if (c > fee) + { + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + } + break; + } } //----------------------------------------------------------------------------- void USER_IMPL::SetPrepaidTraff() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic"); +if (tariff != NULL) + property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic"); } //----------------------------------------------------------------------------- int USER_IMPL::AddMessage(STG_MSG * msg) @@ -1190,7 +1362,7 @@ int USER_IMPL::SendMessage(STG_MSG & msg) const { // No lock `cause we are already locked from caller int ret = -1; -set::iterator it(authorizedBy.begin()); +set::iterator it(authorizedBy.begin()); while (it != authorizedBy.end()) { if (!(*it++)->SendMessage(msg, currIP)) @@ -1256,6 +1428,10 @@ while (it != messages.end()) ++it; } } + else + { + ++it; + } } } //----------------------------------------------------------------------------- @@ -1263,7 +1439,7 @@ while (it != messages.end()) //----------------------------------------------------------------------------- void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive) { -if (newPassive && !oldPassive) +if (newPassive && !oldPassive && user->tariff != NULL) user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(), user->sysAdmin, user->login, @@ -1273,7 +1449,13 @@ if (newPassive && !oldPassive) //----------------------------------------------------------------------------- void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff) { +if (user->settings->GetReconnectOnTariffChange() && user->connected) + user->Disconnect(false, "Change tariff"); user->tariff = user->tariffs->FindByName(newTariff); +if (user->settings->GetReconnectOnTariffChange() && + !user->authorizedBy.empty() && + user->IsInetable()) + user->Connect(false); } //----------------------------------------------------------------------------- void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash) @@ -1282,14 +1464,12 @@ user->lastCashAddTime = *const_cast(&stgTime); user->lastCashAdd = newCash - oldCash; } //----------------------------------------------------------------------------- -void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to) +void CHG_IPS_NOTIFIER::Notify(const USER_IPS & from, const USER_IPS & to) { - printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str()); - if (from != 0) - if (user->connected) - user->Disconnect(false, "Change IP"); - if (to != 0) - if (user->IsInetable()) - user->Connect(false); + printfd(__FILE__, "Change IP from '%s' to '%s'\n", from.GetIpStr().c_str(), to.GetIpStr().c_str()); + if (user->connected) + user->Disconnect(false, "Change IP"); + if (!user->authorizedBy.empty() && user->IsInetable()) + user->Connect(false); } //-----------------------------------------------------------------------------