Messagelib

autocryptstorage.cpp
1/*
2 SPDX-FileCopyrightText: 2020 Sandro Kanuß <sknauss@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "autocryptstorage.h"
8#include "autocryptrecipient_p.h"
9#include "autocryptstorage_p.h"
10
11#include <QDir>
12#include <QFile>
13#include <QStandardPaths>
14#include <QTemporaryFile>
15#include <QUrl>
16#include <autocrypt_debug.h>
17
18using namespace MessageCore;
19
20AutocryptStoragePrivate::AutocryptStoragePrivate()
21 : basePath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/autocrypt"))
22{
23}
24
25AutocryptStorage::Ptr AutocryptStorage::mSelf = nullptr;
26
27AutocryptStorage::Ptr AutocryptStorage::self()
28{
29 if (!mSelf) {
30 mSelf = AutocryptStorage::Ptr(new AutocryptStorage());
31 }
32
33 return mSelf;
34}
35
36QString address2Filename(const QByteArray &addr)
37{
38 const auto url = QUrl::toPercentEncoding(QString::fromUtf8(addr));
39 return QString::fromLatin1(url + ".json");
40}
41
42AutocryptStorage::AutocryptStorage()
43 : d_ptr(new AutocryptStoragePrivate())
44{
45}
46
47AutocryptRecipient::Ptr AutocryptStorage::getRecipient(const QByteArray &addr)
48{
49 Q_D(AutocryptStorage);
50 if (d->recipients.contains(addr)) {
51 return d->recipients.value(addr);
52 }
53
54 const QString fileName(address2Filename(addr));
55 if (d->basePath.exists(fileName)) {
56 QFile file(d->basePath.filePath(fileName));
57 auto recipient = AutocryptRecipient::Ptr(new AutocryptRecipient);
58 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
59 return nullptr;
60 }
61 recipient->fromJson(file.readAll());
62 d->recipients[addr] = recipient;
63 return recipient;
64 }
65 return nullptr;
66}
67
68AutocryptRecipient::Ptr AutocryptStorage::addRecipient(const QByteArray &addr)
69{
70 Q_D(AutocryptStorage);
71
72 auto recipient = getRecipient(addr);
73 if (recipient) {
74 return recipient;
75 }
76
77 recipient = AutocryptRecipient::Ptr(new AutocryptRecipient);
78 recipient->d_func()->addr = addr;
79 d->recipients[addr] = recipient;
80 return recipient;
81}
82
83void AutocryptStorage::deleteRecipient(const QByteArray &addr)
84{
85 Q_D(AutocryptStorage);
86 const QString fileName(address2Filename(addr));
87 d->basePath.remove(fileName);
88 d->recipients.remove(addr);
89}
90
91AutocryptStorage::~AutocryptStorage() = default;
92
93void AutocryptStorage::save()
94{
95 Q_D(AutocryptStorage);
96 if (!d->basePath.exists()) {
97 QDir parent = d->basePath;
98 if (!parent.cdUp()) {
99 qCWarning(AUTOCRYPT_LOG) << parent.absolutePath() << "does not exist. Cancel saving Autocrypt storage.";
100 return;
101 }
102
103 if (!parent.mkdir(d->basePath.dirName())) {
104 qCWarning(AUTOCRYPT_LOG) << "Cancel saving Autocrypt storage, because failed to create" << d->basePath.absolutePath();
105 return;
106 }
107 }
108 const auto keys = d->recipients.keys();
109 for (const auto &addr : keys) {
110 const auto recipient = d->recipients.value(addr);
111 const QString fileName(address2Filename(addr));
112 if (recipient->hasChanged() || !d->basePath.exists(fileName)) {
113 QTemporaryFile file(d->basePath.path() + QLatin1Char('/'));
114 if (!file.open()) {
115 continue;
116 }
117 file.write(recipient->toJson(QJsonDocument::Compact));
118 file.close();
119 d->basePath.remove(fileName);
120 file.rename(d->basePath.filePath(fileName));
121 file.setAutoRemove(false);
122 recipient->setChangedFlag(false);
123 }
124 }
125}
QString absolutePath() const const
bool cdUp()
bool mkdir(const QString &dirName) const const
QString fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:07:25 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.