Make authenticator changes to protocol backwards-compatible
authorBen Rosser <rosser.bjr@gmail.com>
Thu, 24 Dec 2015 03:30:48 +0000 (22:30 -0500)
committerBen Rosser <rosser.bjr@gmail.com>
Sat, 27 May 2017 17:57:46 +0000 (13:57 -0400)
An older client setting up a newer core will cause the core to
default to using the SqlAuthenticator class.

An newer client setting up an older core won't show the auth
selection dialog.

20 files changed:
CMakeLists.txt
src/client/clientauthhandler.cpp
src/common/protocol.h
src/common/protocols/datastream/datastreampeer.cpp
src/common/protocols/legacy/legacypeer.cpp
src/common/quassel.h
src/core/CMakeLists.txt
src/core/authenticator.h
src/core/core.cpp
src/core/core.h
src/core/coreauthhandler.cpp
src/core/coresettings.cpp
src/core/coresettings.h
src/core/ldapauthenticator.cpp
src/core/ldapauthenticator.h
src/core/sqlauthenticator.cpp
src/core/sqlauthenticator.h
src/qtui/coreconfigwizard.cpp
src/qtui/coreconfigwizard.h
src/qtui/ui/coreconfigwizardsyncpage.ui

index f8c0a50..bf56d71 100644 (file)
@@ -521,18 +521,18 @@ endif()
 # Setup LDAP Authentication support.
 #####################################################################
 if(WITH_LDAP)
-       find_package(Ldap)
-       if(LDAP_FOUND)
-               message(STATUS "Enabling LDAP authentication support")
-               set(HAVE_LDAP true)
-               if(HAVE_LDAP)
-                       add_definitions(-DHAVE_LDAP)
-               endif(HAVE_LDAP)
-       else(LDAP_FOUND)
-               message(STATUS "Disabling LDAP authentication support")
-       endif(LDAP_FOUND)
+    find_package(Ldap)
+    if(LDAP_FOUND)
+        message(STATUS "Enabling LDAP authentication support")
+        set(HAVE_LDAP true)
+        if(HAVE_LDAP)
+            add_definitions(-DHAVE_LDAP)
+        endif(HAVE_LDAP)
+    else(LDAP_FOUND)
+        message(STATUS "Disabling LDAP authentication support")
+    endif(LDAP_FOUND)
 else(WITH_LDAP)
-       message(STATUS "Not enabling LDAP authentication support")
+    message(STATUS "Not enabling LDAP authentication support")
 endif(WITH_LDAP)
 
 # Setup KDE / KDE Frameworks
index fc6156d..7ded71d 100644 (file)
@@ -488,7 +488,7 @@ void ClientAuthHandler::onSslErrors()
     default:
         qWarning() << "Certificate digest version" << QString(knownDigestVersion) << "is not supported";
     }
