+
+QString Core::setupCore(const QString &adminUser, const QString &adminPassword, const QString &backend, const QVariantMap &setupData, const QString &authenticator, const QVariantMap &authSetupData)
+{
+ if (_configured)
+ return tr("Core is already configured! Not configuring again...");
+
+ if (adminUser.isEmpty() || adminPassword.isEmpty()) {
+ return tr("Admin user or password not set.");
+ }
+ if (!(_configured = initStorage(backend, setupData, true))) {
+ return tr("Could not setup storage!");
+ }
+
+ quInfo() << "Selected authenticator: " << authenticator;
+ if (!(_configured = initAuthenticator(authenticator, authSetupData, true)))
+ {
+ return tr("Could not setup authenticator!");
+ }
+
+ if (!saveBackendSettings(backend, setupData)) {
+ return tr("Could not save backend settings, probably a permission problem.");
+ }
+ saveAuthenticatorSettings(authenticator, authSetupData);
+
+ quInfo() << qPrintable(tr("Creating admin user..."));
+ _storage->addUser(adminUser, adminPassword);
+ startListening(); // TODO check when we need this
+ return QString();
+}
+
+
+QString Core::setupCoreForInternalUsage()
+{
+ Q_ASSERT(!_storageBackends.isEmpty());
+
+ qsrand(QDateTime::currentDateTime().toTime_t());
+ int pass = 0;
+ for (int i = 0; i < 10; i++) {
+ pass *= 10;
+ pass += qrand() % 10;
+ }
+
+ // mono client currently needs sqlite
+ return setupCore("AdminUser", QString::number(pass), "SQLite", QVariantMap(), "StorageAuth", QVariantMap());
+}
+
+
+/*** Storage Handling ***/
+void Core::registerStorageBackends()
+{
+ // Register storage backends here!
+ registerStorageBackend(new SqliteStorage(this));
+ registerStorageBackend(new PostgreSqlStorage(this));
+}
+
+
+bool Core::registerStorageBackend(Storage *backend)
+{
+ if (backend->isAvailable()) {
+ _storageBackends[backend->displayName()] = backend;
+ return true;
+ }
+ else {
+ backend->deleteLater();
+ return false;
+ }
+}
+
+void Core::unregisterStorageBackends()
+{
+ foreach(Storage *s, _storageBackends.values()) {
+ s->deleteLater();
+ }
+ _storageBackends.clear();
+}
+
+
+void Core::unregisterStorageBackend(Storage *backend)
+{
+ _storageBackends.remove(backend->displayName());
+ backend->deleteLater();
+}
+
+// Authentication handling, now independent from storage.
+// Register and unregister authenticators.
+
+void Core::registerAuthenticators()
+{
+ // Register new authentication backends here!
+ registerAuthenticator(new SqlAuthenticator(this));
+#ifdef HAVE_LDAP
+ registerAuthenticator(new LdapAuthenticator(this));
+#endif
+
+}
+
+bool Core::registerAuthenticator(Authenticator *authenticator)
+{
+ if (authenticator->isAvailable())
+ {
+ _authenticators[authenticator->backendId()] = authenticator;
+ return true;
+ } else {
+ authenticator->deleteLater();
+ return false;
+ }
+}
+
+void Core::unregisterAuthenticators()
+{
+ foreach(Authenticator* a, _authenticators.values())
+ {
+ a->deleteLater();
+ }
+ _authenticators.clear();
+}
+
+void Core::unregisterAuthenticator(Authenticator *backend)
+{
+ _authenticators.remove(backend->backendId());
+ backend->deleteLater();
+}
+
+// old db settings:
+// "Type" => "sqlite"
+bool Core::initStorage(const QString &backend, const QVariantMap &settings, bool setup)
+{
+ _storage = 0;
+
+ if (backend.isEmpty()) {
+ return false;
+ }
+
+ Storage *storage = 0;
+ if (_storageBackends.contains(backend)) {
+ storage = _storageBackends[backend];
+ }
+ else {
+ qCritical() << "Selected storage backend is not available:" << backend;
+ return false;
+ }
+
+ Storage::State storageState = storage->init(settings);
+ switch (storageState) {
+ case Storage::NeedsSetup:
+ if (!setup)
+ return false; // trigger setup process
+ if (storage->setup(settings))
+ return initStorage(backend, settings, false);
+ // if initialization wasn't successful, we quit to keep from coming up unconfigured
+ case Storage::NotAvailable:
+ qCritical() << "FATAL: Selected storage backend is not available:" << backend;
+ exit(EXIT_FAILURE);
+ case Storage::IsReady:
+ // delete all other backends
+ _storageBackends.remove(backend);
+ unregisterStorageBackends();
+ connect(storage, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)), this, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)));
+ }
+ _storage = storage;
+ return true;
+}
+
+// FIXME: Apparently, this is the legacy way of initting storage backends?
+// If there's a not-legacy way, it should be used here
+bool Core::initAuthenticator(const QString &backend, const QVariantMap &settings, bool setup)
+{
+ _authenticator = 0;
+
+ if (backend.isEmpty()) {
+ return false;
+ }
+
+ Authenticator *authenticator = 0;
+ if (_authenticators.contains(backend)) {
+ authenticator = _authenticators[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
+ _authenticators.remove(backend);
+ unregisterAuthenticators();
+ }
+ _authenticator = authenticator;
+ return true;
+}
+
+void Core::syncStorage()
+{
+ if (_storage)
+ _storage->sync();
+}
+
+
+/*** Storage Access ***/
+bool Core::createNetwork(UserId user, NetworkInfo &info)
+{
+ NetworkId networkId = instance()->_storage->createNetwork(user, info);
+ if (!networkId.isValid())
+ return false;
+
+ info.networkId = networkId;
+ return true;
+}
+
+
+/*** Network Management ***/
+
+bool Core::sslSupported()
+{
+#ifdef HAVE_SSL
+ SslServer *sslServer = qobject_cast<SslServer *>(&instance()->_server);
+ return sslServer && sslServer->isCertValid();
+#else