diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h b/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h index 1d18603a3..56e3373ef 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h @@ -774,6 +774,24 @@ public: virtual void setForcePasswordChange(const QString & /* user */, bool /* force */) { } + /** @brief The account fields a self-service edit may change; unset fields are left alone. */ + struct AccountUpdateRecord + { + bool hasRealName = false; + QString realName; + bool hasEmail = false; + QString email; + bool hasCountry = false; + QString country; + }; + virtual bool updateUserAccount(const QString & /* userName */, const AccountUpdateRecord & /* update */) + { + return false; + } + virtual bool setUserAvatar(int /* userId */, const QByteArray & /* image */) + { + return false; + } /** @brief Outcome of reading or writing one account field. */ enum class UserFieldResult { diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index 6d8eb4588..96f1ae423 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -2244,6 +2244,51 @@ void Servatrice_DatabaseInterface::setForcePasswordChange(const QString &user, b execSqlQuery(query); } +bool Servatrice_DatabaseInterface::updateUserAccount(const QString &userName, const AccountUpdateRecord &update) +{ + if (!checkSql()) { + return false; + } + + QStringList queryList; + if (update.hasRealName) { + queryList << "realname=:realName"; + } + if (update.hasEmail) { + queryList << "email=:email"; + } + if (update.hasCountry) { + queryList << "country=:country"; + } + + const QString queryText = QString("update {prefix}_users set %1 where name=:userName").arg(queryList.join(", ")); + QSqlQuery *query = prepareQuery(queryText); + if (update.hasRealName) { + query->bindValue(":realName", update.realName); + } + if (update.hasEmail) { + query->bindValue(":email", update.email); + } + if (update.hasCountry) { + query->bindValue(":country", update.country); + } + query->bindValue(":userName", userName); + + return execSqlQuery(query); +} + +bool Servatrice_DatabaseInterface::setUserAvatar(int userId, const QByteArray &image) +{ + if (!checkSql()) { + return false; + } + + QSqlQuery *query = prepareQuery("update {prefix}_users set avatar_bmp=:image where id=:id"); + query->bindValue(":image", image); + query->bindValue(":id", userId); + return execSqlQuery(query); +} + bool Servatrice_DatabaseInterface::changeUserPassword(const QString &user, const QString &oldPassword, bool oldPasswordNeedsHash, diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index 60e86f285..27e8670a9 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -223,6 +223,8 @@ public: const QString &newPassword, bool newPasswordNeedsHash) override; void setForcePasswordChange(const QString &user, bool force) override; + bool updateUserAccount(const QString &userName, const AccountUpdateRecord &update) override; + bool setUserAvatar(int userId, const QByteArray &image) override; QList getUserBanHistory(const QString &userName) override; bool addWarning(const QString userName, const QString adminName, diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 9a944b870..7d8688db7 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -2903,43 +2903,26 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountEdit(const Comma } } - QStringList queryList({}); - if (cmd.has_real_name()) { - queryList << "realname=:realName"; - } + Server_DatabaseInterface::AccountUpdateRecord update; + update.hasRealName = cmd.has_real_name(); + update.realName = realName; + update.hasCountry = cmd.has_country(); + update.country = country; if (cmd.has_email()) { // a real password is required in order to change the email address if (usingRealPassword || checkedPassword) { - queryList << "email=:email"; + update.hasEmail = true; + update.email = parsedEmailAddress; } else { return Response::RespFunctionNotAllowed; } } - if (cmd.has_country()) { - queryList << "country=:country"; - } - if (queryList.isEmpty()) { + if (!update.hasRealName && !update.hasEmail && !update.hasCountry) { return Response::RespOk; } - QString queryText = QString("update {prefix}_users set %1 where name=:userName").arg(queryList.join(", ")); - QSqlQuery *query = sqlInterface->prepareQuery(queryText); - if (cmd.has_real_name()) { - auto _realName = nameFromStdString(cmd.real_name()); - query->bindValue(":realName", _realName); - } - if (cmd.has_email()) { - const auto _parsedEmailAddress = EmailParser::getParsedEmailAddress(nameFromStdString(cmd.email())); - query->bindValue(":email", _parsedEmailAddress); - } - if (cmd.has_country()) { - auto _country = nameFromStdString(cmd.country()); - query->bindValue(":country", _country); - } - query->bindValue(":userName", userName); - - if (!sqlInterface->execSqlQuery(query)) { + if (!databaseInterface->updateUserAccount(userName, update)) { return Response::RespInternalError; } @@ -2967,10 +2950,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountImage(const Comm QByteArray image(cmd.image().c_str(), length); int id = userInfo->id(); - QSqlQuery *query = sqlInterface->prepareQuery("update {prefix}_users set avatar_bmp=:image where id=:id"); - query->bindValue(":image", image); - query->bindValue(":id", id); - if (!sqlInterface->execSqlQuery(query)) { + if (!databaseInterface->setUserAvatar(id, image)) { return Response::RespInternalError; }