mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-29 00:26:33 +03:00
f8b24ac34d
The problem was that StatusNotFound can indicate either a transient network problem or a permanent server configuration problem.
246 lines
6.3 KiB
C++
246 lines
6.3 KiB
C++
/*
|
|
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
|
|
*
|
|
* 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 "accountstate.h"
|
|
#include "quotainfo.h"
|
|
#include "account.h"
|
|
#include "creds/abstractcredentials.h"
|
|
|
|
#include <QDebug>
|
|
|
|
namespace OCC {
|
|
|
|
Q_GLOBAL_STATIC(AccountStateManager, g_accountStateManager)
|
|
|
|
AccountStateManager *AccountStateManager::instance()
|
|
{
|
|
return g_accountStateManager();
|
|
}
|
|
|
|
AccountStateManager::AccountStateManager()
|
|
: _accountState(0)
|
|
{
|
|
connect(AccountManager::instance(), SIGNAL(accountAdded(AccountPtr)),
|
|
SLOT(slotAccountAdded(AccountPtr)));
|
|
}
|
|
|
|
AccountStateManager::~AccountStateManager()
|
|
{}
|
|
|
|
void AccountStateManager::setAccountState(AccountState *accountState)
|
|
{
|
|
if (_accountState) {
|
|
emit accountStateRemoved(_accountState);
|
|
}
|
|
_accountState = accountState;
|
|
emit accountStateAdded(accountState);
|
|
}
|
|
|
|
void AccountStateManager::slotAccountAdded(AccountPtr account)
|
|
{
|
|
setAccountState(new AccountState(account));
|
|
}
|
|
|
|
AccountState::AccountState(AccountPtr account)
|
|
: QObject(account.data())
|
|
, _account(account)
|
|
, _quotaInfo(new QuotaInfo(this))
|
|
, _state(AccountState::Disconnected)
|
|
, _connectionStatus(ConnectionValidator::Undefined)
|
|
, _waitingForNewCredentials(false)
|
|
{
|
|
qRegisterMetaType<AccountState*>("AccountState*");
|
|
|
|
connect(account.data(), SIGNAL(invalidCredentials()),
|
|
SLOT(slotInvalidCredentials()));
|
|
connect(account.data(), SIGNAL(credentialsFetched(AbstractCredentials*)),
|
|
SLOT(slotCredentialsFetched(AbstractCredentials*)));
|
|
}
|
|
|
|
AccountState::~AccountState()
|
|
{
|
|
}
|
|
|
|
AccountPtr AccountState::account() const
|
|
{
|
|
return _account.toStrongRef();
|
|
}
|
|
|
|
AccountState::ConnectionStatus AccountState::connectionStatus() const
|
|
{
|
|
return _connectionStatus;
|
|
}
|
|
|
|
QStringList AccountState::connectionErrors() const
|
|
{
|
|
return _connectionErrors;
|
|
}
|
|
|
|
QString AccountState::connectionStatusString(ConnectionStatus status)
|
|
{
|
|
return ConnectionValidator::statusString(status);
|
|
}
|
|
|
|
AccountState::State AccountState::state() const
|
|
{
|
|
return _state;
|
|
}
|
|
|
|
void AccountState::setState(State state)
|
|
{
|
|
if (_state != state) {
|
|
qDebug() << "AccountState state change: "
|
|
<< stateString(_state) << "->" << stateString(state);
|
|
State oldState = _state;
|
|
_state = state;
|
|
|
|
if (_state == SignedOut) {
|
|
_connectionStatus = ConnectionValidator::Undefined;
|
|
_connectionErrors.clear();
|
|
} else if (oldState == SignedOut && _state == Disconnected) {
|
|
checkConnectivity();
|
|
}
|
|
|
|
emit stateChanged(_state);
|
|
}
|
|
}
|
|
|
|
QString AccountState::stateString(State state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case SignedOut:
|
|
return QLatin1String("SignedOut");
|
|
case Disconnected:
|
|
return QLatin1String("Disconnected");
|
|
case Connected:
|
|
return QLatin1String("Connected");
|
|
case NetworkError:
|
|
return QLatin1String("NetworkError");
|
|
case ConfigurationError:
|
|
return QLatin1String("ConfigurationError");
|
|
}
|
|
return QLatin1String("Unknown");
|
|
}
|
|
|
|
bool AccountState::isSignedOut() const
|
|
{
|
|
return _state == SignedOut;
|
|
}
|
|
|
|
void AccountState::setSignedOut(bool signedOut)
|
|
{
|
|
if (signedOut) {
|
|
setState(SignedOut);
|
|
} else {
|
|
setState(Disconnected);
|
|
}
|
|
}
|
|
|
|
bool AccountState::isConnected() const
|
|
{
|
|
return _state == Connected;
|
|
}
|
|
|
|
QuotaInfo *AccountState::quotaInfo()
|
|
{
|
|
return _quotaInfo;
|
|
}
|
|
|
|
void AccountState::checkConnectivity()
|
|
{
|
|
if (isSignedOut() || _waitingForNewCredentials) {
|
|
return;
|
|
}
|
|
|
|
ConnectionValidator * conValidator = new ConnectionValidator(account());
|
|
connect(conValidator, SIGNAL(connectionResult(ConnectionValidator::Status,QStringList)),
|
|
SLOT(slotConnectionValidatorResult(ConnectionValidator::Status,QStringList)));
|
|
if (isConnected()) {
|
|
// Use a small authed propfind as a minimal ping when we're
|
|
// already connected.
|
|
conValidator->checkAuthentication();
|
|
} else {
|
|
// Check the server and then the auth.
|
|
conValidator->checkServerAndAuth();
|
|
}
|
|
}
|
|
|
|
void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors)
|
|
{
|
|
if (isSignedOut()) {
|
|
return;
|
|
}
|
|
|
|
if (_connectionStatus != status) {
|
|
qDebug() << "AccountState connection status change: "
|
|
<< connectionStatusString(_connectionStatus) << "->"
|
|
<< connectionStatusString(status);
|
|
_connectionStatus = status;
|
|
}
|
|
_connectionErrors = errors;
|
|
|
|
switch (status)
|
|
{
|
|
case ConnectionValidator::Connected:
|
|
setState(Connected);
|
|
break;
|
|
case ConnectionValidator::Undefined:
|
|
case ConnectionValidator::NotConfigured:
|
|
setState(Disconnected);
|
|
break;
|
|
case ConnectionValidator::ServerVersionMismatch:
|
|
setState(ConfigurationError);
|
|
break;
|
|
case ConnectionValidator::StatusNotFound:
|
|
// This can happen either because the server does not exist
|
|
// or because we are having network issues. The latter one is
|
|
// much more likely, so keep trying to connect.
|
|
setState(NetworkError);
|
|
break;
|
|
case ConnectionValidator::CredentialsWrong:
|
|
account()->handleInvalidCredentials();
|
|
break;
|
|
case ConnectionValidator::UserCanceledCredentials:
|
|
setState(SignedOut);
|
|
break;
|
|
case ConnectionValidator::Timeout:
|
|
setState(NetworkError);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void AccountState::slotInvalidCredentials()
|
|
{
|
|
if (isSignedOut()) {
|
|
return;
|
|
}
|
|
|
|
setState(ConfigurationError);
|
|
_waitingForNewCredentials = true;
|
|
}
|
|
|
|
void AccountState::slotCredentialsFetched(AbstractCredentials* credentials)
|
|
{
|
|
_waitingForNewCredentials = false;
|
|
|
|
if (!credentials->ready()) {
|
|
// User canceled the connection or did not give a password
|
|
setState(SignedOut);
|
|
return;
|
|
}
|
|
|
|
checkConnectivity();
|
|
}
|
|
|
|
} // namespace OCC
|