Server audit table (#2423)

* Creating of server side audit table for auditing actions such as password resets, account registrations and log queries.

* Add migration script

Add migration script for database

* Update database script

Update database script to reflect new audit table

* Creating of server side audit table for auditing actions such as password resets, account registrations and log queries.

* Add migration script

Add migration script for database

* Update database script

Update database script to reflect new audit table

* Corrected results column possible value(s).

* Fixed migration script.

* Added boolean audit logic

Added enable/disable audit options
Added audit functionality for forgot password

* Added registration auditing

Added registration auditing

* Updated ActivateAccount Function

Created clientid variable and used it in preporation for future
potential protocol expansion.

* Extended activation protocol

Added clientid to activation command protocol

* Typo correction

Fix typo's

* Missed type fix

Found the infamous E!

* Updated database function syntax

Updated if/else syntax in db add audit function

* Untabify content

Untab files changed in PR
This commit is contained in:
woogerboy21 2017-02-25 13:48:31 -05:00 committed by GitHub
parent 3c2063df40
commit d0088f6a18
10 changed files with 256 additions and 62 deletions

View file

@ -139,6 +139,7 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
Command_Activate cmdActivate;
cmdActivate.set_user_name(userName.toStdString());
cmdActivate.set_token(token.toStdString());
cmdActivate.set_clientid(getSrvClientID(lastHostname).toStdString());
PendingCommand *pend = prepareSessionCommand(cmdActivate);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(activateResponse(Response)));

View file

