mirror of
https://github.com/nextcloud/desktop.git
synced 2024-12-19 04:11:50 +03:00
7084310a9f
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
290 lines
8.4 KiB
C++
290 lines
8.4 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; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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 ACCOUNTINFO_H
|
|
#define ACCOUNTINFO_H
|
|
|
|
#include "connectionvalidator.h"
|
|
#include "creds/abstractcredentials.h"
|
|
|
|
#include <QByteArray>
|
|
#include <QElapsedTimer>
|
|
#include <QPointer>
|
|
#include <QTimer>
|
|
|
|
#include <memory>
|
|
|
|
class QSettings;
|
|
class FakeAccountState;
|
|
|
|
namespace OCC {
|
|
|
|
class AccountState;
|
|
class Account;
|
|
class AccountApp;
|
|
class RemoteWipe;
|
|
|
|
using AccountStatePtr = QExplicitlySharedDataPointer<AccountState>;
|
|
using AccountAppList = QList<AccountApp *>;
|
|
|
|
/**
|
|
* @brief Extra info about an ownCloud server account.
|
|
* @ingroup gui
|
|
*/
|
|
class AccountState : public QObject, public QSharedData
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(AccountPtr account MEMBER _account)
|
|
|
|
public:
|
|
enum State {
|
|
/// Not even attempting to connect, most likely because the
|
|
/// user explicitly signed out or cancelled a credential dialog.
|
|
SignedOut,
|
|
|
|
/// Account would like to be connected but hasn't heard back yet.
|
|
Disconnected,
|
|
|
|
/// The account is successfully talking to the server.
|
|
Connected,
|
|
|
|
/// There's a temporary problem with talking to the server,
|
|
/// don't bother the user too much and try again.
|
|
ServiceUnavailable,
|
|
|
|
/// Similar to ServiceUnavailable, but we know the server is down
|
|
/// for maintenance
|
|
MaintenanceMode,
|
|
|
|
/// Could not communicate with the server for some reason.
|
|
/// We assume this may resolve itself over time and will try
|
|
/// again automatically.
|
|
NetworkError,
|
|
|
|
/// Server configuration error. (For example: unsupported version)
|
|
ConfigurationError,
|
|
|
|
/// We are currently asking the user for credentials
|
|
AskingCredentials
|
|
};
|
|
|
|
/// The actual current connectivity status.
|
|
using ConnectionStatus = ConnectionValidator::Status;
|
|
|
|
/// Use the account as parent
|
|
explicit AccountState(AccountPtr account);
|
|
~AccountState() override;
|
|
|
|
/** Creates an account state from settings and an Account object.
|
|
*
|
|
* Use from AccountManager with a prepared QSettings object only.
|
|
*/
|
|
static AccountState *loadFromSettings(AccountPtr account, QSettings &settings);
|
|
|
|
AccountPtr account() const;
|
|
|
|
ConnectionStatus connectionStatus() const;
|
|
QStringList connectionErrors() const;
|
|
|
|
State state() const;
|
|
static QString stateString(State state);
|
|
|
|
bool isSignedOut() const;
|
|
|
|
AccountAppList appList() const;
|
|
AccountApp* findApp(const QString &appId) const;
|
|
|
|
/** A user-triggered sign out which disconnects, stops syncs
|
|
* for the account and forgets the password. */
|
|
void signOutByUi();
|
|
|
|
/** Tries to connect from scratch.
|
|
*
|
|
* Does nothing for signed out accounts.
|
|
* Connected accounts will be disconnected and try anew.
|
|
* Disconnected accounts will go to checkConnectivity().
|
|
*
|
|
* Useful for when network settings (proxy) change.
|
|
*/
|
|
void freshConnectionAttempt();
|
|
|
|
/// Move from SignedOut state to Disconnected (attempting to connect)
|
|
void signIn();
|
|
|
|
bool isConnected() const;
|
|
|
|
/** Returns a new settings object for this account, already in the right groups. */
|
|
std::unique_ptr<QSettings> settings();
|
|
|
|
/** Mark the timestamp when the last successful ETag check happened for
|
|
* this account.
|
|
* The checkConnectivity() method uses the timestamp to save a call to
|
|
* the server to validate the connection if the last successful etag job
|
|
* was not so long ago.
|
|
*/
|
|
void tagLastSuccessfullETagRequest(const QDateTime &tp);
|
|
|
|
/** Saves the ETag Response header from the last Notifications api
|
|
* request with statusCode 200.
|
|
*/
|
|
QByteArray notificationsEtagResponseHeader() const;
|
|
|
|
/** Returns the ETag Response header from the last Notifications api
|
|
* request with statusCode 200.
|
|
*/
|
|
void setNotificationsEtagResponseHeader(const QByteArray &value);
|
|
|
|
/** Saves the ETag Response header from the last Navigation Apps api
|
|
* request with statusCode 200.
|
|
*/
|
|
QByteArray navigationAppsEtagResponseHeader() const;
|
|
|
|
/** Returns the ETag Response header from the last Navigation Apps api
|
|
* request with statusCode 200.
|
|
*/
|
|
void setNavigationAppsEtagResponseHeader(const QByteArray &value);
|
|
|
|
///Asks for user credentials
|
|
void handleInvalidCredentials();
|
|
|
|
/** Returns the notifications status retrieved by the notificatons endpoint
|
|
* https://github.com/nextcloud/desktop/issues/2318#issuecomment-680698429
|
|
*/
|
|
bool isDesktopNotificationsAllowed() const;
|
|
|
|
/** Set desktop notifications status retrieved by the notificatons endpoint
|
|
*/
|
|
void setDesktopNotificationsAllowed(bool isAllowed);
|
|
|
|
ConnectionStatus lastConnectionStatus() const;
|
|
|
|
void trySignIn();
|
|
|
|
void systemOnlineConfigurationChanged();
|
|
|
|
public slots:
|
|
/// Triggers a ping to the server to update state and
|
|
/// connection status and errors.
|
|
virtual void checkConnectivity();
|
|
|
|
private:
|
|
virtual void setState(State state);
|
|
void fetchNavigationApps();
|
|
|
|
int retryCount() const;
|
|
void increaseRetryCount();
|
|
void resetRetryCount();
|
|
|
|
signals:
|
|
void stateChanged(OCC::AccountState::State state);
|
|
void isConnectedChanged();
|
|
void hasFetchedNavigationApps();
|
|
void statusChanged();
|
|
void desktopNotificationsAllowedChanged();
|
|
|
|
protected Q_SLOTS:
|
|
void slotConnectionValidatorResult(OCC::ConnectionValidator::Status status, const QStringList &errors);
|
|
|
|
/// When client gets a 401 or 403 checks if server requested remote wipe
|
|
/// before asking for user credentials again
|
|
void slotHandleRemoteWipeCheck();
|
|
|
|
void slotCredentialsFetched(OCC::AbstractCredentials *creds);
|
|
void slotCredentialsAsked(OCC::AbstractCredentials *creds);
|
|
|
|
void slotNavigationAppsFetched(const QJsonDocument &reply, int statusCode);
|
|
void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode);
|
|
void slotOcsError(int statusCode, const QString &message);
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotCheckConnection();
|
|
void slotPushNotificationsReady();
|
|
void slotServerUserStatusChanged();
|
|
|
|
private:
|
|
AccountPtr _account;
|
|
State _state;
|
|
ConnectionStatus _connectionStatus;
|
|
ConnectionStatus _lastConnectionValidatorStatus = ConnectionStatus::Undefined;
|
|
QStringList _connectionErrors;
|
|
bool _waitingForNewCredentials = false;
|
|
QDateTime _timeOfLastETagCheck;
|
|
QPointer<ConnectionValidator> _connectionValidator;
|
|
QByteArray _notificationsEtagResponseHeader;
|
|
QByteArray _navigationAppsEtagResponseHeader;
|
|
|
|
/**
|
|
* Starts counting when the server starts being back up after 503 or
|
|
* maintenance mode. The account will only become connected once this
|
|
* timer exceeds the _maintenanceToConnectedDelay value.
|
|
*/
|
|
QElapsedTimer _timeSinceMaintenanceOver;
|
|
|
|
/**
|
|
* Milliseconds for which to delay reconnection after 503/maintenance.
|
|
*/
|
|
int _maintenanceToConnectedDelay = 0;
|
|
|
|
/**
|
|
* Connects remote wipe check with the account
|
|
* the log out triggers the check (loads app password -> create request)
|
|
*/
|
|
RemoteWipe *_remoteWipe = nullptr;
|
|
|
|
/**
|
|
* Holds the App names and URLs available on the server
|
|
*/
|
|
AccountAppList _apps;
|
|
|
|
bool _isDesktopNotificationsAllowed = false;
|
|
|
|
int _retryCount = 0;
|
|
|
|
QTimer _checkConnectionTimer;
|
|
QElapsedTimer _lastCheckConnectionTimer;
|
|
|
|
explicit AccountState() = default;
|
|
|
|
friend class ::FakeAccountState;
|
|
};
|
|
|
|
class AccountApp : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
AccountApp(const QString &name, const QUrl &url,
|
|
const QString &id, const QUrl &iconUrl,
|
|
QObject* parent = nullptr);
|
|
|
|
[[nodiscard]] QString name() const;
|
|
[[nodiscard]] QUrl url() const;
|
|
[[nodiscard]] QString id() const;
|
|
[[nodiscard]] QUrl iconUrl() const;
|
|
|
|
private:
|
|
QString _name;
|
|
QUrl _url;
|
|
|
|
QString _id;
|
|
QUrl _iconUrl;
|
|
};
|
|
|
|
}
|
|
|
|
Q_DECLARE_METATYPE(OCC::AccountState *)
|
|
Q_DECLARE_METATYPE(OCC::AccountStatePtr)
|
|
|
|
#endif //ACCOUNTINFO_H
|