Messagelib

protectedheadersjob.cpp
1 /*
2  SPDX-FileCopyrightText: 2020 Sandro KnauƟ <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "job/protectedheadersjob.h"
8 
9 #include "contentjobbase_p.h"
10 #include "job/singlepartjob.h"
11 #include "utils/util_p.h"
12 
13 #include "messagecomposer_debug.h"
14 
15 #include <KMime/Content>
16 #include <KMime/KMimeMessage>
17 
18 using namespace MessageComposer;
19 
20 class MessageComposer::ProtectedHeadersJobPrivate : public ContentJobBasePrivate
21 {
22 public:
23  ProtectedHeadersJobPrivate(ProtectedHeadersJob *qq)
24  : ContentJobBasePrivate(qq)
25  {
26  }
27 
28  KMime::Content *content = nullptr;
29  KMime::Message *skeletonMessage = nullptr;
30 
31  bool obvoscate = false;
32 
33  Q_DECLARE_PUBLIC(ProtectedHeadersJob)
34 };
35 
36 ProtectedHeadersJob::ProtectedHeadersJob(QObject *parent)
37  : ContentJobBase(*new ProtectedHeadersJobPrivate(this), parent)
38 {
39 }
40 
41 ProtectedHeadersJob::~ProtectedHeadersJob() = default;
42 
43 void ProtectedHeadersJob::setContent(KMime::Content *content)
44 {
46 
47  d->content = content;
48  if (content) {
49  d->content->assemble();
50  }
51 }
52 
53 void ProtectedHeadersJob::setSkeletonMessage(KMime::Message *skeletonMessage)
54 {
56 
57  d->skeletonMessage = skeletonMessage;
58 }
59 
60 void ProtectedHeadersJob::setObvoscate(bool obvoscate)
61 {
63 
64  d->obvoscate = obvoscate;
65 }
66 
67 void ProtectedHeadersJob::doStart()
68 {
70  Q_ASSERT(d->resultContent == nullptr); // Not processed before.
71  Q_ASSERT(d->skeletonMessage); // We need a skeletonMessage to proceed
72 
73  auto subject = d->skeletonMessage->header<KMime::Headers::Subject>();
74  if (d->obvoscate && subject) {
75  // Create protected header lagacy mimepart with replaced headers
76  auto cjob = new SinglepartJob;
77  auto ct = cjob->contentType();
78  ct->setMimeType("text/plain");
79  ct->setCharset(subject->rfc2047Charset());
80  ct->setParameter(QStringLiteral("protected-headers"), QStringLiteral("v1"));
81  cjob->contentDisposition()->setDisposition(KMime::Headers::contentDisposition::CDinline);
82  cjob->setData(subject->type() + QByteArray(": ") + subject->asUnicodeString().toUtf8());
83 
84  QObject::connect(cjob, &SinglepartJob::finished, this, [d, cjob]() {
85  auto mixedPart = new KMime::Content();
86  const QByteArray boundary = KMime::multiPartBoundary();
87  mixedPart->contentType()->setMimeType("multipart/mixed");
88  mixedPart->contentType(false)->setBoundary(boundary);
89  mixedPart->addContent(cjob->content());
90 
91  // if setContent hasn't been called, we assume that a subjob was added
92  // and we want to use that
93  if (!d->content || !d->content->hasContent()) {
94  Q_ASSERT(d->subjobContents.size() == 1);
95  d->content = d->subjobContents.constFirst();
96  }
97 
98  mixedPart->addContent(d->content);
99  d->content = mixedPart;
100  });
101  appendSubjob(cjob);
102  }
103 
104  ContentJobBase::doStart();
105 }
106 
107 void ProtectedHeadersJob::process()
108 {
109  Q_D(ProtectedHeadersJob);
110 
111  // if setContent hasn't been called, we assume that a subjob was added
112  // and we want to use that
113  if (!d->content || !d->content->hasContent()) {
114  Q_ASSERT(d->subjobContents.size() == 1);
115  d->content = d->subjobContents.constFirst();
116  }
117 
118  auto subject = d->skeletonMessage->header<KMime::Headers::Subject>();
119  const auto headers = d->skeletonMessage->headers();
120  for (const auto &header : headers) {
121  const QByteArray headerType(header->type());
122  if (headerType.startsWith("X-KMail-")) {
123  continue;
124  }
125  if (headerType == "MIME-Version") {
126  continue;
127  }
128  if (headerType == "Bcc") {
129  continue;
130  }
131  if (headerType.startsWith("Content-")) {
132  continue;
133  }
134  auto copyHeader = KMime::Headers::createHeader(headerType);
135  if (!copyHeader) {
136  copyHeader = new KMime::Headers::Generic(headerType.constData(), headerType.size());
137  }
138  copyHeader->from7BitString(header->as7BitString(false));
139  d->content->appendHeader(copyHeader);
140  }
141 
142  if (d->obvoscate && subject) {
143  subject->clear();
144  subject->from7BitString("...");
145  }
146  auto contentType = d->content->header<KMime::Headers::ContentType>();
147  contentType->setParameter(QStringLiteral("protected-headers"), QStringLiteral("v1"));
148 
149  d->resultContent = d->content;
150 
151  emitResult();
152 }
void setMimeType(const QByteArray &mimeType)
virtual void from7BitString(const char *s, size_t len)
Copies headers from skeleton message to content.
void setParameter(const QString &key, const QString &value)
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
The SinglepartJob class.
Definition: singlepartjob.h:31
The ContentJobBase class.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Nov 30 2021 23:05:47 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.