X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/2529ae443070ce292250061b8cd21519ea01ebc4..9d7269d8d8333fc1ff47bedcaf488142570b1258:/projects/stargazer/user_impl.cpp diff --git a/projects/stargazer/user_impl.cpp b/projects/stargazer/user_impl.cpp index f6bf0070..79321987 100644 --- a/projects/stargazer/user_impl.cpp +++ b/projects/stargazer/user_impl.cpp @@ -32,14 +32,9 @@ #define _GNU_SOURCE #endif -#include -#include // access - -#include -#include -#include -#include -#include +#include "user_impl.h" +#include "settings_impl.h" +#include "stg_timer.h" #include "stg/users.h" #include "stg/common.h" @@ -47,9 +42,16 @@ #include "stg/tariff.h" #include "stg/tariffs.h" #include "stg/admin.h" -#include "user_impl.h" -#include "settings_impl.h" -#include "stg_timer.h" + +#include +#include + +#include +#include +#include + +#include +#include // access #ifdef USE_ABSTRACT_SETTINGS USER_IMPL::USER_IMPL(const SETTINGS * s, @@ -113,6 +115,7 @@ USER_IMPL::USER_IMPL(const SETTINGS * s, userdata8(property.userdata8), userdata9(property.userdata9), passiveNotifier(this), + disabledNotifier(this), tariffNotifier(this), cashNotifier(this), ipNotifier(this) @@ -317,7 +320,7 @@ pthread_mutex_destroy(&mutex); //----------------------------------------------------------------------------- void USER_IMPL::SetLogin(const std::string & l) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); assert(login.empty() && "Login is already set"); login = l; id = userIDGenerator.GetNextID(); @@ -325,7 +328,7 @@ id = userIDGenerator.GetNextID(); //----------------------------------------------------------------------------- int USER_IMPL::ReadConf() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_CONF conf; if (store->RestoreUserConf(&conf, login)) @@ -373,7 +376,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::ReadStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_STAT stat; if (store->RestoreUserStat(&stat, login)) @@ -392,7 +395,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::WriteConf() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_CONF conf(property.GetConf()); printfd(__FILE__, "USER::WriteConf()\n"); @@ -411,7 +414,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::WriteStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_STAT stat(property.GetStat()); if (store->SaveUserStat(stat, login)) @@ -430,7 +433,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::WriteMonthStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); time_t tt = stgTime - 3600; struct tm t1; localtime_r(&tt, &t1); @@ -450,7 +453,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::Authorize(uint32_t ip, uint32_t dirs, const AUTH * auth) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); /* * Authorize user. It only means that user will be authorized. Nothing more. * User can be connected or disconnected while authorized. @@ -523,9 +526,9 @@ ScanMessage(); return 0; } //----------------------------------------------------------------------------- -void USER_IMPL::Unauthorize(const AUTH * auth) +void USER_IMPL::Unauthorize(const AUTH * auth, const std::string & reason) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); /* * Authorizer tries to unauthorize user, that was not authorized by it */ @@ -535,6 +538,7 @@ if (!authorizedBy.erase(auth)) if (authorizedBy.empty()) { authorizedModificationTime = stgTime; + lastDisconnectReason = reason; lastIPForDisconnect = currIP; currIP = 0; // DelUser in traffcounter return; @@ -543,7 +547,7 @@ if (authorizedBy.empty()) //----------------------------------------------------------------------------- bool USER_IMPL::IsAuthorizedBy(const AUTH * auth) const { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); // Is this user authorized by specified authorizer? return authorizedBy.find(auth) != authorizedBy.end(); } @@ -561,7 +565,7 @@ void USER_IMPL::Connect(bool fakeConnect) * Connect user to Internet. This function is differ from Authorize() !!! */ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (!fakeConnect) { @@ -577,6 +581,7 @@ if (!fakeConnect) } std::string scriptOnConnectParams; + strprintf(&scriptOnConnectParams, "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", scriptOnConnect.c_str(), @@ -586,6 +591,13 @@ if (!fakeConnect) id, dirsStr); + std::vector::const_iterator it(settings->GetScriptParams().begin()); + while (it != settings->GetScriptParams().end()) + { + scriptOnConnectParams += " \"" + GetParamValue(it->c_str()) + "\""; + ++it; + } + ScriptExec(scriptOnConnectParams.c_str()); } else @@ -612,7 +624,7 @@ void USER_IMPL::Disconnect(bool fakeDisconnect, const std::string & reason) * Disconnect user from Internet. This function is differ from UnAuthorize() !!! */ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (!lastIPForDisconnect) { @@ -644,6 +656,13 @@ if (!fakeDisconnect) id, dirsStr); + std::vector::const_iterator it(settings->GetScriptParams().begin()); + while (it != settings->GetScriptParams().end()) + { + scriptOnDisonnectParams += " \"" + GetParamValue(it->c_str()) + "\""; + ++it; + } + ScriptExec(scriptOnDisonnectParams.c_str()); } else @@ -654,7 +673,12 @@ if (!fakeDisconnect) connected = false; } -if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason)) +std::string reasonMessage(reason); +if (!lastDisconnectReason.empty()) + reasonMessage += ": " + lastDisconnectReason; + +if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, + cash, freeMb, reasonMessage)) { WriteServLog("Cannot write disconnect for user %s.", login.c_str()); WriteServLog("%s", store->GetStrError().c_str()); @@ -667,12 +691,14 @@ DIR_TRAFF zeroSesssion; sessionUpload = zeroSesssion; sessionDownload = zeroSesssion; +sessionUploadModTime = stgTime; +sessionDownloadModTime = stgTime; } //----------------------------------------------------------------------------- void USER_IMPL::PrintUser() const { //return; -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); std::cout << "============================================================" << std::endl; std::cout << "id=" << id << std::endl; std::cout << "login=" << login << std::endl; @@ -708,7 +734,7 @@ std::cout << "============================================================" << s //----------------------------------------------------------------------------- void USER_IMPL::Run() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (stgTime > static_cast(lastWriteStat + settings->GetStatWritePeriod())) { @@ -769,7 +795,7 @@ else //----------------------------------------------------------------------------- void USER_IMPL::UpdatePingTime(time_t t) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); //printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str()); if (t) pingTime = t; @@ -779,7 +805,7 @@ else //----------------------------------------------------------------------------- bool USER_IMPL::IsInetable() { -//STG_LOCKER lock(&mutex, __FILE__, __LINE__); +//STG_LOCKER lock(&mutex); if (disabled || passive) return false; @@ -798,9 +824,9 @@ if (settings->GetShowFeeInCash() || tariff == NULL) return (cash - tariff->GetFee() >= -credit); } //----------------------------------------------------------------------------- -std::string USER_IMPL::GetEnabledDirs() +std::string USER_IMPL::GetEnabledDirs() const { -//STG_LOCKER lock(&mutex, __FILE__, __LINE__); +//STG_LOCKER lock(&mutex); std::string dirs = ""; for(int i = 0; i < DIR_NUM; i++) @@ -814,7 +840,7 @@ void USER_IMPL::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len) void USER_IMPL::AddTraffStatU(int dir, uint32_t ip, uint32_t len) #endif { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (!connected || tariff == NULL) return; @@ -828,10 +854,10 @@ int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; dt[dir] += len; int tt = tariff->GetTraffType(); -if (tt == TRAFF_UP || - tt == TRAFF_UP_DOWN || +if (tt == TARIFF::TRAFF_UP || + tt == TARIFF::TRAFF_UP_DOWN || // Check NEW traff data - (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir])) + (tt == TARIFF::TRAFF_MAX && dt[dir] > down.ConstData()[dir])) { double dc = 0; if (traff < threshold && @@ -872,6 +898,7 @@ if (tt == TRAFF_UP || up = dt; sessionUpload[dir] += len; +sessionUploadModTime = stgTime; //Add detailed stat @@ -906,7 +933,7 @@ void USER_IMPL::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len) void USER_IMPL::AddTraffStatD(int dir, uint32_t ip, uint32_t len) #endif { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (!connected || tariff == NULL) return; @@ -920,10 +947,10 @@ int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; dt[dir] += len; int tt = tariff->GetTraffType(); -if (tt == TRAFF_DOWN || - tt == TRAFF_UP_DOWN || +if (tt == TARIFF::TRAFF_DOWN || + tt == TARIFF::TRAFF_UP_DOWN || // Check NEW traff data - (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir])) + (tt == TARIFF::TRAFF_MAX && up.ConstData()[dir] <= dt[dir])) { double dc = 0; if (traff < threshold && @@ -963,6 +990,7 @@ if (tt == TRAFF_DOWN || down = dt; sessionDownload[dir] += len; +sessionDownloadModTime = stgTime; //Add detailed stat @@ -993,55 +1021,55 @@ else //----------------------------------------------------------------------------- void USER_IMPL::AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); currIP.AddBeforeNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); currIP.DelBeforeNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); currIP.AddAfterNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); currIP.DelAfterNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); connected.AddBeforeNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); connected.DelBeforeNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); connected.AddAfterNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); connected.DelAfterNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::OnAdd() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); std::string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd"; @@ -1063,7 +1091,7 @@ else //----------------------------------------------------------------------------- void USER_IMPL::OnDelete() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel"; @@ -1104,7 +1132,7 @@ if (!traffStatSaved.second.empty()) TRAFF_STAT ts; { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); + STG_LOCKER lock(&mutex); ts.swap(traffStat); } @@ -1120,7 +1148,7 @@ if (ts.size() && !disabledDetailStat) if (!hard) { printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n"); - STG_LOCKER lock(&mutex, __FILE__, __LINE__); + STG_LOCKER lock(&mutex); traffStatSaved.second.swap(ts); traffStatSaved.first = lastWriteDetailedStat; } @@ -1133,7 +1161,7 @@ return 0; //----------------------------------------------------------------------------- double USER_IMPL::GetPassiveTimePart() const { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); static int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -1160,7 +1188,7 @@ return static_cast(dt) / secMonth; //----------------------------------------------------------------------------- void USER_IMPL::SetPassiveTimeAsNewUser() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); time_t t = stgTime; struct tm tm; @@ -1174,7 +1202,7 @@ passiveTime = static_cast(pt * 24 * 3600 * daysCurrMon); //----------------------------------------------------------------------------- void USER_IMPL::MidnightResetSessionStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (connected) { @@ -1185,7 +1213,7 @@ if (connected) //----------------------------------------------------------------------------- void USER_IMPL::ProcessNewMonth() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); // Reset traff if (connected) { @@ -1225,11 +1253,14 @@ if (nextTariff.ConstData() != "") //----------------------------------------------------------------------------- void USER_IMPL::ProcessDayFeeSpread() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (passive.ConstData() || tariff == NULL) return; +if (tariff->GetPeriod() != TARIFF::MONTH) + return; + double fee = tariff->GetFee() / DaysInCurrentMonth(); if (std::fabs(fee) < 1.0e-3) @@ -1259,11 +1290,14 @@ ResetPassiveTime(); //----------------------------------------------------------------------------- void USER_IMPL::ProcessDayFee() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (tariff == NULL) return; +if (tariff->GetPeriod() != TARIFF::MONTH) + return; + double passiveTimePart = 1.0; if (!settings->GetFullFee()) { @@ -1325,6 +1359,39 @@ switch (settings->GetFeeChargeType()) } } //----------------------------------------------------------------------------- +void USER_IMPL::ProcessDailyFee() +{ +STG_LOCKER lock(&mutex); + +if (passive.ConstData() || tariff == NULL) + return; + +if (tariff->GetPeriod() != TARIFF::DAY) + return; + +double fee = tariff->GetFee(); + +if (fee == 0.0) + return; + +double c = cash; +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 1: + if (c + credit >= 0) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 2: + if (c + credit >= fee) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + } +ResetPassiveTime(); +} +//----------------------------------------------------------------------------- void USER_IMPL::SetPrepaidTraff() { if (tariff != NULL) @@ -1333,7 +1400,7 @@ if (tariff != NULL) //----------------------------------------------------------------------------- int USER_IMPL::AddMessage(STG_MSG * msg) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (SendMessage(*msg)) { @@ -1447,6 +1514,28 @@ while (it != messages.end()) } } //----------------------------------------------------------------------------- +std::string USER_IMPL::GetParamValue(const std::string & name) const +{ + std::string lowerName = ToLower(name); + if (lowerName == "id") + { + std::ostringstream stream; + stream << id; + return stream.str(); + } + if (lowerName == "login") return login; + if (lowerName == "currip") return currIP.ToString(); + if (lowerName == "enableddirs") return GetEnabledDirs(); + if (lowerName == "tariff") return property.tariffName; + if (property.Exists(lowerName)) + return property.GetPropertyValue(lowerName); + else + { + WriteServLog("User’s parameter '%s' does not exist.", name.c_str()); + return ""; + } +} +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)