-    
+
     if (knownDigest != calculatedDigest) {
         bool accepted = false;
         bool permanently = false;
index b686a51..d9d1049 100644 (file)
@@ -81,7 +81,7 @@ struct ClientDenied : public HandshakeMessage
 
 struct ClientRegistered : public HandshakeMessage
 {
-    inline ClientRegistered(quint32 coreFeatures, bool coreConfigured, const QVariantList &backendInfo, const QVariantList &authBackendInfo, bool sslSupported)
+    inline ClientRegistered(quint32 coreFeatures, bool coreConfigured, const QVariantList &backendInfo, bool sslSupported, const QVariantList &authBackendInfo)
     : coreFeatures(coreFeatures)
     , coreConfigured(coreConfigured)
     , backendInfo(backendInfo)
@@ -91,11 +91,11 @@ struct ClientRegistered : public HandshakeMessage
 
     quint32 coreFeatures;
     bool coreConfigured;
-    
+
     // The authBackendInfo should be optional!
     QVariantList backendInfo; // TODO: abstract this better
     QVariantList authBackendInfo;
-    
+
     // this is only used by the LegacyProtocol in compat mode
     bool sslSupported;
 };
@@ -103,15 +103,23 @@ struct ClientRegistered : public HandshakeMessage
 
 struct SetupData : public HandshakeMessage
 {
-    inline SetupData(const QString &adminUser, const QString &adminPassword, const QString &backend, const QString &authenticator, const QVariantMap &setupData, const QVariantMap &authSetupData)
-    : adminUser(adminUser), adminPassword(adminPassword), backend(backend), authenticator(authenticator), setupData(setupData), authSetupData(authSetupData) {}
+    inline SetupData(const QString &adminUser, const QString &adminPassword, const QString &backend,
+                     const QVariantMap &setupData, const QString &authenticator = QString(),
+                     const QVariantMap &authSetupData = QVariantMap())
+    : adminUser(adminUser)
+    , adminPassword(adminPassword)
+    , backend(backend)
+    , setupData(setupData)
+    , authenticator(authenticator)
+    , authSetupData(authSetupData)
+    {}
 
     QString adminUser;
     QString adminPassword;
     QString backend;
-       QString authenticator;
     QVariantMap setupData;
-       QVariantMap authSetupData;
+    QString authenticator;
+    QVariantMap authSetupData;
 };
 
 
index b21b9df..acf7a42 100644 (file)
@@ -124,12 +124,12 @@ void DataStreamPeer::handleHandshakeMessage(const QVariantList &mapData)
     }
 
     else if (msgType == "ClientInitAck") {
-        handle(ClientRegistered(m["CoreFeatures"].toUInt(), m["Configured"].toBool(), m["StorageBackends"].toList(), m["AuthBackends"].toList(), false)); // SupportsSsl is obsolete
+        handle(ClientRegistered(m["CoreFeatures"].toUInt(), m["Configured"].toBool(), m["StorageBackends"].toList(), false, m["AuthBackends"].toList())); // SupportsSsl  obsolete
     }
 
     else if (msgType == "CoreSetupData") {
         QVariantMap map = m["SetupData"].toMap();
-        handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["AuthBackend"].toString(), map["ConnectionProperties"].toMap(), map["AuthProperties"].toMap()));
+        handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["ConnectionProperties"].toMap(), map["AuthBackend"].toString(), map["AuthProperties"].toMap()));
     }
 
     else if (msgType == "CoreSetupReject") {
@@ -206,7 +206,7 @@ void DataStreamPeer::dispatch(const SetupData &msg)
     // XXX: make these optional using core features.
     map["AuthBackend"] = msg.authenticator;
     map["AuthProperties"] = msg.authSetupData;
-    
+
     QVariantMap m;
     m["MsgType"] = "CoreSetupData";
     m["SetupData"] = map;
index 8f53fc1..a0afebd 100644 (file)
@@ -170,12 +170,12 @@ void LegacyPeer::handleHandshakeMessage(const QVariant &msg)
             socket()->setProperty("UseCompression", true);
 #endif
 
-        handle(ClientRegistered(m["CoreFeatures"].toUInt(), m["Configured"].toBool(), m["StorageBackends"].toList(), m["AuthBackends"].toList(), m["SupportSsl"].toBool()));
+        handle(ClientRegistered(m["CoreFeatures"].toUInt(), m["Configured"].toBool(), m["StorageBackends"].toList(), m["SupportSsl"].toBool(), m["AuthBackends"].toList()));
     }
 
     else if (msgType == "CoreSetupData") {
         QVariantMap map = m["SetupData"].toMap();
-        handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["AuthBackend"].toString(), map["ConnectionProperties"].toMap(), map["AuthProperties"].toMap()));
+        handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["ConnectionProperties"].toMap(), map["AuthBackend"].toString(), map["AuthProperties"].toMap()));
     }
 
     else if (msgType == "CoreSetupReject") {
index 5097bad..c661320 100644 (file)
@@ -76,8 +76,10 @@ public:
         CustomRateLimits = 0x0080,         /// IRC server custom message rate limits
         DccFileTransfer = 0x0100,
         AwayFormatTimestamp = 0x0200,      /// Timestamp formatting in away (e.g. %%hh:mm%%)
+        // Whether or not the core supports auth backends.
+        AuthBackends = 0x0400,
 
-        NumFeatures = 0x0200
+        NumFeatures = 0x0400
     };
     Q_DECLARE_FLAGS(Features, Feature)
 
