Skip to content

Commit

Permalink
Merge pull request #7385 from nextcloud/bugfix/dealWithToSApp
Browse files Browse the repository at this point in the history
detect the terms of service app is requiring the user to sign them
  • Loading branch information
mgallien authored Oct 22, 2024
2 parents ca516af + 968289c commit 788a381
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/gui/accountsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,9 @@ void AccountSettings::slotAccountStateChanged()
// we can't end up here as the whole block is ifdeffed
Q_UNREACHABLE();
break;
case AccountState::NeedToSignTermsOfService:
showConnectionLabel(tr("You need to accept the terms of service"));
break;
}
} else {
// ownCloud is not yet configured.
Expand Down
15 changes: 15 additions & 0 deletions src/gui/accountstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ AccountState::AccountState(const AccountPtr &account)
this, &AccountState::slotPushNotificationsReady);
connect(account.data(), &Account::serverUserStatusChanged, this,
&AccountState::slotServerUserStatusChanged);
connect(account.data(), &Account::termsOfServiceNeedToBeChecked,
this, [this] () {
checkConnectivity();
});

connect(this, &AccountState::isConnectedChanged, [=]{
// Get the Apps available on the server if we're now connected.
Expand Down Expand Up @@ -159,6 +163,8 @@ QString AccountState::stateString(State state)
return tr("Configuration error");
case AskingCredentials:
return tr("Asking Credentials");
case NeedToSignTermsOfService:
return tr("Need the user to accept the terms of service");
}
return tr("Unknown account state");
}
Expand Down Expand Up @@ -346,6 +352,12 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta

_lastConnectionValidatorStatus = status;

if ((_lastConnectionValidatorStatus == ConnectionValidator::NeedToSignTermsOfService && status == ConnectionValidator::Connected) ||
status == ConnectionValidator::NeedToSignTermsOfService) {

emit termsOfServiceChanged(_account);
}

// Come online gradually from 503, captive portal(redirection) or maintenance mode
if (status == ConnectionValidator::Connected
&& (_connectionStatus == ConnectionValidator::ServiceUnavailable
Expand Down Expand Up @@ -424,6 +436,9 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
setState(NetworkError);
updateRetryCount();
break;
case ConnectionValidator::NeedToSignTermsOfService:
setState(NeedToSignTermsOfService);
break;
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/gui/accountstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ class AccountState : public QObject, public QSharedData
ConfigurationError,

/// We are currently asking the user for credentials
AskingCredentials
AskingCredentials,

/// Need to sign terms of service by going to web UI
NeedToSignTermsOfService,
};

/// The actual current connectivity status.
Expand Down Expand Up @@ -192,6 +195,7 @@ public slots:
void hasFetchedNavigationApps();
void statusChanged();
void desktopNotificationsAllowedChanged();
void termsOfServiceChanged(OCC::AccountPtr account);

protected Q_SLOTS:
void slotConnectionValidatorResult(OCC::ConnectionValidator::Status status, const QStringList &errors);
Expand Down
2 changes: 2 additions & 0 deletions src/gui/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ void Application::slotAccountStateAdded(AccountState *accountState)
_gui.data(), &ownCloudGui::slotAccountStateChanged);
connect(accountState->account().data(), &Account::serverVersionChanged,
_gui.data(), &ownCloudGui::slotTrayMessageIfServerUnsupported);
connect(accountState, &AccountState::termsOfServiceChanged,
_gui.data(), &ownCloudGui::slotNeedToAcceptTermsOfService);
connect(accountState, &AccountState::stateChanged,
_folderManager.data(), &FolderMan::slotAccountStateChanged);
connect(accountState->account().data(), &Account::serverVersionChanged,
Expand Down
31 changes: 30 additions & 1 deletion src/gui/connectionvalidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,20 @@ void ConnectionValidator::slotCapabilitiesRecieved(const QJsonDocument &json)
QString directEditingETag = caps["files"].toObject()["directEditing"].toObject()["etag"].toString();
_account->fetchDirectEditors(directEditingURL, directEditingETag);

fetchUser();
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()
Expand Down Expand Up @@ -319,6 +332,22 @@ void ConnectionValidator::slotUserFetched(UserInfo *userInfo)
#endif
}

