[CSE] Add job to find what folders are encrypted.

This still needs to be correctly setuped in the call chain.
The job returns a QVariantMap with the folder-webdav-url
and the encrypted status.
This commit is contained in:
Tomaz Canabrava 2017-11-20 21:38:17 +01:00
parent 34e6534813
commit d31aa7836a
4 changed files with 139 additions and 0 deletions

View file

@ -360,6 +360,11 @@ void AccountSettings::slotSubfolderContextMenuRequested(const QModelIndex& index
slotMarkSubfolderDecrypted(fileId);
});
ac = menu.addAction(tr("Fetch Enc"));
connect(ac, &QAction::triggered, [this]{
accountsState()->account()->e2e().fetchFolderEncryptedStatus();
});
}
menu.exec(QCursor::pos());
}

View file

@ -18,6 +18,9 @@
#include <QFileInfo>
#include <QDir>
#include <QJsonObject>
#include <QXmlStreamReader>
#include <QXmlStreamNamespaceDeclaration>
#include <QStack>
#include "wordlist.h"
@ -544,6 +547,23 @@ void ClientSideEncryption::getPublicKeyFromServer()
job->start();
}
void ClientSideEncryption::fetchFolderEncryptedStatus() {
auto getEncryptedStatus = new GetFolderEncryptStatus(_account);
getEncryptedStatus ->start();
}
void ClientSideEncryption::folderEncryptedStatusFetched(const QVariantMap& result)
{
qDebug() << "Retrieved correctly the encrypted status of the folders." << result;
}
void ClientSideEncryption::folderEncryptedStatusError(QNetworkReply *reply)
{
qDebug() << "Failed to retrieve the status of the folders.";
if (reply) {
qDebug() << reply->errorString();
}
}
SignPublicKeyApiJob::SignPublicKeyApiJob(const AccountPtr& account, const QString& path, QObject* parent)
: AbstractNetworkJob(account, path, parent)
@ -1165,4 +1185,85 @@ bool GetMetadataApiJob::finished()
emit jsonReceived(json, reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
return true;
}
GetFolderEncryptStatus::GetFolderEncryptStatus(const AccountPtr& account, QObject *parent)
: OCC::AbstractNetworkJob(account, QStringLiteral("remote.php/webdav"), parent)
{
}
void GetFolderEncryptStatus::start()
{
QNetworkRequest req;
req.setPriority(QNetworkRequest::HighPriority);
req.setRawHeader("OCS-APIREQUEST", "true");
req.setRawHeader("Content-Type", "application/xml");
QByteArray xml = "<d:propfind xmlns:d=\"DAV:\"> <d:prop xmlns:nc=\"http://nextcloud.org/ns\"> <nc:is-encrypted/> </d:prop> </d:propfind>";
QBuffer *buf = new QBuffer(this);
buf->setData(xml);
buf->open(QIODevice::ReadOnly);
sendRequest("PROPFIND", Utility::concatUrlPath(account()->url(), path()), req, buf);
AbstractNetworkJob::start();
}
bool GetFolderEncryptStatus::finished()
{
qCInfo(lcCse()) << "GetFolderEncryptStatus of" << reply()->request().url() << "finished with status"
<< reply()->error()
<< (reply()->error() == QNetworkReply::NoError ? QLatin1String("") : errorString());
int http_result_code = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (http_result_code == 207) {
// Parse DAV response
QXmlStreamReader reader(reply());
reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:"));
/* Example Xml
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
<d:response>
<d:href>/remote.php/webdav/</d:href>
<d:propstat>
<d:prop>
<nc:is-encrypted>0</nc:is-encrypted>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
*/
QString currFile;
int currEncryptedStatus = -1;
QMap<QString, bool> folderStatus;
while (!reader.atEnd()) {
auto type = reader.readNext();
if (type == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("href")) {
currFile = reader.readElementText(QXmlStreamReader::SkipChildElements);
}
if (reader.name() == QLatin1String("is-encrypted")) {
currEncryptedStatus = (bool) reader.readElementText(QXmlStreamReader::SkipChildElements).toInt();
}
}
if (!currFile.isEmpty() && currEncryptedStatus != -1) {
folderStatus.insert(currFile, currEncryptedStatus);
currFile.clear();
currEncryptedStatus = -1;
}
}
emit encryptStatusReceived(folderStatus);
} else {
qCWarning(lcCse()) << "*not* successful, http result code is" << http_result_code
<< (http_result_code == 302 ? reply()->header(QNetworkRequest::LocationHeader).toString() : QLatin1String(""));
emit encryptStatusError(http_result_code);
// emit finishedWithError(reply());
}
return true;
}
}

View file

@ -37,13 +37,25 @@ public:
void setTokenForFolder(const QByteArray& folder, const QByteArray& token);
QByteArray tokenForFolder(const QByteArray& folder) const;
//TODO: Perhaps mode this to FolderStatusModel
// (as it makes sense, but it increase the chance
// of conflicts).
void fetchFolderEncryptedStatus();
private slots:
void folderEncryptedStatusFetched(const QVariantMap &values);
void folderEncryptedStatusError(QNetworkReply *reply = 0);
signals:
void initializationFinished();
private:
OCC::AccountPtr _account;
bool isInitialized = false;
//TODO: Save this on disk.
QMap<QByteArray, QByteArray> _folder2token;
QMap<QByteArray, bool> _folder2encryptedStatus;
};
/*
@ -297,5 +309,25 @@ private:
QByteArray _fileId;
};
/* I cant use the propfind network job because it defaults to the
* wrong dav url.
*/
class OWNCLOUDSYNC_EXPORT GetFolderEncryptStatus : public AbstractNetworkJob
{
Q_OBJECT
public:
explicit GetFolderEncryptStatus (const AccountPtr &account, QObject *parent = 0);
public slots:
void start() override;
protected:
bool finished() override;
signals:
void encryptStatusReceived(const QMap<QByteArray, bool> folderMetadata2EncryptionStatus);
void encryptStatusError(int statusCode);
};
} // namespace OCC
#endif

View file

@ -567,6 +567,7 @@ void PropfindJob::start()
buf->setData(xml);
buf->open(QIODevice::ReadOnly);
sendRequest("PROPFIND", makeDavUrl(path()), req, buf);
AbstractNetworkJob::start();
}