From: Marcus Eggenberger Date: Thu, 21 Feb 2008 20:46:03 +0000 (+0000) Subject: migrated passwords from blob to strings (still hashed), for easier migration between... X-Git-Tag: 0.2.0-alpha1~7 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=4ed404c7a72dd21bb06b003274ae544ab5ca1ad7 migrated passwords from blob to strings (still hashed), for easier migration between different storage engines --- diff --git a/src/core/abstractsqlstorage.h b/src/core/abstractsqlstorage.h index a85fdbbf..c94bc4a4 100644 --- a/src/core/abstractsqlstorage.h +++ b/src/core/abstractsqlstorage.h @@ -35,7 +35,7 @@ public: virtual ~AbstractSqlStorage(); protected: - bool init(const QVariantMap &settings = QVariantMap()); + virtual bool init(const QVariantMap &settings = QVariantMap()); virtual void sync(); QSqlDatabase logDb(); diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index 7ae4f0e8..81f2fa9e 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -20,7 +20,6 @@ #include "sqlitestorage.h" -#include #include #include "network.h" @@ -62,13 +61,10 @@ int SqliteStorage::installedSchemaVersion() { } UserId SqliteStorage::addUser(const QString &user, const QString &password) { - QByteArray cryptopass = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha1); - cryptopass = cryptopass.toHex(); - QSqlQuery query(logDb()); query.prepare(queryString("insert_quasseluser")); query.bindValue(":username", user); - query.bindValue(":password", cryptopass); + query.bindValue(":password", cryptedPassword(password)); query.exec(); if(query.lastError().isValid() && query.lastError().number() == 19) { // user already exists - sadly 19 seems to be the general constraint violation error... return 0; @@ -84,13 +80,10 @@ UserId SqliteStorage::addUser(const QString &user, const QString &password) { } void SqliteStorage::updateUser(UserId user, const QString &password) { - QByteArray cryptopass = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha1); - cryptopass = cryptopass.toHex(); - QSqlQuery query(logDb()); query.prepare(queryString("update_userpassword")); query.bindValue(":userid", user.toInt()); - query.bindValue(":password", cryptopass); + query.bindValue(":password", cryptedPassword(password)); query.exec(); } @@ -104,13 +97,10 @@ void SqliteStorage::renameUser(UserId user, const QString &newName) { } UserId SqliteStorage::validateUser(const QString &user, const QString &password) { - QByteArray cryptopass = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha1); - cryptopass = cryptopass.toHex(); - QSqlQuery query(logDb()); query.prepare(queryString("select_authuser")); query.bindValue(":username", user); - query.bindValue(":password", cryptopass); + query.bindValue(":password", cryptedPassword(password)); query.exec(); if(query.first()) { @@ -664,3 +654,50 @@ QString SqliteStorage::backlogFile() { return quasselDir + "quassel-storage.sqlite"; } + +// ONLY NEEDED FOR MIGRATION +bool SqliteStorage::init(const QVariantMap &settings) { + if(!AbstractSqlStorage::init(settings)) + return false; + + QSqlQuery checkMigratedQuery(logDb()); + checkMigratedQuery.prepare("SELECT DISTINCT typeOf(password) FROM quasseluser"); + checkMigratedQuery.exec(); + if(!watchQuery(&checkMigratedQuery)) + return false; + + if(!checkMigratedQuery.first()) + return false; + + QString passType = checkMigratedQuery.value(0).toString().toLower(); + if(passType == "text") + return true; // allready migrated + + Q_ASSERT(passType == "blob"); + + QSqlQuery getPasswordsQuery(logDb()); + getPasswordsQuery.prepare("SELECT userid, password FROM quasseluser"); + getPasswordsQuery.exec(); + + if(!watchQuery(&getPasswordsQuery)) { + qWarning() << "unable to migrate to new password format!"; + return false; + } + + QHash passHash; + while(getPasswordsQuery.next()) { + passHash[getPasswordsQuery.value(0).toInt()] = getPasswordsQuery.value(1).toByteArray(); + } + + QSqlQuery setPasswordsQuery(logDb()); + setPasswordsQuery.prepare("UPDATE quasseluser SET password = :password WHERE userid = :userid"); + foreach(int userId, passHash.keys()) { + setPasswordsQuery.bindValue(":password", QString(passHash[userId])); + setPasswordsQuery.bindValue(":userid", userId); + setPasswordsQuery.exec(); + watchQuery(&setPasswordsQuery); + } + + qDebug() << "successfully migrated passwords!"; + return true; +} diff --git a/src/core/sqlitestorage.h b/src/core/sqlitestorage.h index 4c133e6c..944c46b4 100644 --- a/src/core/sqlitestorage.h +++ b/src/core/sqlitestorage.h @@ -77,6 +77,8 @@ protected: inline virtual QString driverName() { return "QSQLITE"; } inline virtual QString databaseName() { return backlogFile(); } virtual int installedSchemaVersion(); + + virtual bool init(const QVariantMap &settings = QVariantMap()); // only needed for migration private: static QString backlogFile(); diff --git a/src/core/storage.cpp b/src/core/storage.cpp index 26172c89..4bf6b308 100644 --- a/src/core/storage.cpp +++ b/src/core/storage.cpp @@ -20,7 +20,13 @@ #include "storage.h" +#include + Storage::Storage(QObject *parent) : QObject(parent) { } + +QString Storage::cryptedPassword(const QString &password) { + return QString(QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha1).toHex()); +} diff --git a/src/core/storage.h b/src/core/storage.h index 2c975ca8..3e8cbb1c 100644 --- a/src/core/storage.h +++ b/src/core/storage.h @@ -252,8 +252,11 @@ class Storage : public QObject { //! Sent when a user has been removed void userRemoved(UserId); - public: - + protected: + //! when implementing a storage handler, use this method to crypt user passwords. + /** This guarantees compatibility with other storage handlers and allows easy migration + */ + QString cryptedPassword(const QString &password); }; diff --git a/version.inc b/version.inc index 113c435b..ccd8341a 100644 --- a/version.inc +++ b/version.inc @@ -4,8 +4,8 @@ { using namespace Global; quasselVersion = "0.2.0-pre"; - quasselDate = "2008-02-20"; - quasselBuild = 572; + quasselDate = "2008-02-21"; + quasselBuild = 573; //! Minimum client build number the core needs clientBuildNeeded = 563;