diff --git a/src/core/bodypartformatter_impl.cpp b/src/core/bodypartformatter_impl.cpp index a52486f..df8941f 100644 --- a/src/core/bodypartformatter_impl.cpp +++ b/src/core/bodypartformatter_impl.cpp @@ -1,362 +1,362 @@ // SPDX-FileCopyrightText: 2003 Marc Mutz // SPDX-License-Identifier: GPL-2.0-only #include "mimetreeparser_core_debug.h" #include "bodypartformatter.h" #include "bodypartformatterbasefactory.h" #include "bodypartformatterbasefactory_p.h" #include "messagepart.h" #include "objecttreeparser.h" #include "utils.h" #include #include using namespace MimeTreeParser; using namespace MimeTreeParser::Interface; namespace MimeTreeParser { class AnyTypeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { }; class MessageRfc822BodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { return MessagePart::Ptr(new EncapsulatedRfc822MessagePart(objectTreeParser, node, node->bodyAsMessage())); } }; class HeadersBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { return MessagePart::Ptr(new HeadersPart(objectTreeParser, node)); } }; class MultiPartRelatedBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - QList processList(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + QList processList(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (node->contents().isEmpty()) { return {}; } // We rely on the order of the parts. // Theoretically there could also be a Start parameter which would break this.. // https://tools.ietf.org/html/rfc2387#section-4 // We want to display attachments even if displayed inline. QList list; list.append(MimeMessagePart::Ptr(new MimeMessagePart(objectTreeParser, node->contents().at(0), true))); for (int i = 1; i < node->contents().size(); i++) { auto p = node->contents().at(i); if (KMime::isAttachment(p)) { list.append(MimeMessagePart::Ptr(new MimeMessagePart(objectTreeParser, p, true))); } } return list; } }; class MultiPartMixedBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { const auto contents = node->contents(); if (contents.isEmpty()) { return {}; } // we need the intermediate part to preserve the headers (necessary for with protected headers using multipart mixed) auto part = MessagePart::Ptr(new MessagePart(objectTreeParser, {}, node)); part->appendSubPart(MimeMessagePart::Ptr(new MimeMessagePart(objectTreeParser, contents.at(0), false))); return part; } }; class ApplicationPGPEncryptedBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (node->decodedContent().trimmed() != "Version: 1") { qCWarning(MIMETREEPARSER_CORE_LOG) << "Unknown PGP Version String:" << node->decodedContent().trimmed(); } if (!node->parent()) { return MessagePart::Ptr(); } KMime::Content *data = findTypeInDirectChildren(node->parent(), "application/octet-stream"); if (!data) { return MessagePart::Ptr(); // new MimeMessagePart(objectTreeParser, node)); } EncryptedMessagePart::Ptr mp(new EncryptedMessagePart(objectTreeParser, data->decodedText(), QGpgME::openpgp(), node, data)); mp->setIsEncrypted(true); return mp; } }; class ApplicationPkcs7MimeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (node->head().isEmpty()) { return MessagePart::Ptr(); } const QString smimeType = node->contentType()->parameter(QStringLiteral("smime-type")).toLower(); if (smimeType == QLatin1StringView("certs-only")) { return CertMessagePart::Ptr(new CertMessagePart(objectTreeParser, node, QGpgME::smime())); } bool isSigned = (smimeType == QLatin1StringView("signed-data")); bool isEncrypted = (smimeType == QLatin1StringView("enveloped-data")); // Analyze "signTestNode" node to find/verify a signature. // If zero part.objectTreeParser verification was successfully done after // decrypting via recursion by insertAndParseNewChildNode(). KMime::Content *signTestNode = isEncrypted ? nullptr : node; // We try decrypting the content // if we either *know* that it is an encrypted message part // or there is neither signed nor encrypted parameter. MessagePart::Ptr mp; if (!isSigned) { if (isEncrypted) { qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime == S/MIME TYPE: enveloped (encrypted) data"; } else { qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime - type unknown - enveloped (encrypted) data ?"; } auto _mp = EncryptedMessagePart::Ptr(new EncryptedMessagePart(objectTreeParser, node->decodedText(), QGpgME::smime(), node)); mp = _mp; _mp->setIsEncrypted(true); // PartMetaData *messagePart(_mp->partMetaData()); // if (!part.source()->decryptMessage()) { // isEncrypted = true; signTestNode = nullptr; // PENDING(marc) to be abs. sure, we'd need to have to look at the content // } else { // _mp->startDecryption(); // if (messagePart->isDecryptable) { // qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime - encryption found - enveloped (encrypted) data !"; // isEncrypted = true; // part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted); // signTestNode = nullptr; // } else { // // decryption failed, which could be because the part was encrypted but // // decryption failed, or because we didn't know if it was encrypted, tried, // // and failed. If the message was not actually encrypted, we continue // // assuming it's signed // if (_mp->passphraseError() || (smimeType.isEmpty() && messagePart->isEncrypted)) { // isEncrypted = true; // signTestNode = nullptr; // } // if (isEncrypted) { // qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime - ERROR: COULD NOT DECRYPT enveloped data !"; // } else { // qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime - NO encryption found"; // } // } // } } // We now try signature verification if necessarry. if (signTestNode) { if (isSigned) { qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime == S/MIME TYPE: opaque signed data"; } else { qCDebug(MIMETREEPARSER_CORE_LOG) << "pkcs7 mime - type unknown - opaque signed data ?"; } return SignedMessagePart::Ptr(new SignedMessagePart(objectTreeParser, QGpgME::smime(), nullptr, signTestNode)); } return mp; } }; class MultiPartAlternativeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (node->contents().isEmpty()) { return MessagePart::Ptr(); } AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(objectTreeParser, node)); if (mp->mChildParts.isEmpty()) { return MimeMessagePart::Ptr(new MimeMessagePart(objectTreeParser, node->contents().at(0))); } return mp; } }; class MultiPartEncryptedBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (node->contents().isEmpty()) { Q_ASSERT(false); return MessagePart::Ptr(); } const QGpgME::Protocol *protocol = nullptr; /* ATTENTION: This code is to be replaced by the new 'auto-detect' feature. -------------------------------------- */ KMime::Content *data = findTypeInDirectChildren(node, "application/octet-stream"); if (data) { protocol = QGpgME::openpgp(); } else { data = findTypeInDirectChildren(node, "application/pkcs7-mime"); if (data) { protocol = QGpgME::smime(); } } /* --------------------------------------------------------------------------------------------------------------- */ if (!data) { return MessagePart::Ptr(new MimeMessagePart(objectTreeParser, node->contents().at(0))); } EncryptedMessagePart::Ptr mp(new EncryptedMessagePart(objectTreeParser, data->decodedText(), protocol, node, data)); mp->setIsEncrypted(true); return mp; } }; class MultiPartSignedBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: static const QGpgME::Protocol *detectProtocol(const QString &protocolContentType_, const QString &signatureContentType) { auto protocolContentType = protocolContentType_; if (protocolContentType.isEmpty()) { qCWarning(MIMETREEPARSER_CORE_LOG) << "Message doesn't set the protocol for the multipart/signed content-type, " "using content-type of the signature:" << signatureContentType; protocolContentType = signatureContentType; } const QGpgME::Protocol *protocol = nullptr; if (protocolContentType == QLatin1StringView("application/pkcs7-signature") || protocolContentType == QLatin1StringView("application/x-pkcs7-signature")) { protocol = QGpgME::smime(); } else if (protocolContentType == QLatin1StringView("application/pgp-signature") || protocolContentType == QLatin1StringView("application/x-pgp-signature")) { protocol = QGpgME::openpgp(); } return protocol; } - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (node->contents().size() != 2) { qCDebug(MIMETREEPARSER_CORE_LOG) << "mulitpart/signed must have exactly two child parts!" << Qt::endl << "processing as multipart/mixed"; if (!node->contents().isEmpty()) { return MessagePart::Ptr(new MimeMessagePart(objectTreeParser, node->contents().at(0))); } else { return MessagePart::Ptr(); } } KMime::Content *signedData = node->contents().at(0); KMime::Content *signature = node->contents().at(1); Q_ASSERT(signedData); Q_ASSERT(signature); auto protocol = detectProtocol(node->contentType()->parameter(QStringLiteral("protocol")).toLower(), QLatin1StringView(signature->contentType()->mimeType().toLower())); if (!protocol) { return MessagePart::Ptr(new MimeMessagePart(objectTreeParser, signedData)); } return SignedMessagePart::Ptr(new SignedMessagePart(objectTreeParser, protocol, signature, signedData)); } }; class TextHtmlBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { return HtmlMessagePart::Ptr(new HtmlMessagePart(objectTreeParser, node)); } }; class TextPlainBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter { public: - MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const Q_DECL_OVERRIDE + MessagePart::Ptr process(ObjectTreeParser *objectTreeParser, KMime::Content *node) const override { if (KMime::isAttachment(node)) { return AttachmentMessagePart::Ptr(new AttachmentMessagePart(objectTreeParser, node)); } return TextMessagePart::Ptr(new TextMessagePart(objectTreeParser, node)); } }; } // anon namespace void BodyPartFormatterBaseFactoryPrivate::messageviewer_create_builtin_bodypart_formatters() { auto any = new AnyTypeBodyPartFormatter; auto textPlain = new TextPlainBodyPartFormatter; auto pkcs7 = new ApplicationPkcs7MimeBodyPartFormatter; auto pgp = new ApplicationPGPEncryptedBodyPartFormatter; auto html = new TextHtmlBodyPartFormatter; auto headers = new HeadersBodyPartFormatter; auto multipartAlternative = new MultiPartAlternativeBodyPartFormatter; auto multipartMixed = new MultiPartMixedBodyPartFormatter; auto multipartSigned = new MultiPartSignedBodyPartFormatter; auto multipartEncrypted = new MultiPartEncryptedBodyPartFormatter; auto message = new MessageRfc822BodyPartFormatter; auto multipartRelated = new MultiPartRelatedBodyPartFormatter; insert("application", "octet-stream", any); insert("application", "pgp", textPlain); insert("application", "pkcs7-mime", pkcs7); insert("application", "x-pkcs7-mime", pkcs7); insert("application", "pgp-encrypted", pgp); insert("application", "*", any); insert("text", "html", html); insert("text", "rtf", any); insert("text", "plain", textPlain); insert("text", "rfc822-headers", headers); insert("text", "*", textPlain); insert("image", "*", any); insert("message", "rfc822", message); insert("message", "*", any); insert("multipart", "alternative", multipartAlternative); insert("multipart", "encrypted", multipartEncrypted); insert("multipart", "signed", multipartSigned); insert("multipart", "related", multipartRelated); insert("multipart", "*", multipartMixed); insert("*", "*", any); } diff --git a/src/core/messagepart.h b/src/core/messagepart.h index 7c11165..27d2d48 100644 --- a/src/core/messagepart.h +++ b/src/core/messagepart.h @@ -1,376 +1,376 @@ // SPDX-FileCopyrightText: 2015 Sandro Knauß // SPDX-License-Identifier: LGPL-2.0-or-later #pragma once #include "mimetreeparser_core_export.h" #include "partmetadata.h" #include #include #include #include #include #include #include namespace KMime { class Content; } namespace QGpgME { class Protocol; } namespace MimeTreeParser { /** Flags for the encryption state. */ typedef enum { KMMsgEncryptionStateUnknown, KMMsgNotEncrypted, KMMsgPartiallyEncrypted, KMMsgFullyEncrypted, KMMsgEncryptionProblematic } KMMsgEncryptionState; /** Flags for the signature state. */ typedef enum { KMMsgSignatureStateUnknown, KMMsgNotSigned, KMMsgPartiallySigned, KMMsgFullySigned, KMMsgSignatureProblematic } KMMsgSignatureState; class ObjectTreeParser; class MultiPartAlternativeBodyPartFormatter; class SignedMessagePart; class EncryptedMessagePart; class MIMETREEPARSER_CORE_EXPORT MessagePart : public QObject { Q_OBJECT Q_PROPERTY(bool attachment READ isAttachment CONSTANT) Q_PROPERTY(bool root READ isRoot CONSTANT) Q_PROPERTY(bool isHtml READ isHtml CONSTANT) Q_PROPERTY(QString plaintextContent READ plaintextContent CONSTANT) Q_PROPERTY(QString htmlContent READ htmlContent CONSTANT) public: enum Disposition { Inline, Attachment, Invalid }; using Ptr = QSharedPointer; using List = QList; MessagePart(ObjectTreeParser *otp, const QString &text, KMime::Content *node = nullptr); virtual ~MessagePart(); [[nodiscard]] virtual QString text() const; void setText(const QString &text); virtual bool isAttachment() const; void setIsRoot(bool root); [[nodiscard]] bool isRoot() const; void setParentPart(MessagePart *parentPart); MessagePart *parentPart() const; [[nodiscard]] virtual QString plaintextContent() const; [[nodiscard]] virtual QString htmlContent() const; [[nodiscard]] virtual bool isHtml() const; [[nodiscard]] QByteArray mimeType() const; [[nodiscard]] QByteArray charset() const; [[nodiscard]] QString filename() const; [[nodiscard]] Disposition disposition() const; [[nodiscard]] bool isText() const; enum Error { NoError = 0, PassphraseError, NoKeyError, UnknownError, }; [[nodiscard]] Error error() const; [[nodiscard]] QString errorString() const; PartMetaData *partMetaData(); void appendSubPart(const MessagePart::Ptr &messagePart); const QList &subParts() const; [[nodiscard]] bool hasSubParts() const; KMime::Content *node() const; virtual KMMsgSignatureState signatureState() const; virtual KMMsgEncryptionState encryptionState() const; [[nodiscard]] QList signatures() const; [[nodiscard]] QList encryptions() const; /** * Retrieve the header @header in this part or any parent parent. * * Useful for MemoryHole support. */ KMime::Headers::Base *header(const char *header) const; void bindLifetime(KMime::Content *); protected: void parseInternal(KMime::Content *node, bool onlyOneMimePart = false); void parseInternal(const QByteArray &data); [[nodiscard]] QString renderInternalText() const; QString mText; ObjectTreeParser *mOtp; PartMetaData mMetaData; MessagePart *mParentPart; KMime::Content *mNode; QList mNodesToDelete; Error mError; private: QList mBlocks; bool mRoot; }; class MIMETREEPARSER_CORE_EXPORT MimeMessagePart : public MessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; MimeMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node, bool onlyOneMimePart = false); virtual ~MimeMessagePart(); - [[nodiscard]] QString text() const Q_DECL_OVERRIDE; + [[nodiscard]] QString text() const override; - [[nodiscard]] QString plaintextContent() const Q_DECL_OVERRIDE; - [[nodiscard]] QString htmlContent() const Q_DECL_OVERRIDE; + [[nodiscard]] QString plaintextContent() const override; + [[nodiscard]] QString htmlContent() const override; private: friend class AlternativeMessagePart; }; class MIMETREEPARSER_CORE_EXPORT MessagePartList : public MessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; MessagePartList(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); virtual ~MessagePartList() = default; - [[nodiscard]] QString text() const Q_DECL_OVERRIDE; + [[nodiscard]] QString text() const override; - [[nodiscard]] QString plaintextContent() const Q_DECL_OVERRIDE; - [[nodiscard]] QString htmlContent() const Q_DECL_OVERRIDE; + [[nodiscard]] QString plaintextContent() const override; + [[nodiscard]] QString htmlContent() const override; }; class MIMETREEPARSER_CORE_EXPORT TextMessagePart : public MessagePartList { Q_OBJECT public: typedef QSharedPointer Ptr; TextMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); virtual ~TextMessagePart() = default; - [[nodiscard]] KMMsgSignatureState signatureState() const Q_DECL_OVERRIDE; - [[nodiscard]] KMMsgEncryptionState encryptionState() const Q_DECL_OVERRIDE; + [[nodiscard]] KMMsgSignatureState signatureState() const override; + [[nodiscard]] KMMsgEncryptionState encryptionState() const override; private: void parseContent(); KMMsgSignatureState mSignatureState; KMMsgEncryptionState mEncryptionState; friend class ObjectTreeParser; }; class MIMETREEPARSER_CORE_EXPORT AttachmentMessagePart : public TextMessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; AttachmentMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); virtual ~AttachmentMessagePart() = default; - [[nodiscard]] virtual bool isAttachment() const Q_DECL_OVERRIDE + [[nodiscard]] virtual bool isAttachment() const override { return true; } }; class MIMETREEPARSER_CORE_EXPORT HtmlMessagePart : public MessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; HtmlMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); virtual ~HtmlMessagePart() = default; - [[nodiscard]] bool isHtml() const Q_DECL_OVERRIDE + [[nodiscard]] bool isHtml() const override { return true; }; }; class MIMETREEPARSER_CORE_EXPORT AlternativeMessagePart : public MessagePart { Q_OBJECT public: enum HtmlMode { Normal, ///< A normal plaintext message, non-multipart Html, ///< A HTML message, non-multipart MultipartPlain, ///< A multipart/alternative message, the plain text part is currently displayed MultipartHtml, ///< A multipart/altervative message, the HTML part is currently displayed MultipartIcal ///< A multipart/altervative message, the ICal part is currently displayed }; typedef QSharedPointer Ptr; AlternativeMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); virtual ~AlternativeMessagePart(); - [[nodiscard]] QString text() const Q_DECL_OVERRIDE; + [[nodiscard]] QString text() const override; - [[nodiscard]] bool isHtml() const Q_DECL_OVERRIDE; + [[nodiscard]] bool isHtml() const override; - [[nodiscard]] QString plaintextContent() const Q_DECL_OVERRIDE; - [[nodiscard]] QString htmlContent() const Q_DECL_OVERRIDE; + [[nodiscard]] QString plaintextContent() const override; + [[nodiscard]] QString htmlContent() const override; [[nodiscard]] QString icalContent() const; [[nodiscard]] QList availableModes(); private: QMap mChildParts; friend class ObjectTreeParser; friend class MultiPartAlternativeBodyPartFormatter; }; class MIMETREEPARSER_CORE_EXPORT CertMessagePart : public MessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; CertMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node, QGpgME::Protocol *cryptoProto); virtual ~CertMessagePart(); - [[nodiscard]] QString text() const Q_DECL_OVERRIDE; + [[nodiscard]] QString text() const override; private: const QGpgME::Protocol *mCryptoProto; GpgME::ImportResult mInportResult; }; class MIMETREEPARSER_CORE_EXPORT EncapsulatedRfc822MessagePart : public MessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; EncapsulatedRfc822MessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node, const KMime::Message::Ptr &message); virtual ~EncapsulatedRfc822MessagePart() = default; - [[nodiscard]] QString text() const Q_DECL_OVERRIDE; + [[nodiscard]] QString text() const override; [[nodiscard]] QString from() const; [[nodiscard]] QDateTime date() const; private: const KMime::Message::Ptr mMessage; }; class MIMETREEPARSER_CORE_EXPORT EncryptedMessagePart : public MessagePart { Q_OBJECT Q_PROPERTY(bool decryptMessage READ decryptMessage WRITE setDecryptMessage) Q_PROPERTY(bool isEncrypted READ isEncrypted) Q_PROPERTY(bool isNoSecKey READ isNoSecKey) Q_PROPERTY(bool passphraseError READ passphraseError) public: typedef QSharedPointer Ptr; EncryptedMessagePart(ObjectTreeParser *otp, const QString &text, const QGpgME::Protocol *protocol, KMime::Content *node, KMime::Content *encryptedNode = nullptr, bool parseAfterDecryption = true); virtual ~EncryptedMessagePart() = default; - [[nodiscard]] QString text() const Q_DECL_OVERRIDE; + [[nodiscard]] QString text() const override; void setDecryptMessage(bool decrypt); [[nodiscard]] bool decryptMessage() const; void setIsEncrypted(bool encrypted); [[nodiscard]] bool isEncrypted() const; [[nodiscard]] bool isDecryptable() const; [[nodiscard]] bool isNoSecKey() const; [[nodiscard]] bool passphraseError() const; void startDecryption(KMime::Content *data); void startDecryption(); QByteArray mDecryptedData; [[nodiscard]] QString plaintextContent() const override; [[nodiscard]] QString htmlContent() const override; const QGpgME::Protocol *cryptoProto() const; std::vector> decryptRecipients() const; private: [[nodiscard]] bool decrypt(KMime::Content &data); bool mParseAfterDecryption{true}; protected: bool mPassphraseError; bool mNoSecKey; bool mDecryptMessage; const QGpgME::Protocol *mCryptoProto; QByteArray mVerifiedText; std::vector> mDecryptRecipients; KMime::Content *mEncryptedNode; }; class MIMETREEPARSER_CORE_EXPORT SignedMessagePart : public MessagePart { Q_OBJECT Q_PROPERTY(bool isSigned READ isSigned CONSTANT) public: typedef QSharedPointer Ptr; SignedMessagePart(ObjectTreeParser *otp, const QGpgME::Protocol *protocol, KMime::Content *node, KMime::Content *signedData, bool parseAfterDecryption = true); virtual ~SignedMessagePart(); void setIsSigned(bool isSigned); [[nodiscard]] bool isSigned() const; void startVerification(); - [[nodiscard]] QString plaintextContent() const Q_DECL_OVERRIDE; - [[nodiscard]] QString htmlContent() const Q_DECL_OVERRIDE; + [[nodiscard]] QString plaintextContent() const override; + [[nodiscard]] QString htmlContent() const override; const QGpgME::Protocol *cryptoProto() const; private: void sigStatusToMetaData(); void setVerificationResult(const GpgME::VerificationResult &result, const QByteArray &signedData); bool mParseAfterDecryption{true}; protected: const QGpgME::Protocol *mCryptoProto; KMime::Content *mSignedData; std::vector mSignatures; friend EncryptedMessagePart; }; class MIMETREEPARSER_CORE_EXPORT HeadersPart : public MessagePart { Q_OBJECT public: typedef QSharedPointer Ptr; HeadersPart(ObjectTreeParser *otp, KMime::Content *node); virtual ~HeadersPart() = default; }; } diff --git a/src/core/partmodel.h b/src/core/partmodel.h index cd3af56..d64abc9 100644 --- a/src/core/partmodel.h +++ b/src/core/partmodel.h @@ -1,132 +1,132 @@ // SPDX-FileCopyrightText: 2016 Christian Mollekopf // SPDX-License-Identifier: LGPL-2.0-or-later #pragma once #include #include #include #include #include "mimetreeparser_core_export.h" #include namespace QGpgME { class Protocol; } namespace MimeTreeParser { class ObjectTreeParser; } class PartModelPrivate; class MIMETREEPARSER_CORE_EXPORT PartModel : public QAbstractItemModel { Q_OBJECT Q_PROPERTY(bool showHtml READ showHtml WRITE setShowHtml NOTIFY showHtmlChanged) Q_PROPERTY(bool containsHtml READ containsHtml NOTIFY containsHtmlChanged) Q_PROPERTY(bool trimMail READ trimMail WRITE setTrimMail NOTIFY trimMailChanged) Q_PROPERTY(bool isTrimmed READ isTrimmed NOTIFY trimMailChanged) public: PartModel(std::shared_ptr parser); ~PartModel(); static std::pair trim(const QString &text); public: enum class Types : quint8 { Error, Encapsulated, Ical, Plain, None, Html, }; Q_ENUM(Types); enum Roles { TypeRole = Qt::UserRole + 1, ContentRole, IsEmbeddedRole, IsEncryptedRole, IsSignedRole, IsErrorRole, SecurityLevelRole, EncryptionSecurityLevelRole, SignatureSecurityLevelRole, SignatureDetails, EncryptionDetails, ErrorType, ErrorString, SenderRole, DateRole }; enum SecurityLevel { Unknow, Good, NotSoGood, Bad, }; Q_ENUM(SecurityLevel); - QHash roleNames() const Q_DECL_OVERRIDE; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; - QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QHash roleNames() const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; void setShowHtml(bool html); [[nodiscard]] bool showHtml() const; [[nodiscard]] bool containsHtml() const; void setTrimMail(bool trim); bool trimMail() const; bool isTrimmed() const; Q_SIGNALS: void showHtmlChanged(); void trimMailChanged(); void containsHtmlChanged(); private: std::unique_ptr d; }; class MIMETREEPARSER_CORE_EXPORT SignatureInfo { Q_GADGET Q_PROPERTY(QByteArray keyId MEMBER keyId CONSTANT) Q_PROPERTY(bool keyMissing MEMBER keyMissing CONSTANT) Q_PROPERTY(bool keyRevoked MEMBER keyRevoked CONSTANT) Q_PROPERTY(bool keyExpired MEMBER keyExpired CONSTANT) Q_PROPERTY(bool sigExpired MEMBER sigExpired CONSTANT) Q_PROPERTY(bool crlMissing MEMBER crlMissing CONSTANT) Q_PROPERTY(bool crlTooOld MEMBER crlTooOld CONSTANT) Q_PROPERTY(QString signer MEMBER signer CONSTANT) Q_PROPERTY(QStringList signerMailAddresses MEMBER signerMailAddresses CONSTANT) Q_PROPERTY(bool signatureIsGood MEMBER signatureIsGood CONSTANT) Q_PROPERTY(bool isCompliant MEMBER isCompliant CONSTANT) Q_PROPERTY(GpgME::Signature::Validity keyTrust MEMBER keyTrust CONSTANT) public: bool keyRevoked = false; bool keyExpired = false; bool sigExpired = false; bool keyMissing = false; bool crlMissing = false; bool crlTooOld = false; bool isCompliant = false; GpgME::Signature::Validity keyTrust; QByteArray keyId; const QGpgME::Protocol *cryptoProto = nullptr; std::vector> decryptRecipients; QString signer; QStringList signerMailAddresses; bool signatureIsGood = false; };