diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6526377656..6727e17ddf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -270,6 +270,7 @@ set(mirall_SRCS mirall/sslbutton.cpp mirall/syncrunfilelog.cpp mirall/selectivesyncdialog.cpp + mirall/accountmigrator.cpp ) diff --git a/src/mirall/account.cpp b/src/mirall/account.cpp index a413691978..80be3365a8 100644 --- a/src/mirall/account.cpp +++ b/src/mirall/account.cpp @@ -18,6 +18,7 @@ #include "mirall/mirallconfigfile.h" #include "mirall/mirallaccessmanager.h" #include "mirall/quotainfo.h" +#include "mirall/owncloudtheme.h" #include "creds/abstractcredentials.h" #include "creds/credentialsfactory.h" @@ -27,6 +28,8 @@ #include #include #include +#include +#include #include @@ -71,6 +74,7 @@ Account::Account(AbstractSslErrorHandler *sslErrorHandler, QObject *parent) , _treatSslErrorsAsFailure(false) , _state(Account::Disconnected) , _davPath("remote.php/webdav/") + , _wasMigrated(false) { qRegisterMetaType("Account*"); } @@ -112,11 +116,50 @@ void Account::save() Account* Account::restore() { + // try to open the correctly themed settings QScopedPointer settings(settingsWithGroup(Theme::instance()->appName())); + + Account *acc = 0; + 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() ) { + QString oCUrl = oCSettings->value(QLatin1String(urlC)).toString(); + + // in case the urls are equal reset the settings object to read from + // the ownCloud settings object + qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":" + << (QUrl(oCUrl) == QUrl(overrideUrl) ? "Yes" : "No"); + if( QUrl(oCUrl) == QUrl(overrideUrl) ) { + migratedCreds = true; + settings.reset( oCSettings ); + } else { + delete oCSettings; + } + } + } + } + if (!settings->childKeys().isEmpty()) { - Account *acc = new Account; - MirallConfigFile cfg; - acc->setApprovedCerts(QSslCertificate::fromData(cfg.caCerts())); + acc = new Account; + acc->setUrl(settings->value(QLatin1String(urlC)).toUrl()); acc->setCredentials(CredentialsFactory::create(settings->value(QLatin1String(authTypeC)).toString())); @@ -128,6 +171,11 @@ Account* Account::restore() 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(QLatin1String("CaCertificates")).toByteArray())); + acc->setMigrated(migratedCreds); return acc; } return 0; @@ -364,4 +412,14 @@ void Account::slotHandleErrors(QNetworkReply *reply , QList errors) } } +bool Account::wasMigrated() +{ + return _wasMigrated; +} + +void Account::setMigrated(bool mig) +{ + _wasMigrated = mig; +} + } // namespace Mirall diff --git a/src/mirall/account.h b/src/mirall/account.h index d782a7498d..85e91b61ab 100644 --- a/src/mirall/account.h +++ b/src/mirall/account.h @@ -108,6 +108,13 @@ public: /** Returns webdav entry URL, based on url() */ QUrl davUrl() const; + /** set and retrieve the migration flag: if an account of a branded + * client was migrated from a former ownCloud Account, this is true + */ + void setMigrated(bool mig); + bool wasMigrated(); + + QList lastAuthCookies() const; QNetworkReply* headRequest(const QString &relPath); @@ -166,6 +173,7 @@ private: int _state; static QString _configFileName; QString _davPath; // default "remote.php/webdav/"; + bool _wasMigrated; }; } diff --git a/src/mirall/accountmigrator.cpp b/src/mirall/accountmigrator.cpp new file mode 100644 index 0000000000..ba4d49f43b --- /dev/null +++ b/src/mirall/accountmigrator.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) by Klaas Freitag + * + * 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 "mirall/accountmigrator.h" +#include "mirall/mirallconfigfile.h" +#include "mirall/folderman.h" +#include "mirall/theme.h" + + +#include +#include +#include +#include +#include + +namespace Mirall { + +// The purpose of this class is to migrate an existing account that +// was set up with an unbranded client to an branded one. +// The usecase is: Usually people try first with the community client, +// later they maybe switch to a branded client. When they install the +// branded client first, it should automatically pick the information +// from the already configured account. + +AccountMigrator::AccountMigrator() +{ + +} + +// the list of folder definitions which are files in the directory "folders" +// underneath the ownCloud configPath (with ownCloud as a last segment) +// need to be copied to the themed path and adjusted. + +QStringList AccountMigrator::migrateFolderDefinitons() +{ + MirallConfigFile cfg; + QStringList re; + + QString themePath = cfg.configPath(); + // create the original ownCloud config path out of the theme path + // by removing the theme folder and append ownCloud. + QString oCPath = themePath; + if( oCPath.endsWith(QLatin1Char('/')) ) { + oCPath.truncate( oCPath.length()-1 ); + } + oCPath = oCPath.left( oCPath.lastIndexOf('/')); + + themePath += QLatin1String( "folders"); + oCPath += QLatin1String( "/ownCloud/folders" ); + + qDebug() << "Migrator: theme-path: " << themePath; + qDebug() << "Migrator: ownCloud path: " << oCPath; + + // get a dir listing of the ownCloud folder definitions and copy + // them over to the theme dir + QDir oCDir(oCPath); + oCDir.setFilter( QDir::Files ); + QStringList files = oCDir.entryList(); + + foreach( const QString& file, files ) { + QString escapedAlias = FolderMan::instance()->escapeAlias(file); + QString themeFile = themePath + QDir::separator() + file; + QString oCFile = oCPath+QDir::separator()+file; + if( QFile::copy( oCFile, themeFile ) ) { + re.append(file); + qDebug() << "Migrator: Folder definition migrated: " << file; + + // fix the connection entry of the folder definition + QSettings settings(themeFile, QSettings::IniFormat); + settings.beginGroup( escapedAlias ); + settings.setValue(QLatin1String("connection"), Theme::instance()->appName()); + settings.sync(); + } + } + + return re; +} + +} diff --git a/src/mirall/accountmigrator.h b/src/mirall/accountmigrator.h new file mode 100644 index 0000000000..49e3fa04e6 --- /dev/null +++ b/src/mirall/accountmigrator.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) by Klaas Freitag + * + * 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. + */ + +#ifndef ACCOUNTMIGRATOR_H +#define ACCOUNTMIGRATOR_H + +#include + +namespace Mirall { + +class AccountMigrator { + +public: + explicit AccountMigrator(); + + /** + * @brief migrateFolderDefinitons - migrate the folder definition files + * @return the list of migrated folder definitions + */ + QStringList migrateFolderDefinitons(); +signals: + +public slots: + +}; +} + +#endif // ACCOUNTMIGRATOR_H diff --git a/src/mirall/folderman.cpp b/src/mirall/folderman.cpp index b8973d55f6..2cea12209a 100644 --- a/src/mirall/folderman.cpp +++ b/src/mirall/folderman.cpp @@ -13,11 +13,14 @@ */ #include "mirall/folderman.h" +#include "mirall/account.h" + #include "mirall/mirallconfigfile.h" #include "mirall/folder.h" #include "mirall/syncresult.h" #include "mirall/theme.h" #include "mirall/socketapi.h" +#include "mirall/accountmigrator.h" #include @@ -181,6 +184,15 @@ int FolderMan::setupFolders() dir.setFilter(QDir::Files | QDir::Hidden); QStringList list = dir.entryList(); + if( list.count() == 0 ) { + // maybe the account was just migrated. + Account *acc = AccountManager::instance()->account(); + if ( acc && acc->wasMigrated() ) { + AccountMigrator accMig; + list = accMig.migrateFolderDefinitons(); + } + } + foreach ( const QString& alias, list ) { Folder *f = setupFolderFromConfigFile( alias ); if( f ) { diff --git a/src/mirall/owncloudtheme.cpp b/src/mirall/owncloudtheme.cpp index 3c291e80d3..5e5b2a5a9f 100644 --- a/src/mirall/owncloudtheme.cpp +++ b/src/mirall/owncloudtheme.cpp @@ -112,6 +112,16 @@ QPixmap ownCloudTheme::wizardHeaderLogo() const } #endif +QString ownCloudTheme::appName() const +{ + return QLatin1String("owncloud"); +} + +QString ownCloudTheme::appNameGUI() const +{ + return QLatin1String("ownCloud"); +} + } diff --git a/src/mirall/owncloudtheme.h b/src/mirall/owncloudtheme.h index 1d8e599475..9ab83a9ab3 100644 --- a/src/mirall/owncloudtheme.h +++ b/src/mirall/owncloudtheme.h @@ -32,6 +32,8 @@ public: QIcon folderIcon( const QString& ) const; QIcon trayFolderIcon( const QString& ) const Q_DECL_OVERRIDE; QIcon applicationIcon() const Q_DECL_OVERRIDE; + QString appName() const Q_DECL_OVERRIDE; + QString appNameGUI() const Q_DECL_OVERRIDE; QVariant customMedia(CustomMediaType type) Q_DECL_OVERRIDE; QString helpUrl() const Q_DECL_OVERRIDE;