Added token generation, user activation command and response.
This commit is contained in:
parent
42796b0d0e
commit
ff1aed717e
19 changed files with 223 additions and 19 deletions
|
@ -30,6 +30,7 @@ enum ClientStatus {
|
|||
StatusDisconnecting,
|
||||
StatusConnecting,
|
||||
StatusRegistering,
|
||||
StatusActivating,
|
||||
StatusLoggingIn,
|
||||
StatusLoggedIn,
|
||||
};
|
||||
|
@ -60,6 +61,8 @@ signals:
|
|||
void ignoreListReceived(const QList<ServerInfo_User> &ignoreList);
|
||||
void replayAddedEventReceived(const Event_ReplayAdded &event);
|
||||
void registerAccepted();
|
||||
void registerAcceptedNeedsActivate();
|
||||
void activateAccepted();
|
||||
|
||||
void sigQueuePendingCommand(PendingCommand *pend);
|
||||
private:
|
||||
|
@ -72,7 +75,7 @@ protected slots:
|
|||
void processProtocolItem(const ServerMessage &item);
|
||||
protected:
|
||||
QMap<int, PendingCommand *> pendingCommands;
|
||||
QString userName, password, email, country, realName;
|
||||
QString userName, password, email, country, realName, token;
|
||||
int gender;
|
||||
void setStatus(ClientStatus _status);
|
||||
int getNewCmdId() { return nextCmdId++; }
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "pb/session_commands.pb.h"
|
||||
#include "pb/response_login.pb.h"
|
||||
#include "pb/response_register.pb.h"
|
||||
#include "pb/response_activate.pb.h"
|
||||
#include "pb/server_message.pb.h"
|
||||
#include "pb/event_server_identification.pb.h"
|
||||
|
||||
|
@ -30,6 +31,7 @@ RemoteClient::RemoteClient(QObject *parent)
|
|||
connect(this, SIGNAL(sigConnectToServer(QString, unsigned int, QString, QString)), this, SLOT(doConnectToServer(QString, unsigned int, QString, QString)));
|
||||
connect(this, SIGNAL(sigDisconnectFromServer()), this, SLOT(doDisconnectFromServer()));
|
||||
connect(this, SIGNAL(sigRegisterToServer(QString, unsigned int, QString, QString, QString, int, QString, QString)), this, SLOT(doRegisterToServer(QString, unsigned int, QString, QString, QString, int, QString, QString)));
|
||||
connect(this, SIGNAL(sigActivateToServer(QString)), this, SLOT(doActivateToServer(QString)));
|
||||
}
|
||||
|
||||
RemoteClient::~RemoteClient()
|
||||
|
@ -81,6 +83,24 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
|
|||
return;
|
||||
}
|
||||
|
||||
if(getStatus() == StatusActivating)
|
||||
{
|
||||
Command_Activate cmdActivate;
|
||||
cmdActivate.set_user_name(userName.toStdString());
|
||||
cmdActivate.set_token(token.toStdString());
|
||||
|
||||
PendingCommand *pend = prepareSessionCommand(cmdActivate);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(activateResponse(Response)));
|
||||
sendCommand(pend);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
doLogin();
|
||||
}
|
||||
|
||||
void RemoteClient::doLogin()
|
||||
{
|
||||
setStatus(StatusLoggingIn);
|
||||
|
||||
Command_Login cmdLogin;
|
||||
|
@ -122,13 +142,34 @@ void RemoteClient::loginResponse(const Response &response)
|
|||
void RemoteClient::registerResponse(const Response &response)
|
||||
{
|
||||
const Response_Register &resp = response.GetExtension(Response_Register::ext);
|
||||
if (response.response_code() == Response::RespRegistrationAccepted) {
|
||||
switch(response.response_code())
|
||||
{
|
||||
case Response::RespRegistrationAccepted:
|
||||
emit registerAccepted();
|
||||
} else {
|
||||
doLogin();
|
||||
break;
|
||||
case Response::RespRegistrationAcceptedNeedsActivation:
|
||||
emit registerAcceptedNeedsActivate();
|
||||
doLogin();
|
||||
break;
|
||||
default:
|
||||
emit registerError(response.response_code(), QString::fromStdString(resp.denied_reason_str()), resp.denied_end_time());
|
||||
}
|
||||
setStatus(StatusDisconnecting);
|
||||
doDisconnectFromServer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteClient::activateResponse(const Response &response)
|
||||
{
|
||||
const Response_Activate &resp = response.GetExtension(Response_Activate::ext);
|
||||
if (response.response_code() == Response::RespActivationAccepted) {
|
||||
emit activateAccepted();
|
||||
|
||||
doLogin();
|
||||
} else {
|
||||
emit activateError();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteClient::readData()
|
||||
|
@ -201,6 +242,9 @@ void RemoteClient::doConnectToServer(const QString &hostname, unsigned int port,
|
|||
|
||||
userName = _userName;
|
||||
password = _password;
|
||||
lastHostname = hostname;
|
||||
lastPort = port;
|
||||
|
||||
socket->connectToHost(hostname, port);
|
||||
setStatus(StatusConnecting);
|
||||
}
|
||||
|
@ -215,11 +259,23 @@ void RemoteClient::doRegisterToServer(const QString &hostname, unsigned int port
|
|||
gender = _gender;
|
||||
country = _country;
|
||||
realName = _realname;
|
||||
lastHostname = hostname;
|
||||
lastPort = port;
|
||||
|
||||
socket->connectToHost(hostname, port);
|
||||
setStatus(StatusRegistering);
|
||||
}
|
||||
|
||||
void RemoteClient::doActivateToServer(const QString &_token)
|
||||
{
|
||||
doDisconnectFromServer();
|
||||
|
||||
token = _token;
|
||||
|
||||
socket->connectToHost(lastHostname, lastPort);
|
||||
setStatus(StatusActivating);
|
||||
}
|
||||
|
||||
void RemoteClient::doDisconnectFromServer()
|
||||
{
|
||||
timer->stop();
|
||||
|
@ -275,6 +331,11 @@ void RemoteClient::registerToServer(const QString &hostname, unsigned int port,
|
|||
emit sigRegisterToServer(hostname, port, _userName, _password, _email, _gender, _country, _realname);
|
||||
}
|
||||
|
||||
void RemoteClient::activateToServer(const QString &_token)
|
||||
{
|
||||
emit sigActivateToServer(_token);
|
||||
}
|
||||
|
||||
void RemoteClient::disconnectFromServer()
|
||||
{
|
||||
emit sigDisconnectFromServer();
|
||||
|
|
|
@ -13,11 +13,13 @@ signals:
|
|||
void serverTimeout();
|
||||
void loginError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
||||
void registerError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
||||
void activateError();
|
||||
void socketError(const QString &errorString);
|
||||
void protocolVersionMismatch(int clientVersion, int serverVersion);
|
||||
void protocolError();
|
||||
void sigConnectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password);
|
||||
void sigRegisterToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password, const QString &_email, const int _gender, const QString &_country, const QString &_realname);
|
||||
void sigActivateToServer(const QString &_token);
|
||||
void sigDisconnectFromServer();
|
||||
private slots:
|
||||
void slotConnected();
|
||||
|
@ -28,9 +30,13 @@ private slots:
|
|||
void processConnectionClosedEvent(const Event_ConnectionClosed &event);
|
||||
void loginResponse(const Response &response);
|
||||
void registerResponse(const Response &response);
|
||||
void activateResponse(const Response &response);
|
||||
void doConnectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password);
|
||||
void doRegisterToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password, const QString &_email, const int _gender, const QString &_country, const QString &_realname);
|
||||
void doLogin();
|
||||
void doDisconnectFromServer();
|
||||
void doActivateToServer(const QString &_token);
|
||||
|
||||
private:
|
||||
static const int maxTimeout = 10;
|
||||
int timeRunning, lastDataReceived;
|
||||
|
@ -42,6 +48,8 @@ private:
|
|||
|
||||
QTimer *timer;
|
||||
QTcpSocket *socket;
|
||||
QString lastHostname;
|
||||
int lastPort;
|
||||
protected slots:
|
||||
void sendCommandContainer(const CommandContainer &cont);
|
||||
public:
|
||||
|
@ -50,7 +58,7 @@ public:
|
|||
QString peerName() const { return socket->peerName(); }
|
||||
void connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password);
|
||||
void registerToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password, const QString &_email, const int _gender, const QString &_country, const QString &_realname);
|
||||
|
||||
void activateToServer(const QString &_token);
|
||||
void disconnectFromServer();
|
||||
};
|
||||
|
||||
|
|
|
@ -126,8 +126,17 @@ void MainWindow::userInfoReceived(const ServerInfo_User &info)
|
|||
|
||||
void MainWindow::registerAccepted()
|
||||
{
|
||||
QMessageBox::information(this, tr("Success"), tr("Registration accepted.\nNow check your email for instructions on how to activate your account."));
|
||||
actConnect();
|
||||
QMessageBox::information(this, tr("Success"), tr("Registration accepted.\nWill now login."));
|
||||
}
|
||||
|
||||
void MainWindow::registerAcceptedNeedsActivate()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
void MainWindow::activateAccepted()
|
||||
{
|
||||
QMessageBox::information(this, tr("Success"), tr("Account activation accepted.\nWill now login."));
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
@ -299,11 +308,20 @@ void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32
|
|||
actRegister();
|
||||
}
|
||||
break;
|
||||
case Response::RespAccountNotActivated:
|
||||
QMessageBox::critical(this, tr("Error"), tr("Your account has not been activated yet."));
|
||||
case Response::RespAccountNotActivated: {
|
||||
bool ok = false;
|
||||
QString token = QInputDialog::getText(this, tr("Account activation"), tr("Your account has not been activated yet.\n You need to provide the activation token received in the activation email"), QLineEdit::Normal, QString(), &ok);
|
||||
if(ok && !token.isEmpty())
|
||||
{
|
||||
client->activateToServer(token);
|
||||
return;
|
||||
}
|
||||
client->disconnectFromServer();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
QMessageBox::critical(this, tr("Error"), tr("Unknown login error: %1").arg(static_cast<int>(r)));
|
||||
break;
|
||||
}
|
||||
actConnect();
|
||||
}
|
||||
|
@ -350,6 +368,13 @@ void MainWindow::registerError(Response::ResponseCode r, QString reasonStr, quin
|
|||
actRegister();
|
||||
}
|
||||
|
||||
void MainWindow::activateError()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Account activation failed"));
|
||||
client->disconnectFromServer();
|
||||
actConnect();
|
||||
}
|
||||
|
||||
void MainWindow::socketError(const QString &errorStr)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Socket error: %1").arg(errorStr));
|
||||
|
@ -488,7 +513,10 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(client, SIGNAL(userInfoChanged(const ServerInfo_User &)), this, SLOT(userInfoReceived(const ServerInfo_User &)), Qt::BlockingQueuedConnection);
|
||||
|
||||
connect(client, SIGNAL(registerAccepted()), this, SLOT(registerAccepted()));
|
||||
connect(client, SIGNAL(registerAcceptedNeedsActivate()), this, SLOT(registerAcceptedNeedsActivate()));
|
||||
connect(client, SIGNAL(registerError(Response::ResponseCode, QString, quint32)), this, SLOT(registerError(Response::ResponseCode, QString, quint32)));
|
||||
connect(client, SIGNAL(activateAccepted()), this, SLOT(activateAccepted()));
|
||||
connect(client, SIGNAL(activateError()), this, SLOT(activateError()));
|
||||
|
||||
clientThread = new QThread(this);
|
||||
client->moveToThread(clientThread);
|
||||
|
|
|
@ -44,10 +44,13 @@ private slots:
|
|||
void serverTimeout();
|
||||
void loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
||||
void registerError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
||||
void activateError();
|
||||
void socketError(const QString &errorStr);
|
||||
void protocolVersionMismatch(int localVersion, int remoteVersion);
|
||||
void userInfoReceived(const ServerInfo_User &userInfo);
|
||||
void registerAccepted();
|
||||
void registerAcceptedNeedsActivate();
|
||||
void activateAccepted();
|
||||
void localGameEnded();
|
||||
void pixmapCacheSizeChanged(int newSizeInMBs);
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ SET(PROTO_FILES
|
|||
isl_message.proto
|
||||
moderator_commands.proto
|
||||
move_card_to_zone.proto
|
||||
response_activate.proto
|
||||
response_deck_download.proto
|
||||
response_deck_list.proto
|
||||
response_deck_upload.proto
|
||||
|
|
|
@ -32,6 +32,9 @@ message Response {
|
|||
RespAccountNotActivated = 28; // Client attempted to log into a registered username but the account hasn't been activated
|
||||
RespRegistrationDisabled = 29; // Server does not allow clients to register
|
||||
RespRegistrationFailed = 30; // Server accepted a reg request but failed to perform the registration
|
||||
RespActivationAccepted = 31; // Server accepted a reg user activation token
|
||||
RespActivationFailed = 32; // Server didn't accept a reg user activation token
|
||||
RespRegistrationAcceptedNeedsActivation = 33; // Server accepted cient registration, but it will need token activation
|
||||
}
|
||||
enum ResponseType {
|
||||
JOIN_ROOM = 1000;
|
||||
|
@ -44,6 +47,7 @@ message Response {
|
|||
DECK_DOWNLOAD = 1007;
|
||||
DECK_UPLOAD = 1008;
|
||||
REGISTER = 1009;
|
||||
ACTIVATE = 1010;
|
||||
REPLAY_LIST = 1100;
|
||||
REPLAY_DOWNLOAD = 1101;
|
||||
}
|
||||
|
|
7
common/pb/response_activate.proto
Normal file
7
common/pb/response_activate.proto
Normal file
|
@ -0,0 +1,7 @@
|
|||
import "response.proto";
|
||||
|
||||
message Response_Activate {
|
||||
extend Response {
|
||||
optional Response_Activate ext = 1010;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ message SessionCommand {
|
|||
LIST_ROOMS = 1014;
|
||||
JOIN_ROOM = 1015;
|
||||
REGISTER = 1016;
|
||||
ACTIVATE = 1017;
|
||||
REPLAY_LIST = 1100;
|
||||
REPLAY_DOWNLOAD = 1101;
|
||||
REPLAY_MODIFY_MATCH = 1102;
|
||||
|
@ -115,3 +116,14 @@ message Command_Register {
|
|||
optional string country = 5;
|
||||
optional string real_name = 6;
|
||||
}
|
||||
|
||||
// User wants to activate an account
|
||||
message Command_Activate {
|
||||
extend SessionCommand {
|
||||
optional Command_Activate ext = 1017;
|
||||
}
|
||||
// User name client wants to activate
|
||||
required string user_name = 1;
|
||||
// Activation token
|
||||
required string token = 2;
|
||||
}
|
||||
|
|
|
@ -208,9 +208,22 @@ RegistrationResult Server::registerUserAccount(const QString &ipAddress, const C
|
|||
if(password.length() < 6)
|
||||
return PasswordTooShort;
|
||||
|
||||
bool regSucceeded = databaseInterface->registerUser(userName, realName, gender, password, emailAddress, country, false);
|
||||
bool regSucceeded = databaseInterface->registerUser(userName, realName, gender, password, emailAddress, country, !requireEmailForRegistration);
|
||||
|
||||
return regSucceeded ? Accepted : Failed;
|
||||
if(regSucceeded)
|
||||
return requireEmailForRegistration ? AcceptedNeedsActivation : Accepted;
|
||||
else
|
||||
return Failed;
|
||||
}
|
||||
|
||||
bool Server::activateUserAccount(const Command_Activate &cmd)
|
||||
{
|
||||
QString userName = QString::fromStdString(cmd.user_name());
|
||||
QString token = QString::fromStdString(cmd.token());
|
||||
|
||||
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
|
||||
|
||||
return databaseInterface->activateUser(userName, token);
|
||||
}
|
||||
|
||||
bool Server::tooManyRegistrationAttempts(const QString &ipAddress)
|
||||
|
|
|
@ -29,7 +29,7 @@ class CommandContainer;
|
|||
class Command_JoinGame;
|
||||
|
||||
enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive };
|
||||
enum RegistrationResult { Accepted, UserAlreadyExists, EmailRequired, TooManyRequests, InvalidUsername, ClientIsBanned, RegistrationDisabled, Failed, PasswordTooShort };
|
||||
enum RegistrationResult { Accepted, UserAlreadyExists, EmailRequired, TooManyRequests, InvalidUsername, ClientIsBanned, RegistrationDisabled, Failed, PasswordTooShort, AcceptedNeedsActivation };
|
||||
|
||||
class Server : public QObject
|
||||
{
|
||||
|
@ -57,6 +57,7 @@ public:
|
|||
* @return RegistrationResult member indicating whether it succeeded or failed.
|
||||
*/
|
||||
RegistrationResult registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining);
|
||||
bool activateUserAccount(const Command_Activate &cmd);
|
||||
|
||||
bool tooManyRegistrationAttempts(const QString &ipAddress);
|
||||
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
|
||||
virtual bool getRequireRegistration() { return false; }
|
||||
virtual bool registerUser(const QString & /* userName */, const QString & /* realName */, ServerInfo_User_Gender const & /* gender */, const QString & /* password */, const QString & /* emailAddress */, const QString & /* country */, bool /* active = false */) { return false; }
|
||||
virtual bool activateUser(const QString & /* userName */, const QString & /* token */) { return false; }
|
||||
|
||||
enum LogMessage_TargetType { MessageTargetRoom, MessageTargetGame, MessageTargetChat, MessageTargetIslRoom };
|
||||
virtual void logMessage(const int /* senderId */, const QString & /* senderName */, const QString & /* senderIp */, const QString & /* logMessage */, LogMessage_TargetType /* targetType */, const int /* targetId */, const QString & /* targetName */) { };
|
||||
|
|
|
@ -146,6 +146,7 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co
|
|||
case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
|
||||
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
|
||||
case SessionCommand::REGISTER: resp = cmdRegisterAccount(sc.GetExtension(Command_Register::ext), rc); break;
|
||||
case SessionCommand::ACTIVATE: resp = cmdActivateAccount(sc.GetExtension(Command_Activate::ext), rc); break;
|
||||
case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
|
||||
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
|
||||
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
||||
|
@ -439,6 +440,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdRegisterAccount(const Command_
|
|||
return Response::RespRegistrationDisabled;
|
||||
case Accepted:
|
||||
return Response::RespRegistrationAccepted;
|
||||
case AcceptedNeedsActivation:
|
||||
// TODO SEND EMAIL WITH TOKEN TO THE USER
|
||||
return Response::RespRegistrationAcceptedNeedsActivation;
|
||||
case UserAlreadyExists:
|
||||
return Response::RespUserAlreadyExists;
|
||||
case EmailRequired:
|
||||
|
@ -463,6 +467,18 @@ Response::ResponseCode Server_ProtocolHandler::cmdRegisterAccount(const Command_
|
|||
return Response::RespInvalidCommand;
|
||||
}
|
||||
|
||||
Response::ResponseCode Server_ProtocolHandler::cmdActivateAccount(const Command_Activate &cmd, ResponseContainer &rc)
|
||||
{
|
||||
if(server->activateUserAccount(cmd))
|
||||
{
|
||||
qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name());
|
||||
return Response::RespActivationAccepted;
|
||||
} else {
|
||||
qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name());
|
||||
return Response::RespActivationFailed;
|
||||
}
|
||||
}
|
||||
|
||||
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
|
||||
{
|
||||
if (authState == NotLoggedIn)
|
||||
|
|
|
@ -61,6 +61,7 @@ private:
|
|||
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
||||
|
|
|
@ -60,7 +60,9 @@ regonly=0
|
|||
; Enable this feature? Default false.
|
||||
;enabled=false
|
||||
|
||||
; Require users to provide an email address in order to register. Default true.
|
||||
; Require users to provide an email address in order to register. Newly registered users will receive an
|
||||
; activation token by email, and will be required to input back this token on cockatrice at the first login
|
||||
; to get their account activated. Default true.
|
||||
;requireemail=true
|
||||
|
||||
|
||||
|
|
|
@ -70,3 +70,8 @@ QString PasswordHasher::generateRandomSalt(const int len)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString PasswordHasher::generateActivationToken()
|
||||
{
|
||||
return QCryptographicHash::hash(generateRandomSalt().toUtf8(), QCryptographicHash::Md5).toBase64().left(16);
|
||||
}
|
|
@ -8,6 +8,7 @@ public:
|
|||
static void initialize();
|
||||
static QString computeHash(const QString &password, const QString &salt);
|
||||
static QString generateRandomSalt(const int len = 16);
|
||||
static QString generateActivationToken();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -117,11 +117,12 @@ bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const Q
|
|||
return false;
|
||||
|
||||
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
|
||||
QString token = PasswordHasher::generateActivationToken();
|
||||
|
||||
QSqlQuery *query = prepareQuery("insert into {prefix}_users "
|
||||
"(name, realname, gender, password_sha512, email, country, registrationDate, active) "
|
||||
"(name, realname, gender, password_sha512, email, country, registrationDate, active, token) "
|
||||
"values "
|
||||
"(:userName, :realName, :gender, :password_sha512, :email, :country, UTC_TIMESTAMP(), :active)");
|
||||
"(:userName, :realName, :gender, :password_sha512, :email, :country, UTC_TIMESTAMP(), :active, :token)");
|
||||
query->bindValue(":userName", userName);
|
||||
query->bindValue(":realName", realName);
|
||||
query->bindValue(":gender", getGenderChar(gender));
|
||||
|
@ -129,6 +130,7 @@ bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const Q
|
|||
query->bindValue(":email", emailAddress);
|
||||
query->bindValue(":country", country);
|
||||
query->bindValue(":active", active ? 1 : 0);
|
||||
query->bindValue(":token", token);
|
||||
|
||||
if (!execSqlQuery(query)) {
|
||||
qDebug() << "Failed to insert user: " << query->lastError() << " sql: " << query->lastQuery();
|
||||
|
@ -138,6 +140,40 @@ bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const Q
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::activateUser(const QString &userName, const QString &token)
|
||||
{
|
||||
if (!checkSql())
|
||||
return false;
|
||||
|
||||
QSqlQuery *activateQuery = prepareQuery("select name from {prefix}_users where active=0 and name=:username and token=:token");
|
||||
|
||||
activateQuery->bindValue(":username", userName);
|
||||
activateQuery->bindValue(":token", token);
|
||||
if (!execSqlQuery(activateQuery)) {
|
||||
qDebug() << "Account activation failed: SQL error." << activateQuery->lastError()<< " sql: " << activateQuery->lastQuery();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (activateQuery->next()) {
|
||||
const QString name = activateQuery->value(0).toString();
|
||||
// redundant check
|
||||
if(name == userName)
|
||||
{
|
||||
|
||||
QSqlQuery *query = prepareQuery("update {prefix}_users set active=1 where name = :userName");
|
||||
query->bindValue(":userName", userName);
|
||||
|
||||
if (!execSqlQuery(query)) {
|
||||
qDebug() << "Failed to activate user: " << query->lastError() << " sql: " << query->lastQuery();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QChar Servatrice_DatabaseInterface::getGenderChar(ServerInfo_User_Gender const &gender)
|
||||
{
|
||||
switch (gender) {
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
bool getRequireRegistration();
|
||||
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, bool active = false);
|
||||
bool activateUser(const QString &userName, const QString &token);
|
||||
|
||||
void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue