/*
* Copyright (C) by Klaas Freitag
")
.arg(url.toString())
.arg(Theme::instance()->appNameGUI())
.arg(CheckServerJob::versionString(info))
.arg(CheckServerJob::version(info)));
QString p = url.path();
if (p.endsWith("/status.php")) {
// We might be redirected, update the account
QUrl redirectedUrl = url;
redirectedUrl.setPath(url.path().left(url.path().length() - 11));
_ocWizard->account()->setUrl(redirectedUrl);
qDebug() << Q_FUNC_INFO << " was redirected to" << redirectedUrl.toString();
}
DetermineAuthTypeJob *job = new DetermineAuthTypeJob(_ocWizard->account(), this);
job->setIgnoreCredentialFailure(true);
connect(job, SIGNAL(authType(WizardCommon::AuthType)),
_ocWizard, SLOT(setAuthType(WizardCommon::AuthType)));
job->start();
}
void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
{
_ocWizard->displayError(tr("Failed to connect to %1 at %2:
%3")
.arg(Theme::instance()->appNameGUI(),
reply->url().toString(),
reply->errorString()), checkDowngradeAdvised(reply));
}
void OwncloudSetupWizard::slotNoOwnCloudFoundAuthTimeout(const QUrl&url)
{
_ocWizard->displayError(tr("Timeout while trying to connect to %1 at %2.")
.arg(Theme::instance()->appNameGUI(),
url.toString()), false);
}
void OwncloudSetupWizard::slotConnectToOCUrl( const QString& url )
{
qDebug() << "Connect to url: " << url;
AbstractCredentials *creds = _ocWizard->getCredentials();
_ocWizard->account()->setCredentials(creds);
_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()
{
AccountPtr account = _ocWizard->account();
ValidateDavAuthJob *job = new ValidateDavAuthJob(account, this);
job->setIgnoreCredentialFailure(true);
connect(job, SIGNAL(authResult(QNetworkReply*)), SLOT(slotConnectionCheck(QNetworkReply*)));
job->start();
}
bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply)
{
if(reply->url().scheme() != QLatin1String("https")) {
return false;
}
switch (reply->error()) {
case QNetworkReply::NoError:
case QNetworkReply::ContentNotFoundError:
case QNetworkReply::AuthenticationRequiredError:
case QNetworkReply::HostNotFoundError:
return false;
default:
break;
}
// Adhere to HSTS, even though we do not parse it properly
if (reply->hasRawHeader("Strict-Transport-Security")) {
return false;
}
return true;
}
void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply)
{
QString msg = reply->errorString();
switch (reply->error()) {
case QNetworkReply::NoError:
case QNetworkReply::ContentNotFoundError:
_ocWizard->successfulStep();
break;
default:
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 403) {
msg = tr("Access forbidden by server. To verify that you have proper access, "
"click here to access the service with your browser.")
.arg(_ocWizard->account()->url().toString());
}
_ocWizard->show();
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds) {
_ocWizard->back();
}
_ocWizard->displayError(msg, _ocWizard->currentId() == WizardCommon::Page_ServerSetup && checkDowngradeAdvised(reply));
break;
}
}
void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFolder, const QString& remoteFolder)
{
qDebug() << "Setup local sync folder for new oC connection " << localFolder;
const QDir fi( localFolder );
bool nextStep = true;
if( fi.exists() ) {
// there is an existing local folder. If its non empty, it can only be synced if the
// ownCloud is newly created.
_ocWizard->appendToConfigurationLog( tr("Local sync folder %1 already exists, setting it up for sync.
").arg(localFolder));
} else {
QString res = tr("Creating local sync folder %1...").arg(localFolder);
if( fi.mkpath( localFolder ) ) {
Utility::setupFavLink( localFolder );
// FIXME: Create a local sync folder.
res += tr("ok");
} else {
res += tr("failed.");
qDebug() << "Failed to create " << fi.path();
_ocWizard->displayError(tr("Could not create local folder %1").arg(localFolder), false);
nextStep = false;
}
_ocWizard->appendToConfigurationLog( res );
}
if (nextStep) {
EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), _ocWizard->account()->davPath() + remoteFolder, this);
connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotAuthCheckReply(QNetworkReply*)));
job->start();
} else {
finalizeSetup( false );
}
}
// ### TODO move into EntityExistsJob once we decide if/how to return gui strings from jobs
void OwncloudSetupWizard::slotAuthCheckReply(QNetworkReply *reply)
{
bool ok = true;
QString error;
QNetworkReply::NetworkError errId = reply->error();
if( errId == QNetworkReply::NoError ) {
qDebug() << "******** Remote folder found, all cool!";
} else if( errId == QNetworkReply::ContentNotFoundError ) {
if( _remoteFolder.isEmpty() ) {
error = tr("No remote folder specified!");
ok = false;
} else {
createRemoteFolder();
}
} else {
error = tr("Error: %1").arg(reply->errorString());
ok = false;
}
if( !ok ) {
_ocWizard->displayError(error, false);
}
finalizeSetup( ok );
}
void OwncloudSetupWizard::createRemoteFolder()
{
_ocWizard->appendToConfigurationLog( tr("creating folder on ownCloud: %1" ).arg( _remoteFolder ));
MkColJob *job = new MkColJob(_ocWizard->account(), _remoteFolder, this);
connect(job, SIGNAL(finished(QNetworkReply::NetworkError)), SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));
job->start();
}
void OwncloudSetupWizard::slotCreateRemoteFolderFinished( QNetworkReply::NetworkError error )
{
qDebug() << "** webdav mkdir request finished " << error;
// disconnect(ownCloudInfo::instance(), SIGNAL(webdavColCreated(QNetworkReply::NetworkError)),
// this, SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError)));
bool success = true;
if( error == QNetworkReply::NoError ) {
_ocWizard->appendToConfigurationLog( tr("Remote folder %1 created successfully.").arg(_remoteFolder));
} else if( error == 202 ) {
_ocWizard->appendToConfigurationLog( tr("The remote folder %1 already exists. Connecting it for syncing.").arg(_remoteFolder));
} else if( error > 202 && error < 300 ) {
_ocWizard->displayError( tr("The folder creation resulted in HTTP error code %1").arg((int)error ), false);
_ocWizard->appendToConfigurationLog( tr("The folder creation resulted in HTTP error code %1").arg((int)error) );
} else if( error == QNetworkReply::OperationCanceledError ) {
_ocWizard->displayError( tr("The remote folder creation failed because the provided credentials "
"are wrong!"
"
Please go back and check your credentials.
Remote folder creation failed probably because the provided credentials are wrong."
"
Please go back and check your credentials.
") + tr("Successfully connected to %1!") .arg(Theme::instance()->appNameGUI()) + QLatin1String("
")); _ocWizard->successfulStep(); } else { // ### this is not quite true, pass in the real problem as optional parameter _ocWizard->appendToConfigurationLog(QLatin1String("") + tr("Connection to %1 could not be established. Please check again.") .arg(Theme::instance()->appNameGUI()) + QLatin1String("
")); } } bool OwncloudSetupWizard::ensureStartFromScratch(const QString &localFolder) { // first try to rename (backup) the current local dir. bool renameOk = false; while( !renameOk ) { renameOk = FolderMan::instance()->startFromScratch(localFolder); if( ! renameOk ) { QMessageBox::StandardButton but; but = QMessageBox::question( 0, tr("Folder rename failed"), tr("Can't remove and back up the folder because the folder or a file in it is open in another program." " Please close the folder or file and hit retry or cancel the setup."), QMessageBox::Retry | QMessageBox::Abort, QMessageBox::Retry); if( but == QMessageBox::Abort ) { break; } } } return renameOk; } void OwncloudSetupWizard::replaceDefaultAccountWith(AccountPtr newAccount) { // new Account AccountManager *mgr = AccountManager::instance(); mgr->setAccount(newAccount); newAccount->save(); } // Method executed when the user ends has finished the basic setup. void OwncloudSetupWizard::slotAssistantFinished( int result ) { FolderMan *folderMan = FolderMan::instance(); if( result == QDialog::Rejected ) { qDebug() << "Rejected the new config, use the old!"; } else if( result == QDialog::Accepted ) { // This may or may not wipe all folder definitions, depending // on whether a new account is activated or the existing one // is changed. applyAccountChanges(); // But if the user went through with the folder config wizard, // we assume they always want to have only that folder configured. folderMan->removeAllFolderDefinitions(); QString localFolder = QDir::fromNativeSeparators(_ocWizard->localFolder()); if( !localFolder.endsWith(QLatin1Char('/'))) { localFolder.append(QLatin1Char('/')); } bool startFromScratch = _ocWizard->field("OCSyncFromScratch").toBool(); if (!startFromScratch || ensureStartFromScratch(localFolder)) { qDebug() << "Adding folder definition for" << localFolder << _remoteFolder; folderMan->addFolderDefinition(Theme::instance()->appName(), localFolder, _remoteFolder, _ocWizard->selectiveSyncBlacklist() ); _ocWizard->appendToConfigurationLog(tr("Local sync folder %1 successfully created!").arg(localFolder)); } } // notify others. emit ownCloudWizardDone( result ); } void OwncloudSetupWizard::slotSkipFolderConfiguration() { applyAccountChanges(); disconnect( _ocWizard, SIGNAL(basicSetupFinished(int)), this, SLOT(slotAssistantFinished(int)) ); _ocWizard->close(); emit ownCloudWizardDone( QDialog::Accepted ); } void OwncloudSetupWizard::applyAccountChanges() { AccountPtr newAccount = _ocWizard->account(); AccountPtr origAccount = AccountManager::instance()->account(); bool isInitialSetup = (origAccount == 0); // check if either the account changed in a major way bool reinitRequired = newAccount->changed(origAccount, true /* ignoreProtocol, allows http->https */); // If this is a completely new account, replace it entirely // thereby clearing all folder definitions. if (isInitialSetup || reinitRequired) { replaceDefaultAccountWith(newAccount); qDebug() << "Significant changes or first setup: switched to new account"; } // Otherwise, set only URL and credentials else { origAccount->setUrl(newAccount->url()); origAccount->setCredentials(_ocWizard->getCredentials()); qDebug() << "Only password or schema was changed, adjusted existing account"; } } DetermineAuthTypeJob::DetermineAuthTypeJob(AccountPtr account, QObject *parent) : AbstractNetworkJob(account, QString(), parent) , _redirects(0) { } void DetermineAuthTypeJob::start() { QNetworkReply *reply = getRequest(account()->davPath()); setReply(reply); setupConnections(reply); AbstractNetworkJob::start(); } bool DetermineAuthTypeJob::finished() { QUrl redirection = reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); qDebug() << Q_FUNC_INFO << redirection.toString(); if (_redirects >= maxRedirects()) { redirection.clear(); } 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); } } return true; } ValidateDavAuthJob::ValidateDavAuthJob(AccountPtr account, QObject *parent) : AbstractNetworkJob(account, QString(), parent) { } void ValidateDavAuthJob::start() { QString p = account()->davPath(); QNetworkReply *reply = getRequest(p); setReply(reply); setupConnections(reply); AbstractNetworkJob::start(); } bool ValidateDavAuthJob::finished() { emit authResult(reply()); return true; } } // namespace OCC