void ConnectionValidator::slotServerTermsOfServiceRecieved(const QJsonDocument &reply)
{
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;
}
}

fetchUser();
}

#ifndef TOKEN_AUTH_ONLY
void ConnectionValidator::reportConnected() {
reportResult(Connected);
Expand Down
5 changes: 4 additions & 1 deletion src/gui/connectionvalidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ class ConnectionValidator : public QObject
StatusRedirect, // 204 URL received one of redirect HTTP codes (301-307), possibly a captive portal
ServiceUnavailable, // 503 on authed request
MaintenanceMode, // maintenance enabled in status.php
Timeout // actually also used for other errors on the authed request
Timeout, // actually also used for other errors on the authed request
NeedToSignTermsOfService,
};
Q_ENUM(Status);

Expand Down Expand Up @@ -129,13 +130,15 @@ protected slots:

void slotCapabilitiesRecieved(const QJsonDocument &);
void slotUserFetched(OCC::UserInfo *userInfo);
void slotServerTermsOfServiceRecieved(const QJsonDocument &reply);

private:
#ifndef TOKEN_AUTH_ONLY
void reportConnected();
#endif
void reportResult(Status status);
void checkServerCapabilities();
void checkServerTermsOfService();
void fetchUser();

/** Sets the account's server version
Expand Down
6 changes: 6 additions & 0 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ Folder::Folder(const FolderDefinition &definition,
if (!reloadExcludes())
qCWarning(lcFolder, "Could not read system exclude file");

connect(_accountState.data(), &AccountState::termsOfServiceChanged,
this, [this] ()
{
setSyncPaused(_accountState->state() == AccountState::NeedToSignTermsOfService);
});

connect(_accountState.data(), &AccountState::isConnectedChanged, this, &Folder::canSyncChanged);
connect(_engine.data(), &SyncEngine::rootEtag, this, &Folder::etagRetrievedFromSyncEngine);

Expand Down
10 changes: 10 additions & 0 deletions src/gui/owncloudgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,16 @@ void ownCloudGui::slotTrayMessageIfServerUnsupported(Account *account)
}
}

void ownCloudGui::slotNeedToAcceptTermsOfService(OCC::AccountPtr account)
{
slotShowTrayMessage(
tr("Terms of service"),
tr("Your account %1 requires you to accept the terms of service of your server. "
"You will be redirected to %2 to acknowledge that you have read it and agrees with it.")
.arg(account->displayName(), account->url().toString()));
QDesktopServices::openUrl(account->url());
}

void ownCloudGui::slotComputeOverallSyncStatus()
{
bool allSignedOut = true;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/owncloudgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public slots:
void slotOpenPath(const QString &path);
void slotAccountStateChanged();
void slotTrayMessageIfServerUnsupported(OCC::Account *account);

void slotNeedToAcceptTermsOfService(OCC::AccountPtr account);

/**
* Open a share dialog for a file or folder.
Expand Down
1 change: 1 addition & 0 deletions src/libsync/account.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ public slots:
void downloadLimitSettingChanged();
void uploadLimitChanged();
void downloadLimitChanged();
void termsOfServiceNeedToBeChecked();

protected Q_SLOTS:
void slotCredentialsFetched();
Expand Down
4 changes: 4 additions & 0 deletions src/libsync/discoveryphase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,10 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r)
msg = tr("Server error: PROPFIND reply is not XML formatted!");
}

if (r->error() == QNetworkReply::ContentAccessDenied) {
emit _account->termsOfServiceNeedToBeChecked();
}

emit finished(HttpError{ httpCode, msg });
deleteLater();
}
Expand Down

0 comments on commit 788a381

Please sign in to comment.