Implement decryption of images

It is a bit of a hack, but it works...
This commit is contained in:
Nicolas Werner 2019-12-03 23:34:16 +01:00
parent a689118d71
commit 5bfdaff778
6 changed files with 57 additions and 9 deletions

View File

@ -365,6 +365,7 @@ qt5_wrap_cpp(MOC_HEADERS
src/CommunitiesList.h
src/LoginPage.h
src/MainWindow.h
src/MxcImageProvider.h
src/InviteeItem.h
src/QuickSwitcher.h
src/RegisterPage.h

View File

@ -5,7 +5,7 @@
void
MxcImageResponse::run()
{
if (m_requestedSize.isValid()) {
if (m_requestedSize.isValid() && !m_encryptionInfo) {
QString fileName = QString("%1_%2x%3_crop")
.arg(m_id)
.arg(m_requestedSize.width())
@ -65,7 +65,12 @@ MxcImageResponse::run()
return;
}
auto data = QByteArray(res.data(), res.size());
auto temp = res;
if (m_encryptionInfo)
temp = mtx::crypto::to_string(
mtx::crypto::decrypt_file(temp, m_encryptionInfo.value()));
auto data = QByteArray(temp.data(), temp.size());
m_image.loadFromData(data);
m_image.setText("original filename",
QString::fromStdString(originalFilename));

View File

@ -6,14 +6,21 @@
#include <QImage>
#include <QThreadPool>
#include <mtx/common.hpp>
#include <boost/optional.hpp>
class MxcImageResponse
: public QQuickImageResponse
, public QRunnable
{
public:
MxcImageResponse(const QString &id, const QSize &requestedSize)
MxcImageResponse(const QString &id,
const QSize &requestedSize,
boost::optional<mtx::crypto::EncryptedFile> encryptionInfo)
: m_id(id)
, m_requestedSize(requestedSize)
, m_encryptionInfo(encryptionInfo)
{
setAutoDelete(false);
}
@ -29,19 +36,34 @@ public:
QString m_id, m_error;
QSize m_requestedSize;
QImage m_image;
boost::optional<mtx::crypto::EncryptedFile> m_encryptionInfo;
};
class MxcImageProvider : public QQuickAsyncImageProvider
class MxcImageProvider
: public QObject
, public QQuickAsyncImageProvider
{
public:
Q_OBJECT
public slots:
QQuickImageResponse *requestImageResponse(const QString &id,
const QSize &requestedSize) override
{
MxcImageResponse *response = new MxcImageResponse(id, requestedSize);
boost::optional<mtx::crypto::EncryptedFile> info;
auto temp = infos.find("mxc://" + id);
if (temp != infos.end())
info = *temp;
MxcImageResponse *response = new MxcImageResponse(id, requestedSize, info);
pool.start(response);
return response;
}
void addEncryptionInfo(mtx::crypto::EncryptedFile info)
{
infos.insert(QString::fromStdString(info.url), info);
}
private:
QThreadPool pool;
QHash<QString, mtx::crypto::EncryptedFile> infos;
};

View File

@ -673,6 +673,19 @@ TimelineModel::internalAddEvents(
continue; // don't insert redaction into timeline
}
if (auto event =
boost::get<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(&e)) {
auto temp = decryptEvent(*event).event;
auto encInfo = boost::apply_visitor(
[](const auto &ev) -> boost::optional<mtx::crypto::EncryptedFile> {
return eventEncryptionInfo(ev);
},
temp);
if (encInfo)
emit newEncryptedImage(encInfo.value());
}
this->events.insert(id, e);
ids.push_back(id);
}

View File

@ -6,6 +6,7 @@
#include <QHash>
#include <QSet>
#include <mtx/common.hpp>
#include <mtx/responses.hpp>
#include "Cache.h"
@ -188,6 +189,7 @@ signals:
void nextPendingMessage();
void newMessageToSend(mtx::events::collections::TimelineEvents event);
void mediaCached(QString mxcUrl, QString cacheUrl);
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
private:
DecryptionResult decryptEvent(

View File

@ -102,9 +102,14 @@ TimelineViewManager::sync(const mtx::responses::Rooms &rooms)
void
TimelineViewManager::addRoom(const QString &room_id)
{
if (!models.contains(room_id))
models.insert(room_id,
QSharedPointer<TimelineModel>(new TimelineModel(this, room_id)));
if (!models.contains(room_id)) {
QSharedPointer<TimelineModel> newRoom(new TimelineModel(this, room_id));
connect(newRoom.data(),
&TimelineModel::newEncryptedImage,
imgProvider,
&MxcImageProvider::addEncryptionInfo);
models.insert(room_id, std::move(newRoom));
}
}
void