Make the setup wizard compile again

- introduces more jobs
- needs more cleaning up
This commit is contained in:
Daniel Molkentin 2013-10-28 20:01:59 +01:00
parent aa2baa45fb
commit a91799a11c
16 changed files with 314 additions and 330 deletions

View file

@ -212,14 +212,14 @@ set(mirall_SRCS
mirall/folderwizard.cpp
mirall/folderstatusmodel.cpp
mirall/protocolwidget.cpp
# wizard/owncloudwizard.cpp
# wizard/owncloudsetuppage.cpp
# wizard/owncloudhttpcredspage.cpp
# wizard/owncloudwizardresultpage.cpp
# wizard/owncloudwizardcommon.cpp
# wizard/owncloudshibbolethcredspage.cpp
# wizard/owncloudadvancedsetuppage.cpp
# mirall/owncloudsetupwizard.cpp
wizard/owncloudwizard.cpp
wizard/owncloudsetuppage.cpp
wizard/owncloudhttpcredspage.cpp
wizard/owncloudwizardresultpage.cpp
wizard/owncloudwizardcommon.cpp
wizard/owncloudshibbolethcredspage.cpp
wizard/owncloudadvancedsetuppage.cpp
mirall/owncloudsetupwizard.cpp
mirall/updatedetector.cpp
mirall/occinfo.cpp
mirall/sslerrordialog.cpp
@ -237,14 +237,14 @@ set(mirall_HEADERS
mirall/application.h
mirall/systray.h
mirall/folderwizard.h
# mirall/owncloudsetupwizard.h
# wizard/owncloudwizard.h
# wizard/owncloudsetuppage.h
# wizard/owncloudhttpcredspage.h
# wizard/owncloudwizardresultpage.h
# wizard/owncloudwizardcommon.h
# wizard/owncloudshibbolethcredspage.h
# wizard/owncloudadvancedsetuppage.h
mirall/owncloudsetupwizard.h
wizard/owncloudwizard.h
wizard/owncloudsetuppage.h
wizard/owncloudhttpcredspage.h
wizard/owncloudwizardresultpage.h
wizard/owncloudwizardcommon.h
wizard/owncloudshibbolethcredspage.h
wizard/owncloudadvancedsetuppage.h
mirall/folderstatusmodel.h
mirall/updatedetector.h
mirall/sslerrordialog.h

View file

@ -48,13 +48,14 @@ AccountManager *AccountManager::instance()
}
Account::Account(QObject *parent)
Account::Account(AbstractSslErrorHandler *sslErrorHandler, QObject *parent)
: QObject(parent)
, _am(0)
, _credentials(0)
, _treatSslErrorsAsFailure(false)
, _sslErrorHandler(0)
{
setSslErrorHandler(sslErrorHandler);
}
void Account::save(QSettings &settings)
@ -112,11 +113,9 @@ void Account::setCredentials(AbstractCredentials *cred)
SLOT(slotHandleErrors(QNetworkReply*,QList<QSslError>)));
}
static const char WEBDAV_PATH[] = "remote.php/webdav/";
QUrl Account::davUrl() const
{
return concatUrlPath(url(), WEBDAV_PATH);
return concatUrlPath(url(), davPath());
}
QList<QNetworkCookie> Account::lastAuthCookies() const
@ -124,17 +123,36 @@ QList<QNetworkCookie> Account::lastAuthCookies() const
return _am->cookieJar()->cookiesForUrl(_url);
}
QNetworkReply *Account::headRequest(const QString &relPath)
{
return headRequest(concatUrlPath(url(), relPath));
}
QNetworkReply *Account::headRequest(const QUrl &url)
{
QNetworkRequest request(url);
return _am->head(request);
}
QNetworkReply *Account::getRequest(const QString &relPath)
{
QNetworkRequest request(concatUrlPath(url(), relPath));
// ### error handling
return getRequest(concatUrlPath(url(), relPath));
}
QNetworkReply *Account::getRequest(const QUrl &url)
{
QNetworkRequest request(url);
return _am->get(request);
}
QNetworkReply *Account::davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data)
{
req.setUrl(concatUrlPath(davUrl(), relPath));
// ### error handling
return davRequest(verb, concatUrlPath(davUrl(), relPath), req, data);
}
QNetworkReply *Account::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
{
req.setUrl(url);
return _am->sendCustomRequest(req, verb, data);
}
@ -167,7 +185,7 @@ QUrl Account::concatUrlPath(const QUrl &url, const QString &concatPath)
{
QUrl tmpUrl = url;
QString path = tmpUrl.path();
if (!path.endsWith('/')) {
if (!path.endsWith('/') || !concatPath.startsWith('/')) {
path += QLatin1Char('/');
}
path += concatPath;

View file

@ -41,7 +41,7 @@ public:
Account *account() { return _account; }
private:
AccountManager() {}
AccountManager() : _account(0) {}
Account *_account;
static AccountManager *_instance;
};
@ -59,7 +59,9 @@ public:
class Account : public QObject {
Q_OBJECT
public:
Account(QObject *parent = 0);
static QString davPath() { return "remote.php/webdav/"; }
Account(AbstractSslErrorHandler *sslErrorHandler = 0, QObject *parent = 0);
/**
* Saves the account to a given settings file
*/
@ -69,6 +71,14 @@ public:
* Creates an account object from from a given settings file.
*/
static Account* restore(QSettings &settings);
/**
* @brief Creates a minimal account object
*
* This will set up a ssl error handler
*
* @return A new Account object
*/
static Account* create(const QUrl &url);
/** Holds the accounts credentials */
AbstractCredentials* credentials() const;
@ -87,8 +97,12 @@ public:
QList<QNetworkCookie> lastAuthCookies() const;
QNetworkReply* headRequest(const QString &relPath);
QNetworkReply* headRequest(const QUrl &url);
QNetworkReply* getRequest(const QString &relPath);
QNetworkReply* getRequest(const QUrl &url);
QNetworkReply* davRequest(const QByteArray &verb, const QString &relPath, QNetworkRequest req, QIODevice *data = 0);
QNetworkReply* davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data = 0);
/** The certificates of the account */
QList<QSslCertificate> certificateChain() const { return _certificateChain; }
@ -101,7 +115,7 @@ public:
static QUrl concatUrlPath(const QUrl &url, const QString &concatPath);
private slots:
protected slots:
void slotHandleErrors(QNetworkReply*,QList<QSslError>);
private:

View file

@ -174,8 +174,7 @@ void AccountSettings::slotFolderWizardRejected()
void AccountSettings::slotOpenAccountWizard()
{
this->topLevelWidget()->close();
// ### TODO
//OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
}
void AccountSettings::slotAddFolder( Folder *folder )

View file

@ -117,8 +117,10 @@ Application::Application(int &argc, char **argv) :
MirallConfigFile cfg;
QSettings settings(cfg.configFile(), QSettings::IniFormat);
Account *account = Account::restore(settings);
account->setSslErrorHandler(new SslDialogErrorHandler);
AccountManager::instance()->setAccount(account);
if (account) {
account->setSslErrorHandler(new SslDialogErrorHandler);
AccountManager::instance()->setAccount(account);
}
FolderMan::instance()->setSyncEnabled(false);

View file

@ -88,20 +88,19 @@ void ConnectionValidator::checkConnection()
{
if( AccountManager::instance()->account() ) {
CheckServerJob *checkJob = new CheckServerJob(_account, false, this);
connect(checkJob, SIGNAL(instanceFound(QVariantMap)), SLOT(slotStatusFound(QVariantMap)));
connect(checkJob, SIGNAL(networkError(QNetworkReply::NetworkError,QString)),
SLOT(slotNoStatusFound(QNetworkReply::NetworkError,QString)));
connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
connect(checkJob, SIGNAL(networkError(QNetworkReply*)), SLOT(slotNoStatusFound(QNetworkReply*)));
} else {
_errors << tr("No ownCloud account configured");
emit connectionResult( NotConfigured );
}
}
void ConnectionValidator::slotStatusFound( const QVariantMap &info )
void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &info)
{
// status.php was found.
qDebug() << "** Application: ownCloud found: "
<< _account->url() << " with version "
<< url << " with version "
<< CheckServerJob::versionString(info)
<< "(" << CheckServerJob::version(info) << ")";
// now check the authentication
@ -117,12 +116,12 @@ void ConnectionValidator::slotStatusFound( const QVariantMap &info )
}
// status.php could not be loaded.
void ConnectionValidator::slotNoStatusFound(QNetworkReply::NetworkError error, const QString &errStr)
void ConnectionValidator::slotNoStatusFound(QNetworkReply *reply)
{
// ### TODO
_errors.append(tr("Unable to connect to %1").arg(_account->url().toString()));
_errors.append( errStr );
_networkError = (error != QNetworkReply::NoError);
_errors.append( reply->errorString() );
_networkError = (reply->error() != QNetworkReply::NoError);
emit connectionResult( StatusNotFound );
}
@ -133,22 +132,21 @@ void ConnectionValidator::slotCheckAuthentication()
// continue in slotAuthCheck here :-)
PropfindJob *propFind = new PropfindJob(_account, "/", QList<QByteArray>() << "getlastmodified", this);
connect(propFind, SIGNAL(result(QVariantMap)), SLOT(slotAuthSuccess()));
connect(propFind, SIGNAL(networkError(QNetworkReply::NetworkError, QString)),
SLOT(slotAuthFailed(QNetworkReply::NetworkError, QString)));
connect(propFind, SIGNAL(networkError(QNetworkReply*)), SLOT(slotAuthFailed(QNetworkReply*)));
qDebug() << "# checking for authentication settings.";
}
void ConnectionValidator::slotAuthFailed(QNetworkReply::NetworkError error, const QString& errString)
void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
{
Status stat = StatusNotFound;
if( error == QNetworkReply::AuthenticationRequiredError ||
error == QNetworkReply::OperationCanceledError ) { // returned if the user is wrong.
if( reply->error() == QNetworkReply::AuthenticationRequiredError ||
reply->error() == QNetworkReply::OperationCanceledError ) { // returned if the user is wrong.
qDebug() << "******** Password is wrong!";
_errors << tr("The provided credentials are not correct");
stat = CredentialsWrong;
} else if( error != QNetworkReply::NoError ) {
_errors << errString;
} else if( reply->error() != QNetworkReply::NoError ) {
_errors << reply->errorString();
}
emit connectionResult( stat );

View file

@ -58,11 +58,11 @@ signals:
public slots:
protected slots:
void slotStatusFound( const QVariantMap &info );
void slotNoStatusFound(QNetworkReply::NetworkError error, const QString& errString);
void slotStatusFound(const QUrl&url, const QVariantMap &info);
void slotNoStatusFound(QNetworkReply *reply);
void slotCheckAuthentication();
void slotAuthFailed(QNetworkReply::NetworkError error, const QString& errString);
void slotAuthFailed(QNetworkReply *reply);
void slotAuthSuccess();
private:

View file

@ -206,8 +206,7 @@ void FolderWizardTargetPage::slotCreateRemoteFolder(QString folder)
MkColJob *job = new MkColJob(AccountManager::instance()->account(), folder, this);
/* check the owncloud configuration file and query the ownCloud */
connect(job, SIGNAL(finished()), SLOT(slotCreateRemoteFolderFinished()));
connect(job, SIGNAL(networkError(QNetworkReply::NetworkError,QString)),
SLOT(slotHandleNetworkError(QNetworkReply::NetworkError,QString)));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotHandleNetworkError(QNetworkReply*)));
}
void FolderWizardTargetPage::slotCreateRemoteFolderFinished()
@ -217,9 +216,9 @@ void FolderWizardTargetPage::slotCreateRemoteFolderFinished()
slotRefreshFolders();
}
void FolderWizardTargetPage::slotHandleNetworkError(QNetworkReply::NetworkError, const QString& error)
void FolderWizardTargetPage::slotHandleNetworkError(QNetworkReply *reply)
{
qDebug() << "** webdav mkdir request failed:" << error;
qDebug() << "** webdav mkdir request failed:" << reply->error();
showWarn(tr("Failed to create the folder on %1.<br/>Please check manually.")
.arg(Theme::instance()->appNameGUI()));
}

