]> git.stg.codes - stg.git/blobdiff - projects/stargazer/user_impl.cpp
TARIFFS::GetTariffsData become constant.
[stg.git] / projects / stargazer / user_impl.cpp
index 5bb0069fb6f04b79a476001e135d09ddd7a3176d..ae7ccd339e340bd259318cd4190bbeb9cd8b11bb 100644 (file)
 #define _GNU_SOURCE
 #endif
 
-#include <pthread.h>
-#include <unistd.h> // access
-
-#include <cassert>
-#include <cstdlib>
-#include <cmath>
-#include <algorithm>
-#include <functional>
+#include "user_impl.h"
+#include "settings_impl.h"
+#include "stg_timer.h"
 
 #include "stg/users.h"
 #include "stg/common.h"
 #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 <algorithm>
+#include <functional>
+
+#include <cassert>
+#include <cstdlib>
+#include <cmath>
+
+#include <pthread.h>
+#include <unistd.h> // access
 
 #ifdef USE_ABSTRACT_SETTINGS
 USER_IMPL::USER_IMPL(const SETTINGS * s,
@@ -62,12 +64,9 @@ USER_IMPL::USER_IMPL(const SETTINGS * s,
       property(s->GetScriptsDir()),
       WriteServLog(GetStgLogger()),
       lastScanMessages(0),
-      login(),
       id(0),
       __connected(0),
       connected(__connected),
-      enabledDirs(),
-      userIDGenerator(),
       __currIP(0),
       currIP(__currIP),
       lastIPForDisconnect(0),
@@ -76,11 +75,8 @@ USER_IMPL::USER_IMPL(const SETTINGS * s,
       store(st),
       tariffs(t),
       tariff(NULL),
-      traffStat(),
-      traffStatSaved(),
       settings(s),
-      authorizedBy(),
-      messages(),
+      authorizedModificationTime(0),
       deleted(false),
       lastWriteStat(0),
       lastWriteDetailedStat(0),
@@ -118,14 +114,11 @@ USER_IMPL::USER_IMPL(const SETTINGS * s,
       userdata7(property.userdata7),
       userdata8(property.userdata8),
       userdata9(property.userdata9),
-      sessionUpload(),
-      sessionDownload(),
       passiveNotifier(this),
+      disabledNotifier(this),
       tariffNotifier(this),
       cashNotifier(this),
-      ipNotifier(this),
-      mutex(),
-      errorStr()
+      ipNotifier(this)
 {
 password = "*_EMPTY_PASSWORD_*";
 tariffName = NO_TARIFF_NAME;
@@ -155,12 +148,9 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
       property(s->GetScriptsDir()),
       WriteServLog(GetStgLogger()),
       lastScanMessages(0),
-      login(),
       id(0),
       __connected(0),
       connected(__connected),
-      enabledDirs(),
-      userIDGenerator(),
       __currIP(0),
       currIP(__currIP),
       lastIPForDisconnect(0),
@@ -169,11 +159,8 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
       store(st),
       tariffs(t),
       tariff(NULL),
-      traffStat(),
-      traffStatSaved(),
       settings(s),
-      authorizedBy(),
-      messages(),
+      authorizedModificationTime(0),
       deleted(false),
       lastWriteStat(0),
       lastWriteDetailedStat(0),
@@ -211,15 +198,11 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
       userdata7(property.userdata7),
       userdata8(property.userdata8),
       userdata9(property.userdata9),
-      sessionUpload(),
-      sessionDownload(),
       passiveNotifier(this),
       disabledNotifier(this),
       tariffNotifier(this),
       cashNotifier(this),
-      ipNotifier(this),
-      mutex(),
-      errorStr()
+      ipNotifier(this)
 {
 password = "*_EMPTY_PASSWORD_*";
 tariffName = NO_TARIFF_NAME;
@@ -250,7 +233,6 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u)
       id(u.id),
       __connected(0),
       connected(__connected),
-      enabledDirs(),
       userIDGenerator(u.userIDGenerator),
       __currIP(u.__currIP),
       currIP(__currIP),
@@ -263,7 +245,7 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u)
       traffStat(u.traffStat),
       traffStatSaved(u.traffStatSaved),
       settings(u.settings),
-      authorizedBy(),
+      authorizedModificationTime(u.authorizedModificationTime),
       messages(u.messages),
       deleted(u.deleted),
       lastWriteStat(u.lastWriteStat),
@@ -308,9 +290,7 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u)
       disabledNotifier(this),
       tariffNotifier(this),
       cashNotifier(this),
-      ipNotifier(this),
-      mutex(),
-      errorStr()
+      ipNotifier(this)
 {
 if (&u == this)
     return;
@@ -340,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();
@@ -348,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))
@@ -396,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))
@@ -415,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");
@@ -434,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))
@@ -453,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);
@@ -473,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.
@@ -537,6 +517,8 @@ else
         }
     }
 
