Skip to content

Commit

Permalink
Introduce last login time on UserAccount struct
Browse files Browse the repository at this point in the history
Also stores last-login in server's xml configuration.
  • Loading branch information
bear101 committed Oct 18, 2024
1 parent 2103bd7 commit f6f19c5
Show file tree
Hide file tree
Showing 14 changed files with 67 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Library/TeamTalk.NET/TeamTalk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2168,6 +2168,10 @@ public struct UserAccount
* Date/time is converted local time. */
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TeamTalkBase.TT_STRLEN)]
public string szLastModified;
/** @brief Timestamp of user account's last successful login.
* Read-only property. Date/time is converted local time. */
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TeamTalkBase.TT_STRLEN)]
public string szLastLoginTime;
}
/** @} */

Expand Down
4 changes: 4 additions & 0 deletions Library/TeamTalkJNI/jni/ttconvert-jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,7 @@ void setUserAccount(JNIEnv* env, UserAccount& account, jobject lpAccount, JConve
jfieldID fid_audbps = env->GetFieldID(cls_account, "nAudioCodecBpsLimit", "I");
jfieldID fid_abuse = env->GetFieldID(cls_account, "abusePrevent", "Ldk/bearware/AbusePrevention;");
jfieldID fid_mod = env->GetFieldID(cls_account, "szLastModified", "Ljava/lang/String;");
jfieldID fid_login = env->GetFieldID(cls_account, "szLastLoginTime", "Ljava/lang/String;");

assert(fid_user);
assert(fid_passwd);
Expand All @@ -1409,6 +1410,7 @@ void setUserAccount(JNIEnv* env, UserAccount& account, jobject lpAccount, JConve
assert(fid_audbps);
assert(fid_abuse);
assert(fid_mod);
assert(fid_login);

if(conv == N2J)
{
Expand All @@ -1425,6 +1427,7 @@ void setUserAccount(JNIEnv* env, UserAccount& account, jobject lpAccount, JConve
env->SetObjectField(lpAccount, fid_op, intArr);
env->SetIntField(lpAccount, fid_audbps, account.nAudioCodecBpsLimit);
env->SetObjectField(lpAccount, fid_mod, NEW_JSTRING(env, account.szLastModified));
env->SetObjectField(lpAccount, fid_login, NEW_JSTRING(env, account.szLastLoginTime));

jobject ap_obj = newAbusePrevention(env, &account.abusePrevent);
assert(ap_obj);
Expand All @@ -1447,6 +1450,7 @@ void setUserAccount(JNIEnv* env, UserAccount& account, jobject lpAccount, JConve
TO_INT32_ARRAY(tmp, account.autoOperatorChannels, TT_CHANNELS_OPERATOR_MAX);
account.nAudioCodecBpsLimit = env->GetIntField(lpAccount, fid_audbps);
TT_STRCPY(account.szLastModified, ttstr(env, (jstring)env->GetObjectField(lpAccount, fid_mod)));
TT_STRCPY(account.szLastLoginTime, ttstr(env, (jstring)env->GetObjectField(lpAccount, fid_login)));
jobject ap_obj = env->GetObjectField(lpAccount, fid_abuse);
assert(ap_obj);
setAbusePrevention(env, account.abusePrevent, ap_obj, conv);
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkJNI/src/dk/bearware/UserAccount.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class UserAccount {
public int nAudioCodecBpsLimit;
public AbusePrevention abusePrevent = new AbusePrevention();
public String szLastModified = "";
public String szLastLoginTime = "";

public void copy(UserAccount u)
{
Expand Down
25 changes: 25 additions & 0 deletions Library/TeamTalkJNI/test/dk/bearware/TeamTalkTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
Expand Down Expand Up @@ -4494,6 +4495,30 @@ public void testUserStateMediaFile() {
assertEquals("User is not streaming", UserState.USERSTATE_NONE, (msg.user.uUserState & UserState.USERSTATE_MEDIAFILE_AUDIO));
}

@Test
public void testUserAcountLastLogin() {
final String USERNAME = "tt_test", PASSWORD = "tt_test", NICKNAME = "jUnit - " + getTestMethodName();
int USERRIGHTS = UserRight.USERRIGHT_TRANSMIT_MEDIAFILE | UserRight.USERRIGHT_CREATE_TEMPORARY_CHANNEL;
makeUserAccount(NICKNAME, USERNAME, PASSWORD, USERRIGHTS);

TeamTalkBase client = newClientInstance();
connect(client);
login(client, NICKNAME, USERNAME, PASSWORD);

UserAccount first_login_account = new UserAccount();
assertTrue("get account", client.getMyUserAccount(first_login_account));
//assertEquals("1970/01/01 00:00", first_login_account.szLastLoginTime);

assertTrue("disconnect", client.disconnect());
connect(client);
login(client, NICKNAME, USERNAME, PASSWORD);

UserAccount second_login_account = new UserAccount();
assertTrue("get account again", client.getMyUserAccount(second_login_account));
//assertNotEquals("1970/01/01 00:00", second_login_account.szLastLoginTime);
assertNotEquals(first_login_account.szLastLoginTime, second_login_account.szLastLoginTime);
}

/* cannot test output levels since a user is muted by sound system after decoding and callback.
@Test
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/bin/dll/Convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,7 @@ void Convert(const teamtalk::UserAccount& useraccount, UserAccount& result)
result.abusePrevent.nCommandsLimit = useraccount.abuse.n_cmds;
result.abusePrevent.nCommandsIntervalMSec = useraccount.abuse.cmd_msec;
ACE_OS::strsncpy(result.szLastModified, teamtalk::DateToString(useraccount.lastupdated).c_str(), TT_STRLEN);
ACE_OS::strsncpy(result.szLastLoginTime, teamtalk::DateToString(useraccount.lastlogin).c_str(), TT_STRLEN);
}

void Convert(const UserAccount& useraccount, teamtalk::UserAccount& result)
Expand Down
14 changes: 14 additions & 0 deletions Library/TeamTalkLib/bin/ttsrv/ServerXML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,7 @@ namespace teamtalk{
PutInteger(userElement, "userdata", user.userdata);
PutString(userElement, "init-channel", UnicodeToUtf8(user.init_channel).c_str());
PutString(userElement, "modified-time", DateToString(user.lastupdated.sec()).c_str());
PutString(userElement, "last-login-time", DateToString(user.lastlogin.sec()).c_str());
TiXmlElement opchanElement("channel-operator");
for(intset_t::const_iterator i=user.auto_op_channels.begin();
i!=user.auto_op_channels.end();i++)
Expand Down Expand Up @@ -1386,6 +1387,9 @@ namespace teamtalk{
GetInteger(userElement, "audiocodec-bps-limit", bpslimit);
GetString(userElement, "modified-time", tmp);
user.lastupdated = StringToDate(tmp);
tmp.clear();
GetString(userElement, "last-login-time", tmp);
user.lastlogin = StringToDate(tmp);

if(b)
{
Expand Down Expand Up @@ -1440,6 +1444,8 @@ namespace teamtalk{
user = int_user;
if(user.usertype == USERTYPE_ADMIN)
user.userrights = USERRIGHT_ALL;

UpdateLastLogin(user);
return true;
}
return false;
Expand Down Expand Up @@ -1479,6 +1485,14 @@ namespace teamtalk{
return false;
}

void ServerXML::UpdateLastLogin(const UserAccount& user)
{
RemoveUser(UnicodeToUtf8(user.username).c_str());
UserAccount updateduser = user;
updateduser.lastlogin = ACE_OS::gettimeofday();
AddNewUser(updateduser);
}

/******* </users> ******/

/********** files in static channels **************/
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/bin/ttsrv/ServerXML.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ namespace teamtalk {
bool GetNextUser(int index, UserAccount& user);
bool AuthenticateUser(UserAccount& user);
bool GetUser(const std::string& username, UserAccount& user);
void UpdateLastLogin(const UserAccount& user);
/****** </users> *****/

/********** <serverbans> ************/
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/teamtalk/Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ namespace teamtalk {
GetProperty(properties, TT_AUTOOPCHANNELS, useraccount.auto_op_channels);
GetProperty(properties, TT_AUDIOBPSLIMIT, useraccount.audiobpslimit);
GetProperty(properties, TT_MODIFIEDTIME, useraccount.lastupdated);
GetProperty(properties, TT_LASTLOGINTIME, useraccount.lastlogin);

vector<int> flood;
if(GetProperty(properties, TT_CMDFLOOD, flood))
Expand Down
3 changes: 2 additions & 1 deletion Library/TeamTalkLib/teamtalk/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <set>
#include <map>

#define TEAMTALK_PROTOCOL_VERSION ACE_TEXT("5.13")
#define TEAMTALK_PROTOCOL_VERSION ACE_TEXT("5.14")

/* parameter names */
#define TT_USERID ACE_TEXT("userid")
Expand Down Expand Up @@ -142,6 +142,7 @@
#define TT_TOTMEDIAFILE ACE_TEXT("mediafiletot") // v5.12
#define TT_TRANSFERKEY ACE_TEXT("filetxkey") // v5.13
#define TT_BANOWNER ACE_TEXT("owner") // v5.13
#define TT_LASTLOGINTIME ACE_TEXT("lastlogin") // v5.14

// Client ---> Server
// -------------------------
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/teamtalk/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ namespace teamtalk {
Abuse abuse;
ACE_TString nickname; /* TODO: add to TT API */
ACE_Time_Value lastupdated;
ACE_Time_Value lastlogin;

UserAccount();
bool IsWebLogin() const;
Expand Down
9 changes: 8 additions & 1 deletion Library/TeamTalkLib/teamtalk/server/ServerNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include <ace/OS_NS_sys_socket.h>

#include <stack>
#include <queue>
#include <memory>
#include <vector>
#include <algorithm>
Expand Down Expand Up @@ -2741,6 +2740,14 @@ ErrorMsg ServerNode::UserLogin(int userid, const ACE_TString& username,
m_srvguard->OnUserLogin(*user);
}

// update last login
if (IsAutoSaving())
{
auto err = m_srvguard->SaveConfiguration(*user, *this);
if (err.success() && (m_properties.logevents & SERVERLOGEVENT_SERVER_SAVECONFIG))
m_srvguard->OnSaveConfiguration(user.get());
}

return ErrorMsg(TT_CMDERR_SUCCESS);
}

Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/teamtalk/server/ServerUser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@ void AppendUserAccount(const UserAccount& useraccount, ACE_TString& command)
AppendProperty(TT_AUDIOBPSLIMIT, useraccount.audiobpslimit, command);
AppendProperty(TT_CMDFLOOD, useraccount.abuse.toParam(), command);
AppendProperty(TT_MODIFIEDTIME, useraccount.lastupdated, command);
AppendProperty(TT_LASTLOGINTIME, useraccount.lastlogin, command);
}

void ServerUser::DoAccepted(const UserAccount& useraccount)
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkPy/TeamTalk5.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ class UserAccount(Structure):
("nAudioCodecBpsLimit", INT32),
("abusePrevent", AbusePrevention),
("szLastModified", TTCHAR*TT_STRLEN),
("szLastLoginTime", TTCHAR*TT_STRLEN),
]
def __init__(self):
assert(DBG_SIZEOF(TTType.USERACCOUNT) == ctypes.sizeof(UserAccount))
Expand Down
3 changes: 3 additions & 0 deletions Library/TeamTalk_DLL/TeamTalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -2067,6 +2067,9 @@ extern "C" {
/** @brief Timestamp of last modification of user account.
* Date/time is converted local time. */
TTCHAR szLastModified[TT_STRLEN];
/** @brief Timestamp of user account's last successful login.
* Read-only property. Date/time is converted local time. */
TTCHAR szLastLoginTime[TT_STRLEN];
} UserAccount;
/** @} */

Expand Down

0 comments on commit f6f19c5

Please sign in to comment.