index f2cbb48..6e98037 100644 (file)
@@ -2,7 +2,7 @@
 
 set(SOURCES
     abstractsqlstorage.cpp
-       authenticator.cpp
+    authenticator.cpp
     core.cpp
     corealiasmanager.cpp
     coreapplication.cpp
index 8029631..e0d4370 100644 (file)
 #include "types.h"
 
 class Authenticator : public QObject {
-  
-       Q_OBJECT
-       
+
+    Q_OBJECT
+
 public:
     Authenticator(QObject *parent = 0);
     virtual ~Authenticator() {};
 
     enum State {
-        IsReady,               // ready to go
-        NeedsSetup,            // need basic setup (ask the user for input)
-        NotAvailable   // remove the authenticator backend from the list of avaliable authenticators.
+        IsReady,        // ready to go
+        NeedsSetup,        // need basic setup (ask the user for input)
+        NotAvailable     // remove the authenticator backend from the list of avaliable authenticators.
     };
 
 
 public slots:
-       // General
-       
+    // General
+
     //! Check if the authenticator type is available.
     /** An authenticator subclass should return true if it can be successfully used, i.e. if all
      *  prerequisites are in place.
@@ -53,7 +53,7 @@ public slots:
     //! Returns the display name of the authenticator backend
     /** \return A string that can be used by the client to name the authenticator backend */
     virtual QString displayName() const = 0;
-       
+
     //! Returns a description of this authenticator backend
     /** \return A string that can be displayed by the client to describe the authenticator */
     virtual QString description() const = 0;
@@ -84,9 +84,9 @@ public slots:
      *  \return A valid UserId if the password matches the username; 0 else
      */
     virtual UserId validateUser(const QString &user, const QString &password) = 0;
-       
+
 private:
-       
+
 };
-  
-#endif
\ No newline at end of file
+
+#endif
index 035cc41..96fdc20 100644 (file)
@@ -175,8 +175,8 @@ Core::Core()
     }
 
     registerStorageBackends();
-       registerAuthenticatorBackends();
-       
+    registerAuthenticatorBackends();
+
     connect(&_storageSyncTimer, SIGNAL(timeout()), this, SLOT(syncStorage()));
     _storageSyncTimer.start(10 * 60 * 1000); // 10 minutes
 }
@@ -189,15 +189,15 @@ void Core::init()
     QVariantMap dbsettings = cs.storageSettings().toMap();
     _configured = initStorage(dbsettings.value("Backend").toString(), dbsettings.value("ConnectionProperties").toMap());
 
-       // Not entirely sure what is 'legacy' about the above, but it seems to be the way things work!
-       QVariantMap authSettings = cs.authSettings().toMap();
-       initAuthenticator(authSettings.value("AuthBackend").toString(), authSettings.value("ConnectionProperties").toMap());
-       
+    // Not entirely sure what is 'legacy' about the above, but it seems to be the way things work!
+    QVariantMap authSettings = cs.authSettings().toMap();
+    initAuthenticator(authSettings.value("AuthBackend").toString(), authSettings.value("ConnectionProperties").toMap());
+
     if (Quassel::isOptionSet("select-backend")) {
         selectBackend(Quassel::optionValue("select-backend"));
         exit(0);
     }
