syncrunfilelog.cpp
systray.cpp
thumbnailjob.cpp
- quotainfo.cpp
+ userinfo.cpp
accountstate.cpp
addcertificatedialog.cpp
authenticationdialog.cpp
#include "configfile.h"
#include "account.h"
#include "accountstate.h"
-#include "quotainfo.h"
+#include "userinfo.h"
#include "accountmanager.h"
#include "owncloudsetupwizard.h"
#include "creds/abstractcredentials.h"
, _ui(new Ui::AccountSettings)
, _wasDisabledBefore(false)
, _accountState(accountState)
- , _quotaInfo(accountState)
+ , _userInfo(accountState, false, true)
, _menuShown(false)
{
_ui->setupUi(this);
connect(_accountState, &AccountState::stateChanged, this, &AccountSettings::slotAccountStateChanged);
slotAccountStateChanged();
- connect(&_quotaInfo, &QuotaInfo::quotaUpdated,
+ connect(&_userInfo, &UserInfo::quotaUpdated,
this, &AccountSettings::slotUpdateQuota);
// Connect E2E stuff
bool AccountSettings::event(QEvent *e)
{
if (e->type() == QEvent::Hide || e->type() == QEvent::Show) {
- _quotaInfo.setActive(isVisible());
+ _userInfo.setActive(isVisible());
}
if (e->type() == QEvent::Show) {
// Expand the folder automatically only if there's only one, see #4283
#include <QTimer>
#include "folder.h"
-#include "quotainfo.h"
+#include "userinfo.h"
#include "progressdispatcher.h"
#include "owncloudgui.h"
#include "folderstatusmodel.h"
QUrl _OCUrl;
bool _wasDisabledBefore;
AccountState *_accountState;
- QuotaInfo _quotaInfo;
+ UserInfo _userInfo;
QAction *_toggleSignInOutAction;
QAction *_addAccountAction;
return;
}
- ConnectionValidator *conValidator = new ConnectionValidator(account());
+ ConnectionValidator *conValidator = new ConnectionValidator(AccountStatePtr(this));
_connectionValidator = conValidator;
connect(conValidator, &ConnectionValidator::connectionResult,
this, &AccountState::slotConnectionValidatorResult);
#include "connectionvalidator.h"
#include "account.h"
+#include "accountstate.h"
+#include "userinfo.h"
#include "networkjobs.h"
#include "clientproxy.h"
#include <creds/abstractcredentials.h>
// This makes sure we get tried often enough without "ConnectionValidator already running"
static qint64 timeoutToUseMsec = qMax(1000, ConnectionValidator::DefaultCallingIntervalMsec - 5 * 1000);
-ConnectionValidator::ConnectionValidator(AccountPtr account, QObject *parent)
+ConnectionValidator::ConnectionValidator(AccountStatePtr accountState, QObject *parent)
: QObject(parent)
- , _account(account)
+ , _accountState(accountState)
+ , _account(accountState->account())
, _isCheckingServerAndAuth(false)
{
}
void ConnectionValidator::fetchUser()
{
- JsonApiJob *job = new JsonApiJob(_account, QLatin1String("ocs/v1.php/cloud/user"), this);
- job->setTimeout(timeoutToUseMsec);
- QObject::connect(job, &JsonApiJob::jsonReceived, this, &ConnectionValidator::slotUserFetched);
- job->start();
+ UserInfo *userInfo = new UserInfo(_accountState.data(), true, true, this);
+ QObject::connect(userInfo, &UserInfo::fetchedLastInfo, this, &ConnectionValidator::slotUserFetched);
+ userInfo->setActive(true);
}
bool ConnectionValidator::setAndCheckServerVersion(const QString &version)
return true;
}
-void ConnectionValidator::slotUserFetched(const QJsonDocument &json)
+void ConnectionValidator::slotUserFetched(UserInfo *userInfo)
{
- QString user = json.object().value("ocs").toObject().value("data").toObject().value("id").toString();
- if (!user.isEmpty()) {
- _account->setDavUser(user);
- }
- QString displayName = json.object().value("ocs").toObject().value("data").toObject().value("display-name").toString();
- if (!displayName.isEmpty()) {
- _account->setDavDisplayName(displayName);
+ if(userInfo) {
+ userInfo->setActive(false);
+ userInfo->deleteLater();
}
+
#ifndef TOKEN_AUTH_ONLY
- AvatarJob *job = new AvatarJob(_account, _account->davUser(), 128, this);
- job->setTimeout(20 * 1000);
- QObject::connect(job, &AvatarJob::avatarPixmap, this, &ConnectionValidator::slotAvatarImage);
- job->start();
+ connect(_account->e2e(), &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected);
+ _account->e2e()->initialize();
#else
reportResult(Connected);
#endif
}
#ifndef TOKEN_AUTH_ONLY
-void ConnectionValidator::slotAvatarImage(const QImage &img)
-{
- _account->setAvatar(img);
- connect(_account->e2e(), &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected);
- _account->e2e()->initialize();
-}
-
void ConnectionValidator::reportConnected() {
reportResult(Connected);
}
+---------------------------------+
|
fetchUser
- PropfindJob
- |
- +-> slotUserFetched
- AvatarJob
- |
- +-> slotAvatarImage -->
+ Utilizes the UserInfo class to fetch the user and avatar image
+-----------------------------------+
|
+-> Client Side Encryption Checks --+ --reportResult()
\endcode
*/
+class UserInfo;
+
class ConnectionValidator : public QObject
{
Q_OBJECT
public:
- explicit ConnectionValidator(AccountPtr account, QObject *parent = nullptr);
+ explicit ConnectionValidator(AccountStatePtr accountState, QObject *parent = nullptr);
enum Status {
Undefined,
void slotAuthSuccess();
void slotCapabilitiesRecieved(const QJsonDocument &);
- void slotUserFetched(const QJsonDocument &);
-#ifndef TOKEN_AUTH_ONLY
- void slotAvatarImage(const QImage &img);
-#endif
+ void slotUserFetched(UserInfo *userInfo);
private:
+#ifndef TOKEN_AUTH_ONLY
void reportConnected();
+#endif
void reportResult(Status status);
void checkServerCapabilities();
void fetchUser();
bool setAndCheckServerVersion(const QString &version);
QStringList _errors;
+ AccountStatePtr _accountState;
AccountPtr _account;
bool _isCheckingServerAndAuth;
};
+++ /dev/null
-/*
- * 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.
- */
-
-#include "quotainfo.h"
-#include "account.h"
-#include "accountstate.h"
-#include "networkjobs.h"
-#include "folderman.h"
-#include "creds/abstractcredentials.h"
-#include <theme.h>
-
-#include <QTimer>
-
-namespace OCC {
-
-namespace {
- static const int defaultIntervalT = 30 * 1000;
- static const int failIntervalT = 5 * 1000;
-}
-
-QuotaInfo::QuotaInfo(AccountState *accountState, QObject *parent)
- : QObject(parent)
- , _accountState(accountState)
- , _lastQuotaTotalBytes(0)
- , _lastQuotaUsedBytes(0)
- , _active(false)
-{
- connect(accountState, &AccountState::stateChanged,
- this, &QuotaInfo::slotAccountStateChanged);
- connect(&_jobRestartTimer, &QTimer::timeout, this, &QuotaInfo::slotCheckQuota);
- _jobRestartTimer.setSingleShot(true);
-}
-
-void QuotaInfo::setActive(bool active)
-{
- _active = active;
- slotAccountStateChanged();
-}
-
-
-void QuotaInfo::slotAccountStateChanged()
-{
- if (canGetQuota()) {
- auto elapsed = _lastQuotaRecieved.msecsTo(QDateTime::currentDateTime());
- if (_lastQuotaRecieved.isNull() || elapsed >= defaultIntervalT) {
- slotCheckQuota();
- } else {
- _jobRestartTimer.start(defaultIntervalT - elapsed);
- }
- } else {
- _jobRestartTimer.stop();
- }
-}
-
-void QuotaInfo::slotRequestFailed()
-{
- _lastQuotaTotalBytes = 0;
- _lastQuotaUsedBytes = 0;
- _jobRestartTimer.start(failIntervalT);
-}
-
-bool QuotaInfo::canGetQuota() const
-{
- if (!_accountState || !_active) {
- return false;
- }
- AccountPtr account = _accountState->account();
- return _accountState->isConnected()
- && account->credentials()
- && account->credentials()->ready();
-}
-
-QString QuotaInfo::quotaBaseFolder() const
-{
- return Theme::instance()->quotaBaseFolder();
-}
-
-void QuotaInfo::slotCheckQuota()
-{
- if (!canGetQuota()) {
- return;
- }
-
- if (_job) {
- // The previous job was not finished? Then we cancel it!
- _job->deleteLater();
- }
-
- AccountPtr account = _accountState->account();
- _job = new PropfindJob(account, quotaBaseFolder(), this);
- _job->setProperties(QList<QByteArray>() << "quota-available-bytes"
- << "quota-used-bytes");
- connect(_job.data(), &PropfindJob::result, this, &QuotaInfo::slotUpdateLastQuota);
- connect(_job.data(), &AbstractNetworkJob::networkError, this, &QuotaInfo::slotRequestFailed);
- _job->start();
-}
-
-void QuotaInfo::slotUpdateLastQuota(const QVariantMap &result)
-{
- // The server can return fractional bytes (#1374)
- // <d:quota-available-bytes>1374532061.2</d:quota-available-bytes>
- qint64 avail = result["quota-available-bytes"].toDouble();
- _lastQuotaUsedBytes = result["quota-used-bytes"].toDouble();
- // negative value of the available quota have special meaning (#3940)
- _lastQuotaTotalBytes = avail >= 0 ? _lastQuotaUsedBytes + avail : avail;
- emit quotaUpdated(_lastQuotaTotalBytes, _lastQuotaUsedBytes);
- _jobRestartTimer.start(defaultIntervalT);
- _lastQuotaRecieved = QDateTime::currentDateTime();
-}
-}
+++ /dev/null
-/*
- * 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 QUOTAINFO_H
-#define QUOTAINFO_H
-
-#include <QObject>
-#include <QPointer>
-#include <QVariant>
-#include <QTimer>
-#include <QDateTime>
-
-namespace OCC {
-class AccountState;
-class PropfindJob;
-
-/**
- * @brief handles getting the quota to display in the UI
- *
- * It is typically owned by the AccountSetting page.
- *
- * The quota is requested if these 3 conditions are met:
- * - This object is active via setActive() (typically if the settings page is visible.)
- * - The account is connected.
- * - Every 30 seconds (defaultIntervalT) or 5 seconds in case of failure (failIntervalT)
- *
- * We only request the quota when the UI is visible otherwise this might slow down the server with
- * too many requests. But we still need to do it every 30 seconds otherwise user complains that the
- * quota is not updated fast enough when changed on the server.
- *
- * If the quota job is not finished within 30 seconds, it is cancelled and another one is started
- *
- * @ingroup gui
- */
-class QuotaInfo : public QObject
-{
- Q_OBJECT
-public:
- explicit QuotaInfo(OCC::AccountState *accountState, QObject *parent = nullptr);
-
- qint64 lastQuotaTotalBytes() const { return _lastQuotaTotalBytes; }
- qint64 lastQuotaUsedBytes() const { return _lastQuotaUsedBytes; }
-
- /**
- * When the quotainfo is active, it requests the quota at regular interval.
- * When setting it to active it will request the quota immediately if the last time
- * the quota was requested was more than the interval
- */
- void setActive(bool active);
-
-public Q_SLOTS:
- void slotCheckQuota();
-
-private Q_SLOTS:
- void slotUpdateLastQuota(const QVariantMap &);
- void slotAccountStateChanged();
- void slotRequestFailed();
-
-Q_SIGNALS:
- void quotaUpdated(qint64 total, qint64 used);
-
-private:
- bool canGetQuota() const;
-
- /// Returns the folder that quota shall be retrieved for
- QString quotaBaseFolder() const;
-
- QPointer<AccountState> _accountState;
- qint64 _lastQuotaTotalBytes;
- qint64 _lastQuotaUsedBytes;
- QTimer _jobRestartTimer;
- QDateTime _lastQuotaRecieved; // the time at which the quota was received last
- bool _active; // if we should check at regular interval (when the UI is visible)
- QPointer<PropfindJob> _job; // the currently running job
-};
-
-
-} // namespace OCC
-
-#endif //QUOTAINFO_H
--- /dev/null
+/*
+ * Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
+ * Copyright (C) by Michael Schuster <michael@nextcloud.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.
+ */
+
+#include "userinfo.h"
+#include "account.h"
+#include "accountstate.h"
+#include "networkjobs.h"
+#include "folderman.h"
+#include "creds/abstractcredentials.h"
+#include <theme.h>
+
+#include <QTimer>
+#include <QJsonDocument>
+#include <QJsonObject>
+
+namespace OCC {
+
+namespace {
+ static const int defaultIntervalT = 30 * 1000;
+ static const int failIntervalT = 5 * 1000;
+}
+
+UserInfo::UserInfo(AccountState *accountState, bool allowDisconnectedAccountState, bool fetchAvatarImage, QObject *parent)
+ : QObject(parent)
+ , _accountState(accountState)
+ , _allowDisconnectedAccountState(allowDisconnectedAccountState)
+ , _fetchAvatarImage(fetchAvatarImage)
+ , _lastQuotaTotalBytes(0)
+ , _lastQuotaUsedBytes(0)
+ , _active(false)
+{
+ connect(accountState, &AccountState::stateChanged,
+ this, &UserInfo::slotAccountStateChanged);
+ connect(&_jobRestartTimer, &QTimer::timeout, this, &UserInfo::slotFetchInfo);
+ _jobRestartTimer.setSingleShot(true);
+}
+
+void UserInfo::setActive(bool active)
+{
+ _active = active;
+ slotAccountStateChanged();
+}
+
+
+void UserInfo::slotAccountStateChanged()
+{
+ if (canGetInfo()) {
+ auto elapsed = _lastInfoReceived.msecsTo(QDateTime::currentDateTime());
+ if (_lastInfoReceived.isNull() || elapsed >= defaultIntervalT) {
+ slotFetchInfo();
+ } else {
+ _jobRestartTimer.start(defaultIntervalT - elapsed);
+ }
+ } else {
+ _jobRestartTimer.stop();
+ }
+}
+
+void UserInfo::slotRequestFailed()
+{
+ _lastQuotaTotalBytes = 0;
+ _lastQuotaUsedBytes = 0;
+ _jobRestartTimer.start(failIntervalT);
+}
+
+bool UserInfo::canGetInfo() const
+{
+ if (!_accountState || !_active) {
+ return false;
+ }
+ AccountPtr account = _accountState->account();
+ return (_accountState->isConnected() || _allowDisconnectedAccountState)
+ && account->credentials()
+ && account->credentials()->ready();
+}
+
+void UserInfo::slotFetchInfo()
+{
+ if (!canGetInfo()) {
+ return;
+ }
+
+ if (_job) {
+ // The previous job was not finished? Then we cancel it!
+ _job->deleteLater();
+ }
+
+ AccountPtr account = _accountState->account();
+ _job = new JsonApiJob(account, QLatin1String("ocs/v1.php/cloud/user"), this);
+ _job->setTimeout(20 * 1000);
+ connect(_job.data(), &JsonApiJob::jsonReceived, this, &UserInfo::slotUpdateLastInfo);
+ connect(_job.data(), &AbstractNetworkJob::networkError, this, &UserInfo::slotRequestFailed);
+ _job->start();
+}
+
+void UserInfo::slotUpdateLastInfo(const QJsonDocument &json)
+{
+ auto objData = json.object().value("ocs").toObject().value("data").toObject();
+
+ AccountPtr account = _accountState->account();
+
+ // User Info
+ QString user = objData.value("id").toString();
+ if (!user.isEmpty()) {
+ account->setDavUser(user);
+ }
+ QString displayName = objData.value("display-name").toString();
+ if (!displayName.isEmpty()) {
+ account->setDavDisplayName(displayName);
+ }
+
+ // Quota
+ auto objQuota = objData.value("quota").toObject();
+ qint64 used = objQuota.value("used").toDouble();
+ qint64 total = objQuota.value("total").toDouble();
+
+ if(_lastInfoReceived.isNull() || _lastQuotaUsedBytes != used || _lastQuotaTotalBytes != total) {
+ _lastQuotaUsedBytes = used;
+ _lastQuotaTotalBytes = total;
+ emit quotaUpdated(_lastQuotaTotalBytes, _lastQuotaUsedBytes);
+ }
+
+ _jobRestartTimer.start(defaultIntervalT);
+ _lastInfoReceived = QDateTime::currentDateTime();
+
+ // Avatar Image
+ if(_fetchAvatarImage) {
+ AvatarJob *job = new AvatarJob(account, account->davUser(), 128, this);
+ job->setTimeout(20 * 1000);
+ QObject::connect(job, &AvatarJob::avatarPixmap, this, &UserInfo::slotAvatarImage);
+ job->start();
+ }
+ else
+ emit fetchedLastInfo(this);
+}
+
+void UserInfo::slotAvatarImage(const QImage &img)
+{
+ _accountState->account()->setAvatar(img);
+
+ emit fetchedLastInfo(this);
+}
+
+} // namespace OCC
--- /dev/null
+/*
+ * Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
+ * Copyright (C) by Michael Schuster <michael@nextcloud.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 USERINFO_H
+#define USERINFO_H
+
+#include <QObject>
+#include <QPointer>
+#include <QVariant>
+#include <QTimer>
+#include <QDateTime>
+
+namespace OCC {
+class AccountState;
+class JsonApiJob;
+
+/**
+ * @brief handles getting the user info and quota to display in the UI
+ *
+ * It is typically owned by the AccountSetting page.
+ *
+ * The user info and quota is requested if these 3 conditions are met:
+ * - This object is active via setActive() (typically if the settings page is visible.)
+ * - The account is connected.
+ * - Every 30 seconds (defaultIntervalT) or 5 seconds in case of failure (failIntervalT)
+ *
+ * We only request the info when the UI is visible otherwise this might slow down the server with
+ * too many requests. But we still need to do it every 30 seconds otherwise user complains that the
+ * quota is not updated fast enough when changed on the server.
+ *
+ * If the fetch job is not finished within 30 seconds, it is cancelled and another one is started
+ *
+ * Constructor notes:
+ * - allowDisconnectedAccountState: set to true if you want to ignore AccountState's isConnected() state,
+ * this is used by ConnectionValidator (prior having a valid AccountState).
+ * - fetchAvatarImage: set to false if you don't want to fetch the avatar image
+ *
+ * @ingroup gui
+ *
+ * Here follows the state machine
+
+ \code{.unparsed}
+ *---> slotFetchInfo
+ JsonApiJob (ocs/v1.php/cloud/user)
+ |
+ +-> slotUpdateLastInfo
+ AvatarJob (if _fetchAvatarImage is true)
+ |
+ +-> slotAvatarImage -->
+ +-----------------------------------+
+ |
+ +-> Client Side Encryption Checks --+ --reportResult()
+ \endcode
+ */
+class UserInfo : public QObject
+{
+ Q_OBJECT
+public:
+ explicit UserInfo(OCC::AccountState *accountState, bool allowDisconnectedAccountState, bool fetchAvatarImage, QObject *parent = nullptr);
+
+ qint64 lastQuotaTotalBytes() const { return _lastQuotaTotalBytes; }
+ qint64 lastQuotaUsedBytes() const { return _lastQuotaUsedBytes; }
+
+ /**
+ * When the quotainfo is active, it requests the quota at regular interval.
+ * When setting it to active it will request the quota immediately if the last time
+ * the quota was requested was more than the interval
+ */
+ void setActive(bool active);
+
+public Q_SLOTS:
+ void slotFetchInfo();
+
+private Q_SLOTS:
+ void slotUpdateLastInfo(const QJsonDocument &json);
+ void slotAccountStateChanged();
+ void slotRequestFailed();
+ void slotAvatarImage(const QImage &img);
+
+Q_SIGNALS:
+ void quotaUpdated(qint64 total, qint64 used);
+ void fetchedLastInfo(UserInfo *userInfo);
+
+private:
+ bool canGetInfo() const;
+
+ QPointer<AccountState> _accountState;
+ bool _allowDisconnectedAccountState;
+ bool _fetchAvatarImage;
+
+ qint64 _lastQuotaTotalBytes;
+ qint64 _lastQuotaUsedBytes;
+ QTimer _jobRestartTimer;
+ QDateTime _lastInfoReceived; // the time at which the user info and quota was received last
+ bool _active; // if we should check at regular interval (when the UI is visible)
+ QPointer<JsonApiJob> _job; // the currently running job
+};
+
+
+} // namespace OCC
+
+#endif //USERINFO_H