+if (authorizedBy.empty())
+    authorizedModificationTime = stgTime;
 authorizedBy.insert(auth);
 
 ScanMessage();
@@ -544,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
  */
@@ -555,6 +537,8 @@ if (!authorizedBy.erase(auth))
 
 if (authorizedBy.empty())
     {
+    authorizedModificationTime = stgTime;
+    lastDisconnectReason = reason;
     lastIPForDisconnect = currIP;
     currIP = 0; // DelUser in traffcounter
     return;
@@ -563,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();
 }
@@ -581,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)
     {
@@ -597,6 +581,7 @@ if (!fakeConnect)
             }
 
         std::string scriptOnConnectParams;
+
         strprintf(&scriptOnConnectParams,
                 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
                 scriptOnConnect.c_str(),
@@ -606,6 +591,13 @@ if (!fakeConnect)
                 id,
                 dirsStr);
 
+        std::vector<std::string>::const_iterator it(settings->GetScriptParams().begin());
+        while (it != settings->GetScriptParams().end())
+            {
+            scriptOnConnectParams += " \"" + GetParamValue(it->c_str()) + "\"";
+            ++it;
+            }
+
         ScriptExec(scriptOnConnectParams.c_str());
         }
     else
@@ -632,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)
     {
@@ -642,6 +634,7 @@ if (!lastIPForDisconnect)
 
 if (!fakeDisconnect)
     {
+    lastDisconnectReason = reason;
     std::string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect";
 
     if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
@@ -663,6 +656,13 @@ if (!fakeDisconnect)
                 id,
                 dirsStr);
 
+        std::vector<std::string>::const_iterator it(settings->GetScriptParams().begin());
+        while (it != settings->GetScriptParams().end())
+            {
+            scriptOnDisonnectParams += " \"" + GetParamValue(it->c_str()) + "\"";
+            ++it;
+            }
+
         ScriptExec(scriptOnDisonnectParams.c_str());
         }
     else
@@ -673,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());
@@ -686,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;
@@ -727,7 +734,7 @@ std::cout << "============================================================" << s
 //-----------------------------------------------------------------------------
 void USER_IMPL::Run()
 {
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+STG_LOCKER lock(&mutex);
 
 if (stgTime > static_cast<time_t>(lastWriteStat + settings->GetStatWritePeriod()))
     {
@@ -788,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;
@@ -798,7 +805,7 @@ else
 //-----------------------------------------------------------------------------
 bool USER_IMPL::IsInetable()
 {
-//STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+//STG_LOCKER lock(&mutex);
 
 if (disabled || passive)
     return false;
@@ -817,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++)
@@ -833,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;
@@ -891,6 +898,7 @@ if (tt == TRAFF_UP ||
 
 up = dt;
 sessionUpload[dir] += len;
+sessionUploadModTime = stgTime;
 
 //Add detailed stat
 
@@ -925,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;
@@ -982,6 +990,7 @@ if (tt == TRAFF_DOWN ||
 
 down = dt;
 sessionDownload[dir] += len;
+sessionDownloadModTime = stgTime;
 
 //Add detailed stat
 
@@ -1012,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";
 
@@ -1082,7 +1091,7 @@ else
 //-----------------------------------------------------------------------------
 void USER_IMPL::OnDelete()
 {
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+STG_LOCKER lock(&mutex);
 
 std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel";
 
@@ -1123,7 +1132,7 @@ if (!traffStatSaved.second.empty())
 TRAFF_STAT ts;
 
     {
-    STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+    STG_LOCKER lock(&mutex);
     ts.swap(traffStat);
     }
 
@@ -1139,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;
             }
@@ -1152,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};
@@ -1179,7 +1188,7 @@ return static_cast<double>(dt) / secMonth;
 //-----------------------------------------------------------------------------
 void USER_IMPL::SetPassiveTimeAsNewUser()
 {
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+STG_LOCKER lock(&mutex);
 
 time_t t = stgTime;
 struct tm tm;
@@ -1193,7 +1202,7 @@ passiveTime = static_cast<time_t>(pt * 24 * 3600 * daysCurrMon);
 //-----------------------------------------------------------------------------
 void USER_IMPL::MidnightResetSessionStat()
 {
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+STG_LOCKER lock(&mutex);
 
 if (connected)
     {
@@ -1204,7 +1213,7 @@ if (connected)
 //-----------------------------------------------------------------------------
 void USER_IMPL::ProcessNewMonth()
 {
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+STG_LOCKER lock(&mutex);
 //  Reset traff
 if (connected)
     {
@@ -1244,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)
@@ -1278,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())
     {
@@ -1344,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)
@@ -1352,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))
     {
@@ -1466,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)