Merge pull request #7389 from nextcloud/bugfix/dealWithToSApp

content access denied error during discovery: verify server access
This commit is contained in:
Matthieu Gallien 2024-10-22 18:05:31 +02:00 коммит произвёл GitHub
Родитель 788a381bce 0b0b80b70f
Коммит 0190bf68f3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 118 добавлений и 29 удалений

Просмотреть файл

@ -48,6 +48,7 @@ AccountState::AccountState(const AccountPtr &account)
, _state(AccountState::Disconnected)
, _connectionStatus(ConnectionValidator::Undefined)
, _waitingForNewCredentials(false)
, _termsOfServiceChecker(_account)
, _maintenanceToConnectedDelay(60000 + (QRandomGenerator::global()->generate() % (4 * 60000))) // 1-5min delay
, _remoteWipe(new RemoteWipe(_account))
, _isDesktopNotificationsAllowed(true)
@ -64,10 +65,18 @@ AccountState::AccountState(const AccountPtr &account)
this, &AccountState::slotPushNotificationsReady);
connect(account.data(), &Account::serverUserStatusChanged, this,
&AccountState::slotServerUserStatusChanged);
connect(&_termsOfServiceChecker, &TermsOfServiceChecker::done,
this, [this] ()
{
if (_termsOfServiceChecker.needToSign()) {
slotConnectionValidatorResult(ConnectionValidator::NeedToSignTermsOfService, {});
}
});
connect(account.data(), &Account::termsOfServiceNeedToBeChecked,
this, [this] () {
checkConnectivity();
});
this, [this] ()
{
_termsOfServiceChecker.start();
});
connect(this, &AccountState::isConnectedChanged, [=]{
// Get the Apps available on the server if we're now connected.
@ -353,7 +362,7 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
_lastConnectionValidatorStatus = status;
if ((_lastConnectionValidatorStatus == ConnectionValidator::NeedToSignTermsOfService && status == ConnectionValidator::Connected) ||
status == ConnectionValidator::NeedToSignTermsOfService) {
(status == ConnectionValidator::NeedToSignTermsOfService && _lastConnectionValidatorStatus != status)) {
emit termsOfServiceChanged(_account);
}

Просмотреть файл

@ -227,6 +227,7 @@ private:
bool _waitingForNewCredentials = false;
QDateTime _timeOfLastETagCheck;
QPointer<ConnectionValidator> _connectionValidator;
TermsOfServiceChecker _termsOfServiceChecker;
QByteArray _notificationsEtagResponseHeader;
QByteArray _navigationAppsEtagResponseHeader;

Просмотреть файл

@ -42,7 +42,10 @@ ConnectionValidator::ConnectionValidator(AccountStatePtr accountState, const QSt
, _previousErrors(previousErrors)
, _accountState(accountState)
, _account(accountState->account())
, _termsOfServiceChecker(_account)
{
connect(&_termsOfServiceChecker, &TermsOfServiceChecker::done,
this, &ConnectionValidator::termsOfServiceCheckDone);
}
void ConnectionValidator::checkServerAndAuth()
@ -270,19 +273,6 @@ void ConnectionValidator::slotCapabilitiesRecieved(const QJsonDocument &json)
checkServerTermsOfService();
}
void ConnectionValidator::checkServerTermsOfService()
{
// The main flow now needs the capabilities
auto *job = new JsonApiJob(_account, QLatin1String("ocs/v2.php/apps/terms_of_service/terms"), this);
job->setTimeout(timeoutToUseMsec);
QObject::connect(job, &JsonApiJob::jsonReceived, this, &ConnectionValidator::slotServerTermsOfServiceRecieved);
QObject::connect(job, &JsonApiJob::networkError, this, [] (QNetworkReply *reply)
{
qCInfo(lcConnectionValidator()) << "network error" << reply->error();
});
job->start();
}
void ConnectionValidator::fetchUser()
{
auto *userInfo = new UserInfo(_accountState.data(), true, true, this);
@ -317,6 +307,11 @@ bool ConnectionValidator::setAndCheckServerVersion(const QString &version)
return true;
}
void ConnectionValidator::checkServerTermsOfService()
{
_termsOfServiceChecker.start();
}
void ConnectionValidator::slotUserFetched(UserInfo *userInfo)
{
if(userInfo) {
@ -332,17 +327,11 @@ void ConnectionValidator::slotUserFetched(UserInfo *userInfo)
#endif
}
void ConnectionValidator::slotServerTermsOfServiceRecieved(const QJsonDocument &reply)
void ConnectionValidator::termsOfServiceCheckDone()
{
qCDebug(lcConnectionValidator) << "Terms of service status" << reply;
if (reply.object().contains("ocs")) {
const auto hasSigned = reply.object().value("ocs").toObject().value("data").toObject().value("hasSigned").toBool(false);
if (!hasSigned) {
reportResult(NeedToSignTermsOfService);
return;
}
if (_termsOfServiceChecker.needToSign()) {
reportResult(NeedToSignTermsOfService);
return;
}
fetchUser();
@ -366,4 +355,60 @@ void ConnectionValidator::reportResult(Status status)
deleteLater();
}
TermsOfServiceChecker::TermsOfServiceChecker(AccountPtr account, QObject *parent)
: QObject(parent)
, _account(account)
{
}
TermsOfServiceChecker::TermsOfServiceChecker(QObject *parent)
: QObject(parent)
{
}
bool TermsOfServiceChecker::needToSign() const
{
return _needToSign;
}
void TermsOfServiceChecker::start()
{
checkServerTermsOfService();
}
void TermsOfServiceChecker::slotServerTermsOfServiceRecieved(const QJsonDocument &reply)
{
qCDebug(lcConnectionValidator) << "Terms of service status" << reply;
if (reply.object().contains("ocs")) {
const auto needToSign = !reply.object().value("ocs").toObject().value("data").toObject().value("hasSigned").toBool(false);
if (needToSign != _needToSign) {
_needToSign = needToSign;
emit needToSignChanged();
}
} else if (_needToSign) {
_needToSign = false;
emit needToSignChanged();
}
emit done();
}
void TermsOfServiceChecker::checkServerTermsOfService()
{
if (!_account) {
emit done();
}
// The main flow now needs the capabilities
auto *job = new JsonApiJob(_account, QLatin1String("ocs/v2.php/apps/terms_of_service/terms"), this);
job->setTimeout(timeoutToUseMsec);
QObject::connect(job, &JsonApiJob::jsonReceived, this, &TermsOfServiceChecker::slotServerTermsOfServiceRecieved);
QObject::connect(job, &JsonApiJob::networkError, this, [] (QNetworkReply *reply)
{
qCInfo(lcConnectionValidator()) << "network error" << reply->error();
});
job->start();
}
} // namespace OCC

Просмотреть файл

@ -75,6 +75,37 @@ namespace OCC {
class UserInfo;
class TermsOfServiceChecker : public QObject
{
Q_OBJECT
Q_PROPERTY(bool needToSign READ needToSign NOTIFY needToSignChanged FINAL)
public:
explicit TermsOfServiceChecker(AccountPtr account,
QObject *parent = nullptr);
explicit TermsOfServiceChecker(QObject *parent = nullptr);
[[nodiscard]] bool needToSign() const;
public slots:
void start();
signals:
void needToSignChanged();
void done();
private slots:
void slotServerTermsOfServiceRecieved(const QJsonDocument &reply);
private:
void checkServerTermsOfService();
AccountPtr _account;
bool _needToSign = false;
};
class ConnectionValidator : public QObject
{
Q_OBJECT
@ -130,7 +161,8 @@ protected slots:
void slotCapabilitiesRecieved(const QJsonDocument &);
void slotUserFetched(OCC::UserInfo *userInfo);
void slotServerTermsOfServiceRecieved(const QJsonDocument &reply);
void termsOfServiceCheckDone();
private:
#ifndef TOKEN_AUTH_ONLY
@ -138,7 +170,6 @@ private:
#endif
void reportResult(Status status);
void checkServerCapabilities();
void checkServerTermsOfService();
void fetchUser();
/** Sets the account's server version
@ -147,10 +178,13 @@ private:
*/
bool setAndCheckServerVersion(const QString &version);
void checkServerTermsOfService();
const QStringList _previousErrors;
QStringList _errors;
AccountStatePtr _accountState;
AccountPtr _account;
TermsOfServiceChecker _termsOfServiceChecker;
bool _isCheckingServerAndAuth = false;
};
}