From: Michael Marley Date: Wed, 4 Apr 2018 12:25:14 +0000 (-0400) Subject: Cache strict sysident mappings X-Git-Tag: travis-deploy-test~124 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=8697a21faab21ae23646f559cba9a85bd95b2ad7 Cache strict sysident mappings To avoid unnecessary database hits, we store a mapping of all permitted strict sysidents in memory. This mapping is reloaded on SIGHUP. A miss will make a call to the database. Co-authored-by: Sai Nane Co-authored-by: Michael Marley --- diff --git a/src/core/SQL/PostgreSQL/select_all_authusernames.sql b/src/core/SQL/PostgreSQL/select_all_authusernames.sql new file mode 100644 index 00000000..1f480bab --- /dev/null +++ b/src/core/SQL/PostgreSQL/select_all_authusernames.sql @@ -0,0 +1,2 @@ +SELECT userid, username +FROM quasseluser; diff --git a/src/core/SQL/SQLite/select_all_authusernames.sql b/src/core/SQL/SQLite/select_all_authusernames.sql new file mode 100644 index 00000000..1f480bab --- /dev/null +++ b/src/core/SQL/SQLite/select_all_authusernames.sql @@ -0,0 +1,2 @@ +SELECT userid, username +FROM quasseluser; diff --git a/src/core/core.cpp b/src/core/core.cpp index 73fde97c..aa520633 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -236,8 +236,12 @@ void Core::init() connect(&_v6server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); if (!startListening()) exit(1); // TODO make this less brutal - if (Quassel::isOptionSet("oidentd")) + if (Quassel::isOptionSet("oidentd")) { _oidentdConfigGenerator = new OidentdConfigGenerator(Quassel::isOptionSet("oidentd-strict"), this); + if (Quassel::isOptionSet("oidentd-strict")) { + cacheSysident(); + } + } } @@ -329,6 +333,7 @@ QString Core::setupCore(const QString &adminUser, const QString &adminPassword, quInfo() << qPrintable(tr("Creating admin user...")); _storage->addUser(adminUser, adminPassword); + cacheSysident(); startListening(); // TODO check when we need this return QString(); } @@ -548,6 +553,31 @@ bool Core::reloadCerts() #endif } +void Core::cacheSysident() { + if(isConfigured()) { + instance()->_authusernames = instance()->_storage->getAllAuthusernames(); + } +} + +QString Core::strictSysident(UserId user) { + QMap *allAuthusernames = &instance()->_authusernames; + auto authusername = allAuthusernames->find(user); + if (authusername == allAuthusernames->end()) { + // A new user got added since we last pulled our cache from the database. + // There's no way to avoid a database hit - we don't even know the authname! + cacheSysident(); + authusername = allAuthusernames->find(user); + if (authusername == allAuthusernames->end()) { + // ...something very weird is going on if we ended up here (an active CoreSession without a corresponding database entry?) + QDebug d = qWarning(); + d << "Unable to find authusername for UserId" << user; + d.nospace(); + d << ", this should never happen!"; + return "unknown"; // Should we just terminate the program instead? + } + } + return *authusername; +} bool Core::startListening() { diff --git a/src/core/core.h b/src/core/core.h index a29d6724..91aafd27 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -501,6 +501,12 @@ public: return instance()->_storage->getAuthusername(user); } + //! Get a usable sysident for the given user in oidentd-strict mode + /** \param user The user to retrieve the sysident for + * \return The authusername + */ + QString strictSysident(UserId user); + //! Get a Hash of all last seen message ids /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds @@ -584,6 +590,8 @@ public: */ static bool reloadCerts(); + static void cacheSysident(); + static QVariantList backendInfo(); static QVariantList authenticatorInfo(); @@ -667,6 +675,7 @@ private: DeferredSharedPtr _storage; ///< Active storage backend DeferredSharedPtr _authenticator; ///< Active authenticator QTimer _storageSyncTimer; + QMap _authusernames; #ifdef HAVE_SSL SslServer _server, _v6server; diff --git a/src/core/coreapplication.cpp b/src/core/coreapplication.cpp index 91c41717..7f4388b2 100644 --- a/src/core/coreapplication.cpp +++ b/src/core/coreapplication.cpp @@ -56,7 +56,8 @@ bool CoreApplicationInternal::init() _coreCreated = true; Quassel::registerReloadHandler([]() { - // Currently, only reloading SSL certificates is supported + // Currently, only reloading SSL certificates and the sysident cache is supported + Core::cacheSysident(); return Core::reloadCerts(); }); diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index b2637397..41bf2d6f 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -509,8 +509,7 @@ void CoreSession::createIdentity(const Identity &identity, const QVariantMap &ad } const QString CoreSession::strictSysident() { - const QString authusername = Core::getAuthusername(_user); - return authusername; + return Core::instance()->strictSysident(_user); } void CoreSession::createIdentity(const CoreIdentity &identity) diff --git a/src/core/postgresqlstorage.cpp b/src/core/postgresqlstorage.cpp index 48ee466d..f976f095 100644 --- a/src/core/postgresqlstorage.cpp +++ b/src/core/postgresqlstorage.cpp @@ -1702,6 +1702,19 @@ QList PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId return messagelist; } +QMap PostgreSqlStorage::getAllAuthusernames() { + QMap authusernames; + QSqlQuery query(logDb()); + query.prepare(queryString("select_all_authusernames")); + safeExec(query); + watchQuery(query); + + while (query.next()) { + authusernames[query.value(0).toInt()] = query.value(1).toString(); + } + return authusernames; +} + const QString PostgreSqlStorage::getAuthusername(UserId user) { QString authusername; QSqlQuery query(logDb()); diff --git a/src/core/postgresqlstorage.h b/src/core/postgresqlstorage.h index ad09ff99..2445c615 100644 --- a/src/core/postgresqlstorage.h +++ b/src/core/postgresqlstorage.h @@ -106,6 +106,7 @@ public slots: QList requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1) override; /* Sysident handling */ + virtual QMap getAllAuthusernames(); virtual const QString getAuthusername(UserId user); protected: diff --git a/src/core/sql.qrc b/src/core/sql.qrc index 597df0f7..edaaa326 100644 --- a/src/core/sql.qrc +++ b/src/core/sql.qrc @@ -30,6 +30,7 @@ ./SQL/PostgreSQL/migrate_write_quasseluser.sql ./SQL/PostgreSQL/migrate_write_sender.sql ./SQL/PostgreSQL/migrate_write_usersetting.sql + ./SQL/PostgreSQL/select_all_authusernames.sql ./SQL/PostgreSQL/select_authenticator.sql ./SQL/PostgreSQL/select_authuser.sql ./SQL/PostgreSQL/select_authusername.sql @@ -140,6 +141,7 @@ ./SQL/SQLite/migrate_read_quasseluser.sql ./SQL/SQLite/migrate_read_sender.sql ./SQL/SQLite/migrate_read_usersetting.sql + ./SQL/SQLite/select_all_authusernames.sql ./SQL/SQLite/select_authenticator.sql ./SQL/SQLite/select_authuser.sql ./SQL/SQLite/select_authusername.sql diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index 0962fac1..69c41b8f 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -1820,6 +1820,28 @@ QList SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las return messagelist; } +QMap SqliteStorage::getAllAuthusernames() +{ + QMap authusernames; + + QSqlDatabase db = logDb(); + db.transaction(); + { + QSqlQuery query(db); + query.prepare(queryString("select_all_authusernames")); + + lockForRead(); + safeExec(query); + watchQuery(query); + while (query.next()) { + authusernames[query.value(0).toInt()] = query.value(1).toString(); + } + } + db.commit(); + unlock(); + return authusernames; +} + const QString SqliteStorage::getAuthusername(UserId user) { QString authusername; QSqlQuery query(logDb()); diff --git a/src/core/sqlitestorage.h b/src/core/sqlitestorage.h index 15d54373..fcc85ff4 100644 --- a/src/core/sqlitestorage.h +++ b/src/core/sqlitestorage.h @@ -107,6 +107,7 @@ public slots: QList requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1) override; /* Sysident handling */ + virtual QMap getAllAuthusernames(); virtual const QString getAuthusername(UserId user); protected: diff --git a/src/core/storage.h b/src/core/storage.h index c77e9ebf..c809a7f4 100644 --- a/src/core/storage.h +++ b/src/core/storage.h @@ -442,6 +442,11 @@ public slots: */ virtual QList requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1) = 0; + //! Fetch all authusernames + /** \return Map of all current UserIds to permitted idents + */ + virtual QMap getAllAuthusernames() = 0; + //! Get the auth username associated with a userId /** \param user The user to retrieve the username for * \return The username for the user