Add --select-authenticator switch to core
authorBen Rosser <rosser.bjr@gmail.com>
Mon, 1 Feb 2016 00:17:46 +0000 (19:17 -0500)
committerBen Rosser <rosser.bjr@gmail.com>
Sat, 27 May 2017 18:00:11 +0000 (14:00 -0400)
The select-authenticator switch now behaves exactly like the
select-backend switch for storage backends, allowing the user to
reconfigure their authenticator from the commandline or do initial
core setup.

Initial core setup should look something like this now:
quasselcore -c _dir_ --select-backend=SQLite --select-authenticator=Database

src/common/main.cpp
src/core/core.cpp
src/core/core.h

index 74b97e7..0441f2c 100644 (file)
@@ -163,6 +163,7 @@ int main(int argc, char **argv)
 #endif
     cliParser->addOption("logfile", 'l', "Log to a file", "path");
     cliParser->addOption("select-backend", 0, "Switch storage backend (migrating data if possible)", "backendidentifier");
+       cliParser->addOption("select-authenticator", 0, "Switch auth backend", "authidentifier");
     cliParser->addSwitch("add-user", 0, "Starts an interactive session to add a new core user");
     cliParser->addOption("change-userpass", 0, "Starts an interactive session to change the password of the user identified by <username>", "username");
     cliParser->addSwitch("oidentd", 0, "Enable oidentd integration");
index 3c529d3..67f3a81 100644 (file)
@@ -193,13 +193,16 @@ void Core::init()
     QVariantMap authSettings = cs.authSettings().toMap();
     initAuthenticator(authSettings.value("AuthBackend").toString(), authSettings.value("ConnectionProperties").toMap());
 
-    if (Quassel::isOptionSet("select-backend")) {
-        selectBackend(Quassel::optionValue("select-backend"));
+    if (Quassel::isOptionSet("select-backend") || Quassel::isOptionSet("select-authenticator")) {
+        if (Quassel::isOptionSet("select-backend")) {
+            selectBackend(Quassel::optionValue("select-backend"));
+        }
+        if (Quassel::isOptionSet("select-authenticator")) {
+            selectAuthenticator(Quassel::optionValue("select-authenticator"));
+        }
         exit(0);
     }
 
-    // TODO: add --select-authenticator command line option and code.
-
     if (!_configured) {
         if (!_storageBackends.count()) {
             qWarning() << qPrintable(tr("Could not initialize any storage backend! Exiting..."));
@@ -882,6 +885,50 @@ bool Core::selectBackend(const QString &backend)
     return true;
 }
 
+// XXX: I am not sure if this function is implemented correctly.
+// There is currently no concept of migraiton between auth backends.
+bool Core::selectAuthenticator(const QString &backend)
+{
+    // Register all authentication backends.
+    registerAuthenticatorBackends();
+    if (!_authenticatorBackends.contains(backend)) {
+        qWarning() << qPrintable(QString("Core::selectAuthenticator(): unsupported backend: %1").arg(backend));
+        qWarning() << "    supported backends are:" << qPrintable(QStringList(_authenticatorBackends.keys()).join(", "));
+        return false;
+    }
+
+    Authenticator *authenticator = _authenticatorBackends[backend];
+    QVariantMap settings = promptForSettings(authenticator);
+
+    Authenticator::State state = authenticator->init(settings);
+    switch (state) {
+    case Authenticator::IsReady:
+        saveAuthBackendSettings(backend, settings);
+        qWarning() << "Switched auth backend to:" << qPrintable(backend);
+//        qWarning() << "Auth backend already initialized. Skipping Migration";
+        return true;
+    case Authenticator::NotAvailable:
+        qCritical() << "Auth backend is not available:" << qPrintable(backend);
+        return false;
+    case Authenticator::NeedsSetup:
+        if (!authenticator->setup(settings)) {
+            qWarning() << qPrintable(QString("Core::selectAuthenticator(): unable to setup authenticator: %1").arg(backend));
+            return false;
+        }
+
+        if (authenticator->init(settings) != Authenticator::IsReady) {
+            qWarning() << qPrintable(QString("Core::migrateBackend(): unable to initialize authenticator: %1").arg(backend));
+            return false;
+        }
+
+        saveAuthBackendSettings(backend, settings);
+        qWarning() << "Switched auth backend to:" << qPrintable(backend);
+    }
+    
+    _authenticator = authenticator;
+       return true;
+}
+
 
 bool Core::createUser()
 {
@@ -1049,12 +1096,12 @@ void Core::saveAuthBackendSettings(const QString &backend, const QVariantMap &se
     CoreSettings().setAuthSettings(dbsettings);
 }
 
-
-QVariantMap Core::promptForSettings(const Storage *storage)
+// Generic version of promptForSettings that doesn't care what *type* of
+// backend it runs over.
+QVariantMap Core::promptForSettings(QStringList keys, QVariantMap defaults)
 {
     QVariantMap settings;
 
-    QStringList keys = storage->setupKeys();
     if (keys.isEmpty())
         return settings;
 
@@ -1062,7 +1109,6 @@ QVariantMap Core::promptForSettings(const Storage *storage)
     QTextStream in(stdin);
     out << "Default values are in brackets" << endl;
 
-    QVariantMap defaults = storage->setupDefaults();
     QString value;
     foreach(QString key, keys) {
         QVariant val;
@@ -1100,6 +1146,23 @@ QVariantMap Core::promptForSettings(const Storage *storage)
     return settings;
 }
 
+// Since an auth and storage backend work basically the same way,
+// use polymorphism here on this routine.
+QVariantMap Core::promptForSettings(const Storage *storage)
+{
+    QStringList keys = storage->setupKeys();
+    QVariantMap defaults = storage->setupDefaults();
+    return Core::promptForSettings(keys, defaults);
+    
+}
+
+QVariantMap Core::promptForSettings(const Authenticator *authenticator)
+{
+    QStringList keys = authenticator->setupKeys();
+    QVariantMap defaults = authenticator->setupDefaults();
+    return Core::promptForSettings(keys, defaults);
+}
+
 
 #ifdef Q_OS_WIN
 void Core::stdInEcho(bool on)
index 9971278..3eb4313 100644 (file)
@@ -618,10 +618,14 @@ private:
     void unregisterAuthenticatorBackend(Authenticator *);
 
     bool selectBackend(const QString &backend);
+    bool selectAuthenticator(const QString &backend);
     bool createUser();
     bool saveBackendSettings(const QString &backend, const QVariantMap &settings);
     void saveAuthBackendSettings(const QString &backend, const QVariantMap &settings);
+
     QVariantMap promptForSettings(const Storage *storage);
+    QVariantMap promptForSettings(const Authenticator *authenticator);
+    QVariantMap promptForSettings(QStringList keys, QVariantMap defaults);
 
 private:
     QSet<CoreAuthHandler *> _connectingClients;