2014-12-17 16:09:57 +03:00
|
|
|
/*
|
|
|
|
* 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
|
2016-10-25 12:00:07 +03:00
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2014-12-17 16:09:57 +03:00
|
|
|
*
|
|
|
|
* 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 <QByteArray>
|
2017-08-16 09:36:52 +03:00
|
|
|
#include <QElapsedTimer>
|
2015-05-15 13:26:23 +03:00
|
|
|
#include <QPointer>
|
2014-12-17 16:09:57 +03:00
|
|
|
#include "connectionvalidator.h"
|
2015-09-05 16:39:22 +03:00
|
|
|
#include "creds/abstractcredentials.h"
|
2021-09-09 12:18:22 +03:00
|
|
|
|
2015-06-15 16:04:39 +03:00
|
|
|
#include <memory>
|
2014-12-17 16:09:57 +03:00
|
|
|
|
2015-06-15 16:04:39 +03:00
|
|
|
class QSettings;
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
namespace OCC {
|
|
|
|
|
|
|
|
class AccountState;
|
|
|
|
class Account;
|
2020-01-15 18:23:46 +03:00
|
|
|
class AccountApp;
|
2019-07-24 14:56:21 +03:00
|
|
|
class RemoteWipe;
|
2014-12-17 16:09:57 +03:00
|
|
|
|
2020-08-12 16:23:11 +03:00
|
|
|
using AccountStatePtr = QExplicitlySharedDataPointer<AccountState>;
|
|
|
|
using AccountAppList = QList<AccountApp *>;
|
2016-03-16 21:07:40 +03:00
|
|
|
|
2015-06-29 19:56:09 +03:00
|
|
|
/**
|
|
|
|
* @brief Extra info about an ownCloud server account.
|
|
|
|
* @ingroup gui
|
2014-12-17 16:09:57 +03:00
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
class AccountState : public QObject, public QSharedData
|
|
|
|
{
|
2014-12-17 16:09:57 +03:00
|
|
|
Q_OBJECT
|
2019-06-05 21:57:15 +03:00
|
|
|
Q_PROPERTY(AccountPtr account MEMBER _account)
|
|
|
|
|
2014-12-17 16:09:57 +03:00
|
|
|
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,
|
|
|
|
|
2015-04-24 12:32:47 +03:00
|
|
|
/// There's a temporary problem with talking to the server,
|
|
|
|
/// don't bother the user too much and try again.
|
|
|
|
ServiceUnavailable,
|
2015-02-25 11:49:39 +03:00
|
|
|
|
2017-05-08 13:39:08 +03:00
|
|
|
/// Similar to ServiceUnavailable, but we know the server is down
|
|
|
|
/// for maintenance
|
|
|
|
MaintenanceMode,
|
|
|
|
|
2014-12-17 16:09:57 +03:00
|
|
|
/// Could not communicate with the server for some reason.
|
|
|
|
/// We assume this may resolve itself over time and will try
|
|
|
|
/// again automatically.
|
|
|
|
NetworkError,
|
|
|
|
|
2017-07-13 12:27:02 +03:00
|
|
|
/// Server configuration error. (For example: unsupported version)
|
|
|
|
ConfigurationError,
|
|
|
|
|
|
|
|
/// We are currently asking the user for credentials
|
|
|
|
AskingCredentials
|
2014-12-17 16:09:57 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/// The actual current connectivity status.
|
2020-08-12 16:23:11 +03:00
|
|
|
using ConnectionStatus = ConnectionValidator::Status;
|
2014-12-17 16:09:57 +03:00
|
|
|
|
2014-12-18 14:09:48 +03:00
|
|
|
/// Use the account as parent
|
2016-03-01 18:08:23 +03:00
|
|
|
explicit AccountState(AccountPtr account);
|
2021-08-17 13:39:31 +03:00
|
|
|
~AccountState() override;
|
2014-12-17 16:09:57 +03:00
|
|
|
|
2016-03-01 18:08:23 +03:00
|
|
|
/** Creates an account state from settings and an Account object.
|
|
|
|
*
|
|
|
|
* Use from AccountManager with a prepared QSettings object only.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
static AccountState *loadFromSettings(AccountPtr account, QSettings &settings);
|
2016-03-01 18:08:23 +03:00
|
|
|
|
|
|
|
/** Writes account state information to settings.
|
|
|
|
*
|
|
|
|
* It does not write the Account data.
|
|
|
|
*/
|
2017-05-17 11:55:42 +03:00
|
|
|
void writeToSettings(QSettings &settings);
|
2016-03-01 18:08:23 +03:00
|
|
|
|
2014-12-18 14:09:48 +03:00
|
|
|
AccountPtr account() const;
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
ConnectionStatus connectionStatus() const;
|
|
|
|
QStringList connectionErrors() const;
|
|
|
|
|
|
|
|
State state() const;
|
2015-07-01 13:30:18 +03:00
|
|
|
static QString stateString(State state);
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
bool isSignedOut() const;
|
2015-12-09 13:06:28 +03:00
|
|
|
|
2020-01-15 18:23:46 +03:00
|
|
|
AccountAppList appList() const;
|
2020-01-17 22:21:42 +03:00
|
|
|
AccountApp* findApp(const QString &appId) const;
|
2020-01-15 18:23:46 +03:00
|
|
|
|
2015-12-09 13:06:28 +03:00
|
|
|
/** A user-triggered sign out which disconnects, stops syncs
|
|
|
|
* for the account and forgets the password. */
|
|
|
|
void signOutByUi();
|
|
|
|
|
2017-11-05 21:50:09 +03:00
|
|
|
/** 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();
|
|
|
|
|
2015-12-09 13:06:28 +03:00
|
|
|
/// Move from SignedOut state to Disconnected (attempting to connect)
|
|
|
|
void signIn();
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
bool isConnected() const;
|
|
|
|
|
2015-06-15 16:04:39 +03:00
|
|
|
/** Returns a new settings object for this account, already in the right groups. */
|
2015-07-02 14:31:42 +03:00
|
|
|
std::unique_ptr<QSettings> settings();
|
2015-06-15 16:04:39 +03:00
|
|
|
|
2015-10-19 12:50:26 +03:00
|
|
|
/** 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
|
2015-11-19 08:17:15 +03:00
|
|
|
* was not so long ago.
|
2015-10-19 12:50:26 +03:00
|
|
|
*/
|
2020-12-03 18:27:43 +03:00
|
|
|
void tagLastSuccessfullETagRequest(const QDateTime &tp);
|
2015-10-19 12:50:26 +03:00
|
|
|
|
2018-03-02 00:19:04 +03:00
|
|
|
/** 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);
|
|
|
|
|
2018-04-10 16:38:59 +03:00
|
|
|
/** 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);
|
|
|
|
|
2019-07-24 14:56:21 +03:00
|
|
|
///Asks for user credentials
|
|
|
|
void handleInvalidCredentials();
|
|
|
|
|
2021-03-21 22:55:21 +03:00
|
|
|
/** Returns the notifications status retrieved by the notificatons endpoint
|
2021-03-16 22:24:11 +03:00
|
|
|
* https://github.com/nextcloud/desktop/issues/2318#issuecomment-680698429
|
|
|
|
*/
|
2021-03-21 22:55:21 +03:00
|
|
|
bool isDesktopNotificationsAllowed() const;
|
2021-03-16 22:24:11 +03:00
|
|
|
|
2021-03-21 22:55:21 +03:00
|
|
|
/** Set desktop notifications status retrieved by the notificatons endpoint
|
2021-03-16 22:24:11 +03:00
|
|
|
*/
|
2021-03-30 13:53:47 +03:00
|
|
|
void setDesktopNotificationsAllowed(bool isAllowed);
|
2021-03-16 22:24:11 +03:00
|
|
|
|
2017-07-04 13:23:23 +03:00
|
|
|
public slots:
|
|
|
|
/// Triggers a ping to the server to update state and
|
|
|
|
/// connection status and errors.
|
|
|
|
void checkConnectivity();
|
|
|
|
|
2014-12-17 16:09:57 +03:00
|
|
|
private:
|
|
|
|
void setState(State state);
|
2020-01-15 18:23:46 +03:00
|
|
|
void fetchNavigationApps();
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
signals:
|
2020-11-30 14:17:47 +03:00
|
|
|
void stateChanged(State state);
|
2016-04-28 23:43:53 +03:00
|
|
|
void isConnectedChanged();
|
2020-01-15 18:23:46 +03:00
|
|
|
void hasFetchedNavigationApps();
|
2021-03-21 22:55:21 +03:00
|
|
|
void statusChanged();
|
2021-04-21 20:04:21 +03:00
|
|
|
void desktopNotificationsAllowedChanged();
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
protected Q_SLOTS:
|
2017-05-17 11:55:42 +03:00
|
|
|
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors);
|
2019-07-24 14:56:21 +03:00
|
|
|
|
|
|
|
/// When client gets a 401 or 403 checks if server requested remote wipe
|
|
|
|
/// before asking for user credentials again
|
|
|
|
void slotHandleRemoteWipeCheck();
|
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
void slotCredentialsFetched(AbstractCredentials *creds);
|
|
|
|
void slotCredentialsAsked(AbstractCredentials *creds);
|
2014-12-17 16:09:57 +03:00
|
|
|
|
2020-01-15 18:23:46 +03:00
|
|
|
void slotNavigationAppsFetched(const QJsonDocument &reply, int statusCode);
|
|
|
|
void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode);
|
|
|
|
void slotOcsError(int statusCode, const QString &message);
|
|
|
|
|
2014-12-17 16:09:57 +03:00
|
|
|
private:
|
2015-04-17 18:56:17 +03:00
|
|
|
AccountPtr _account;
|
2014-12-17 16:09:57 +03:00
|
|
|
State _state;
|
|
|
|
ConnectionStatus _connectionStatus;
|
|
|
|
QStringList _connectionErrors;
|
|
|
|
bool _waitingForNewCredentials;
|
2020-12-03 18:27:43 +03:00
|
|
|
QDateTime _timeOfLastETagCheck;
|
2015-05-15 13:26:23 +03:00
|
|
|
QPointer<ConnectionValidator> _connectionValidator;
|
2018-03-02 00:19:04 +03:00
|
|
|
QByteArray _notificationsEtagResponseHeader;
|
2018-04-10 16:38:59 +03:00
|
|
|
QByteArray _navigationAppsEtagResponseHeader;
|
2017-07-04 13:23:23 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
2019-07-24 14:56:21 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Connects remote wipe check with the account
|
|
|
|
* the log out triggers the check (loads app password -> create request)
|
|
|
|
*/
|
|
|
|
RemoteWipe *_remoteWipe;
|
|
|
|
|
2020-01-15 18:23:46 +03:00
|
|
|
/**
|
|
|
|
* Holds the App names and URLs available on the server
|
|
|
|
*/
|
|
|
|
AccountAppList _apps;
|
|
|
|
|
2021-03-21 22:55:21 +03:00
|
|
|
bool _isDesktopNotificationsAllowed;
|
2014-12-17 16:09:57 +03:00
|
|
|
};
|
2020-01-15 18:23:46 +03:00
|
|
|
|
|
|
|
class AccountApp : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
AccountApp(const QString &name, const QUrl &url,
|
|
|
|
const QString &id, const QUrl &iconUrl,
|
2020-08-12 17:14:48 +03:00
|
|
|
QObject* parent = nullptr);
|
2020-01-15 18:23:46 +03:00
|
|
|
|
|
|
|
QString name() const;
|
|
|
|
QUrl url() const;
|
|
|
|
QString id() const;
|
|
|
|
QUrl iconUrl() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
QString _name;
|
|
|
|
QUrl _url;
|
|
|
|
|
|
|
|
QString _id;
|
|
|
|
QUrl _iconUrl;
|
|
|
|
};
|
|
|
|
|
2014-12-17 16:09:57 +03:00
|
|
|
}
|
|
|
|
|
2017-05-17 11:55:42 +03:00
|
|
|
Q_DECLARE_METATYPE(OCC::AccountState *)
|
2016-03-16 21:07:40 +03:00
|
|
|
Q_DECLARE_METATYPE(OCC::AccountStatePtr)
|
2014-12-17 16:09:57 +03:00
|
|
|
|
|
|
|
#endif //ACCOUNTINFO_H
|