mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
edit locally requires a valid token
check on server that the token received during a request to open a local file is indeed a valid one Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
parent
615c02e3d3
commit
f9949ee0de
@ -61,6 +61,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QGuiApplication>
|
||||
#include <QUrlQuery>
|
||||
|
||||
class QSocket;
|
||||
|
||||
@ -764,8 +765,16 @@ void Application::handleEditLocally(const QUrl &url) const
|
||||
// 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)
|
||||
|
||||
@ -1422,7 +1422,7 @@ void FolderMan::setDirtyNetworkLimits()
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
@ -1447,6 +1447,12 @@ void FolderMan::editFileLocally(const QString &accountDisplayName, const QString
|
||||
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) {
|
||||
@ -1488,23 +1494,38 @@ void FolderMan::editFileLocally(const QString &accountDisplayName, const QString
|
||||
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,
|
||||
|
||||
@ -214,7 +214,7 @@ public:
|
||||
void setDirtyNetworkLimits();
|
||||
|
||||
/** opens a file with default app, if the file is present **/
|
||||
void editFileLocally(const QString &accountDisplayName, const QString &relPath);
|
||||
void editFileLocally(const QString &accountDisplayName, const QString &relPath, const QString &token);
|
||||
|
||||
signals:
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user