@ -137,6 +137,7 @@ message Command_Activate {
required string user_name = 1;
// Activation token
required string token = 2;
optional string clientid = 3;
}
message Command_AccountEdit {

View file

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS `cockatrice_audit` (
`id` int(7) unsigned zerofill NOT NULL auto_increment,
`id_server` tinyint(3) NOT NULL,
`name` varchar(35) NOT NULL,
`ip_address` varchar(255) NOT NULL,
`clientid` varchar(15) NOT NULL,
`incidentDate` datetime NOT NULL default '0000-00-00 00:00:00',
`action` varchar(35) NOT NULL,
`results` ENUM('fail', 'success') NOT NULL DEFAULT 'fail',
`details` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
UPDATE cockatrice_schema_version SET version=22 WHERE version=21;

View file

@ -353,6 +353,22 @@ log_user_msg_chat=false
; Log user messages coming from other servers in the network
log_user_msg_isl=false
[audit]
; Servatrice can record certain actions being performed in the database for server operators to better understand
; if some one may be abusing application functionality. Enabling auditing will allow servatrice to record any
; of the below enabled audit functionality to be recorded.
; Default: true
enable_audit=true
; Servatrice can record when users attempt a new account registration. Should we enable auditing for this action?
; Default: true
enable_registration_audit=true
; Servatrice can record when a users attempts to reset the account password. Should we enable auditing for this action?
; Default: true
enable_forgotpassword_audit=true
; EXPERIMENTAL - NOT WORKING YET
; The following settings are relative to the server network functionality, that is not yet complete.

View file

@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_schema_version` (
PRIMARY KEY (`version`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO cockatrice_schema_version VALUES(21);
INSERT INTO cockatrice_schema_version VALUES(22);
-- users and user data tables
CREATE TABLE IF NOT EXISTS `cockatrice_users` (
@ -267,3 +267,17 @@ CREATE TABLE IF NOT EXISTS `cockatrice_forgot_password` (
PRIMARY KEY (`id`),
KEY `user_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cockatrice_audit` (
`id` int(7) unsigned zerofill NOT NULL auto_increment,
`id_server` tinyint(3) NOT NULL,
`name` varchar(35) NOT NULL,
`ip_address` varchar(255) NOT NULL,
`clientid` varchar(15) NOT NULL,
`incidentDate` datetime NOT NULL default '0000-00-00 00:00:00',
`action` varchar(35) NOT NULL,
`results` ENUM('fail', 'success') NOT NULL DEFAULT 'fail',
`details` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

View file

@ -252,11 +252,17 @@ bool Servatrice::initServer()
}
}
qDebug() << "Forgot password enabled: " << getEnableForgotPassword();
if (getEnableForgotPassword()) {
qDebug() << "Forgot password token life (in minutes): " << getForgotPasswordTokenLife();
qDebug() << "Forgot password challenge on: " << getEnableForgotPasswordChallenge();
}
qDebug() << "Forgot password enabled: " << getEnableForgotPassword();
if (getEnableForgotPassword()) {
qDebug() << "Forgot password token life (in minutes): " << getForgotPasswordTokenLife();
qDebug() << "Forgot password challenge on: " << getEnableForgotPasswordChallenge();
}
qDebug() << "Auditing enabled: " << getEnableAudit();
if (getEnableAudit()) {
qDebug() << "Audit registration attempts enabled: " << getEnableRegistrationAudit();
qDebug() << "Audit forgot password attepts enabled: " << getEnableForgotPasswordAudit();
}
if (getDBTypeString() == "mysql") {
databaseType = DatabaseMySql;
@ -550,49 +556,49 @@ void Servatrice::statusUpdate()
if (getRegistrationEnabled() && getEnableInternalSMTPClient())
{
if (getRequireEmailActivationEnabled())
{
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_activation_emails a left join {prefix}_users b on a.name = b.name");
if (!servatriceDatabaseInterface->execSqlQuery(query))
return;
if (getRequireEmailActivationEnabled())
{
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_activation_emails a left join {prefix}_users b on a.name = b.name");
if (!servatriceDatabaseInterface->execSqlQuery(query))
return;
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery("delete from {prefix}_activation_emails where name = :name");
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery("delete from {prefix}_activation_emails where name = :name");
while (query->next()) {
const QString userName = query->value(0).toString();
const QString emailAddress = query->value(1).toString();
const QString token = query->value(2).toString();
while (query->next()) {
const QString userName = query->value(0).toString();
const QString emailAddress = query->value(1).toString();
const QString token = query->value(2).toString();
if (smtpClient->enqueueActivationTokenMail(userName, emailAddress, token))
{
queryDelete->bindValue(":name", userName);
servatriceDatabaseInterface->execSqlQuery(queryDelete);
}
}
}
if (smtpClient->enqueueActivationTokenMail(userName, emailAddress, token))
{
queryDelete->bindValue(":name", userName);
servatriceDatabaseInterface->execSqlQuery(queryDelete);
}
}
}
if (getEnableForgotPassword())
{
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_forgot_password a left join {prefix}_users b on a.name = b.name where a.emailed = 0");
if (!servatriceDatabaseInterface->execSqlQuery(query))
return;
if (getEnableForgotPassword())
{
QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select a.name, b.email, b.token from {prefix}_forgot_password a left join {prefix}_users b on a.name = b.name where a.emailed = 0");
if (!servatriceDatabaseInterface->execSqlQuery(query))
return;
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery("update {prefix}_forgot_password set emailed = 1 where name = :name");
QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery("update {prefix}_forgot_password set emailed = 1 where name = :name");
while (query->next()) {
const QString userName = query->value(0).toString();
const QString emailAddress = query->value(1).toString();
const QString token = query->value(2).toString();
while (query->next()) {
const QString userName = query->value(0).toString();
const QString emailAddress = query->value(1).toString();
const QString token = query->value(2).toString();
if (smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token))
{
queryDelete->bindValue(":name", userName);
servatriceDatabaseInterface->execSqlQuery(queryDelete);
}
}
}
if (smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token))
{
queryDelete->bindValue(":name", userName);
servatriceDatabaseInterface->execSqlQuery(queryDelete);
}
}
}
smtpClient->sendAllEmails();
smtpClient->sendAllEmails();
}
}
@ -877,17 +883,29 @@ bool Servatrice::getEnableInternalSMTPClient() const {
}
bool Servatrice::getEnableForgotPassword() const {
return settingsCache->value("forgotpassword/enable", false).toBool();
return settingsCache->value("forgotpassword/enable", false).toBool();
}
int Servatrice::getForgotPasswordTokenLife() const {
return settingsCache->value("forgotpassword/tokenlife", 60).toInt();
return settingsCache->value("forgotpassword/tokenlife", 60).toInt();
}
bool Servatrice::getEnableForgotPasswordChallenge() const {
return settingsCache->value("forgotpassword/enablechallenge", false).toBool();
return settingsCache->value("forgotpassword/enablechallenge", false).toBool();
}
QString Servatrice::getEmailBlackList() const {
return settingsCache->value("registration/emailproviderblacklist").toString();
}
bool Servatrice::getEnableAudit() const {
return settingsCache->value("audit/enable_audit", true).toBool();
}
bool Servatrice::getEnableRegistrationAudit() const {
return settingsCache->value("audit/enable_registration_audit", true).toBool();
}
bool Servatrice::getEnableForgotPasswordAudit() const {
return settingsCache->value("audit/enable_forgotpassword_audit", true).toBool();
}

View file

@ -193,6 +193,9 @@ public:
bool getEnableLogQuery() const;
bool getEnableForgotPassword() const;
bool getEnableForgotPasswordChallenge() const;
bool getEnableAudit() const;
bool getEnableRegistrationAudit() const;
bool getEnableForgotPasswordAudit() const;
int getIdleClientTimeout() const;
int getServerID() const;
int getMaxGameInactivityTime() const;

View file

@ -1218,3 +1218,26 @@ bool Servatrice_DatabaseInterface::validateTableColumnStringData(const QString &
return false;
}
void Servatrice_DatabaseInterface::addAuditRecord(const QString &user, const QString &ipaddress, const QString &clientid, const QString &action, const QString &details, const bool &results = false)
{
if (!checkSql())
return;
if (!server->getEnableAudit())
return;
if (user.isEmpty() || ipaddress.isEmpty() || clientid.isEmpty() || action.isEmpty())
return;
QSqlQuery *query = prepareQuery("insert into {prefix}_audit (id_server,name,ip_address,clientid,incidentDate,action,results,details) values (:idserver,:username,:ipaddress,:clientid,NOW(),:action,:results,:details)");
query->bindValue(":idserver", server->getServerID());
query->bindValue(":username", user);
query->bindValue(":ipaddress", ipaddress);
query->bindValue(":clientid", clientid);
query->bindValue(":action", action);
query->bindValue(":results", results ? "success" : "fail");
query->bindValue(":details", details);
execSqlQuery(query);
}

View file

@ -9,7 +9,7 @@
#include "server.h"
#include "server_database_interface.h"
#define DATABASE_SCHEMA_VERSION 21
#define DATABASE_SCHEMA_VERSION 22
class Servatrice;
@ -86,6 +86,7 @@ public:
bool doesForgotPasswordExist(const QString &user);
bool updateUserToken(const QString &token, const QString &user);
bool validateTableColumnStringData(const QString &table, const QString &column, const QString &_user, const QString &_datatocheck);
void addAuditRecord(const QString &user, const QString &ipaddress, const QString &clientid, const QString &action, const QString &details, const bool &results);
};
#endif

View file

@ -881,8 +881,12 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
qDebug() << "Got register command: " << userName;
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
if (!registrationEnabled)
if (!registrationEnabled) {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Server functionality disabled", false);
return Response::RespRegistrationDisabled;
}
QString emailBlackList = servatrice->getEmailBlackList();
QString emailAddress = QString::fromStdString(cmd.email());
@ -892,6 +896,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
if (!emailBlackList.trimmed().isEmpty()) {
foreach(QString blackListEmailAddress, emailBlackListFilters) {
if (emailAddress.contains(blackListEmailAddress, Qt::CaseInsensitive)) {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Email used is blacklisted", false);
return Response::RespEmailBlackListed;
}
}
@ -909,20 +916,34 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
QString errorString;
if (!sqlInterface->usernameIsValid(userName, errorString))
{
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Username is invalid", false);
Response_Register *re = new Response_Register;
re->set_denied_reason_str(errorString.toStdString());
rc.setResponseExtension(re);
return Response::RespUsernameInvalid;
}
if (userName.toLower().simplified() == "servatrice")
return Response::RespUsernameInvalid;
if (userName.toLower().simplified() == "servatrice") {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Username is invalid", false);
return Response::RespUsernameInvalid;
}
if (sqlInterface->userExists(userName)) {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Username already exists", false);
if(sqlInterface->userExists(userName))
return Response::RespUserAlreadyExists;
}
if (servatrice->getMaxAccountsPerEmail() && !(sqlInterface->checkNumberOfUserAccounts(emailAddress) < servatrice->getMaxAccountsPerEmail()))
{
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Too many usernames registered with this email address", false);
return Response::RespTooManyRequests;
}
@ -930,6 +951,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
int banSecondsRemaining;
if (sqlInterface->checkUserIsBanned(this->getAddress(), userName, clientId, banReason, banSecondsRemaining))
{
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "User is banned", false);
Response_Register *re = new Response_Register;
re->set_denied_reason_str(banReason.toStdString());
if (banSecondsRemaining != 0)
@ -938,8 +962,12 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
return Response::RespUserIsBanned;
}
if (tooManyRegistrationAttempts(this->getAddress()))
if (tooManyRegistrationAttempts(this->getAddress())) {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Too many registration attempts from this ip address", false);
return Response::RespTooManyRequests;
}
QString realName = QString::fromStdString(cmd.real_name());
ServerInfo_User_Gender gender = cmd.gender();
@ -947,8 +975,12 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
QString password = QString::fromStdString(cmd.password());
// TODO make this configurable?
if(password.length() < 6)
if (password.length() < 6) {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Password is too short", false);
return Response::RespPasswordTooShort;
}
QString token;
bool requireEmailActivation = settingsCache->value("registration/requireemailactivation", true).toBool();
@ -964,11 +996,22 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
if (!sqlInterface->execSqlQuery(query))
return Response::RespRegistrationFailed;
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "", true);
return Response::RespRegistrationAcceptedNeedsActivation;
} else {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "", true);
return Response::RespRegistrationAccepted;
}
} else {
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", "Unknown reason for failure", false);
return Response::RespRegistrationFailed;
}
}
@ -984,13 +1027,25 @@ Response::ResponseCode AbstractServerSocketInterface::cmdActivateAccount(const C
{
QString userName = QString::fromStdString(cmd.user_name());
QString token = QString::fromStdString(cmd.token());
QString clientID = QString::fromStdString(cmd.clientid());
if (clientID.isEmpty())
clientID = "UNKNOWN";
if(sqlInterface->activateUser(userName, token))
{
qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name());
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), clientID, "ACTIVATE_ACCOUNT", "", true);
return Response::RespActivationAccepted;
} else {
qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name());
if (servatrice->getEnableRegistrationAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), clientID, "ACTIVATE_ACCOUNT", "Failed to activate account, incorrect activation token", false);
return Response::RespActivationFailed;
}
}
@ -1067,13 +1122,25 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordRequest(c
{
qDebug() << "Received forgot password request from user: " << QString::fromStdString(cmd.user_name());
if (!servatrice->getEnableForgotPassword())
return Response::RespFunctionNotAllowed;
if (!servatrice->getEnableForgotPassword()) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_REQUEST", "Server functionality disabled", false);
if (!sqlInterface->userExists(QString::fromStdString(cmd.user_name())))
return Response::RespFunctionNotAllowed;
}
if (!sqlInterface->userExists(QString::fromStdString(cmd.user_name()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_REQUEST", "User does not exist", false);
return Response::RespFunctionNotAllowed;
}
if (sqlInterface->doesForgotPasswordExist(QString::fromStdString(cmd.user_name()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_REQUEST", "Request already exists", true);
Response_ForgotPasswordRequest *re = new Response_ForgotPasswordRequest;
re->set_challenge_email(false);
rc.setResponseExtension(re);
@ -1081,10 +1148,17 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordRequest(c
}
QString banReason; int banTimeRemaining;
if (sqlInterface->checkUserIsBanned(this->getAddress(), QString::fromStdString(cmd.user_name()), QString::fromStdString(cmd.clientid()), banReason, banTimeRemaining))
if (sqlInterface->checkUserIsBanned(this->getAddress(), QString::fromStdString(cmd.user_name()), QString::fromStdString(cmd.clientid()), banReason, banTimeRemaining)) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_REQUEST", "User is banned", false);
return Response::RespFunctionNotAllowed;
}
if (servatrice->getEnableForgotPasswordChallenge()) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_REQUEST", "Request does not exist, challenge requested", true);
Response_ForgotPasswordRequest *re = new Response_ForgotPasswordRequest;
re->set_challenge_email(true);
rc.setResponseExtension(re);
@ -1092,6 +1166,10 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordRequest(c
}
else {
if (sqlInterface->addForgotPassword(QString::fromStdString(cmd.user_name()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_REQUEST", "Request does not exist, challenge not requested", true);
Response_ForgotPasswordRequest *re = new Response_ForgotPasswordRequest;
re->set_challenge_email(false);
rc.setResponseExtension(re);
@ -1107,13 +1185,24 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordReset(con
Q_UNUSED(rc);
qDebug() << "Received forgot password reset from user: " << QString::fromStdString(cmd.user_name());
if (!sqlInterface->doesForgotPasswordExist(QString::fromStdString(cmd.user_name())))
return Response::RespFunctionNotAllowed;
if (!sqlInterface->doesForgotPasswordExist(QString::fromStdString(cmd.user_name()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET", "Request does not exist for user", false);
if (!sqlInterface->validateTableColumnStringData("{prefix}_users","token", QString::fromStdString(cmd.user_name()),QString::fromStdString(cmd.token())))
return Response::RespFunctionNotAllowed;
}
if (!sqlInterface->validateTableColumnStringData("{prefix}_users", "token", QString::fromStdString(cmd.user_name()), QString::fromStdString(cmd.token()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET", "Failed token validation", false);
return Response::RespFunctionNotAllowed;
}
if (sqlInterface->changeUserPassword(QString::fromStdString(cmd.user_name()), "", QString::fromStdString(cmd.new_password()), true)) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET", "", true);
sqlInterface->removeForgotPassword(QString::fromStdString(cmd.user_name()));
return Response::RespOk;
}
@ -1126,12 +1215,24 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordChallenge
Q_UNUSED(rc);
qDebug() << "Received forgot password challenge from user: " << QString::fromStdString(cmd.user_name());
if (sqlInterface->doesForgotPasswordExist(QString::fromStdString(cmd.user_name())))
return Response::RespOk;
if (sqlInterface->doesForgotPasswordExist(QString::fromStdString(cmd.user_name()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_CHALLANGE", "Request does not exist for user", false);
return Response::RespOk;
}
if (sqlInterface->validateTableColumnStringData("{prefix}_users", "email", QString::fromStdString(cmd.user_name()), QString::fromStdString(cmd.email()))) {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_CHALLANGE", "", true);
if (sqlInterface->validateTableColumnStringData("{prefix}_users","email", QString::fromStdString(cmd.user_name()), QString::fromStdString(cmd.email())))
if (sqlInterface->addForgotPassword(QString::fromStdString(cmd.user_name())))
return Response::RespOk;
}
else {
if (servatrice->getEnableForgotPasswordAudit())
sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET_CHALLANGE", "Failed to answer email challenge question", false);
}
return Response::RespFunctionNotAllowed;
}