#include "network.h"
#include "postgresqlstorage.h"
#include "quassel.h"
+#include "sqlauthenticator.h"
#include "sqlitestorage.h"
#include "util.h"
Core::Core()
: QObject(),
- _storage(0)
+ _storage(0),
+ _authenticator(0)
{
#ifdef HAVE_UMASK
umask(S_IRWXG | S_IRWXO);
}
registerStorageBackends();
-
+ registerAuthenticatorBackends();
+
connect(&_storageSyncTimer, SIGNAL(timeout()), this, SLOT(syncStorage()));
_storageSyncTimer.start(10 * 60 * 1000); // 10 minutes
}
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());
+
if (Quassel::isOptionSet("select-backend")) {
selectBackend(Quassel::optionValue("select-backend"));
exit(0);
}
+
+ // TODO: add --select-authenticator command line option and code.
if (!_configured) {
if (!_storageBackends.count()) {
/*** Core Setup ***/
-QString Core::setup(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData)
+QString Core::setup(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authBackend, const QVariantMap &authSetupData)
{
- return instance()->setupCore(adminUser, adminPassword, backend, setupData);
+ return instance()->setupCore(adminUser, adminPassword, backend, setupData, authBackend, authSetupData);
}
-QString Core::setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData)
+QString Core::setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authBackend, const QVariantMap &authSetupData)
{
if (_configured)
return tr("Core is already configured! Not configuring again...");
if (!saveBackendSettings(backend, setupData)) {
return tr("Could not save backend settings, probably a permission problem.");
}
+ saveAuthBackendSettings(authBackend, authSetupData);
quInfo() << qPrintable(tr("Creating admin user..."));
_storage->addUser(adminUser, adminPassword);
}
// mono client currently needs sqlite
- return setupCore("AdminUser", QString::number(pass), "SQLite", QVariantMap());
+ return setupCore("AdminUser", QString::number(pass), "SQLite", QVariantMap(), "StorageAuth", QVariantMap());
}
}
}
-
void Core::unregisterStorageBackends()
{
foreach(Storage *s, _storageBackends.values()) {
backend->deleteLater();
}
+// Authentication handling, now independent from storage.
+// Register and unregister authenticators.
+
+void Core::registerAuthenticatorBackends()
+{
+ // Register new authentication backends here!
+ //registerAuthenticatorBackend(new LdapAuthenticator(this));
+ registerAuthenticatorBackend(new SqlAuthenticator(this));
+
+}
+
+bool Core::registerAuthenticatorBackend(Authenticator *authenticator)
+{
+ 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();
+}
+
+void Core::unregisterAuthenticatorBackend(Authenticator *backend)
+{
+ _authenticatorBackends.remove(backend->displayName());
+ backend->deleteLater();
+}
// old db settings:
// "Type" => "sqlite"
return true;
}
+// XXX: TODO: Apparently, this is legacy?
+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];
+ }
+ else {
+ qCritical() << "Selected auth backend is not available:" << backend;
+ return false;
+ }
+
+ Authenticator::State authState = authenticator->init(settings);
+ switch (authState) {
+ case Authenticator::NeedsSetup:
+ if (!setup)
+ return false; // trigger setup process
+ if (authenticator->setup(settings))
+ return initAuthenticator(backend, settings, false);
+ // if initialization wasn't successful, we quit to keep from coming up unconfigured
+ case Authenticator::NotAvailable:
+ qCritical() << "FATAL: Selected auth backend is not available:" << backend;
+ exit(EXIT_FAILURE);
+ case Authenticator::IsReady:
+ // delete all other backends
+ _authenticatorBackends.remove(backend);
+ unregisterAuthenticatorBackends();
+ }
+ _authenticator = authenticator;
+ return true;
+}
void Core::syncStorage()
{
return backends;
}
+QVariantList Core::authenticatorInfo()
+{
+ QVariantList backends;
+ foreach(const Authenticator *backend, instance()->_authenticatorBackends.values()) {
+ QVariantMap v;
+ v["DisplayName"] = backend->displayName();
+ v["Description"] = backend->description();
+ v["SetupKeys"] = backend->setupKeys();
+ v["SetupDefaults"] = backend->setupDefaults();
+ backends.append(v);
+ }
+ return backends;
+}
// migration / backend selection
bool Core::selectBackend(const QString &backend)
return s.sync();
}
+void Core::saveAuthBackendSettings(const QString &backend, const QVariantMap &settings)
+{
+ QVariantMap dbsettings;
+ dbsettings["AuthBackend"] = backend;
+ dbsettings["ConnectionProperties"] = settings;
+ CoreSettings().setAuthSettings(dbsettings);
+}
+
QVariantMap Core::promptForSettings(const Storage *storage)
{