Handle the fact that the user might cancel the password dialog

Add a new state of the account in which the credidentials are invalid,
but we are still trying to get the user enter his password.

Make sure that fetched() is ALWAYS emitted after we call fetch on the
credidentials, so we can know that the user pressed cancel. In that
case, go in the SignedOut state.

Fixes #1353
This commit is contained in:
Olivier Goffart 2014-01-28 11:06:40 +01:00
parent f408593d27
commit e31000d759
9 changed files with 44 additions and 45 deletions

View file

@ -238,9 +238,8 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
_password = pwd;
_ready = true;
persist(account);
Q_EMIT fetched();
break;
}
emit fetched();
}
qDebug() << "Error while reading password" << job->errorString();
}

View file

@ -67,7 +67,8 @@ class Account : public QObject {
public:
enum State { Disconnected = 0, /// no network connection
Connected, /// account is online
SignedOut /// Disconnected + credential token has been discarded
SignedOut, /// Disconnected + credential token has been discarded
InvalidCredidential /// The credidential are invalids and we are asking for them to the user
};
static QString davPath() { return "remote.php/webdav/"; }

View file

@ -210,14 +210,20 @@ void Application::slotCheckConnection()
Account *account = AccountManager::instance()->account();
if( account ) {
if (account->state() == Account::InvalidCredidential
|| account->state() == Account::SignedOut) {
//Do not try to connect if we are logged out
return;
}
AbstractCredentials* credentials(account->credentials());
if (! credentials->ready()) {
connect( credentials, SIGNAL(fetched()),
this, SLOT(slotCredentialsFetched()));
this, SLOT(slotCredentialsFetched()), Qt::UniqueConnection);
credentials->fetch(account);
} else {
runValidator();
slotCredentialsFetched();
}
} else {
// let gui open the setup wizard
@ -228,14 +234,21 @@ void Application::slotCheckConnection()
void Application::slotCredentialsFetched()
{
Account *account = AccountManager::instance()->account();
disconnect(account->credentials(), SIGNAL(fetched()),
this, SLOT(slotCredentialsFetched()));
runValidator();
}
Q_ASSERT(account);
disconnect(account->credentials(), SIGNAL(fetched()), this, SLOT(slotCredentialsFetched()));
if (!account->credentials()->ready()) {
// User canceled the connection or did not give a password
account->setState(Account::SignedOut);
return;
}
if (account->state() == Account::InvalidCredidential) {
// Then we ask again for the credidentials if they are wrong again
account->setState(Account::Disconnected);
}
void Application::runValidator()
{
_conValidator = new ConnectionValidator(AccountManager::instance()->account());
if (_conValidator)
_conValidator->deleteLater();
_conValidator = new ConnectionValidator(account);
connect( _conValidator, SIGNAL(connectionResult(ConnectionValidator::Status)),
this, SLOT(slotConnectionValidatorResult(ConnectionValidator::Status)) );
_conValidator->checkConnection();

View file

@ -73,20 +73,19 @@ protected slots:
void slotConnectionValidatorResult(ConnectionValidator::Status);
void slotStartUpdateDetector();
void slotUseMonoIconsChanged( bool );
void slotCredentialsFetched();
void slotLogin();
void slotLogout();
void slotCleanup();
void slotAccountChanged(Account *newAccount, Account *oldAccount);
void slotCredentialsFetched();
private:
void setHelp();
void runValidator();
QPointer<ownCloudGui> _gui;
QPointer<SocketApi> _socketApi;
ConnectionValidator *_conValidator;
QPointer<ConnectionValidator> _conValidator;
Theme *_theme;

View file

@ -129,7 +129,6 @@ void ConnectionValidator::slotCheckAuthentication()
// simply GET the webdav root, will fail if credentials are wrong.
// continue in slotAuthCheck here :-)
PropfindJob *job = new PropfindJob(_account, "/", this);
job->setIgnoreCredentialFailure(true);
job->setProperties(QList<QByteArray>() << "getlastmodified");
connect(job, SIGNAL(result(QVariantMap)), SLOT(slotAuthSuccess()));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotAuthFailed(QNetworkReply*)));

View file

@ -25,6 +25,7 @@
#include <QTimer>
#include <QMutex>
#include <QDebug>
#include <QCoreApplication>
#include "json.h"
@ -89,17 +90,9 @@ void AbstractNetworkJob::setPath(const QString &path)
_path = path;
}
void AbstractNetworkJob::slotError(QNetworkReply::NetworkError)
{
qDebug() << metaObject()->className() << "Error:" << _reply->errorString();
emit networkError(_reply);
}
void AbstractNetworkJob::setupConnections(QNetworkReply *reply)
{
connect(reply, SIGNAL(finished()), SLOT(slotFinished()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(slotError(QNetworkReply::NetworkError)));
}
QNetworkReply* AbstractNetworkJob::davRequest(const QByteArray &verb, const QString &relPath,
@ -137,25 +130,21 @@ void AbstractNetworkJob::slotFinished()
{
if( _reply->error() != QNetworkReply::NoError ) {
qDebug() << Q_FUNC_INFO << _reply->error() << _reply->errorString();
emit networkError(_reply);
}
static QMutex mutex;
finished();
AbstractCredentials *creds = _account->credentials();
if (creds->stillValid(_reply) || _ignoreCredentialFailure) {
finished();
} else {
// If other jobs that still were created from before
// the account was put offline by the code below,
// we do want them to fail silently while we
// query the user
if (mutex.tryLock()) {
Account *a = account();
bool fetched = creds->fetchFromUser(a);
if (fetched) {
a->setState(Account::Connected);
}
mutex.unlock();
}
if (!creds->stillValid(_reply) &&! _ignoreCredentialFailure
&& _account->state() != Account::InvalidCredidential) {
// invalidate & forget token/password
_account->credentials()->invalidateToken(_account);
_account->setState(Account::InvalidCredidential);
// but try to re-sign in.
connect( creds, SIGNAL(fetched()),
qApp, SLOT(slotCredentialsFetched()), Qt::UniqueConnection);
creds->fetch(_account); // this triggers Application::runValidator when the credidentials are fetched
}
deleteLater();
}

View file

@ -73,7 +73,6 @@ protected:
private slots:
void slotFinished();
void slotError(QNetworkReply::NetworkError);
virtual void slotTimeout() {}
private:

View file

@ -86,7 +86,6 @@ void OwncloudSetupWizard::startWizard()
account = new Account;
account->setCredentials(CredentialsFactory::create("dummy"));
} else {
account->credentials()->fetch(account);
_ocWizard->setConfigExists(true);
}
account->setSslErrorHandler(new SslDialogErrorHandler);
@ -450,7 +449,7 @@ void DetermineAuthTypeJob::start()
void DetermineAuthTypeJob::finished()
{
QUrl redirection = reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
qDebug() << redirection.toString();
qDebug() << Q_FUNC_INFO << redirection.toString();
if (_redirects >= maxRedirects()) {
redirection.clear();
}

View file

@ -64,7 +64,8 @@ void QuotaInfo::slotRequestFailed()
void QuotaInfo::slotCheckQuota()
{
if (!_account.isNull() && _account->credentials() && _account->credentials()->ready()) {
if (!_account.isNull() && _account->credentials() && _account->credentials()->ready()
&& _account->state() == Account::Connected) {
CheckQuotaJob *job = new CheckQuotaJob(_account, "/", this);
connect(job, SIGNAL(quotaRetrieved(qint64,qint64)), SLOT(slotUpdateLastQuota(qint64,qint64)));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotRequestFailed()));