parent
b73ef58567
commit
07a8cd0a5f
6 changed files with 86 additions and 52 deletions
|
@ -5,6 +5,7 @@
|
|||
project(Servatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
|
||||
set(servatrice_SOURCES
|
||||
src/email_parser.cpp
|
||||
src/main.cpp
|
||||
src/servatrice.cpp
|
||||
src/servatrice_connection_pool.cpp
|
||||
|
|
54
servatrice/src/email_parser.cpp
Normal file
54
servatrice/src/email_parser.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "email_parser.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
|
||||
QPair<QString, QString> EmailParser::parseEmailAddress(const QString &dirtyEmailAddress)
|
||||
{
|
||||
// https://www.regular-expressions.info/email.html
|
||||
static const QRegularExpression emailRegex(R"(^([A-Z0-9._%+-]+)@([A-Z0-9.-]+\.[A-Z]{2,})$)",
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
const auto match = emailRegex.match(dirtyEmailAddress);
|
||||
|
||||
if (dirtyEmailAddress.isEmpty() || !match.hasMatch()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString capturedEmailUser = match.captured(1);
|
||||
QString capturedEmailAddressDomain = match.captured(2);
|
||||
|
||||
// Replace googlemail.com with gmail.com, as is standard nowadays
|
||||
// https://www.gmass.co/blog/domains-gmail-com-googlemail-com-and-google-com/
|
||||
if (capturedEmailAddressDomain.toLower() == "googlemail.com") {
|
||||
capturedEmailAddressDomain = "gmail.com";
|
||||
}
|
||||
|
||||
// Trim out dots and pluses from Google/Gmail domains
|
||||
if (capturedEmailAddressDomain.toLower() == "gmail.com") {
|
||||
// Remove all content after first plus sign (as unnecessary with gmail)
|
||||
// https://gmail.googleblog.com/2008/03/2-hidden-ways-to-get-more-from-your.html
|
||||
const auto firstPlusSign = capturedEmailUser.indexOf("+");
|
||||
if (firstPlusSign != -1) {
|
||||
capturedEmailUser = capturedEmailUser.left(firstPlusSign);
|
||||
}
|
||||
|
||||
// Remove all periods (as unnecessary with gmail)
|
||||
// https://gmail.googleblog.com/2008/03/2-hidden-ways-to-get-more-from-your.html
|
||||
capturedEmailUser.replace(".", "");
|
||||
}
|
||||
|
||||
return {capturedEmailUser, capturedEmailAddressDomain};
|
||||
}
|
||||
|
||||
QString EmailParser::getParsedEmailAddress(const QString &dirtyEmailAddress)
|
||||
{
|
||||
const auto parsedEmailAddress = EmailParser::parseEmailAddress(dirtyEmailAddress);
|
||||
return EmailParser::getParsedEmailAddress(parsedEmailAddress);
|
||||
}
|
||||
|
||||
QString EmailParser::getParsedEmailAddress(const QPair<QString, QString> &emailAddressIntermediate)
|
||||
{
|
||||
const auto emailUser = emailAddressIntermediate.first;
|
||||
const auto emailDomain = emailAddressIntermediate.second;
|
||||
return emailUser + "@" + emailDomain;
|
||||
}
|
15
servatrice/src/email_parser.h
Normal file
15
servatrice/src/email_parser.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COCKATRICE_EMAILPARSER_H
|
||||
#define COCKATRICE_EMAILPARSER_H
|
||||
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
|
||||
class EmailParser
|
||||
{
|
||||
public:
|
||||
static QPair<QString, QString> parseEmailAddress(const QString &dirtyEmailAddress);
|
||||
static QString getParsedEmailAddress(const QString &dirtyEmailAddress);
|
||||
static QString getParsedEmailAddress(const QPair<QString, QString> &emailAddressIntermediate);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_EMAILPARSER_H
|
|
@ -20,6 +20,7 @@
|
|||
#include "servatrice.h"
|
||||
|
||||
#include "decklist.h"
|
||||
#include "email_parser.h"
|
||||
#include "featureset.h"
|
||||
#include "isl_interface.h"
|
||||
#include "main.h"
|
||||
|
@ -627,7 +628,7 @@ void Servatrice::statusUpdate()
|
|||
|
||||
while (servDbSelQuery->next()) {
|
||||
const QString userName = servDbSelQuery->value(0).toString();
|
||||
const QString emailAddress = servDbSelQuery->value(1).toString();
|
||||
const auto emailAddress = EmailParser::getParsedEmailAddress(servDbSelQuery->value(1).toString());
|
||||
const QString token = servDbSelQuery->value(2).toString();
|
||||
|
||||
if (smtpClient->enqueueActivationTokenMail(userName, emailAddress, token)) {
|
||||
|
@ -649,7 +650,7 @@ void Servatrice::statusUpdate()
|
|||
|
||||
while (forgotPwQuery->next()) {
|
||||
const QString userName = forgotPwQuery->value(0).toString();
|
||||
const QString emailAddress = forgotPwQuery->value(1).toString();
|
||||
const auto emailAddress = EmailParser::getParsedEmailAddress(forgotPwQuery->value(1).toString());
|
||||
const QString token = forgotPwQuery->value(2).toString();
|
||||
|
||||
if (smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token)) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "serversocketinterface.h"
|
||||
|
||||
#include "decklist.h"
|
||||
#include "email_parser.h"
|
||||
#include "main.h"
|
||||
#include "pb/command_deck_del.pb.h"
|
||||
#include "pb/command_deck_del_dir.pb.h"
|
||||
|
@ -1004,43 +1005,6 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com
|
|||
return Response::RespOk;
|
||||
}
|
||||
|
||||
QPair<QString, QString> AbstractServerSocketInterface::parseEmailAddress(const QString &emailAddress)
|
||||
{
|
||||
// https://www.regular-expressions.info/email.html
|
||||
static const QRegularExpression emailRegex(R"(^([A-Z0-9._%+-]+)@([A-Z0-9.-]+\.[A-Z]{2,})$)",
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
const auto match = emailRegex.match(emailAddress);
|
||||
|
||||
if (emailAddress.isEmpty() || !match.hasMatch()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString capturedEmailUser = match.captured(1);
|
||||
QString capturedEmailAddressDomain = match.captured(2);
|
||||
|
||||
// Replace googlemail.com with gmail.com, as is standard nowadays
|
||||
// https://www.gmass.co/blog/domains-gmail-com-googlemail-com-and-google-com/
|
||||
if (capturedEmailAddressDomain.toLower() == "googlemail.com") {
|
||||
capturedEmailAddressDomain = "gmail.com";
|
||||
}
|
||||
|
||||
// Trim out dots and pluses from Google/Gmail domains
|
||||
if (capturedEmailAddressDomain.toLower() == "gmail.com") {
|
||||
// Remove all content after first plus sign (as unnecessary with gmail)
|
||||
// https://gmail.googleblog.com/2008/03/2-hidden-ways-to-get-more-from-your.html
|
||||
const int firstPlusSign = capturedEmailUser.indexOf("+");
|
||||
if (firstPlusSign != -1) {
|
||||
capturedEmailUser = capturedEmailUser.left(firstPlusSign);
|
||||
}
|
||||
|
||||
// Remove all periods (as unnecessary with gmail)
|
||||
// https://gmail.googleblog.com/2008/03/2-hidden-ways-to-get-more-from-your.html
|
||||
capturedEmailUser.replace(".", "");
|
||||
}
|
||||
|
||||
return {capturedEmailUser, capturedEmailAddressDomain};
|
||||
}
|
||||
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const Command_Register &cmd,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
|
@ -1059,9 +1023,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
|
|||
|
||||
const QString emailBlackList = servatrice->getEmailBlackList();
|
||||
const QString emailWhiteList = servatrice->getEmailWhiteList();
|
||||
auto parsedEmailAddress = parseEmailAddress(nameFromStdString(cmd.email()));
|
||||
const QString emailUser = parsedEmailAddress.first;
|
||||
const QString emailDomain = parsedEmailAddress.second;
|
||||
const auto parsedEmailParts = EmailParser::parseEmailAddress(nameFromStdString(cmd.email()));
|
||||
const auto emailUser = parsedEmailParts.first;
|
||||
const auto emailDomain = parsedEmailParts.second;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
const QStringList emailBlackListFilters = emailBlackList.split(",", Qt::SkipEmptyParts);
|
||||
const QStringList emailWhiteListFilters = emailWhiteList.split(",", Qt::SkipEmptyParts);
|
||||
|
@ -1126,9 +1090,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
|
|||
return Response::RespUserAlreadyExists;
|
||||
}
|
||||
|
||||
QString emailAddress = emailUser + "@" + emailDomain;
|
||||
const auto parsedEmailAddress = EmailParser::getParsedEmailAddress(parsedEmailParts);
|
||||
if (servatrice->getMaxAccountsPerEmail() > 0 &&
|
||||
sqlInterface->checkNumberOfUserAccounts(emailAddress) >= servatrice->getMaxAccountsPerEmail()) {
|
||||
sqlInterface->checkNumberOfUserAccounts(parsedEmailAddress) >= servatrice->getMaxAccountsPerEmail()) {
|
||||
if (servatrice->getEnableRegistrationAudit())
|
||||
sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(),
|
||||
"REGISTER_ACCOUNT", "Too many usernames registered with this email address",
|
||||
|
@ -1184,7 +1148,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C
|
|||
}
|
||||
|
||||
bool requireEmailActivation = settingsCache->value("registration/requireemailactivation", true).toBool();
|
||||
bool regSucceeded = sqlInterface->registerUser(userName, realName, password, passwordNeedsHash, emailAddress,
|
||||
bool regSucceeded = sqlInterface->registerUser(userName, realName, password, passwordNeedsHash, parsedEmailAddress,
|
||||
country, !requireEmailActivation);
|
||||
|
||||
if (regSucceeded) {
|
||||
|
@ -1262,7 +1226,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountEdit(const Comma
|
|||
return Response::RespFunctionNotAllowed;
|
||||
|
||||
QString realName = nameFromStdString(cmd.real_name());
|
||||
QString emailAddress = nameFromStdString(cmd.email());
|
||||
const auto parsedEmailAddress = EmailParser::getParsedEmailAddress(nameFromStdString(cmd.email()));
|
||||
QString country = nameFromStdString(cmd.country());
|
||||
|
||||
bool checkedPassword = false;
|
||||
|
@ -1310,8 +1274,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountEdit(const Comma
|
|||
query->bindValue(":realName", _realName);
|
||||
}
|
||||
if (cmd.has_email()) {
|
||||
auto _emailAddress = nameFromStdString(cmd.email());
|
||||
query->bindValue(":email", _emailAddress);
|
||||
const auto _parsedEmailAddress = EmailParser::getParsedEmailAddress(nameFromStdString(cmd.email()));
|
||||
query->bindValue(":email", _parsedEmailAddress);
|
||||
}
|
||||
if (cmd.has_country()) {
|
||||
auto _country = nameFromStdString(cmd.country());
|
||||
|
@ -1326,7 +1290,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountEdit(const Comma
|
|||
userInfo->set_real_name(realName.toStdString());
|
||||
}
|
||||
if (cmd.has_email()) {
|
||||
userInfo->set_email(emailAddress.toStdString());
|
||||
userInfo->set_email(parsedEmailAddress.toStdString());
|
||||
}
|
||||
if (cmd.has_country()) {
|
||||
userInfo->set_country(country.toStdString());
|
||||
|
@ -1543,8 +1507,8 @@ AbstractServerSocketInterface::cmdForgotPasswordChallenge(const Command_ForgotPa
|
|||
return Response::RespFunctionNotAllowed;
|
||||
}
|
||||
|
||||
if (!sqlInterface->validateTableColumnStringData("{prefix}_users", "email", userName,
|
||||
nameFromStdString(cmd.email()))) {
|
||||
const auto parsedEmailAddress = EmailParser::getParsedEmailAddress(nameFromStdString(cmd.email()));
|
||||
if (!sqlInterface->validateTableColumnStringData("{prefix}_users", "email", userName, parsedEmailAddress)) {
|
||||
if (servatrice->getEnableForgotPasswordAudit()) {
|
||||
sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(),
|
||||
"PASSWORD_RESET_CHALLENGE", "Failed to answer email challenge question",
|
||||
|
|
|
@ -131,7 +131,6 @@ private:
|
|||
bool removeAdminFlagFromUser(const QString &user, int flag);
|
||||
|
||||
bool isPasswordLongEnough(const int passwordLength);
|
||||
static QPair<QString, QString> parseEmailAddress(const QString &emailAddress);
|
||||
void removeSaidMessages(const QString &userName, int amount);
|
||||
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue