AccountManager: Move out of libsync

The AccountManager does not belong in the libsync because it is not
part of the synchronisation algorithm, but is just an helper class
for the UI to maintain the account and read/save the config
This commit is contained in:
Olivier Goffart 2015-04-09 16:19:17 +02:00
parent 85ff245aef
commit afdd01488f
15 changed files with 231 additions and 188 deletions

View file

@ -366,8 +366,6 @@ int main(int argc, char **argv) {
account->setCredentials(cred);
account->setSslErrorHandler(sslErrorHandler);
AccountManager::instance()->setAccount(account);
restart_sync:
CSYNC *_csync_ctx;

View file

@ -36,6 +36,7 @@ set(client_UI
qt_wrap_ui(client_UI_SRCS ${client_UI})
set(client_SRCS
accountmanager.cpp
accountsettings.cpp
application.cpp
folder.cpp

164
src/gui/accountmanager.cpp Normal file
View file

@ -0,0 +1,164 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "accountmanager.h"
#include <theme.h>
#include <creds/credentialsfactory.h>
#include <creds/abstractcredentials.h>
#include <cookiejar.h>
#include <QSettings>
#include <QDir>
#include <QNetworkAccessManager>
namespace {
static const char urlC[] = "url";
static const char authTypeC[] = "authType";
static const char userC[] = "user";
static const char httpUserC[] = "http_user";
static const char caCertsKeyC[] = "CaCertificates";
}
namespace OCC {
AccountManager *AccountManager::instance()
{
static AccountManager instance;
return &instance;
}
void AccountManager::setAccount(AccountPtr account)
{
if (_account) {
emit accountRemoved(_account);
}
_account = account;
if (account) {
emit accountAdded(account);
}
}
bool AccountManager::restore()
{
// try to open the correctly themed settings
QScopedPointer<QSettings> settings(Account::settingsWithGroup(Theme::instance()->appName()));
AccountPtr acc;
bool migratedCreds = false;
// if the settings file could not be opened, the childKeys list is empty
if( settings->childKeys().isEmpty() ) {
// Now try to open the original ownCloud settings to see if they exist.
QString oCCfgFile = QDir::fromNativeSeparators( settings->fileName() );
// replace the last two segments with ownCloud/owncloud.cfg
oCCfgFile = oCCfgFile.left( oCCfgFile.lastIndexOf('/'));
oCCfgFile = oCCfgFile.left( oCCfgFile.lastIndexOf('/'));
oCCfgFile += QLatin1String("/ownCloud/owncloud.cfg");
qDebug() << "Migrate: checking old config " << oCCfgFile;
QFileInfo fi( oCCfgFile );
if( fi.isReadable() ) {
QSettings *oCSettings = new QSettings(oCCfgFile, QSettings::IniFormat);
oCSettings->beginGroup(QLatin1String("ownCloud"));
// Check the theme url to see if it is the same url that the oC config was for
QString overrideUrl = Theme::instance()->overrideServerUrl();
if( !overrideUrl.isEmpty() ) {
if (overrideUrl.endsWith('/')) { overrideUrl.chop(1); }
QString oCUrl = oCSettings->value(QLatin1String(urlC)).toString();
if (oCUrl.endsWith('/')) { oCUrl.chop(1); }
// in case the urls are equal reset the settings object to read from
// the ownCloud settings object
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
<< (oCUrl == overrideUrl ? "Yes" : "No");
if( oCUrl == overrideUrl ) {
migratedCreds = true;
settings.reset( oCSettings );
} else {
delete oCSettings;
}
}
}
}
if (!settings->childKeys().isEmpty()) {
acc = AccountPtr(new Account);
acc->setSharedThis(acc);
acc->setUrl(settings->value(QLatin1String(urlC)).toUrl());
acc->setCredentials(CredentialsFactory::create(settings->value(QLatin1String(authTypeC)).toString()));
// We want to only restore settings for that auth type and the user value
acc->_settingsMap.insert(QLatin1String(userC), settings->value(userC));
QString authTypePrefix = settings->value(authTypeC).toString() + "_";
Q_FOREACH(QString key, settings->childKeys()) {
if (!key.startsWith(authTypePrefix))
continue;
acc->_settingsMap.insert(key, settings->value(key));
}
// now the cert, it is in the general group
settings->beginGroup(QLatin1String("General"));
acc->setApprovedCerts(QSslCertificate::fromData(settings->value(caCertsKeyC).toByteArray()));
acc->setMigrated(migratedCreds);
setAccount(acc);
return true;
}
return false;
}
void AccountManager::save()
{
auto acc = account();
if (!acc) { return; }
QScopedPointer<QSettings> settings(Account::settingsWithGroup(Theme::instance()->appName()));
settings->setValue(QLatin1String(urlC), acc->_url.toString());
if (acc->_credentials) {
acc->_credentials->persist();
Q_FOREACH(QString key, acc->_settingsMap.keys()) {
settings->setValue(key, acc->_settingsMap.value(key));
}
settings->setValue(QLatin1String(authTypeC), acc->_credentials->authType());
// HACK: Save http_user also as user
if (acc->_settingsMap.contains(httpUserC))
settings->setValue(userC, acc->_settingsMap.value(httpUserC));
}
settings->sync();
// Save accepted certificates.
settings->beginGroup(QLatin1String("General"));
qDebug() << "Saving " << acc->approvedCerts().count() << " unknown certs.";
QByteArray certs;
Q_FOREACH( const QSslCertificate& cert, acc->approvedCerts() ) {
certs += cert.toPem() + '\n';
}
if (!certs.isEmpty()) {
settings->setValue( QLatin1String(caCertsKeyC), certs );
}
// Save cookies.
if (acc->_am) {
CookieJar* jar = qobject_cast<CookieJar*>(acc->_am->cookieJar());
if (jar) {
qDebug() << "Saving cookies.";
jar->save();
}
}
}
}

49
src/gui/accountmanager.h Normal file
View file

@ -0,0 +1,49 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#pragma once
#include "account.h"
namespace OCC {
class OWNCLOUDSYNC_EXPORT AccountManager : public QObject {
Q_OBJECT
public:
static AccountManager *instance();
~AccountManager() {}
void setAccount(AccountPtr account);
AccountPtr account() { return _account; }
/**
* Saves the account to a given settings file
*/
void save();
/**
* Creates an account object from from a given settings file.
* return true if the account was restored
*/
bool restore();
Q_SIGNALS:
void accountAdded(AccountPtr account);
void accountRemoved(AccountPtr account);
private:
AccountManager() {}
AccountPtr _account;
};
}

View file

@ -26,6 +26,7 @@
#include "accountstate.h"
#include "quotainfo.h"
#include "creds/abstractcredentials.h"
#include "accountmanager.h"
#include <math.h>

View file

@ -13,6 +13,7 @@
#include "accountstate.h"
#include "quotainfo.h"
#include "accountmanager.h"
#include "account.h"
#include "creds/abstractcredentials.h"

View file

@ -34,6 +34,7 @@
#include "sharedialog.h"
#include "updater/updater.h"
#include "accountmanager.h"
#include "creds/abstractcredentials.h"
#include "config.h"
@ -126,10 +127,8 @@ Application::Application(int &argc, char **argv) :
// account manager.
AccountStateManager::instance();
AccountPtr account = Account::restore();
if (account) {
account->setSslErrorHandler(new SslDialogErrorHandler);
AccountManager::instance()->setAccount(account);
if (AccountManager::instance()->restore()) {
AccountManager::instance()->account()->setSslErrorHandler(new SslDialogErrorHandler);
}
FolderMan::instance()->setSyncEnabled(false);
@ -230,10 +229,7 @@ void Application::slotCleanup()
{
// explicitly close windows. This is somewhat of a hack to ensure
// that saving the geometries happens ASAP during a OS shutdown
AccountPtr account = AccountManager::instance()->account();
if (account) {
account->save();
}
AccountManager::instance()->save();
FolderMan::instance()->unloadAndDeleteAllFolders();
_gui->slotShutdown();

View file

@ -21,6 +21,7 @@
#include "account.h"
#include "accountmigrator.h"
#include "accountstate.h"
#include "accountmanager.h"
#include "filesystem.h"
#ifdef Q_OS_MAC

View file

@ -31,6 +31,7 @@
#include "account.h"
#include "accountstate.h"
#include "openfilemanager.h"
#include "accountmanager.h"
#include "creds/abstractcredentials.h"
#include <QDesktopServices>

View file

@ -29,6 +29,7 @@
#include "account.h"
#include "networkjobs.h"
#include "sslerrordialog.h"
#include "accountmanager.h"
#include "creds/credentialsfactory.h"
#include "creds/abstractcredentials.h"
@ -80,14 +81,9 @@ void OwncloudSetupWizard::startWizard()
FolderMan *folderMan = FolderMan::instance();
bool multiFolderSetup = folderMan->map().count() > 1;
// ###
AccountPtr account = Account::restore();
if (!account) {
AccountPtr account = Account::create();
_ocWizard->setConfigExists(false);
account = Account::create();
account->setCredentials(CredentialsFactory::create("dummy"));
} else {
_ocWizard->setConfigExists(true);
}
account->setSslErrorHandler(new SslDialogErrorHandler);
_ocWizard->setAccount(account);
_ocWizard->setOCUrl(account->url().toString());
@ -421,7 +417,7 @@ void OwncloudSetupWizard::replaceDefaultAccountWith(AccountPtr newAccount)
// new Account
AccountManager *mgr = AccountManager::instance();
mgr->setAccount(newAccount);
newAccount->save();
mgr->save();
}
// Method executed when the user ends has finished the basic setup.

View file

@ -19,6 +19,7 @@
#include "json.h"
#include "folderman.h"
#include "folder.h"
#include "accountmanager.h"
#include "theme.h"
#include "syncresult.h"

View file

@ -17,6 +17,7 @@
#include "wizard/owncloudwizard.h"
#include "wizard/abstractcredswizardpage.h"
#include <accountmanager.h>
namespace OCC {

View file

@ -27,6 +27,7 @@
#include "theme.h"
#include "configfile.h"
#include "selectivesyncdialog.h"
#include <accountmanager.h>
#include "creds/abstractcredentials.h"
#include "networkjobs.h"

View file

@ -35,40 +35,6 @@
namespace OCC {
static const char urlC[] = "url";
static const char authTypeC[] = "authType";
static const char userC[] = "user";
static const char httpUserC[] = "http_user";
static const char caCertsKeyC[] = "CaCertificates";
AccountManager *AccountManager::_instance = 0;
AccountManager *AccountManager::instance()
{
static QMutex mutex;
if (!_instance)
{
QMutexLocker lock(&mutex);
if (!_instance) {
_instance = new AccountManager;
}
}
return _instance;
}
void AccountManager::setAccount(AccountPtr account)
{
if (_account) {
emit accountRemoved(_account);
}
_account = account;
if (account) {
emit accountAdded(account);
}
}
Account::Account(QObject *parent)
: QObject(parent)
, _url(Theme::instance()->overrideServerUrl())
@ -104,113 +70,6 @@ AccountPtr Account::sharedFromThis()
return _sharedThis.toStrongRef();
}
void Account::save()
{
QScopedPointer<QSettings> settings(settingsWithGroup(Theme::instance()->appName()));
settings->setValue(QLatin1String(urlC), _url.toString());
if (_credentials) {
_credentials->persist();
Q_FOREACH(QString key, _settingsMap.keys()) {
settings->setValue(key, _settingsMap.value(key));
}
settings->setValue(QLatin1String(authTypeC), _credentials->authType());
// HACK: Save http_user also as user
if (_settingsMap.contains(httpUserC))
settings->setValue(userC, _settingsMap.value(httpUserC));
}
settings->sync();
// Save accepted certificates.
settings->beginGroup(QLatin1String("General"));
qDebug() << "Saving " << approvedCerts().count() << " unknown certs.";
QByteArray certs;
Q_FOREACH( const QSslCertificate& cert, approvedCerts() ) {
certs += cert.toPem() + '\n';
}
if (!certs.isEmpty()) {
settings->setValue( QLatin1String(caCertsKeyC), certs );
}
// Save cookies.
if (_am) {
CookieJar* jar = qobject_cast<CookieJar*>(_am->cookieJar());
if (jar) {
qDebug() << "Saving cookies.";
jar->save();
}
}
}
AccountPtr Account::restore()
{
// try to open the correctly themed settings
QScopedPointer<QSettings> settings(settingsWithGroup(Theme::instance()->appName()));
AccountPtr acc;
bool migratedCreds = false;
// if the settings file could not be opened, the childKeys list is empty
if( settings->childKeys().isEmpty() ) {
// Now try to open the original ownCloud settings to see if they exist.
QString oCCfgFile = QDir::fromNativeSeparators( settings->fileName() );
// replace the last two segments with ownCloud/owncloud.cfg
oCCfgFile = oCCfgFile.left( oCCfgFile.lastIndexOf('/'));
oCCfgFile = oCCfgFile.left( oCCfgFile.lastIndexOf('/'));
oCCfgFile += QLatin1String("/ownCloud/owncloud.cfg");
qDebug() << "Migrate: checking old config " << oCCfgFile;
QFileInfo fi( oCCfgFile );
if( fi.isReadable() ) {
QSettings *oCSettings = new QSettings(oCCfgFile, QSettings::IniFormat);
oCSettings->beginGroup(QLatin1String("ownCloud"));
// Check the theme url to see if it is the same url that the oC config was for
QString overrideUrl = Theme::instance()->overrideServerUrl();
if( !overrideUrl.isEmpty() ) {
if (overrideUrl.endsWith('/')) { overrideUrl.chop(1); }
QString oCUrl = oCSettings->value(QLatin1String(urlC)).toString();
if (oCUrl.endsWith('/')) { oCUrl.chop(1); }
// in case the urls are equal reset the settings object to read from
// the ownCloud settings object
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
<< (oCUrl == overrideUrl ? "Yes" : "No");
if( oCUrl == overrideUrl ) {
migratedCreds = true;
settings.reset( oCSettings );
} else {
delete oCSettings;
}
}
}
}
if (!settings->childKeys().isEmpty()) {
acc = AccountPtr(new Account);
acc->setSharedThis(acc);
acc->setUrl(settings->value(QLatin1String(urlC)).toUrl());
acc->setCredentials(CredentialsFactory::create(settings->value(QLatin1String(authTypeC)).toString()));
// We want to only restore settings for that auth type and the user value
acc->_settingsMap.insert(QLatin1String(userC), settings->value(userC));
QString authTypePrefix = settings->value(authTypeC).toString() + "_";
Q_FOREACH(QString key, settings->childKeys()) {
if (!key.startsWith(authTypePrefix))
continue;
acc->_settingsMap.insert(key, settings->value(key));
}
// now the cert, it is in the general group
settings->beginGroup(QLatin1String("General"));
acc->setApprovedCerts(QSslCertificate::fromData(settings->value(caCertsKeyC).toByteArray()));
acc->setMigrated(migratedCreds);
return acc;
}
return AccountPtr();
}
static bool isEqualExceptProtocol(const QUrl &url1, const QUrl &url2)
{

View file

@ -39,24 +39,6 @@ typedef QSharedPointer<Account> AccountPtr;
class QuotaInfo;
class AccessManager;
class OWNCLOUDSYNC_EXPORT AccountManager : public QObject {
Q_OBJECT
public:
static AccountManager *instance();
~AccountManager() {}
void setAccount(AccountPtr account);
AccountPtr account() { return _account; }
Q_SIGNALS:
void accountAdded(AccountPtr account);
void accountRemoved(AccountPtr account);
private:
AccountManager() {}
AccountPtr _account;
static AccountManager *_instance;
};
/* Reimplement this to handle SSL errors */
class AbstractSslErrorHandler {
@ -80,16 +62,6 @@ public:
void setSharedThis(AccountPtr sharedThis);
AccountPtr sharedFromThis();
/**
* Saves the account to a given settings file
*/
void save();
/**
* Creates an account object from from a given settings file.
*/
static AccountPtr restore();
/**
* @brief Checks the Account instance is different from \param other
*
@ -191,6 +163,7 @@ private:
QString _pemPrivateKey;
QString _davPath; // default "remote.php/webdav/";
bool _wasMigrated;
friend class AccountManager;
};
}