diff --git a/libguh-core/usermanager.cpp b/libguh-core/usermanager.cpp index b3278adb..5b1932fd 100644 --- a/libguh-core/usermanager.cpp +++ b/libguh-core/usermanager.cpp @@ -70,7 +70,7 @@ UserManager::UserError UserManager::createUser(const QString &username, const QS return UserErrorBadPassword; } - QString checkForDuplicateUserQuery = QString("SELECT * FROM users WHERE username = \"%1\";").arg(username); + QString checkForDuplicateUserQuery = QString("SELECT * FROM users WHERE lower(username) = \"%1\";").arg(username.toLower()); QSqlQuery result = m_db.exec(checkForDuplicateUserQuery); if (result.first()) { qCWarning(dcUserManager) << "Username already in use"; @@ -93,13 +93,13 @@ UserManager::UserError UserManager::createUser(const QString &username, const QS UserManager::UserError UserManager::removeUser(const QString &username) { - QString dropUserQuery = QString("DELETE FROM users WHERE username =\"%1\";").arg(username); + QString dropUserQuery = QString("DELETE FROM users WHERE lower(username) =\"%1\";").arg(username.toLower()); QSqlQuery result = m_db.exec(dropUserQuery); if (result.numRowsAffected() == 0) { return UserErrorInvalidUserId; } - QString dropTokensQuery = QString("DELETE FROM tokens WHERE username = \"%1\";").arg(username); + QString dropTokensQuery = QString("DELETE FROM tokens WHERE lower(username) = \"%1\";").arg(username.toLower()); m_db.exec(dropTokensQuery); return UserErrorNoError; @@ -112,7 +112,7 @@ QByteArray UserManager::authenticate(const QString &username, const QString &pas return QByteArray(); } - QString passwordQuery = QString("SELECT password, salt FROM users WHERE username = \"%1\";").arg(username); + QString passwordQuery = QString("SELECT password, salt FROM users WHERE lower(username) = \"%1\";").arg(username.toLower()); QSqlQuery result = m_db.exec(passwordQuery); if (!result.first()) { qCWarning(dcUserManager) << "No such username" << username; @@ -171,8 +171,8 @@ QList UserManager::tokens(const QString &username) const qCWarning(dcUserManager) << "Username did not pass validation:" << username; return ret; } - QString getTokensQuery = QString("SELECT id, username, creationdate, deviceName FROM tokens WHERE username = \"%1\";") - .arg(username); + QString getTokensQuery = QString("SELECT id, username, creationdate, deviceName FROM tokens WHERE lower(username) = \"%1\";") + .arg(username.toLower()); QSqlQuery result = m_db.exec(getTokensQuery); if (m_db.lastError().type() != QSqlError::NoError) { qCWarning(dcUserManager) << "Query for tokens failed:" << m_db.lastError().databaseText() << m_db.lastError().driverText() << getTokensQuery; diff --git a/tests/auto/guhtestbase.cpp b/tests/auto/guhtestbase.cpp index 34804b4c..d097376d 100644 --- a/tests/auto/guhtestbase.cpp +++ b/tests/auto/guhtestbase.cpp @@ -121,9 +121,10 @@ GuhTestBase::GuhTestBase(QObject *parent) : QSignalSpy spy(GuhCore::instance(), SIGNAL(initialized())); spy.wait(); + // Yes, we're intentionally mixing upper/lower case email here... username should not be case sensitive GuhCore::instance()->userManager()->removeUser("dummy@guh.io"); GuhCore::instance()->userManager()->createUser("dummy@guh.io", "DummyPW1!"); - m_apiToken = GuhCore::instance()->userManager()->authenticate("dummy@guh.io", "DummyPW1!", "testcase"); + m_apiToken = GuhCore::instance()->userManager()->authenticate("Dummy@guh.io", "DummyPW1!", "testcase"); } void GuhTestBase::initTestCase() diff --git a/tests/auto/jsonrpc/testjsonrpc.cpp b/tests/auto/jsonrpc/testjsonrpc.cpp index c2bd37b5..a39f45b8 100644 --- a/tests/auto/jsonrpc/testjsonrpc.cpp +++ b/tests/auto/jsonrpc/testjsonrpc.cpp @@ -173,9 +173,9 @@ void TestJSONRPC::testInitialSetup() QCOMPARE(response.value("status").toString(), QStringLiteral("success")); QCOMPARE(GuhCore::instance()->userManager()->users().count(), 0); - // Now lets play by the rules + // Now lets play by the rules (with an uppercase email) spy.clear(); - m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.CreateUser\", \"params\": {\"username\": \"dummy@guh.io\", \"password\": \"DummyPW1!\"}}"); + m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.CreateUser\", \"params\": {\"username\": \"Dummy@guh.io\", \"password\": \"DummyPW1!\"}}"); if (spy.count() == 0) { spy.wait(); } @@ -200,7 +200,7 @@ void TestJSONRPC::testInitialSetup() // Now lets authenticate with a wrong user spy.clear(); - m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.Authenticate\", \"params\": {\"username\": \"dummy@wrong.domain\", \"password\": \"DummyPW1!\", \"deviceName\": \"testcase\"}}"); + m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.Authenticate\", \"params\": {\"username\": \"Dummy@wrong.domain\", \"password\": \"DummyPW1!\", \"deviceName\": \"testcase\"}}"); if (spy.count() == 0) { spy.wait(); } @@ -215,7 +215,7 @@ void TestJSONRPC::testInitialSetup() // Now lets authenticate with a wrong password spy.clear(); - m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.Authenticate\", \"params\": {\"username\": \"dummy@guh.io\", \"password\": \"wrongpw\", \"deviceName\": \"testcase\"}}"); + m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.Authenticate\", \"params\": {\"username\": \"Dummy@guh.io\", \"password\": \"wrongpw\", \"deviceName\": \"testcase\"}}"); if (spy.count() == 0) { spy.wait(); } @@ -228,7 +228,7 @@ void TestJSONRPC::testInitialSetup() QVERIFY(response.value("params").toMap().value("token").toByteArray().isEmpty()); - // Now lets authenticate for real + // Now lets authenticate for real (but intentionally use a lowercase email here, should still work) spy.clear(); m_mockTcpServer->injectData(m_clientId, "{\"id\": 555, \"method\": \"JSONRPC.Authenticate\", \"params\": {\"username\": \"dummy@guh.io\", \"password\": \"DummyPW1!\", \"deviceName\": \"testcase\"}}"); if (spy.count() == 0) {