-    
+
     // TODO: add --select-authenticator command line option and code.
 
     if (!_configured) {
@@ -313,6 +313,12 @@ QString Core::setupCore(const QString &adminUser, const QString &adminPassword,
         return tr("Could not setup storage!");
     }
 
+    quInfo() << "Selected authenticator: " << authBackend;
+    if (!(_configured = initAuthenticator(authBackend, authSetupData, true)))
+    {
+        return tr("Could not setup authenticator!");
+    }
+
     if (!saveBackendSettings(backend, setupData)) {
         return tr("Could not save backend settings, probably a permission problem.");
     }
@@ -383,38 +389,38 @@ void Core::unregisterStorageBackend(Storage *backend)
 void Core::registerAuthenticatorBackends()
 {
     // Register new authentication backends here!
-       registerAuthenticatorBackend(new SqlAuthenticator(this));
+    registerAuthenticatorBackend(new SqlAuthenticator(this));
 #ifdef HAVE_LDAP
     registerAuthenticatorBackend(new LdapAuthenticator(this));
 #endif
-    
+
 }
 
 bool Core::registerAuthenticatorBackend(Authenticator *authenticator)
 {
-       if (authenticator->isAvailable())
-       {
-               _authenticatorBackends[authenticator->displayName()] = authenticator;
-               return true;
-       } else {
-               authenticator->deleteLater();
-               return false;
-       }
+    if (authenticator->isAvailable())
+    {
+        _authenticatorBackends[authenticator->displayName()] = authenticator;
+        return true;
+    } else {
+        authenticator->deleteLater();
+        return false;
+    }
 }
 
 void Core::unregisterAuthenticatorBackends()
 {
-       foreach(Authenticator* a, _authenticatorBackends.values())
-       {
-               a->deleteLater();
-       }
-       _authenticatorBackends.clear();
+    foreach(Authenticator* a, _authenticatorBackends.values())
+    {
+        a->deleteLater();
+    }
+    _authenticatorBackends.clear();
 }
 
 void Core::unregisterAuthenticatorBackend(Authenticator *backend)
 {
-       _authenticatorBackends.remove(backend->displayName());
-       backend->deleteLater();
+    _authenticatorBackends.remove(backend->displayName());
+    backend->deleteLater();
 }
 
 // old db settings:
@@ -461,11 +467,11 @@ bool Core::initStorage(const QString &backend, const QVariantMap &settings, bool
 bool Core::initAuthenticator(const QString &backend, const QVariantMap &settings, bool setup)
 {
     _authenticator = 0;
-    
+
     if (backend.isEmpty()) {
             return false;
     }
-    
+
     Authenticator *authenticator = 0;
     if (_authenticatorBackends.contains(backend)) {
         authenticator = _authenticatorBackends[backend];
@@ -492,7 +498,7 @@ bool Core::initAuthenticator(const QString &backend, const QVariantMap &settings
         unregisterAuthenticatorBackends();
     }
     _authenticator = authenticator;
-    return true;       
+    return true;
 }
 
 void Core::syncStorage()
index ff226a8..644e9b9 100644 (file)
@@ -84,7 +84,7 @@ public:
     static inline UserId authenticateUser(const QString &userName, const QString &password) {
         return instance()->_authenticator->validateUser(userName, password);
     }
-    
+
     //! Add a new user, exposed so auth providers can call this without being the storage.
     /**
      * \param userName The user's login name
@@ -572,7 +572,7 @@ private slots:
 
     bool initStorage(const QString &backend, const QVariantMap &settings, bool setup = false);
     bool initAuthenticator(const QString &backend, const QVariantMap &settings, bool setup = false);
-    
+
     void socketError(QAbstractSocket::SocketError err, const QString &errorString);
     void setupClientSession(RemotePeer *, UserId);
 
@@ -593,12 +593,12 @@ private:
     bool registerStorageBackend(Storage *);
     void unregisterStorageBackends();
     void unregisterStorageBackend(Storage *);
-    
+
     void registerAuthenticatorBackends();
     bool registerAuthenticatorBackend(Authenticator *);
     void unregisterAuthenticatorBackends();
     void unregisterAuthenticatorBackend(Authenticator *);
-    
+
     bool selectBackend(const QString &backend);
     bool createUser();
     bool saveBackendSettings(const QString &backend, const QVariantMap &settings);
index af5ef47..47c5796 100644 (file)
@@ -172,16 +172,17 @@ void CoreAuthHandler::handle(const RegisterClient &msg)
     }
 
     QVariantList backends;
-       QVariantList authenticators;
+    QVariantList authenticators;
     bool configured = Core::isConfigured();
     if (!configured)
-       {
+    {
         backends = Core::backendInfo();
-               authenticators = Core::authenticatorInfo();
-       }
+        authenticators = Core::authenticatorInfo();
+    }
 
     // useSsl is only used for the legacy protocol
-    _peer->dispatch(ClientRegistered(Quassel::features(), configured, backends, authenticators, useSsl));
+    // XXX: FIXME: use client features here: we cannot pass authenticators if the client is too old!
+    _peer->dispatch(ClientRegistered(Quassel::features(), configured, backends, useSsl, authenticators));
 
     if (_legacy && useSsl)
         startSsl();
@@ -195,7 +196,16 @@ void CoreAuthHandler::handle(const SetupData &msg)
     if (!checkClientRegistered())
         return;
 
-    QString result = Core::setup(msg.adminUser, msg.adminPassword, msg.backend, msg.setupData, msg.authenticator, msg.authSetupData);
+    // The default parameter to authBackend is Database.
+    // Maybe this should be hardcoded elsewhere, i.e. as a define.
+    QString authBackend = msg.authenticator;
+    quInfo() << "[" << authBackend << "]";
+    if (authBackend.trimmed().isEmpty() || authBackend == 0)
+    {
+        authBackend = QString("Database");
+    }
+
+    QString result = Core::setup(msg.adminUser, msg.adminPassword, msg.backend, msg.setupData, authBackend, msg.authSetupData);
     if (!result.isEmpty())
         _peer->dispatch(SetupFailed(result));
     else
@@ -210,12 +220,12 @@ void CoreAuthHandler::handle(const Login &msg)
 
     //UserId uid = Core::validateUser(msg.user, msg.password);
     UserId uid = Core::authenticateUser(msg.user, msg.password);
-       
-       // Try doing direct database auth if the provider failed, first.
-       if (uid == 0) {
-               uid = Core::validateUser(msg.user, msg.password);
-       }
-    
+
+    // Try doing direct database auth if the provider failed, first.
+    if (uid == 0) {
+        uid = Core::validateUser(msg.user, msg.password);
+    }
+
     if (uid == 0) {
         quInfo() << qPrintable(tr("Invalid login attempt from %1 as \"%2\"").arg(socket()->peerAddress().toString(), msg.user));
         _peer->dispatch(LoginFailed(tr("<b>Invalid username or password!</b><br>The username/password combination you supplied could not be found in the database.")));
index 243374b..45d9f67 100644 (file)
@@ -45,13 +45,13 @@ QVariant CoreSettings::storageSettings(const QVariant &def)
 
 QVariant CoreSettings::authSettings(const QVariant &def)
 {
-       return localValue("AuthSettings", def);
+    return localValue("AuthSettings", def);
 }
 
 void CoreSettings::setAuthSettings(const QVariant &data)
 {
-       setLocalValue("AuthSettings", data);
-}      
+    setLocalValue("AuthSettings", data);
+}
 
 // FIXME remove
 QVariant CoreSettings::oldDbSettings()
index bbb19f9..adc36b8 100644 (file)
@@ -32,8 +32,8 @@ public:
     void setStorageSettings(const QVariant &data);
     QVariant storageSettings(const QVariant &def = QVariant());
 
-       void setAuthSettings(const QVariant &data);
-       QVariant authSettings(const QVariant &def = QVariant());
+    void setAuthSettings(const QVariant &data);
+    QVariant authSettings(const QVariant &def = QVariant());
 
     QVariant oldDbSettings();  // FIXME remove
 
index 9439a6b..378fc4b 100644 (file)
 
 /* This file contains an implementation of an LDAP Authenticator, as an example
  * of what a custom external auth provider could do.
- * 
+ *
  * It's based off of this pull request for quassel by abustany:
  * https://github.com/quassel/quassel/pull/4/
- * 
+ *
  */
 
 #include "ldapauthenticator.h"
 
 LdapAuthenticator::LdapAuthenticator(QObject *parent)
     : Authenticator(parent),
-       _connection(0)
+    _connection(0)
 {
 }
 
 
 LdapAuthenticator::~LdapAuthenticator()
 {
-       if (_connection != 0)
-       {
-               ldap_unbind_ext(_connection, 0, 0);
+    if (_connection != 0)
+    {
+        ldap_unbind_ext(_connection, 0, 0);
     }
 }
 
@@ -98,7 +98,7 @@ void LdapAuthenticator::setConnectionProperties(const QVariantMap &properties)
     _hostName = properties["Hostname"].toString();
     _port = properties["Port"].toInt();
     _baseDN = properties["Base DN"].toString();
-       _filter = properties["Filter"].toString();
+    _filter = properties["Filter"].toString();
     _bindDN = properties["Bind DN"].toString();
     _bindPassword = properties["Bind Password"].toString();
     _uidAttribute = properties["UID Attribute"].toString();
@@ -110,43 +110,43 @@ void LdapAuthenticator::setConnectionProperties(const QVariantMap &properties)
 // through the default core method.
 UserId LdapAuthenticator::validateUser(const QString &username, const QString &password)
 {
-       bool result = ldapAuth(username, password);
-       if (!result)
-       {
-               return UserId();
-       }
-
-       // If auth succeeds, but the user has not logged into quassel previously, make
-       // a new user for them and return that ID.
-       // Users created via LDAP have empty usernames.
-       UserId quasselID = Core::validateUser(username, QString());
-       if (!quasselID.isValid())
-       {
-               return Core::addUser(username, QString());
-       }
-       return quasselID;
+    bool result = ldapAuth(username, password);
+    if (!result)
+    {
+        return UserId();
+    }
+
+    // If auth succeeds, but the user has not logged into quassel previously, make
+    // a new user for them and return that ID.
+    // Users created via LDAP have empty usernames.
+    UserId quasselID = Core::validateUser(username, QString());
+    if (!quasselID.isValid())
+    {
+        return Core::addUser(username, QString());
+    }
+    return quasselID;
 }
 
 bool LdapAuthenticator::setup(const QVariantMap &settings)
 {
-       setConnectionProperties(settings);
-       bool status = ldapConnect();
-       return status;
+    setConnectionProperties(settings);
+    bool status = ldapConnect();
+    return status;
 }
 
 Authenticator::State LdapAuthenticator::init(const QVariantMap &settings)
 {
-       setConnectionProperties(settings);
-       
-       bool status = ldapConnect();
-       if (!status)
-       {
-               quInfo() << qPrintable(displayName()) << "Authenticator cannot connect.";
-               return NotAvailable;
-       }
-       
-       quInfo() << qPrintable(displayName()) << "Authenticator is ready.";
-       return IsReady;
+    setConnectionProperties(settings);
+
+    bool status = ldapConnect();
+    if (!status)
+    {
+        quInfo() << qPrintable(displayName()) << "Authenticator cannot connect.";
+        return NotAvailable;
+    }
+
+    quInfo() << qPrintable(displayName()) << "Authenticator is ready.";
+    return IsReady;
 }
 
 // Method based on abustany LDAP quassel patch.
@@ -158,12 +158,12 @@ bool LdapAuthenticator::ldapConnect()
 
     int res, v = LDAP_VERSION3;
 
-       QString serverURI;
-       QByteArray serverURIArray;
-       
-       // Convert info to hostname:port.
-       serverURI = _hostName + ":" + QString::number(_port);
-       serverURIArray = serverURI.toLocal8Bit();
+    QString serverURI;
+    QByteArray serverURIArray;
+
+    // Convert info to hostname:port.
+    serverURI = _hostName + ":" + QString::number(_port);
+    serverURIArray = serverURI.toLocal8Bit();
     res = ldap_initialize(&_connection, serverURIArray);
 
     if (res != LDAP_SUCCESS) {
@@ -201,7 +201,7 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor
 
     int res;
 
-       // Attempt to establish a connection.
+    // Attempt to establish a connection.
     if (_connection == 0) {
         if (not ldapConnect()) {
             return false;
@@ -209,12 +209,12 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor
     }
 
     struct berval cred;
-       
-       // Convert some things to byte arrays as needed.
-       QByteArray bindPassword = _bindPassword.toLocal8Bit();
-       QByteArray bindDN = _bindDN.toLocal8Bit();
-       QByteArray baseDN = _baseDN.toLocal8Bit();
-       QByteArray uidAttribute = _uidAttribute.toLocal8Bit();
+
+    // Convert some things to byte arrays as needed.
+    QByteArray bindPassword = _bindPassword.toLocal8Bit();
+    QByteArray bindDN = _bindDN.toLocal8Bit();
+    QByteArray baseDN = _baseDN.toLocal8Bit();
+    QByteArray uidAttribute = _uidAttribute.toLocal8Bit();
 
     cred.bv_val = const_cast<char*>(bindPassword.size() > 0 ? bindPassword.constData() : NULL);
     cred.bv_len = bindPassword.size();
@@ -268,10 +268,10 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor
     }
 
     // The original implementation had requiredAttributes. I have not included this code
-    // but it would be easy to re-add if someone wants this feature. 
+    // but it would be easy to re-add if someone wants this feature.
     // Ben Rosser <bjr@acm.jhu.edu> (12/23/15).
-    
+
     ldap_memfree(userDN);
     ldap_msgfree(msg);
-    return true;       
-}
\ No newline at end of file
+    return true;
+}
index 3b7c2aa..cf14694 100644 (file)
 
 /* This file contains an implementation of an LDAP Authenticator, as an example
  * of what a custom external auth provider could do.
- * 
+ *
  * It's based off of this pull request for quassel by abustany:
  * https://github.com/quassel/quassel/pull/4/
- * 
+ *
  */
 
 #ifndef LDAPAUTHENTICATOR_H
@@ -54,11 +54,11 @@ public slots:
     QString description() const;
     virtual QStringList setupKeys() const;
     virtual QVariantMap setupDefaults() const;
+
     bool setup(const QVariantMap &settings = QVariantMap());
     State init(const QVariantMap &settings = QVariantMap());
     UserId validateUser(const QString &user, const QString &password);
-       
+
 protected:
     virtual void setConnectionProperties(const QVariantMap &properties);
     bool ldapConnect();
@@ -76,13 +76,13 @@ private:
     int _port;
     QString _bindDN;
     QString _baseDN;
-       QString _filter;
+    QString _filter;
     QString _bindPassword;
     QString _uidAttribute;
 
-       // The actual connection object.
-       LDAP *_connection;
-       
+    // The actual connection object.
+    LDAP *_connection;
+
 };
 
 
index fe8fffc..52f0ac6 100644 (file)
@@ -63,14 +63,14 @@ UserId SqlAuthenticator::validateUser(const QString &user, const QString &passwo
 
 bool SqlAuthenticator::setup(const QVariantMap &settings)
 {
-       return true;
+    return true;
 }
 
 Authenticator::State SqlAuthenticator::init(const QVariantMap &settings)
 {
-       // TODO: FIXME: this should check if the storage provider is ready, but I don't
-       // know if there's an exposed way to do that at the moment.
-       
-       quInfo() << qPrintable(displayName()) << "Authenticator is ready.";
-       return IsReady;
-}
\ No newline at end of file
+    // TODO: FIXME: this should check if the storage provider is ready, but I don't
+    // know if there's an exposed way to do that at the moment.
+
+    quInfo() << qPrintable(displayName()) << "Authenticator is ready.";
+    return IsReady;
+}
index 1b71ee2..51d051e 100644 (file)
@@ -42,7 +42,7 @@ public slots:
     bool setup(const QVariantMap &settings = QVariantMap());
     State init(const QVariantMap &settings = QVariantMap());
     UserId validateUser(const QString &user, const QString &password);
-    
+
     /* User handling */
     //virtual UserId getUserId(const QString &username);
 
index d2ce4b8..5119f17 100644 (file)
@@ -27,6 +27,8 @@
 #include "coreconfigwizard.h"
 #include "coreconnection.h"
 
+#include "client.h"
+
 CoreConfigWizard::CoreConfigWizard(CoreConnection *connection, const QList<QVariant> &backends, const QList<QVariant> &authenticators, QWidget *parent)
     : QWizard(parent),
     _connection(connection)
@@ -36,7 +38,7 @@ CoreConfigWizard::CoreConfigWizard(CoreConnection *connection, const QList<QVari
 
     foreach(const QVariant &v, backends)
     _backends[v.toMap()["DisplayName"].toString()] = v;
-    
+
     foreach(const QVariant &v, authenticators)
     _authenticators[v.toMap()["DisplayName"].toString()] = v;
 
@@ -45,8 +47,8 @@ CoreConfigWizard::CoreConfigWizard(CoreConnection *connection, const QList<QVari
     setPage(AuthenticationSelectionPage, new CoreConfigWizardPages::AuthenticationSelectionPage(_authenticators, this));
     setPage(StorageSelectionPage, new CoreConfigWizardPages::StorageSelectionPage(_backends, this));
     syncPage = new CoreConfigWizardPages::SyncPage(this);
-    connect(syncPage, SIGNAL(setupCore(const QString &, const QVariantMap &, const QString &, const QVariantMap &)), 
-                       SLOT(prepareCoreSetup(const QString &, const QVariantMap &, const QString &, const QVariantMap &)));
+    connect(syncPage, SIGNAL(setupCore(const QString &, const QVariantMap &, const QString &, const QVariantMap &)),
+            SLOT(prepareCoreSetup(const QString &, const QVariantMap &, const QString &, const QVariantMap &)));
     setPage(SyncPage, syncPage);
     syncRelayPage = new CoreConfigWizardPages::SyncRelayPage(this);
     connect(syncRelayPage, SIGNAL(startOver()), this, SLOT(startOver()));
@@ -89,7 +91,7 @@ QHash<QString, QVariant> CoreConfigWizard::backends() const
 
 QHash<QString, QVariant> CoreConfigWizard::authenticators() const
 {
-       return _authenticators;
+    return _authenticators;
 }
 
 void CoreConfigWizard::prepareCoreSetup(const QString &backend, const QVariantMap &properties, const QString &authBackend, const QVariantMap &authProperties)
@@ -98,7 +100,14 @@ void CoreConfigWizard::prepareCoreSetup(const QString &backend, const QVariantMa
     foreach(int idx, visitedPages())
     page(idx)->setEnabled(false);
 
-    coreConnection()->setupCore(Protocol::SetupData(field("adminUser.user").toString(), field("adminUser.password").toString(), backend, authBackend, properties, authProperties));
+    // FIXME? We need to be able to set up older cores that don't have auth backend support.
+    // So if the core doesn't support that feature, don't pass those parameters.
+    if (!(Client::coreFeatures() & Quassel::AuthBackends))
+    {
+        coreConnection()->setupCore(Protocol::SetupData(field("adminUser.user").toString(), field("adminUser.password").toString(), backend, properties));
+    } else {
+        coreConnection()->setupCore(Protocol::SetupData(field("adminUser.user").toString(), field("adminUser.password").toString(), backend, properties, authBackend, authProperties));
+    }
 }
 
 
@@ -184,7 +193,13 @@ AdminUserPage::AdminUserPage(QWidget *parent) : QWizardPage(parent)
 
 int AdminUserPage::nextId() const
 {
-    return CoreConfigWizard::AuthenticationSelectionPage;
+    // If the core doesn't support auth backends, skip that page!
+    if (!(Client::coreFeatures() & Quassel::AuthBackends))
+    {
+        return CoreConfigWizard::StorageSelectionPage;
+    } else {
+        return CoreConfigWizard::AuthenticationSelectionPage;
+    }
 }
 
 
@@ -510,23 +525,23 @@ void SyncPage::initializePage()
     complete = false;
     hasError = false;
 
-       // Fill in sync info about the storage layer. 
+    // Fill in sync info about the storage layer.
     StorageSelectionPage *storagePage = qobject_cast<StorageSelectionPage *>(wizard()->page(CoreConfigWizard::StorageSelectionPage));
     QString backend = storagePage->selectedBackend();
     QVariantMap properties = storagePage->connectionProperties();
-       Q_ASSERT(!backend.isEmpty());
+    Q_ASSERT(!backend.isEmpty());
     ui.backend->setText(backend);
-    
-       // Fill in synci nfo about the authentication layer.
-       AuthenticationSelectionPage *authPage = qobject_cast<AuthenticationSelectionPage *>(wizard()->page(CoreConfigWizard::AuthenticationSelectionPage));
-       QString authBackend = authPage->selectedBackend();
+
+    // Fill in sync info about the authentication layer.
+    AuthenticationSelectionPage *authPage = qobject_cast<AuthenticationSelectionPage *>(wizard()->page(CoreConfigWizard::AuthenticationSelectionPage));
+    QString authBackend = authPage->selectedBackend();
     QVariantMap authProperties = authPage->connectionProperties();
-       Q_ASSERT(!authBackend.isEmpty());
+    Q_ASSERT(!authBackend.isEmpty());
     ui.authBackend->setText(authBackend);
 
     ui.user->setText(wizard()->field("adminUser.user").toString());
 
-       emit setupCore(backend, properties, authBackend, authProperties);
+    emit setupCore(backend, properties, authBackend, authProperties);
 }
 
 
index 60691a7..5b7cb8a 100644 (file)
@@ -120,7 +120,7 @@ public:
     int nextId() const;
     QString selectedBackend() const;
     QVariantMap connectionProperties() const;
-    
+
 private slots:
     void on_backendList_currentIndexChanged();
 private:
index 0bd6097..1911be9 100644 (file)
@@ -64,7 +64,7 @@
            </widget>
           </item>
           <item row="2" column="0" >
-           <widget class="QLabel" name="label_2" >
+           <widget class="QLabel" name="label_3" >
             <property name="font" >
              <font>
               <weight>75</weight>