#include <QMessageBox>
#include <QDesktopServices>
#include <QGuiApplication>
+#include <QUrlQuery>
class QSocket;
// for a sample URL "nc://open/admin@nextcloud.lan:8080/Photos/lovely.jpg", QUrl::path would return "admin@nextcloud.lan:8080/Photos/lovely.jpg"
const auto accountDisplayName = pathSplit.takeFirst();
const auto fileRemotePath = pathSplit.join('/');
+ const auto urlQuery = QUrlQuery{url};
- FolderMan::instance()->editFileLocally(accountDisplayName, fileRemotePath);
+ auto token = QString{};
+ if (urlQuery.hasQueryItem(QStringLiteral("token"))) {
+ token = urlQuery.queryItemValue(QStringLiteral("token"));
+ } else {
+ qCWarning(lcApplication) << "Invalid URL for file local editing: missing token";
+ }
+
+ FolderMan::instance()->editFileLocally(accountDisplayName, fileRemotePath, token);
}
QString substLang(const QString &lang)
}
}
-void FolderMan::editFileLocally(const QString &accountDisplayName, const QString &relPath)
+void FolderMan::editFileLocally(const QString &accountDisplayName, const QString &relPath, const QString &token)
{
const auto showError = [this](const OCC::AccountStatePtr accountState, const QString &errorMessage, const QString &subject) {
if (accountState && accountState->account()) {
messageBox->raise();
};
+ if (token.isEmpty()) {
+ qCWarning(lcFolderMan) << "Edit locally request is missing a valid token. Impossible to open the file.";
+ showError({}, tr("Edit locally request is not valid. Opening the file is forbidden."), accountDisplayName);
+ return;
+ }
+
const auto accountFound = AccountManager::instance()->account(accountDisplayName);
if (!accountFound) {
showError(accountFound, tr("Could not find a file for local editing. Make sure its path is valid and it is synced locally."), relPath);
return;
}
- folderForFile->startSync();
- _localFileEditingSyncFinishedConnections.insert(localFilePath, QObject::connect(folderForFile, &Folder::syncFinished, this,
- [this, localFilePath](const OCC::SyncResult &result) {
- Q_UNUSED(result);
- const auto foundConnectionIt = _localFileEditingSyncFinishedConnections.find(localFilePath);
- if (foundConnectionIt != std::end(_localFileEditingSyncFinishedConnections) && foundConnectionIt.value()) {
- QObject::disconnect(foundConnectionIt.value());
- _localFileEditingSyncFinishedConnections.erase(foundConnectionIt);
- }
- // In case the VFS mode is enabled and a file is not yet hydrated, we must call QDesktopServices::openUrl
- // from a separate thread, or, there will be a freeze. To avoid searching for a specific folder and checking
- // if the VFS is enabled - we just always call it from a separate thread.
- QtConcurrent::run([localFilePath]() {
- QDesktopServices::openUrl(QUrl::fromLocalFile(localFilePath));
+
+ const auto checkTokenForEditLocally = new SimpleApiJob(accountFound->account(), QStringLiteral("/ocs/v2.php/apps/files/api/v1/openlocaleditor/%1").arg(token));
+ checkTokenForEditLocally->setVerb(SimpleApiJob::Verb::Post);
+ checkTokenForEditLocally->setBody(QByteArray{"path=/"}.append(relPath.toUtf8()));
+ connect(checkTokenForEditLocally, &SimpleApiJob::resultReceived, checkTokenForEditLocally, [this, folderForFile, localFilePath, showError, accountFound, relPath] (int statusCode) {
+ constexpr auto HTTP_OK_CODE = 200;
+ if (statusCode != HTTP_OK_CODE) {
Systray::instance()->destroyEditFileLocallyLoadingDialog();
- });
- }));
+ showError(accountFound, tr("Could not validate the request to open a file from server."), relPath);
+ qCInfo(lcFolderMan()) << "token check result" << statusCode;
+ return;
+ }
+
+ folderForFile->startSync();
+ _localFileEditingSyncFinishedConnections.insert(localFilePath, QObject::connect(folderForFile, &Folder::syncFinished, this,
+ [this, localFilePath](const OCC::SyncResult &result) {
+ Q_UNUSED(result);
+ const auto foundConnectionIt = _localFileEditingSyncFinishedConnections.find(localFilePath);
+ if (foundConnectionIt != std::end(_localFileEditingSyncFinishedConnections) && foundConnectionIt.value()) {
+ QObject::disconnect(foundConnectionIt.value());
+ _localFileEditingSyncFinishedConnections.erase(foundConnectionIt);
+ }
+ // In case the VFS mode is enabled and a file is not yet hydrated, we must call QDesktopServices::openUrl
+ // from a separate thread, or, there will be a freeze. To avoid searching for a specific folder and checking
+ // if the VFS is enabled - we just always call it from a separate thread.
+ QtConcurrent::run([localFilePath]() {
+ QDesktopServices::openUrl(QUrl::fromLocalFile(localFilePath));
+ Systray::instance()->destroyEditFileLocallyLoadingDialog();
+ });
+ }));
+ });
+ checkTokenForEditLocally->start();
}
void FolderMan::trayOverallStatus(const QList<Folder *> &folders,