View file

@ -77,7 +77,7 @@ protected slots:
void slotAddRemoteFolder();
void slotCreateRemoteFolder(QString);
void slotCreateRemoteFolderFinished();
void slotHandleNetworkError(QNetworkReply::NetworkError, const QString& error);
void slotHandleNetworkError(QNetworkReply*);
void slotUpdateDirectories(QStringList);
void slotRefreshFolders();
void slotItemExpanded(QTreeWidgetItem*);

View file

@ -15,6 +15,8 @@
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QSslConfiguration>
#include <QBuffer>
#include <QXmlStreamReader>
@ -28,6 +30,8 @@
#include "mirall/networkjobs.h"
#include "mirall/account.h"
#include "creds/credentialsfactory.h"
namespace Mirall {
AbstractNetworkJob::AbstractNetworkJob(Account *account, const QString &path, QObject *parent)
@ -40,16 +44,12 @@ AbstractNetworkJob::AbstractNetworkJob(Account *account, const QString &path, QO
void AbstractNetworkJob::setReply(QNetworkReply *reply)
{
if (_reply) {
_reply->deleteLater();
}
_reply = reply;
}
QNetworkReply *AbstractNetworkJob::takeReply()
{
QNetworkReply *reply = _reply;
_reply = 0;
return reply;
}
void AbstractNetworkJob::setAccount(Account *account)
{
_account = account;
@ -63,18 +63,15 @@ void AbstractNetworkJob::setPath(const QString &path)
void AbstractNetworkJob::slotError()
{
qDebug() << metaObject()->className() << "Error:" << _reply->errorString();
emit networkError(_reply->error(), _reply->errorString());
emit networkError(_reply);
deleteLater();
}
void AbstractNetworkJob::setupConnections(QNetworkReply *reply)
{
connect( reply, SIGNAL( finished()), SLOT(slotFinished()) );
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(slotError()));
// connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
// ownCloudInfo::instance(), SLOT(slotError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(finished()), SLOT(slotFinished()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(slotError()));
}
QNetworkReply* AbstractNetworkJob::davRequest(const QByteArray &verb, const QString &relPath,
@ -83,11 +80,31 @@ QNetworkReply* AbstractNetworkJob::davRequest(const QByteArray &verb, const QStr
return _account->davRequest(verb, relPath, req, data);
}
QNetworkReply *AbstractNetworkJob::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
{
return _account->davRequest(verb, url, req, data);
}
QNetworkReply* AbstractNetworkJob::getRequest(const QString &relPath)
{
return _account->getRequest(relPath);
}
QNetworkReply *AbstractNetworkJob::getRequest(const QUrl &url)
{
return _account->getRequest(url);
}
QNetworkReply *AbstractNetworkJob::headRequest(const QString &relPath)
{
return _account->headRequest(relPath);
}
QNetworkReply *AbstractNetworkJob::headRequest(const QUrl &url)
{
return _account->headRequest(url);
}
AbstractNetworkJob::~AbstractNetworkJob() {
_reply->deleteLater();
}
@ -161,9 +178,7 @@ MkColJob::MkColJob(Account *account, const QString &path, QObject *parent)
void MkColJob::slotFinished()
{
// ### useful error handling?
// QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
emit finished();
emit finished(reply()->error());
deleteLater();
}
@ -222,7 +237,7 @@ void LsColJob::slotFinished()
/*********************************************************************************************/
CheckServerJob::CheckServerJob(Account *account, bool followRedirect, QObject *parent)
: AbstractNetworkJob(account, QLatin1String("/status.php") , parent)
: AbstractNetworkJob(account, QLatin1String("status.php") , parent)
, _followRedirects(followRedirect)
, _redirectCount(0)
{
@ -251,7 +266,7 @@ void CheckServerJob::slotFinished()
// ### this should no longer be needed
if( reply()->error() == QNetworkReply::NoError && reply()->size() == 0 ) {
// This seems to be a bit strange behaviour of QNetworkAccessManager.
// It calls the finised slot multiple times but only the first read wins.
// It calls the finished slot multiple times but only the first read wins.
// That happend when the code connected the finished signal of the manager.
// It did not happen when the code connected to the reply finish signal.
qDebug() << "WRN: NetworkReply with not content but also no error! " << reply();
@ -270,12 +285,10 @@ void CheckServerJob::slotFinished()
if (requestedUrl.scheme() == QLatin1String("https") &&
redirectUrl.scheme() == QLatin1String("http")) {
qDebug() << Q_FUNC_INFO << "HTTPS->HTTP downgrade detected!";
} else if (requestedUrl == redirectUrl || _redirectCount >= MAX_REDIRECTS) {
} else if (requestedUrl == redirectUrl || _redirectCount >= maxRedirects()) {
qDebug() << Q_FUNC_INFO << "Redirect loop detected!";
} else {
takeReply()->deleteLater();
// ### FIXME
//setReply(getRequest(redirectUrl));
setReply(getRequest(redirectUrl));
setupConnections(reply());
return;
}
@ -292,7 +305,7 @@ void CheckServerJob::slotFinished()
if( status.contains("installed")
&& status.contains("version")
&& status.contains("versionstring") ) {
emit instanceFound(status);
emit instanceFound(reply()->url(), status);
} else {
qDebug() << "No proper answer on " << requestedUrl;
}
@ -366,4 +379,16 @@ void PropfindJob::slotFinished()
deleteLater();
}
EntityExistsJob::EntityExistsJob(Account *account, const QString &path, QObject *parent)
: AbstractNetworkJob(account, path, parent)
{
setReply(headRequest(path));
setupConnections(reply());
}
void EntityExistsJob::slotFinished()
{
emit exists(reply());
}
} // namespace Mirall

View file

@ -17,14 +17,15 @@
#define NETWORKJOBS_H
#include <QObject>
#include <QNetworkRequest>
#include <QNetworkReply>
class QNetworkReply;
class QUrl;
namespace Mirall {
class Account;
class AbstractSslErrorHandler;
/**
* @brief The AbstractNetworkJob class
@ -42,17 +43,23 @@ public:
void setReply(QNetworkReply *reply);
QNetworkReply* reply() const { return _reply; }
QNetworkReply* takeReply(); // for redirect handling
signals:
void networkError(QNetworkReply::NetworkError, const QString& errorString);
void networkError(QNetworkReply *reply);
protected:
void setupConnections(QNetworkReply *reply);
QNetworkReply* davRequest(const QByteArray& verb, const QString &relPath,
QNetworkRequest req = QNetworkRequest(),
QIODevice *data = 0);
QNetworkReply* davRequest(const QByteArray& verb, const QUrl &url,
QNetworkRequest req = QNetworkRequest(),
QIODevice *data = 0);
QNetworkReply* getRequest(const QString &relPath);
QNetworkReply* getRequest(const QUrl &url);
QNetworkReply* headRequest(const QString &relPath);
QNetworkReply* headRequest(const QUrl &url);
int maxRedirects() const { return 10; }
private slots:
virtual void slotFinished() = 0;
@ -64,6 +71,20 @@ private:
QString _path;
};
/**
* @brief The EntityExistsJob class
*/
class EntityExistsJob : public AbstractNetworkJob {
Q_OBJECT
public:
explicit EntityExistsJob(Account *account, const QString &path, QObject* parent = 0);
signals:
void exists(QNetworkReply*);
private slots:
virtual void slotFinished();
};
/**
* @brief The LsColJob class
*/
@ -74,7 +95,6 @@ public:
signals:
void directoryListing(const QStringList &items);
void networkError();
private slots:
virtual void slotFinished();
@ -106,8 +126,7 @@ public:
explicit MkColJob(Account *account, const QString &path, QObject *parent = 0);
signals:
void finished();
void networkError();
void finished(QNetworkReply::NetworkError);
private slots:
virtual void slotFinished();
@ -126,8 +145,7 @@ public:
static bool installed(const QVariantMap &info);
signals:
void instanceFound(const QVariantMap &info);
void networkError();
void instanceFound(const QUrl&url, const QVariantMap &info);
private slots:
virtual void slotFinished();
@ -135,8 +153,6 @@ private slots:
private:
bool _followRedirects;
bool _redirectCount;
static const int MAX_REDIRECTS = 10;
};

View file

@ -91,8 +91,7 @@ bool ownCloudGui::checkConfigExists(bool openSettings)
return true;
} else {
qDebug() << "No configured folders yet, starting setup wizard";
//### TODO
//OwncloudSetupWizard::runWizard(this, SLOT(slotownCloudWizardDone(int)));
OwncloudSetupWizard::runWizard(this, SLOT(slotownCloudWizardDone(int)));
return false;
}
}

View file

@ -28,7 +28,9 @@
#include "mirall/mirallaccessmanager.h"
#include "mirall/account.h"
#include "mirall/networkjobs.h"
#include "mirall/sslerrordialog.h"
#include "creds/credentialsfactory.h"
#include "creds/abstractcredentials.h"
#include "creds/dummycredentials.h"
@ -36,11 +38,8 @@ namespace Mirall {
OwncloudSetupWizard::OwncloudSetupWizard(QObject* parent) :
QObject( parent ),
_account(0),
_ocWizard(new OwncloudWizard),
_mkdirRequestReply(),
_checkInstallationRequest(),
_checkRemoteFolderRequest(),
_configHandle(),
_remoteFolder()
{
connect( _ocWizard, SIGNAL(determineAuthType(const QString&)),
@ -80,24 +79,15 @@ void OwncloudSetupWizard::runWizard(QObject* obj, const char* amember, QWidget *
void OwncloudSetupWizard::startWizard()
{
// Set useful default values.
MirallConfigFile cfgFile;
Account *account = AccountManager::instance()->account();
_ocWizard->setConfigExists( account != 0 );
// Fill the entry fields with existing values.
QString url = account->url();
//QString user = cfgFile.ownCloudUser();
bool configExists = !( url.isEmpty()/* || user.isEmpty()*/ );
if( !url.isEmpty() ) {
_ocWizard->setOCUrl( url );
if (!account) {
account = new Account(new SslDialogErrorHandler);
account->setCredentials(CredentialsFactory::create("dummy"));
}
_ocWizard->setAccount(account);
_remoteFolder = Theme::instance()->defaultServerFolder();
// remoteFolder may be empty, which means /
QString localFolder = Theme::instance()->defaultClientFolder();
// if its a relative path, prepend with users home dir, otherwise use as absolute path
@ -118,184 +108,62 @@ void OwncloudSetupWizard::startWizard()
_ocWizard->raise();
}
void OwncloudSetupWizard::slotDetermineAuthType(const QString& serverUrl)
// also checks if an installation is valid and determines auth type in a second step
void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
{
QString url(serverUrl);
qDebug() << "Connect to url: " << url;
_ocWizard->setField(QLatin1String("OCUrl"), url );
_ocWizard->appendToConfigurationLog(tr("Trying to connect to %1 at %2 to determine authentication type...")
.arg( Theme::instance()->appNameGUI() ).arg(url) );
// write a temporary config.
QDateTime now = QDateTime::currentDateTime();
// remove a possibly existing custom config.
if( ! _configHandle.isEmpty() ) {
// remove the old config file.
MirallConfigFile oldConfig( _configHandle );
oldConfig.cleanupCustomConfig();
}
_configHandle = now.toString(QLatin1String("MMddyyhhmmss"));
MirallConfigFile cfgFile( _configHandle, true );
if( url.isEmpty() ) return;
if( !( url.startsWith(QLatin1String("https://")) || url.startsWith(QLatin1String("http://"))) ) {
qDebug() << "url does not start with a valid protocol, assuming https.";
url.prepend(QLatin1String("https://"));
// FIXME: give a hint about the auto completion
_ocWizard->setOCUrl(url);
}
cfgFile.writeOwncloudConfig( Theme::instance()->appName(),
url,
new DummyCredentials);
ownCloudInfo* info = ownCloudInfo::instance();
info->setCustomConfigHandle( _configHandle );
if( info->isConfigured() ) {
// reset the SSL Untrust flag to let the SSL dialog appear again.
info->resetSSLUntrust();
connect(info, SIGNAL(ownCloudInfoFound(QString,QString,QString,QString)),
SLOT(slotOwnCloudFoundAuth(QString,QString,QString,QString)));
connect(info, SIGNAL(noOwncloudFound(QNetworkReply*)),
SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
_checkInstallationRequest = info->checkInstallation();
} else {
qDebug() << " ownCloud seems not to be configured, can not start test connect.";
QString fixedUrl = urlString;
QUrl url = QUrl::fromUserInput(fixedUrl);
// fromUserInput defaults to http, not http if no scheme is specified
if (!fixedUrl.startsWith("http://") || !fixedUrl.startsWith("https://")) {
url.setScheme("https");
}
Account *account = _ocWizard->account();
account->setUrl(url);
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), false, this);
connect(job, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotOwnCloudFoundAuth(QUrl,QVariantMap)));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
}
void OwncloudSetupWizard::slotOwnCloudFoundAuth( const QString& url, const QString& infoString, const QString& version, const QString& )
void OwncloudSetupWizard::slotOwnCloudFoundAuth(const QUrl& url, const QVariantMap &info)
{
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(QString,QString,QString,QString)),
this, SLOT(slotOwnCloudFoundAuth(QString,QString,QString,QString)));
disconnect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
_ocWizard->appendToConfigurationLog(tr("<font color=\"green\">Successfully connected to %1: %2 version %3 (%4)</font><br/><br/>")
.arg( url ).arg(Theme::instance()->appNameGUI()).arg(infoString).arg(version));
.arg(url.toString())
.arg(Theme::instance()->appNameGUI())
.arg(CheckServerJob::versionString(info))
.arg(CheckServerJob::version(info)));
MirallAccessManager* nm = new MirallAccessManager(this);
// TODO: We should get this path from owncloud info.
QNetworkReply* reply = nm->get (QNetworkRequest (url + "/remote.php/webdav/"));
connect (reply, SIGNAL(finished()),
this, SLOT(slotAuthCheckReplyFinished()));
nm->setProperty ("mirallRedirs", QVariant (0));
DetermineAuthTypeJob *job = new DetermineAuthTypeJob(_ocWizard->account(), this);
connect(job, SIGNAL(authType(WizardCommon::AuthType)),
_ocWizard, SLOT(setAuthType(WizardCommon::AuthType)));
}
void OwncloudSetupWizard::slotAuthCheckReplyFinished()
void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
{
QNetworkReply* reply = qobject_cast< QNetworkReply* > (sender ());
QUrl redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
QNetworkAccessManager* nm = reply->manager ();
const int redirCount = nm->property ("mirallRedirs").toInt();
if (redirCount > 10) {
redirection.clear ();
}
disconnect (reply, SIGNAL(finished()),
this, SLOT(slotAuthCheckReplyFinished()));
if ((reply->error () == QNetworkReply::AuthenticationRequiredError) || redirection.isEmpty()) {
reply->deleteLater();
nm->deleteLater();
_ocWizard->setAuthType (WizardCommon::HttpCreds);
} else if (redirection.toString().endsWith ("/remote.php/webdav/")) {
QNetworkReply* newReply = nm->get (QNetworkRequest(redirection));
connect (newReply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(slotAuthCheckReplyError(QNetworkReply::NetworkError)));
connect (newReply, SIGNAL(finished()),
this, SLOT(slotAuthCheckReplyFinished(QNetworkReply::NetworkError)));
reply->deleteLater();
nm->setProperty ("mirallRedirs", QVariant(redirCount + 1));
} else {
QRegExp shibbolethyWords ("SAML|wayf");
shibbolethyWords.setCaseSensitivity (Qt::CaseInsensitive);
if (redirection.toString ().contains (shibbolethyWords)) {
_ocWizard->setAuthType(WizardCommon::Shibboleth);
} else {
// TODO: Send an error.
// eh?
_ocWizard->setAuthType (WizardCommon::HttpCreds);
}
reply->deleteLater();
nm->deleteLater();
}
}
void OwncloudSetupWizard::slotNoOwnCloudFoundAuth( QNetworkReply *err )
{
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudInfoFound(QString,QString,QString,QString)),
this, SLOT(slotOwnCloudFound(QString,QString,QString,QString)));
disconnect(ownCloudInfo::instance(), SIGNAL(noOwncloudFound(QNetworkReply*)),
this, SLOT(slotNoOwnCloudFound(QNetworkReply*)));
_ocWizard->displayError(tr("Failed to connect to %1:<br/>%2").
arg(Theme::instance()->appNameGUI()).arg(err->errorString()));
// remove the config file again
MirallConfigFile cfgFile( _configHandle );
cfgFile.cleanupCustomConfig();
_ocWizard->displayError(tr("Failed to connect to %1 at %2:<br/>%3")
.arg(Theme::instance()->appNameGUI())
.arg(reply->url().toString())
.arg(reply->errorString()));
}
void OwncloudSetupWizard::slotConnectToOCUrl( const QString& url )
{
qDebug() << "Connect to url: " << url;
_ocWizard->account()->setCredentials(_ocWizard->getCredentials());
_ocWizard->setField(QLatin1String("OCUrl"), url );
_ocWizard->appendToConfigurationLog(tr("Trying to connect to %1 at %2...")
.arg( Theme::instance()->appNameGUI() ).arg(url) );
testOwnCloudConnect();
}
void OwncloudSetupWizard::testOwnCloudConnect()
{
// write a temporary config.
QDateTime now = QDateTime::currentDateTime();
if( _configHandle.isEmpty() ) {
_configHandle = now.toString(QLatin1String("MMddyyhhmmss"));
}
MirallConfigFile cfgFile( _configHandle, true );
QString url = _ocWizard->field(QLatin1String("OCUrl")).toString();
if( url.isEmpty() ) return;
if( !( url.startsWith(QLatin1String("https://")) || url.startsWith(QLatin1String("http://"))) ) {
qDebug() << "url does not start with a valid protocol, assuming https.";
url.prepend(QLatin1String("https://"));
// FIXME: give a hint about the auto completion
_ocWizard->setOCUrl(url);
}
cfgFile.writeOwncloudConfig( Theme::instance()->appName(),
url,
_ocWizard->getCredentials());
ownCloudInfo* info(ownCloudInfo::instance());
info->setCustomConfigHandle( _configHandle );
// If there is already a config, take its proxy config.
if( info->isConfigured() ) {
MirallConfigFile prevCfg;
cfgFile.setProxyType( prevCfg.proxyType(), prevCfg.proxyHostName(), prevCfg.proxyPort(),
prevCfg.proxyNeedsAuth(), prevCfg.proxyUser(), prevCfg.proxyPassword() );
}
connect( info,SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotConnectionCheck(QString,QNetworkReply*)));
qDebug() << "# checking for authentication settings.";
_checkRemoteFolderRequest = info->getWebDAVPath(_remoteFolder ); // this call needs to be authenticated.
// continue in slotConnectionCheck
ValidateDavAuthJob *job = new ValidateDavAuthJob(_ocWizard->account(), this);
connect(job, SIGNAL(authResult(QNetworkReply*)), SLOT(slotConnectionCheck(QNetworkReply*)));
}
void OwncloudSetupWizard::slotConnectionCheck(const QString&, QNetworkReply* reply)
void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply)
{
// disconnect from ownCloud Info signals
disconnect(ownCloudInfo::instance(), SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this, SLOT(slotConnectionCheck(QString,QNetworkReply*)));
switch (reply->error()) {
case QNetworkReply::NoError:
case QNetworkReply::ContentNotFoundError:
@ -312,8 +180,6 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
{
qDebug() << "Setup local sync folder for new oC connection " << localFolder;
const QDir fi( localFolder );
// FIXME: Show problems with local folder properly.
bool localFolderOk = true;
if( fi.exists() ) {
// there is an existing local folder. If its non empty, it can only be synced if the
@ -325,38 +191,20 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
Utility::setupFavLink( localFolder );
// FIXME: Create a local sync folder.
res += tr("ok");
EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), remoteFolder, this);
connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotAuthCheckReply(QNetworkReply*)));
} else {
res += tr("failed.");
qDebug() << "Failed to create " << fi.path();
localFolderOk = false;
_ocWizard->displayError(tr("Could not create local folder %1").arg(localFolder));
}
_ocWizard->appendToConfigurationLog( res );
}
if( localFolderOk ) {
checkRemoteFolder(remoteFolder);
}
}
void OwncloudSetupWizard::checkRemoteFolder(const QString& remoteFolder)
// ### TODO move into EntityExistsJob once we decide if/how to return gui strings from jobs
void OwncloudSetupWizard::slotAuthCheckReply(QNetworkReply *reply)
{
ownCloudInfo* info(ownCloudInfo::instance());
connect( info,SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheckReply(QString,QNetworkReply*)));
qDebug() << "# checking for existence of remote folder.";
info->setCustomConfigHandle(_configHandle);
_checkRemoteFolderRequest = info->getWebDAVPath(remoteFolder); // this call needs to be authenticated.
// continue in slotAuthCheckReply
}
void OwncloudSetupWizard::slotAuthCheckReply( const QString&, QNetworkReply *reply )
{
// disconnect from ownCloud Info signals
disconnect( ownCloudInfo::instance(),SIGNAL(ownCloudDirExists(QString,QNetworkReply*)),
this,SLOT(slotAuthCheckReply(QString,QNetworkReply*)));
bool ok = true;
QString error;
QNetworkReply::NetworkError errId = reply->error();
@ -364,11 +212,11 @@ void OwncloudSetupWizard::slotAuthCheckReply( const QString&, QNetworkReply *rep
if( errId == QNetworkReply::NoError ) {
qDebug() << "******** Remote folder found, all cool!";
} else if( errId == QNetworkReply::ContentNotFoundError ) {
if( createRemoteFolder() ) {
return; // Finish here, the mkdir request will go on.
} else {
error = tr("The remote folder could not be accessed!");
if( _remoteFolder.isEmpty() ) {
error = tr("No remote folder specified!");
ok = false;
} else {
createRemoteFolder();
}
} else {
error = tr("Error: %1").arg(reply->errorString());
@ -382,25 +230,19 @@ void OwncloudSetupWizard::slotAuthCheckReply( const QString&, QNetworkReply *rep
finalizeSetup( ok );
}
bool OwncloudSetupWizard::createRemoteFolder()
void OwncloudSetupWizard::createRemoteFolder()
{
if( _remoteFolder.isEmpty() ) return false;
_ocWizard->appendToConfigurationLog( tr("creating folder on ownCloud: %1" ).arg( _remoteFolder ));
ownCloudInfo* info(ownCloudInfo::instance());
connect(info, SIGNAL(webdavColCreated(QNetworkReply::NetworkError)),
this, SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));
_mkdirRequestReply = info->mkdirRequest( _remoteFolder );
return (_mkdirRequestReply != NULL);
MkColJob *job = new MkColJob(_ocWizard->account(), _remoteFolder, this);
connect(job, SIGNAL(finished(QNetworkReply::NetworkError)), SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));
}
void OwncloudSetupWizard::slotCreateRemoteFolderFinished( QNetworkReply::NetworkError error )
{
qDebug() << "** webdav mkdir request finished " << error;
disconnect(ownCloudInfo::instance(), SIGNAL(webdavColCreated(QNetworkReply::NetworkError)),
this, SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));
// disconnect(ownCloudInfo::instance(), SIGNAL(webdavColCreated(QNetworkReply::NetworkError)),
// this, SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));
bool success = true;
@ -459,7 +301,7 @@ void OwncloudSetupWizard::finalizeSetup( bool success )
// accept the custom config to be the main one if Accepted.
void OwncloudSetupWizard::slotAssistantFinished( int result )
{
MirallConfigFile cfg( _configHandle );
MirallConfigFile cfg;
FolderMan *folderMan = FolderMan::instance();
if( result == QDialog::Rejected ) {
@ -535,29 +377,63 @@ void OwncloudSetupWizard::slotAssistantFinished( int result )
}
}
// clear the custom config handle
_configHandle.clear();
ownCloudInfo::instance()->setCustomConfigHandle( QString::null );
// // clear the custom config handle
// _configHandle.clear();
// ownCloudInfo::instance()->setCustomConfigHandle( QString::null );
// notify others.
emit ownCloudWizardDone( result );
}
void OwncloudSetupWizard::slotClearPendingRequests()
DetermineAuthTypeJob::DetermineAuthTypeJob(Account *account, QObject *parent)
: AbstractNetworkJob(account, QString(), parent)
, _redirects(0)
{
qDebug() << "Pending request: " << _mkdirRequestReply;
if( _mkdirRequestReply && _mkdirRequestReply->isRunning() ) {
qDebug() << "ABORTing pending mkdir request.";
_mkdirRequestReply->abort();
QNetworkReply *reply = getRequest(Account::davPath());
setReply(reply);
setupConnections(reply);
}
void DetermineAuthTypeJob::slotFinished()
{
QUrl redirection = reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (_redirects >= maxRedirects()) {
redirection.clear();
}
if( _checkInstallationRequest && _checkInstallationRequest->isRunning() ) {
qDebug() << "ABORTing pending check installation request.";
_checkInstallationRequest->abort();
}
if( _checkRemoteFolderRequest && _checkRemoteFolderRequest->isRunning() ) {
qDebug() << "ABORTing pending remote folder check request.";
_checkRemoteFolderRequest->abort();
if ((reply()->error() == QNetworkReply::AuthenticationRequiredError) || redirection.isEmpty()) {
emit authType(WizardCommon::HttpCreds);
} else if (redirection.toString().endsWith(Account::davPath())) {
// do a new run
_redirects++;
setReply(getRequest(redirection));
setupConnections(reply());
} else {
QRegExp shibbolethyWords("SAML|wayf");
shibbolethyWords.setCaseSensitivity(Qt::CaseInsensitive);
if (redirection.toString().contains(shibbolethyWords)) {
emit authType(WizardCommon::Shibboleth);
} else {
// TODO: Send an error.
// eh?
emit authType(WizardCommon::HttpCreds);
}
}
deleteLater();
}
ValidateDavAuthJob::ValidateDavAuthJob(Account *account, QObject *parent)
: AbstractNetworkJob(account, QString(), parent)
{
QNetworkReply *reply = getRequest(Account::davPath());
setReply(reply);
setupConnections(reply);
}
void ValidateDavAuthJob::slotFinished()
{
emit authResult(reply());
deleteLater();
}
} // ns Mirall

View file

@ -22,10 +22,37 @@
#include <QPointer>
#include "mirall/theme.h"
#include "mirall/networkjobs.h"
#include "wizard/owncloudwizardcommon.h"
namespace Mirall {
class OwncloudWizard;
class Account;
class ValidateDavAuthJob : public AbstractNetworkJob {
Q_OBJECT
public:
ValidateDavAuthJob(Account* account, QObject *parent = 0);
signals:
void authResult(QNetworkReply*);
private slots:
void slotFinished();
};
class DetermineAuthTypeJob : public AbstractNetworkJob {
Q_OBJECT
public:
explicit DetermineAuthTypeJob(Account *account, QObject *parent = 0);
signals:
void authType(WizardCommon::AuthType);
private slots:
void slotFinished();
private:
int _redirects;
};
class OwncloudSetupWizard : public QObject
{
@ -40,18 +67,16 @@ signals:
private slots:
void slotDetermineAuthType(const QString&);
void slotOwnCloudFoundAuth(const QString&, const QString&, const QString&, const QString&);
void slotAuthCheckReplyFinished();
void slotNoOwnCloudFoundAuth(QNetworkReply*);
void slotOwnCloudFoundAuth(const QUrl&, const QVariantMap&);
void slotNoOwnCloudFoundAuth(QNetworkReply *reply);
void slotConnectToOCUrl(const QString&);
void slotConnectionCheck(const QString&, QNetworkReply*);
void slotConnectionCheck(QNetworkReply*);
void slotCreateLocalAndRemoteFolders(const QString&, const QString&);
void slotAuthCheckReply(const QString&, QNetworkReply*);
void slotAuthCheckReply(QNetworkReply*);
void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError);
void slotAssistantFinished( int );
void slotClearPendingRequests();
private:
explicit OwncloudSetupWizard(QObject *parent = 0 );
@ -59,16 +84,13 @@ private:
void startWizard();
void testOwnCloudConnect();
void checkRemoteFolder(const QString& remoteFolder);
bool createRemoteFolder();
void createRemoteFolder();
void finalizeSetup( bool );
Account* _account;
OwncloudWizard* _ocWizard;
QPointer<QNetworkReply> _mkdirRequestReply;
QPointer<QNetworkReply> _checkInstallationRequest;
QPointer<QNetworkReply> _checkRemoteFolderRequest;
QString _configHandle;
QString _remoteFolder;
};
}

View file

@ -14,9 +14,11 @@
* for more details.
*/
#include "wizard/owncloudwizard.h"
#include "mirall/account.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/theme.h"
#include "wizard/owncloudwizard.h"
#include "wizard/owncloudsetuppage.h"
#include "wizard/owncloudhttpcredspage.h"
#include "wizard/owncloudshibbolethcredspage.h"
@ -77,6 +79,16 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
setSubTitleFormat(Qt::RichText);
}
void OwncloudWizard::setAccount(Account *account)
{
_account = account;
}
Account *OwncloudWizard::account() const
{
return _account;
}
void OwncloudWizard::setMultipleFoldersExist(bool exist)
{
_advancedSetupPage->setMultipleFoldersExist(exist);

View file

@ -23,6 +23,7 @@
namespace Mirall {
class Account;
class OwncloudSetupPage;
class OwncloudHttpCredsPage;
class OwncloudShibbolethCredsPage;
@ -43,6 +44,8 @@ public:
OwncloudWizard(QWidget *parent = 0);
void setAccount(Account *account);
Account* account() const;
void setOCUrl( const QString& );
void setupCustomMedia( QVariant, QLabel* );
@ -56,10 +59,10 @@ public:
void setConfigExists( bool );
bool configExists();
void successfulStep();
void setAuthType(WizardCommon::AuthType type);
AbstractCredentials* getCredentials() const;
public slots:
void setAuthType(WizardCommon::AuthType type);
void setRemoteFolder( const QString& );
void appendToConfigurationLog( const QString& msg, LogType type = LogParagraph );
void slotCurrentPageChanged( int );
@ -73,6 +76,7 @@ signals:
void basicSetupFinished( int );
private:
Account* _account;
OwncloudSetupPage* _setupPage;
OwncloudHttpCredsPage* _httpCredsPage;
OwncloudShibbolethCredsPage* _shibbolethCredsPage;