From 5597ebe455cc4f6cd39758682a16dfa4697973e0 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 11:38:39 +0200 Subject: [PATCH 01/10] Account: Add a scoped pointer to the ownCloud theme. --- src/mirall/account.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/mirall/account.cpp b/src/mirall/account.cpp index a413691978..ac7208eabe 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" @@ -113,9 +114,19 @@ void Account::save() Account* Account::restore() { QScopedPointer settings(settingsWithGroup(Theme::instance()->appName())); + QScopedPointer ocTheme(new ownCloudTheme); + + Account *acc = 0; + MirallConfigFile cfg; + + if( settings->childKeys().isEmpty() ) { + // Now try to open the original ownCloud settings to see if they exist. + cfg.setTheme(ocTheme.data()); + } + if (!settings->childKeys().isEmpty()) { - Account *acc = new Account; - MirallConfigFile cfg; + acc = new Account; + acc->setApprovedCerts(QSslCertificate::fromData(cfg.caCerts())); acc->setUrl(settings->value(QLatin1String(urlC)).toUrl()); acc->setCredentials(CredentialsFactory::create(settings->value(QLatin1String(authTypeC)).toString())); From 8d3806b0808f3057a29a93bec6812a1be9877ebf Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 16:47:58 +0200 Subject: [PATCH 02/10] folderman: make escapeAlias public as its now used in accountmigrator. --- src/mirall/folderman.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mirall/folderman.h b/src/mirall/folderman.h index 0f4a79d708..5b3f6c642a 100644 --- a/src/mirall/folderman.h +++ b/src/mirall/folderman.h @@ -83,6 +83,8 @@ public: void removeMonitorPath( const QString& alias, const QString& path ); void addMonitorPath( const QString& alias, const QString& path ); + QString escapeAlias( const QString& ) const; + signals: /** * signal to indicate a folder named by alias has changed its sync state. @@ -130,7 +132,6 @@ private: // Escaping of the alias which is used in QSettings AND the file // system, thus need to be escaped. - QString escapeAlias( const QString& ) const; QString unescapeAlias( const QString& ) const; void removeFolder( const QString& ); From e795d04f30e80d49971bcfe76c8ca7d1ce5f13e8 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 16:45:21 +0200 Subject: [PATCH 03/10] cfg migration: Add a account migrator class. --- src/CMakeLists.txt | 1 + src/mirall/accountmigrator.cpp | 86 ++++++++++++++++++++++++++++++++++ src/mirall/accountmigrator.h | 39 +++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 src/mirall/accountmigrator.cpp create mode 100644 src/mirall/accountmigrator.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 669854fd28..e07325da41 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -105,6 +105,7 @@ set(libsync_SRCS mirall/clientproxy.cpp mirall/syncrunfilelog.cpp mirall/cookiejar.cpp + mirall/accountmigrator.cpp creds/dummycredentials.cpp creds/abstractcredentials.cpp creds/credentialsfactory.cpp diff --git a/src/mirall/accountmigrator.cpp b/src/mirall/accountmigrator.cpp new file mode 100644 index 0000000000..c9af1b7d5f --- /dev/null +++ b/src/mirall/accountmigrator.cpp @@ -0,0 +1,86 @@ +/* + * 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 + +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(QObject *parent) : + QObject(parent) +{ + +} + +// 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" ); + + // 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); + + // 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..1d3e971d12 --- /dev/null +++ b/src/mirall/accountmigrator.h @@ -0,0 +1,39 @@ +/* + * 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 QObject +{ + Q_OBJECT +public: + explicit AccountMigrator(QObject *parent = 0); + + /** + * @brief migrateFolderDefinitons - migrate the folder definition files + * @return the list of migrated folder definitions + */ + QStringList migrateFolderDefinitons(); +signals: + +public slots: + +}; +} + +#endif // ACCOUNTMIGRATOR_H From ff0ba56bc3e516e2ae3c5c367700dfc5d0a816d1 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 16:47:17 +0200 Subject: [PATCH 04/10] ownCloud Theme: Implement appName() and appNameGUI(). --- src/mirall/owncloudtheme.cpp | 10 ++++++++++ src/mirall/owncloudtheme.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/mirall/owncloudtheme.cpp b/src/mirall/owncloudtheme.cpp index f73aa7c552..24759cb6cf 100644 --- a/src/mirall/owncloudtheme.cpp +++ b/src/mirall/owncloudtheme.cpp @@ -124,6 +124,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 df67361660..af1c0420c6 100644 --- a/src/mirall/owncloudtheme.h +++ b/src/mirall/owncloudtheme.h @@ -33,6 +33,9 @@ public: QIcon trayFolderIcon( const QString& ) const; QIcon folderDisabledIcon() const; QIcon applicationIcon() const; + QString appName() const; + QString appNameGUI() const; + QVariant customMedia(CustomMediaType type); QString helpUrl() const; From 6ed6f84f6e8b5a04f4328b3ec4cd717bbf2d8026 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 16:51:47 +0200 Subject: [PATCH 05/10] Account: Add a wasMigrated flag. If an account in a branded client was migrated from a former ownCloud configuration, the method wasMigrated() will return true. --- src/mirall/account.cpp | 11 +++++++++++ src/mirall/account.h | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/src/mirall/account.cpp b/src/mirall/account.cpp index ac7208eabe..49bc753208 100644 --- a/src/mirall/account.cpp +++ b/src/mirall/account.cpp @@ -72,6 +72,7 @@ Account::Account(AbstractSslErrorHandler *sslErrorHandler, QObject *parent) , _treatSslErrorsAsFailure(false) , _state(Account::Disconnected) , _davPath("remote.php/webdav/") + , _wasMigrated(false) { qRegisterMetaType("Account*"); } @@ -375,4 +376,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; }; } From 653b8494f505d4be353f54ec234604c64625ba0f Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 16:53:46 +0200 Subject: [PATCH 06/10] FolderMan: Migrate folderlist if no folder definitions can be found and the account indicates that it was migrated. In that case, read the folder definitions from the ownCloud config directory. --- src/mirall/folderman.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mirall/folderman.cpp b/src/mirall/folderman.cpp index 6c4b1b801e..7aa08f4a31 100644 --- a/src/mirall/folderman.cpp +++ b/src/mirall/folderman.cpp @@ -13,10 +13,13 @@ */ #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/accountmigrator.h" #include @@ -147,6 +150,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 ) { From da4958c7160ded00b1f1f99567c99c3b7be47bff Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 16:55:00 +0200 Subject: [PATCH 07/10] Account: Read settings from ownCloud config if no branded exists. If there is not yet a config for a branded client, but one for the "normal" client targetting the same URL, it will be migrated. --- src/mirall/account.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/mirall/account.cpp b/src/mirall/account.cpp index 49bc753208..fc282d406f 100644 --- a/src/mirall/account.cpp +++ b/src/mirall/account.cpp @@ -114,21 +114,46 @@ void Account::save() Account* Account::restore() { + // try to open the correctly themed settings QScopedPointer settings(settingsWithGroup(Theme::instance()->appName())); - QScopedPointer ocTheme(new ownCloudTheme); Account *acc = 0; - MirallConfigFile cfg; + 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. - cfg.setTheme(ocTheme.data()); + QString oCCfgFile = 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"); + + 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 + if( oCUrl == overrideUrl ) { + migratedCreds = true; + settings.reset( oCSettings ); + } else { + delete oCSettings; + } + } + } } if (!settings->childKeys().isEmpty()) { acc = new Account; - acc->setApprovedCerts(QSslCertificate::fromData(cfg.caCerts())); acc->setUrl(settings->value(QLatin1String(urlC)).toUrl()); acc->setCredentials(CredentialsFactory::create(settings->value(QLatin1String(authTypeC)).toString())); @@ -140,6 +165,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; From 65f313f1b450000b9d806b04efaadeec035cc51f Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Thu, 12 Jun 2014 17:34:39 +0200 Subject: [PATCH 08/10] Account: Added missing include statement. --- src/mirall/account.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mirall/account.cpp b/src/mirall/account.cpp index fc282d406f..f057324ed9 100644 --- a/src/mirall/account.cpp +++ b/src/mirall/account.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include From 0e45dd7a3d49ee4d30bc3f8b0d3c39c947ed0865 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Fri, 13 Jun 2014 11:58:16 +0200 Subject: [PATCH 09/10] AccountMigrator: Do not inherit from QObject as it is not needed yet. As requested by Danimos review. --- src/mirall/accountmigrator.cpp | 3 +-- src/mirall/accountmigrator.h | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/mirall/accountmigrator.cpp b/src/mirall/accountmigrator.cpp index c9af1b7d5f..51e3f2ecb1 100644 --- a/src/mirall/accountmigrator.cpp +++ b/src/mirall/accountmigrator.cpp @@ -31,8 +31,7 @@ namespace Mirall { // branded client first, it should automatically pick the information // from the already configured account. -AccountMigrator::AccountMigrator(QObject *parent) : - QObject(parent) +AccountMigrator::AccountMigrator() { } diff --git a/src/mirall/accountmigrator.h b/src/mirall/accountmigrator.h index 1d3e971d12..49e3fa04e6 100644 --- a/src/mirall/accountmigrator.h +++ b/src/mirall/accountmigrator.h @@ -14,15 +14,14 @@ #ifndef ACCOUNTMIGRATOR_H #define ACCOUNTMIGRATOR_H -#include +#include namespace Mirall { -class AccountMigrator : public QObject -{ - Q_OBJECT +class AccountMigrator { + public: - explicit AccountMigrator(QObject *parent = 0); + explicit AccountMigrator(); /** * @brief migrateFolderDefinitons - migrate the folder definition files From e17243bc1fd5d774a3a4d4d59c0a621f907edecd Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Wed, 25 Jun 2014 11:11:27 +0200 Subject: [PATCH 10/10] AccountMigrator: Read path from QDir::fromNativeSeperators(), add debug. --- src/mirall/account.cpp | 9 +++++++-- src/mirall/accountmigrator.cpp | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mirall/account.cpp b/src/mirall/account.cpp index f057324ed9..80be3365a8 100644 --- a/src/mirall/account.cpp +++ b/src/mirall/account.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -124,12 +125,14 @@ Account* Account::restore() // 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 = settings->fileName(); + 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); @@ -142,7 +145,9 @@ Account* Account::restore() // in case the urls are equal reset the settings object to read from // the ownCloud settings object - if( oCUrl == overrideUrl ) { + qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":" + << (QUrl(oCUrl) == QUrl(overrideUrl) ? "Yes" : "No"); + if( QUrl(oCUrl) == QUrl(overrideUrl) ) { migratedCreds = true; settings.reset( oCSettings ); } else { diff --git a/src/mirall/accountmigrator.cpp b/src/mirall/accountmigrator.cpp index 51e3f2ecb1..ba4d49f43b 100644 --- a/src/mirall/accountmigrator.cpp +++ b/src/mirall/accountmigrator.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace Mirall { @@ -55,7 +56,10 @@ QStringList AccountMigrator::migrateFolderDefinitons() oCPath = oCPath.left( oCPath.lastIndexOf('/')); themePath += QLatin1String( "folders"); - oCPath += QLatin1String( "ownCloud/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 @@ -69,6 +73,7 @@ QStringList AccountMigrator::migrateFolderDefinitons() 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); @@ -79,7 +84,6 @@ QStringList AccountMigrator::migrateFolderDefinitons() } return re; - } }