diff options
Diffstat (limited to 'framework')
-rw-r--r-- | framework/src/domain/composercontroller.cpp | 53 | ||||
-rw-r--r-- | framework/src/domain/mime/mailtemplates.cpp | 45 | ||||
-rw-r--r-- | framework/src/domain/mime/mailtemplates.h | 2 |
3 files changed, 76 insertions, 24 deletions
diff --git a/framework/src/domain/composercontroller.cpp b/framework/src/domain/composercontroller.cpp index fb3857a5..630f9e10 100644 --- a/framework/src/domain/composercontroller.cpp +++ b/framework/src/domain/composercontroller.cpp | |||
@@ -38,6 +38,8 @@ | |||
38 | #include "mime/mailtemplates.h" | 38 | #include "mime/mailtemplates.h" |
39 | #include "mime/mailcrypto.h" | 39 | #include "mime/mailcrypto.h" |
40 | 40 | ||
41 | Q_DECLARE_METATYPE(GpgME::Key); | ||
42 | |||
41 | class IdentitySelector : public Selector { | 43 | class IdentitySelector : public Selector { |
42 | public: | 44 | public: |
43 | IdentitySelector(ComposerController &controller) : Selector(new IdentitiesModel), mController(controller) | 45 | IdentitySelector(ComposerController &controller) : Selector(new IdentitiesModel), mController(controller) |
@@ -105,6 +107,18 @@ public: | |||
105 | item->setData(addressee, ComposerController::AddresseeNameRole); | 107 | item->setData(addressee, ComposerController::AddresseeNameRole); |
106 | item->setData(false, ComposerController::KeyFoundRole); | 108 | item->setData(false, ComposerController::KeyFoundRole); |
107 | appendRow(QList<QStandardItem*>() << item); | 109 | appendRow(QList<QStandardItem*>() << item); |
110 | findKey(addressee, item); | ||
111 | } | ||
112 | |||
113 | void findKey(const QString &addressee, QStandardItem *item) | ||
114 | { | ||
115 | auto keys = MailCrypto::findKeys(QStringList{} << addressee, false, MailCrypto::OPENPGP); | ||
116 | if (item) { | ||
117 | if (!keys.empty()) { | ||
118 | item->setData(true, ComposerController::KeyFoundRole); | ||
119 | item->setData(QVariant::fromValue(keys.front()), ComposerController::KeyRole); | ||
120 | } | ||
121 | } | ||
108 | } | 122 | } |
109 | 123 | ||
110 | void remove(const QString &addressee) | 124 | void remove(const QString &addressee) |
@@ -118,6 +132,30 @@ public: | |||
118 | } | 132 | } |
119 | } | 133 | } |
120 | 134 | ||
135 | bool foundAllKeys() | ||
136 | { | ||
137 | std::vector<GpgME::Key> keys; | ||
138 | auto root = invisibleRootItem(); | ||
139 | for (int row = 0; row < root->rowCount(); row++) { | ||
140 | auto item = root->child(row, 0); | ||
141 | if (!item->data(ComposerController::KeyFoundRole).toBool()) { | ||
142 | return false; | ||
143 | } | ||
144 | } | ||
145 | return true; | ||
146 | } | ||
147 | |||
148 | std::vector<GpgME::Key> getKeys() | ||
149 | { | ||
150 | std::vector<GpgME::Key> keys; | ||
151 | auto root = invisibleRootItem(); | ||
152 | for (int row = 0; row < root->rowCount(); row++) { | ||
153 | auto item = root->child(row, 0); | ||
154 | keys.push_back(item->data(ComposerController::KeyRole).value<GpgME::Key>()); | ||
155 | } | ||
156 | return keys; | ||
157 | } | ||
158 | |||
121 | void setStringList(const QStringList &list) | 159 | void setStringList(const QStringList &list) |
122 | { | 160 | { |
123 | clear(); | 161 | clear(); |
@@ -479,8 +517,21 @@ KMime::Message::Ptr ComposerController::assembleMessage() | |||
479 | if (getSign()) { | 517 | if (getSign()) { |
480 | signingKeys = mPersonalKeys; | 518 | signingKeys = mPersonalKeys; |
481 | } | 519 | } |
520 | std::vector<GpgME::Key> encryptionKeys; | ||
521 | if (getEncrypt()) { | ||
522 | if (!mToModel->foundAllKeys() || !mCcModel->foundAllKeys() || !mBccModel->foundAllKeys()) { | ||
523 | qWarning() << "Can't encrypt with missing keys"; | ||
524 | return nullptr; | ||
525 | } | ||
526 | auto toKeys = mToModel->getKeys(); | ||
527 | encryptionKeys.insert(std::end(encryptionKeys), std::begin(toKeys), std::end(toKeys)); | ||
528 | auto ccKeys = mCcModel->getKeys(); | ||
529 | encryptionKeys.insert(std::end(encryptionKeys), std::begin(ccKeys), std::end(ccKeys)); | ||
530 | auto bccKeys = mBccModel->getKeys(); | ||
531 | encryptionKeys.insert(std::end(encryptionKeys), std::begin(bccKeys), std::end(bccKeys)); | ||
532 | } | ||
482 | 533 | ||
483 | return MailTemplates::createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), getHtmlBody(), attachments, signingKeys); | 534 | return MailTemplates::createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), getHtmlBody(), attachments, signingKeys, encryptionKeys); |
484 | } | 535 | } |
485 | 536 | ||
486 | void ComposerController::updateSendAction() | 537 | void ComposerController::updateSendAction() |
diff --git a/framework/src/domain/mime/mailtemplates.cpp b/framework/src/domain/mime/mailtemplates.cpp index bbe079d8..5f5b35df 100644 --- a/framework/src/domain/mime/mailtemplates.cpp +++ b/framework/src/domain/mime/mailtemplates.cpp | |||
@@ -958,7 +958,7 @@ static KMime::Types::Mailbox::List stringListToMailboxes(const QStringList &list | |||
958 | return mailboxes; | 958 | return mailboxes; |
959 | } | 959 | } |
960 | 960 | ||
961 | KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, const QList<Attachment> &attachments, const std::vector<GpgME::Key> &signingKeys) | 961 | KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, const QList<Attachment> &attachments, const std::vector<GpgME::Key> &signingKeys, const std::vector<GpgME::Key> &encryptionKeys) |
962 | { | 962 | { |
963 | auto mail = existingMessage; | 963 | auto mail = existingMessage; |
964 | if (!mail) { | 964 | if (!mail) { |
@@ -995,41 +995,42 @@ KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMes | |||
995 | } | 995 | } |
996 | mail->assemble(); | 996 | mail->assemble(); |
997 | 997 | ||
998 | KMime::Content *bodyPart; | 998 | std::unique_ptr<KMime::Content> bodyPart{[&] { |
999 | if (!attachments.isEmpty()) { | 999 | if (!attachments.isEmpty()) { |
1000 | bodyPart = new KMime::Content; | 1000 | auto bodyPart = new KMime::Content; |
1001 | bodyPart->contentType(true)->setMimeType("multipart/mixed"); | 1001 | bodyPart->contentType(true)->setMimeType("multipart/mixed"); |
1002 | bodyPart->contentType()->setBoundary(KMime::multiPartBoundary()); | 1002 | bodyPart->contentType()->setBoundary(KMime::multiPartBoundary()); |
1003 | bodyPart->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit); | 1003 | bodyPart->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit); |
1004 | bodyPart->setPreamble("This is a multi-part message in MIME format.\n"); | 1004 | bodyPart->setPreamble("This is a multi-part message in MIME format.\n"); |
1005 | bodyPart->addContent(createBodyPart(body.toUtf8(), htmlBody)); | 1005 | bodyPart->addContent(createBodyPart(body.toUtf8(), htmlBody)); |
1006 | for (const auto &attachment : attachments) { | 1006 | for (const auto &attachment : attachments) { |
1007 | bodyPart->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name)); | 1007 | bodyPart->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name)); |
1008 | } | ||
1009 | return bodyPart; | ||
1010 | } else { | ||
1011 | return createBodyPart(body.toUtf8(), htmlBody); | ||
1008 | } | 1012 | } |
1009 | } else { | 1013 | }()}; |
1010 | bodyPart = createBodyPart(body.toUtf8(), htmlBody); | ||
1011 | } | ||
1012 | bodyPart->assemble(); | 1014 | bodyPart->assemble(); |
1013 | 1015 | ||
1014 | KMime::Content *signedResult = nullptr; | 1016 | QByteArray bodyData; |
1015 | if (!signingKeys.empty()) { | 1017 | if (!signingKeys.empty() || !encryptionKeys.empty()) { |
1016 | signedResult = MailCrypto::sign(bodyPart, signingKeys); | 1018 | auto result = MailCrypto::processCrypto(bodyPart.get(), signingKeys, encryptionKeys, MailCrypto::OPENPGP); |
1017 | if (!signedResult) { | 1019 | if (!result) { |
1018 | qWarning() << "Signing failed"; | 1020 | qWarning() << "Signing failed"; |
1019 | return {}; | 1021 | return {}; |
1020 | } | 1022 | } |
1023 | bodyData = result->encodedContent(); | ||
1021 | } else { | 1024 | } else { |
1022 | if (!bodyPart->contentType(false)) { | 1025 | if (!bodyPart->contentType(false)) { |
1023 | bodyPart->contentType(true)->setMimeType("text/plain"); | 1026 | bodyPart->contentType(true)->setMimeType("text/plain"); |
1024 | bodyPart->assemble(); | 1027 | bodyPart->assemble(); |
1025 | } | 1028 | } |
1029 | bodyData = bodyPart->encodedContent(); | ||
1026 | } | 1030 | } |
1027 | 1031 | ||
1028 | const QByteArray allData = mail->head() + (signedResult ? signedResult->encodedContent() : bodyPart->encodedContent()); | ||
1029 | delete bodyPart; | ||
1030 | KMime::Message::Ptr resultMessage(new KMime::Message); | 1032 | KMime::Message::Ptr resultMessage(new KMime::Message); |
1031 | resultMessage->setContent(allData); | 1033 | resultMessage->setContent(mail->head() + bodyData); |
1032 | resultMessage->parse(); // Not strictly necessary. | 1034 | resultMessage->parse(); // Not strictly necessary. |
1033 | |||
1034 | return resultMessage; | 1035 | return resultMessage; |
1035 | } | 1036 | } |
diff --git a/framework/src/domain/mime/mailtemplates.h b/framework/src/domain/mime/mailtemplates.h index 51db2ba0..21efb5a0 100644 --- a/framework/src/domain/mime/mailtemplates.h +++ b/framework/src/domain/mime/mailtemplates.h | |||
@@ -37,5 +37,5 @@ namespace MailTemplates | |||
37 | void reply(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback, const KMime::Types::AddrSpecList &me = {}); | 37 | void reply(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback, const KMime::Types::AddrSpecList &me = {}); |
38 | QString plaintextContent(const KMime::Message::Ptr &origMsg); | 38 | QString plaintextContent(const KMime::Message::Ptr &origMsg); |
39 | QString body(const KMime::Message::Ptr &msg, bool &isHtml); | 39 | QString body(const KMime::Message::Ptr &msg, bool &isHtml); |
40 | KMime::Message::Ptr createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, const QList<Attachment> &attachments, const std::vector<GpgME::Key> &signingKeys = {}); | 40 | KMime::Message::Ptr createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, const QList<Attachment> &attachments, const std::vector<GpgME::Key> &signingKeys = {}, const std::vector<GpgME::Key> &encryptionKeys = {}); |
41 | }; | 41 | }; |