Messagelib

dkimwidgetinfo.cpp
1 /*
2  SPDX-FileCopyrightText: 2019-2021 Laurent Montel <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "dkimwidgetinfo.h"
8 #include "dkimmanager.h"
9 #include "dkimutil.h"
10 #include "messageviewer_dkimcheckerdebug.h"
11 #include <KColorScheme>
12 #include <KLocalizedString>
13 
14 #include <QHBoxLayout>
15 #include <QLabel>
16 
17 using namespace MessageViewer;
18 DKIMWidgetInfo::DKIMWidgetInfo(QWidget *parent)
19  : QWidget(parent)
20  , mLabel(new QLabel(this))
21 {
22  auto mainLayout = new QHBoxLayout(this);
23  mainLayout->setObjectName(QStringLiteral("mainLayout"));
24  mainLayout->setContentsMargins({});
25 
26  mLabel->setAutoFillBackground(true);
27  mLabel->setObjectName(QStringLiteral("label"));
28  mainLayout->addWidget(mLabel);
29  connect(DKIMManager::self(), &DKIMManager::result, this, &DKIMWidgetInfo::setResult);
30  connect(DKIMManager::self(), &DKIMManager::clearInfo, this, &DKIMWidgetInfo::clear);
31  initColors();
32 }
33 
34 DKIMWidgetInfo::~DKIMWidgetInfo() = default;
35 
36 void DKIMWidgetInfo::initColors()
37 {
38  const KColorScheme colorScheme{QPalette::Active};
39  mWarningColor = colorScheme.background(KColorScheme::NeutralBackground).color();
40  mErrorColor = colorScheme.background(KColorScheme::NegativeBackground).color();
41  mOkColor = colorScheme.background(KColorScheme::PositiveBackground).color();
42  mDefaultColor = palette().window().color();
43 }
44 
45 MessageViewer::DKIMCheckSignatureJob::CheckSignatureResult DKIMWidgetInfo::result() const
46 {
47  return mResult;
48 }
49 
50 Akonadi::Item::Id DKIMWidgetInfo::currentItemId() const
51 {
52  return mCurrentItemId;
53 }
54 
55 void DKIMWidgetInfo::setCurrentItemId(Akonadi::Item::Id currentItemId)
56 {
57  mCurrentItemId = currentItemId;
58 }
59 
60 void DKIMWidgetInfo::setResult(const DKIMCheckSignatureJob::CheckSignatureResult &checkResult, Akonadi::Item::Id id)
61 {
62  if (mCurrentItemId == id) {
63  if (mResult != checkResult) {
64  mResult = checkResult;
65  updateInfo();
66  }
67  }
68 }
69 
70 void DKIMWidgetInfo::clear()
71 {
72  mLabel->clear();
73  mLabel->setToolTip(QString());
74  QPalette pal = mLabel->palette();
75  pal.setColor(backgroundRole(), mDefaultColor);
76  mLabel->setPalette(pal);
77  mCurrentItemId = -1;
78  mResult = {};
79 }
80 
81 void DKIMWidgetInfo::updateInfo()
82 {
83  QPalette pal = mLabel->palette();
84  switch (mResult.status) {
85  case DKIMCheckSignatureJob::DKIMStatus::Unknown:
86  pal.setColor(backgroundRole(), mDefaultColor);
87  mLabel->setPalette(pal);
88  mLabel->setText(i18n("Unknown"));
89  break;
90  case DKIMCheckSignatureJob::DKIMStatus::Valid:
91  if (mResult.sdid.isEmpty()) {
92  qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "mResult.sdid is empty. It's a bug";
93  }
94  mLabel->setText(i18n("DKIM: valid (signed by %1)", mResult.sdid));
95  pal.setColor(backgroundRole(), (mResult.warning != DKIMCheckSignatureJob::DKIMWarning::Any) ? mWarningColor : mOkColor);
96  mLabel->setPalette(pal);
97  break;
98  case DKIMCheckSignatureJob::DKIMStatus::Invalid:
99  pal.setColor(backgroundRole(), mErrorColor);
100  mLabel->setPalette(pal);
101  mLabel->setText(i18n("DKIM: invalid"));
102  break;
103  case DKIMCheckSignatureJob::DKIMStatus::EmailNotSigned:
104  mLabel->setText(i18n("DKIM: Not signed"));
105  pal.setColor(backgroundRole(), mDefaultColor);
106  mLabel->setPalette(pal);
107  break;
108  case DKIMCheckSignatureJob::DKIMStatus::NeedToBeSigned:
109  mLabel->setText(i18n("DKIM: Should Be Signed by %1", mResult.sdid));
110  pal.setColor(backgroundRole(), mErrorColor);
111  mLabel->setPalette(pal);
112  break;
113  }
114  updateToolTip();
115 }
116 
117 void DKIMWidgetInfo::updateToolTip()
118 {
119  QString tooltip;
120  if (mResult.status == DKIMCheckSignatureJob::DKIMStatus::Invalid) {
121  switch (mResult.error) {
122  case DKIMCheckSignatureJob::DKIMError::Any:
123  break;
124  case DKIMCheckSignatureJob::DKIMError::CorruptedBodyHash:
125  tooltip = i18n("Body Hash was corrupted.");
126  break;
127  case DKIMCheckSignatureJob::DKIMError::DomainNotExist:
128  tooltip = i18n("The domain doesn't exist.");
129  break;
130  case DKIMCheckSignatureJob::DKIMError::MissingFrom:
131  tooltip = i18n("Missing header From.");
132  break;
133  case DKIMCheckSignatureJob::DKIMError::MissingSignature:
134  tooltip = i18n("Missing signature.");
135  break;
136  case DKIMCheckSignatureJob::DKIMError::InvalidQueryMethod:
137  tooltip = i18n("Invalid query method.");
138  break;
139  case DKIMCheckSignatureJob::DKIMError::InvalidHeaderCanonicalization:
140  tooltip = i18n("Invalid header canonicalization.");
141  break;
142  case DKIMCheckSignatureJob::DKIMError::InvalidBodyCanonicalization:
143  tooltip = i18n("Invalid body canonicalization.");
144  break;
145  case DKIMCheckSignatureJob::DKIMError::InvalidBodyHashAlgorithm:
146  tooltip = i18n("Unknown Body Hash Algorithm.");
147  break;
148  case DKIMCheckSignatureJob::DKIMError::InvalidSignAlgorithm:
149  tooltip = i18n("Signature algorithm is invalid.");
150  break;
151  case DKIMCheckSignatureJob::DKIMError::PublicKeyWasRevoked:
152  tooltip = i18n("The public key was revoked.");
153  break;
154  case DKIMCheckSignatureJob::DKIMError::SignatureTooLarge:
155  tooltip = i18n("Signature is too large.");
156  break;
157  case DKIMCheckSignatureJob::DKIMError::InsupportedHashAlgorithm:
158  tooltip = i18n("Hash Algorithm is unsupported.");
159  break;
160  case DKIMCheckSignatureJob::DKIMError::PublicKeyTooSmall:
161  tooltip = i18n("Public key is too small.");
162  break;
163  case DKIMCheckSignatureJob::DKIMError::ImpossibleToVerifySignature:
164  tooltip = i18n("Impossible to verify signature.");
165  break;
166  case DKIMCheckSignatureJob::DKIMError::DomainI:
167  tooltip = i18n("AUID must be in the same domain as SDID (s-flag set in key record).");
168  break;
169  case DKIMCheckSignatureJob::DKIMError::TestKeyMode:
170  tooltip = i18n("The signing domain is only testing DKIM.");
171  break;
172  case DKIMCheckSignatureJob::DKIMError::ImpossibleToDownloadKey:
173  tooltip = i18n("Impossible to download key.");
174  break;
175  case DKIMCheckSignatureJob::DKIMError::HashAlgorithmUnsafeSha1:
176  tooltip = i18n("Hash Algorithm unsafe (sha1)");
177  break;
178  case DKIMCheckSignatureJob::DKIMError::IDomainError:
179  tooltip = i18n("AUID is not in a subdomain of SDID");
180  break;
181  case DKIMCheckSignatureJob::DKIMError::PublicKeyConversionError:
182  tooltip = i18n("Problem during converting public key");
183  break;
184  }
185  }
186 
187  switch (mResult.warning) {
188  case DKIMCheckSignatureJob::DKIMWarning::Any:
189  break;
190  case DKIMCheckSignatureJob::DKIMWarning::SignatureExpired:
191  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + i18n("Signature expired");
192  break;
193  case DKIMCheckSignatureJob::DKIMWarning::SignatureCreatedInFuture:
194  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + i18n("Signature created in the future");
195  break;
196  case DKIMCheckSignatureJob::DKIMWarning::SignatureTooSmall:
197  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + i18n("Signature too small");
198  break;
199  case DKIMCheckSignatureJob::DKIMWarning::HashAlgorithmUnsafe:
200  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + i18n("Hash Algorithm unsafe (sha1)");
201  break;
202  case DKIMCheckSignatureJob::DKIMWarning::PublicRsaKeyTooSmall:
203  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + i18n("Public Key too small");
204  break;
205  }
206 
207  if (mResult.status != DKIMCheckSignatureJob::DKIMStatus::Invalid) {
208  QStringList tooltipList;
209  for (const DKIMCheckSignatureJob::DKIMCheckSignatureAuthenticationResult &result : std::as_const(mResult.listSignatureAuthenticationResult)) {
210  switch (result.status) {
211  case DKIMCheckSignatureJob::DKIMStatus::Unknown:
212  break;
213  case DKIMCheckSignatureJob::DKIMStatus::Invalid:
214  switch (result.method) {
215  case DKIMCheckSignatureJob::AuthenticationMethod::Unknown: {
216  break;
217  }
218  case DKIMCheckSignatureJob::AuthenticationMethod::Spf:
219  case DKIMCheckSignatureJob::AuthenticationMethod::Dkim:
220  case DKIMCheckSignatureJob::AuthenticationMethod::Dmarc:
221  case DKIMCheckSignatureJob::AuthenticationMethod::Auth:
222  case DKIMCheckSignatureJob::AuthenticationMethod::Dkimatps: {
223  const QString str = i18nc("method name: info about it from parsing",
224  "%1: %2",
225  MessageViewer::DKIMUtil::convertAuthenticationMethodEnumToString(result.method),
226  result.infoResult);
227  if (!tooltipList.contains(str)) {
228  tooltipList.append(str);
229  }
230  break;
231  }
232  }
233  break;
234 
235  case DKIMCheckSignatureJob::DKIMStatus::NeedToBeSigned:
236  break;
237  case DKIMCheckSignatureJob::DKIMStatus::EmailNotSigned:
238  switch (result.method) {
239  case DKIMCheckSignatureJob::AuthenticationMethod::Unknown: {
240  break;
241  }
242  case DKIMCheckSignatureJob::AuthenticationMethod::Spf:
243  case DKIMCheckSignatureJob::AuthenticationMethod::Dkim:
244  case DKIMCheckSignatureJob::AuthenticationMethod::Dmarc:
245  case DKIMCheckSignatureJob::AuthenticationMethod::Auth:
246  case DKIMCheckSignatureJob::AuthenticationMethod::Dkimatps: {
247  const QString str = i18n("%1: None", MessageViewer::DKIMUtil::convertAuthenticationMethodEnumToString(result.method));
248  if (!tooltipList.contains(str)) {
249  tooltipList.append(str);
250  }
251  break;
252  }
253  }
254  break;
255  case DKIMCheckSignatureJob::DKIMStatus::Valid:
256  switch (result.method) {
257  case DKIMCheckSignatureJob::AuthenticationMethod::Unknown: {
258  break;
259  }
260  case DKIMCheckSignatureJob::AuthenticationMethod::Dkim: {
261  const QString str =
262  i18n("%1: Valid (Signed by %2)", MessageViewer::DKIMUtil::convertAuthenticationMethodEnumToString(result.method), result.sdid);
263  if (!tooltipList.contains(str)) {
264  tooltipList.append(str);
265  }
266  break;
267  }
268  case DKIMCheckSignatureJob::AuthenticationMethod::Spf: {
269  const QString str = i18nc("method name: info about it from parsing",
270  "%1: %2",
271  MessageViewer::DKIMUtil::convertAuthenticationMethodEnumToString(result.method),
272  result.infoResult);
273  if (!tooltipList.contains(str)) {
274  tooltipList.append(str);
275  }
276 
277  break;
278  }
279  case DKIMCheckSignatureJob::AuthenticationMethod::Auth:
280  case DKIMCheckSignatureJob::AuthenticationMethod::Dkimatps:
281  case DKIMCheckSignatureJob::AuthenticationMethod::Dmarc: {
282  const QString str = i18n("%1: Valid", MessageViewer::DKIMUtil::convertAuthenticationMethodEnumToString(result.method));
283  if (!tooltipList.contains(str)) {
284  tooltipList.append(str);
285  }
286 
287  break;
288  }
289  }
290  break;
291  }
292  }
293  if (!tooltipList.isEmpty()) {
294  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + tooltipList.join(QLatin1Char('\n'));
295  }
296  if (mResult.listSignatureAuthenticationResult.isEmpty()) {
297  tooltip += (tooltip.isEmpty() ? QChar() : QLatin1Char('\n')) + i18n("Not Signed");
298  }
299  }
300  qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) << "mResult.authentication " << mResult.listSignatureAuthenticationResult;
301 
302  mLabel->setToolTip(tooltip);
303 }
void setColor(QPalette::ColorGroup group, QPalette::ColorRole role, const QColor &color)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
void append(const T &value)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const const
bool isEmpty() const const
QString i18n(const char *text, const TYPE &arg...)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Dec 4 2021 23:12:53 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.