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,
|
StatusDisconnecting,
|
||||||
StatusConnecting,
|
StatusConnecting,
|
||||||
StatusRegistering,
|
StatusRegistering,
|
||||||
|
StatusActivating,
|
||||||
StatusLoggingIn,
|
StatusLoggingIn,
|
||||||
StatusLoggedIn,
|
StatusLoggedIn,
|
||||||
};
|
};
|
||||||
|
@ -60,6 +61,8 @@ signals:
|
||||||
void ignoreListReceived(const QList<ServerInfo_User> &ignoreList);
|
void ignoreListReceived(const QList<ServerInfo_User> &ignoreList);
|
||||||
void replayAddedEventReceived(const Event_ReplayAdded &event);
|
void replayAddedEventReceived(const Event_ReplayAdded &event);
|
||||||
void registerAccepted();
|
void registerAccepted();
|
||||||
|
void registerAcceptedNeedsActivate();
|
||||||
|
void activateAccepted();
|
||||||
|
|
||||||
void sigQueuePendingCommand(PendingCommand *pend);
|
void sigQueuePendingCommand(PendingCommand *pend);
|
||||||
private:
|
private:
|
||||||
|
@ -72,7 +75,7 @@ protected slots:
|
||||||
void processProtocolItem(const ServerMessage &item);
|
void processProtocolItem(const ServerMessage &item);
|
||||||
protected:
|
protected:
|
||||||
QMap<int, PendingCommand *> pendingCommands;
|
QMap<int, PendingCommand *> pendingCommands;
|
||||||
QString userName, password, email, country, realName;
|
QString userName, password, email, country, realName, token;
|
||||||
int gender;
|
int gender;
|
||||||
void setStatus(ClientStatus _status);
|
void setStatus(ClientStatus _status);
|
||||||
int getNewCmdId() { return nextCmdId++; }
|
int getNewCmdId() { return nextCmdId++; }
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "pb/session_commands.pb.h"
|
#include "pb/session_commands.pb.h"
|
||||||
#include "pb/response_login.pb.h"
|
#include "pb/response_login.pb.h"
|
||||||
#include "pb/response_register.pb.h"
|
#include "pb/response_register.pb.h"
|
||||||
|
#include "pb/response_activate.pb.h"
|
||||||
#include "pb/server_message.pb.h"
|
#include "pb/server_message.pb.h"
|
||||||
#include "pb/event_server_identification.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(sigConnectToServer(QString, unsigned int, QString, QString)), this, SLOT(doConnectToServer(QString, unsigned int, QString, QString)));
|
||||||
connect(this, SIGNAL(sigDisconnectFromServer()), this, SLOT(doDisconnectFromServer()));
|
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(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()
|
RemoteClient::~RemoteClient()
|
||||||
|
@ -81,6 +83,24 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
|
||||||
return;
|
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);
|
setStatus(StatusLoggingIn);
|
||||||
|
|
||||||
Command_Login cmdLogin;
|
Command_Login cmdLogin;
|
||||||
|
@ -122,13 +142,34 @@ void RemoteClient::loginResponse(const Response &response)
|
||||||
void RemoteClient::registerResponse(const Response &response)
|
void RemoteClient::registerResponse(const Response &response)
|
||||||
{
|
{
|
||||||
const Response_Register &resp = response.GetExtension(Response_Register::ext);
|
const Response_Register &resp = response.GetExtension(Response_Register::ext);
|
||||||
if (response.response_code() == Response::RespRegistrationAccepted) {
|
switch(response.response_code())
|
||||||
emit registerAccepted();
|
{
|
||||||
} else {
|
case Response::RespRegistrationAccepted:
|
||||||
emit registerError(response.response_code(), QString::fromStdString(resp.denied_reason_str()), resp.denied_end_time());
|
emit registerAccepted();
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
setStatus(StatusDisconnecting);
|
|
||||||
doDisconnectFromServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::readData()
|
void RemoteClient::readData()
|
||||||
|
@ -201,6 +242,9 @@ void RemoteClient::doConnectToServer(const QString &hostname, unsigned int port,
|
||||||
|
|
||||||
userName = _userName;
|
userName = _userName;
|
||||||
password = _password;
|
password = _password;
|
||||||
|
lastHostname = hostname;
|
||||||
|
lastPort = port;
|
||||||
|
|
||||||
socket->connectToHost(hostname, port);
|
socket->connectToHost(hostname, port);
|
||||||
setStatus(StatusConnecting);
|
setStatus(StatusConnecting);
|
||||||
}
|
}
|
||||||
|
@ -215,11 +259,23 @@ void RemoteClient::doRegisterToServer(const QString &hostname, unsigned int port
|
||||||
gender = _gender;
|
gender = _gender;
|
||||||
country = _country;
|
country = _country;
|
||||||
realName = _realname;
|
realName = _realname;
|
||||||
|
lastHostname = hostname;
|
||||||
|
lastPort = port;
|
||||||
|
|
||||||
socket->connectToHost(hostname, port);
|
socket->connectToHost(hostname, port);
|
||||||
setStatus(StatusRegistering);
|
setStatus(StatusRegistering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteClient::doActivateToServer(const QString &_token)
|
||||||
|
{
|
||||||
|
doDisconnectFromServer();
|
||||||
|
|
||||||
|
token = _token;
|
||||||
|
|
||||||
|
socket->connectToHost(lastHostname, lastPort);
|
||||||
|
setStatus(StatusActivating);
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteClient::doDisconnectFromServer()
|
void RemoteClient::doDisconnectFromServer()
|
||||||
{
|
{
|
||||||
timer->stop();
|
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);
|
emit sigRegisterToServer(hostname, port, _userName, _password, _email, _gender, _country, _realname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteClient::activateToServer(const QString &_token)
|
||||||
|
{
|
||||||
|
emit sigActivateToServer(_token);
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteClient::disconnectFromServer()
|
void RemoteClient::disconnectFromServer()
|
||||||
{
|
{
|
||||||
emit sigDisconnectFromServer();
|
emit sigDisconnectFromServer();
|
||||||
|
|
|
@ -13,11 +13,13 @@ signals:
|
||||||
void serverTimeout();
|
void serverTimeout();
|
||||||
void loginError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
void loginError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
||||||
void registerError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
void registerError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
|
||||||
|
void activateError();
|
||||||
void socketError(const QString &errorString);
|
void socketError(const QString &errorString);
|
||||||
void protocolVersionMismatch(int clientVersion, int serverVersion);
|
void protocolVersionMismatch(int clientVersion, int serverVersion);
|
||||||
void protocolError();
|
void protocolError();
|
||||||
void sigConnectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password);
|
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 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();
|
void sigDisconnectFromServer();
|
||||||
private slots:
|
private slots:
|
||||||
void slotConnected();
|
void slotConnected();
|
||||||
|
@ -28,9 +30,13 @@ private slots:
|
||||||
void processConnectionClosedEvent(const Event_ConnectionClosed &event);
|
void processConnectionClosedEvent(const Event_ConnectionClosed &event);
|
||||||
void loginResponse(const Response &response);
|
void loginResponse(const Response &response);
|
||||||
void registerResponse(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 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 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 doDisconnectFromServer();
|
||||||
|
void doActivateToServer(const QString &_token);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int maxTimeout = 10;
|
static const int maxTimeout = 10;
|
||||||
int timeRunning, lastDataReceived;
|
int timeRunning, lastDataReceived;
|
||||||
|
@ -42,6 +48,8 @@ private:
|
||||||
|
|
||||||
QTimer *timer;
|
QTimer *timer;
|
||||||
QTcpSocket *socket;
|
QTcpSocket *socket;
|
||||||
|
QString lastHostname;
|
||||||
|
int lastPort;
|
||||||
protected slots:
|
protected slots:
|
||||||
void sendCommandContainer(const CommandContainer &cont);
|
void sendCommandContainer(const CommandContainer &cont);
|
||||||
public:
|
public:
|
||||||
|
@ -50,7 +58,7 @@ public:
|
||||||
QString peerName() const { return socket->peerName(); }
|
QString peerName() const { return socket->peerName(); }
|
||||||
void connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password);
|
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 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();
|
void disconnectFromServer();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,17 @@ void MainWindow::userInfoReceived(const ServerInfo_User &info)
|
||||||
|
|
||||||
void MainWindow::registerAccepted()
|
void MainWindow::registerAccepted()
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, tr("Success"), tr("Registration accepted.\nNow check your email for instructions on how to activate your account."));
|
QMessageBox::information(this, tr("Success"), tr("Registration accepted.\nWill now login."));
|
||||||
actConnect();
|
}
|
||||||
|
|
||||||
|
void MainWindow::registerAcceptedNeedsActivate()
|
||||||
|
{
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::activateAccepted()
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Success"), tr("Account activation accepted.\nWill now login."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
@ -299,11 +308,20 @@ void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32
|
||||||
actRegister();
|
actRegister();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Response::RespAccountNotActivated:
|
case Response::RespAccountNotActivated: {
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Your account has not been activated yet."));
|
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;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Unknown login error: %1").arg(static_cast<int>(r)));
|
QMessageBox::critical(this, tr("Error"), tr("Unknown login error: %1").arg(static_cast<int>(r)));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
actConnect();
|
actConnect();
|
||||||
}
|
}
|
||||||
|
@ -350,6 +368,13 @@ void MainWindow::registerError(Response::ResponseCode r, QString reasonStr, quin
|
||||||
actRegister();
|
actRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::activateError()
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Account activation failed"));
|
||||||
|
client->disconnectFromServer();
|
||||||
|
actConnect();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::socketError(const QString &errorStr)
|
void MainWindow::socketError(const QString &errorStr)
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Socket error: %1").arg(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(userInfoChanged(const ServerInfo_User &)), this, SLOT(userInfoReceived(const ServerInfo_User &)), Qt::BlockingQueuedConnection);
|
||||||
|
|
||||||
connect(client, SIGNAL(registerAccepted()), this, SLOT(registerAccepted()));
|
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(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);
|
clientThread = new QThread(this);
|
||||||
client->moveToThread(clientThread);
|
client->moveToThread(clientThread);
|
||||||
|
|
|
@ -44,10 +44,13 @@ private slots:
|
||||||
void serverTimeout();
|
void serverTimeout();
|
||||||
void loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
void loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
||||||
void registerError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
void registerError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
|
||||||
|
void activateError();
|
||||||
void socketError(const QString &errorStr);
|
void socketError(const QString &errorStr);
|
||||||
void protocolVersionMismatch(int localVersion, int remoteVersion);
|
void protocolVersionMismatch(int localVersion, int remoteVersion);
|
||||||
void userInfoReceived(const ServerInfo_User &userInfo);
|
void userInfoReceived(const ServerInfo_User &userInfo);
|
||||||
void registerAccepted();
|
void registerAccepted();
|
||||||
|
void registerAcceptedNeedsActivate();
|
||||||
|
void activateAccepted();
|
||||||
void localGameEnded();
|
void localGameEnded();
|
||||||
void pixmapCacheSizeChanged(int newSizeInMBs);
|
void pixmapCacheSizeChanged(int newSizeInMBs);
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ SET(PROTO_FILES
|
||||||
isl_message.proto
|
isl_message.proto
|
||||||
moderator_commands.proto
|
moderator_commands.proto
|
||||||
move_card_to_zone.proto
|
move_card_to_zone.proto
|
||||||
|
response_activate.proto
|
||||||
response_deck_download.proto
|
response_deck_download.proto
|
||||||
response_deck_list.proto
|
response_deck_list.proto
|
||||||
response_deck_upload.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
|
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
|
RespRegistrationDisabled = 29; // Server does not allow clients to register
|
||||||
RespRegistrationFailed = 30; // Server accepted a reg request but failed to perform the registration
|
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 {
|
enum ResponseType {
|
||||||
JOIN_ROOM = 1000;
|
JOIN_ROOM = 1000;
|
||||||
|
@ -44,6 +47,7 @@ message Response {
|
||||||
DECK_DOWNLOAD = 1007;
|
DECK_DOWNLOAD = 1007;
|
||||||
DECK_UPLOAD = 1008;
|
DECK_UPLOAD = 1008;
|
||||||
REGISTER = 1009;
|
REGISTER = 1009;
|
||||||
|
ACTIVATE = 1010;
|
||||||
REPLAY_LIST = 1100;
|
REPLAY_LIST = 1100;
|
||||||
REPLAY_DOWNLOAD = 1101;
|
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;
|
LIST_ROOMS = 1014;
|
||||||
JOIN_ROOM = 1015;
|
JOIN_ROOM = 1015;
|
||||||
REGISTER = 1016;
|
REGISTER = 1016;
|
||||||
|
ACTIVATE = 1017;
|
||||||
REPLAY_LIST = 1100;
|
REPLAY_LIST = 1100;
|
||||||
REPLAY_DOWNLOAD = 1101;
|
REPLAY_DOWNLOAD = 1101;
|
||||||
REPLAY_MODIFY_MATCH = 1102;
|
REPLAY_MODIFY_MATCH = 1102;
|
||||||
|
@ -115,3 +116,14 @@ message Command_Register {
|
||||||
optional string country = 5;
|
optional string country = 5;
|
||||||
optional string real_name = 6;
|
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)
|
if(password.length() < 6)
|
||||||
return PasswordTooShort;
|
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)
|
bool Server::tooManyRegistrationAttempts(const QString &ipAddress)
|
||||||
|
|
|
@ -29,7 +29,7 @@ class CommandContainer;
|
||||||
class Command_JoinGame;
|
class Command_JoinGame;
|
||||||
|
|
||||||
enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive };
|
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
|
class Server : public QObject
|
||||||
{
|
{
|
||||||
|
@ -57,6 +57,7 @@ public:
|
||||||
* @return RegistrationResult member indicating whether it succeeded or failed.
|
* @return RegistrationResult member indicating whether it succeeded or failed.
|
||||||
*/
|
*/
|
||||||
RegistrationResult registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining);
|
RegistrationResult registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining);
|
||||||
|
bool activateUserAccount(const Command_Activate &cmd);
|
||||||
|
|
||||||
bool tooManyRegistrationAttempts(const QString &ipAddress);
|
bool tooManyRegistrationAttempts(const QString &ipAddress);
|
||||||
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
|
|
||||||
virtual bool getRequireRegistration() { return false; }
|
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 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 };
|
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 */) { };
|
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::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
|
||||||
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::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::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::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_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;
|
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
||||||
|
@ -437,8 +438,11 @@ Response::ResponseCode Server_ProtocolHandler::cmdRegisterAccount(const Command_
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case RegistrationDisabled:
|
case RegistrationDisabled:
|
||||||
return Response::RespRegistrationDisabled;
|
return Response::RespRegistrationDisabled;
|
||||||
case Accepted:
|
case Accepted:
|
||||||
return Response::RespRegistrationAccepted;
|
return Response::RespRegistrationAccepted;
|
||||||
|
case AcceptedNeedsActivation:
|
||||||
|
// TODO SEND EMAIL WITH TOKEN TO THE USER
|
||||||
|
return Response::RespRegistrationAcceptedNeedsActivation;
|
||||||
case UserAlreadyExists:
|
case UserAlreadyExists:
|
||||||
return Response::RespUserAlreadyExists;
|
return Response::RespUserAlreadyExists;
|
||||||
case EmailRequired:
|
case EmailRequired:
|
||||||
|
@ -463,6 +467,18 @@ Response::ResponseCode Server_ProtocolHandler::cmdRegisterAccount(const Command_
|
||||||
return Response::RespInvalidCommand;
|
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)
|
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
|
|
|
@ -61,6 +61,7 @@ private:
|
||||||
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdRegisterAccount(const Command_Register &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 cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
||||||
|
|
|
@ -60,7 +60,9 @@ regonly=0
|
||||||
; Enable this feature? Default false.
|
; Enable this feature? Default false.
|
||||||
;enabled=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
|
;requireemail=true
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,3 +70,8 @@ QString PasswordHasher::generateRandomSalt(const int len)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString PasswordHasher::generateActivationToken()
|
||||||
|
{
|
||||||
|
return QCryptographicHash::hash(generateRandomSalt().toUtf8(), QCryptographicHash::Md5).toBase64().left(16);
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ public:
|
||||||
static void initialize();
|
static void initialize();
|
||||||
static QString computeHash(const QString &password, const QString &salt);
|
static QString computeHash(const QString &password, const QString &salt);
|
||||||
static QString generateRandomSalt(const int len = 16);
|
static QString generateRandomSalt(const int len = 16);
|
||||||
|
static QString generateActivationToken();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -117,11 +117,12 @@ bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const Q
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
|
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
|
||||||
|
QString token = PasswordHasher::generateActivationToken();
|
||||||
|
|
||||||
QSqlQuery *query = prepareQuery("insert into {prefix}_users "
|
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 "
|
"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(":userName", userName);
|
||||||
query->bindValue(":realName", realName);
|
query->bindValue(":realName", realName);
|
||||||
query->bindValue(":gender", getGenderChar(gender));
|
query->bindValue(":gender", getGenderChar(gender));
|
||||||
|
@ -129,6 +130,7 @@ bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const Q
|
||||||
query->bindValue(":email", emailAddress);
|
query->bindValue(":email", emailAddress);
|
||||||
query->bindValue(":country", country);
|
query->bindValue(":country", country);
|
||||||
query->bindValue(":active", active ? 1 : 0);
|
query->bindValue(":active", active ? 1 : 0);
|
||||||
|
query->bindValue(":token", token);
|
||||||
|
|
||||||
if (!execSqlQuery(query)) {
|
if (!execSqlQuery(query)) {
|
||||||
qDebug() << "Failed to insert user: " << query->lastError() << " sql: " << query->lastQuery();
|
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;
|
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)
|
QChar Servatrice_DatabaseInterface::getGenderChar(ServerInfo_User_Gender const &gender)
|
||||||
{
|
{
|
||||||
switch (gender) {
|
switch (gender) {
|
||||||
|
|
|
@ -65,6 +65,7 @@ public:
|
||||||
|
|
||||||
bool getRequireRegistration();
|
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 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);
|
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