detect the terms of service app is requiring the user to sign them

will query the sign state for the terms of service and automatically
pause or resume sync

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
Matthieu Gallien 2024-10-21 18:25:36 +02:00
Родитель ca516af4d4
Коммит 8ddf11d960
9 изменённых файлов: 72 добавлений и 4 удалений

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

@ -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.

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

@ -159,6 +159,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");
}
@ -346,6 +348,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
@ -424,6 +432,9 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
setState(NetworkError);
updateRetryCount();
break;
case ConnectionValidator::NeedToSignTermsOfService:
setState(NeedToSignTermsOfService);
break;
}
}

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

@ -82,7 +82,10 @@ public:
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.
@ -192,6 +195,7 @@ signals:
void hasFetchedNavigationApps();
void statusChanged();
void desktopNotificationsAllowedChanged();
void termsOfServiceChanged(OCC::AccountPtr account);
protected Q_SLOTS:
void slotConnectionValidatorResult(OCC::ConnectionValidator::Status status, const QStringList &errors);

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

@ -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,

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

@ -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()
@ -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);

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

@ -95,7 +95,8 @@ public:
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);
@ -129,6 +130,7 @@ protected slots:
void slotCapabilitiesRecieved(const QJsonDocument &);
void slotUserFetched(OCC::UserInfo *userInfo);
void slotServerTermsOfServiceRecieved(const QJsonDocument &reply);
private:
#ifndef TOKEN_AUTH_ONLY
@ -136,6 +138,7 @@ private:
#endif
void reportResult(Status status);
void checkServerCapabilities();
void checkServerTermsOfService();
void fetchUser();
/** Sets the account's server version

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

@ -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);

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

@ -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;

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

@ -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.