Libkleo

keygroupconfig.cpp
1/*
2 kleo/keygroupconfig.cpp
3
4 This file is part of libkleopatra, the KDE keymanagement library
5 SPDX-FileCopyrightText: 2021 g10 Code GmbH
6 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11#include <config-libkleo.h>
12
13#include "keygroupconfig.h"
14
15#include "debug.h"
16#include "keygroup.h"
17
18#include <libkleo/keycache.h>
19#include <libkleo/keyhelpers.h>
20#include <libkleo/qtstlhelpers.h>
21
22#include <libkleo_debug.h>
23
24#include <KConfigGroup>
25#include <KSharedConfig>
26
27#include <QString>
28
29#include <gpgme++/key.h>
30
31using namespace Kleo;
32using namespace GpgME;
33
34static const QString groupNamePrefix = QStringLiteral("Group-");
35
36class KeyGroupConfig::Private
37{
38public:
39 explicit Private(const QString &filename);
40
41 std::vector<KeyGroup> readGroups() const;
42 KeyGroup writeGroup(const KeyGroup &group);
43 bool removeGroup(const KeyGroup &group);
44
45private:
46 KeyGroup readGroup(const KSharedConfigPtr &groupsConfig, const QString &groupId) const;
47
48private:
49 QString filename;
50};
51
52KeyGroupConfig::Private::Private(const QString &filename)
53 : filename{filename}
54{
55 if (filename.isEmpty()) {
56 qCWarning(LIBKLEO_LOG) << __func__ << "Warning: name of configuration file is empty";
57 }
58}
59
60KeyGroup KeyGroupConfig::Private::readGroup(const KSharedConfigPtr &groupsConfig, const QString &groupId) const
61{
62 const KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + groupId);
63
64 const QString groupName = configGroup.readEntry("Name", QString());
65 const auto fingerprints = toStdStrings(configGroup.readEntry("Keys", QStringList()));
66 const std::vector<Key> groupKeys = KeyCache::instance()->findByFingerprint(fingerprints);
67
68 // treat group as immutable if any of its entries is immutable
69 const QStringList entries = configGroup.keyList();
70 const bool isImmutable = (configGroup.isImmutable() //
71 || std::any_of(entries.begin(), entries.end(), [configGroup](const QString &entry) {
72 return configGroup.isEntryImmutable(entry);
73 }));
74
75 KeyGroup g(groupId, groupName, groupKeys, KeyGroup::ApplicationConfig);
76 g.setIsImmutable(isImmutable);
77 // qCDebug(LIBKLEO_LOG) << "Read group" << g;
78
79 return g;
80}
81
82std::vector<KeyGroup> KeyGroupConfig::Private::readGroups() const
83{
84 qCDebug(LIBKLEO_LOG) << __func__ << "Reading groups";
85 std::vector<KeyGroup> groups;
86
87 if (filename.isEmpty()) {
88 return groups;
89 }
90
91 const KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(filename);
92 const QStringList configGroups = groupsConfig->groupList();
93 for (const QString &configGroupName : configGroups) {
94 // qCDebug(LIBKLEO_LOG) << "Reading config group" << configGroupName;
95 if (configGroupName.startsWith(groupNamePrefix)) {
96 const QString keyGroupId = configGroupName.mid(groupNamePrefix.size());
97 if (keyGroupId.isEmpty()) {
98 qCWarning(LIBKLEO_LOG) << "Config group" << configGroupName << "has empty group id";
99 continue;
100 }
101 KeyGroup group = readGroup(groupsConfig, keyGroupId);
102 groups.push_back(group);
103 }
104 }
105
106 return groups;
107}
108
109KeyGroup KeyGroupConfig::Private::writeGroup(const KeyGroup &group)
110{
111 if (filename.isEmpty()) {
112 return {};
113 }
114
115 if (group.isNull()) {
116 qCDebug(LIBKLEO_LOG) << __func__ << "Error: group is null";
117 return group;
118 }
119
120 KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(filename);
121 KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + group.id());
122
123 qCDebug(LIBKLEO_LOG) << __func__ << "Writing config group" << configGroup.name();
124 configGroup.writeEntry("Name", group.name());
125 configGroup.writeEntry("Keys", Kleo::getFingerprints(group.keys()));
126
127 // reread group to ensure that it reflects the saved group in case of immutable entries
128 return readGroup(groupsConfig, group.id());
129}
130
131bool KeyGroupConfig::Private::removeGroup(const KeyGroup &group)
132{
133 if (filename.isEmpty()) {
134 return false;
135 }
136
137 if (group.isNull()) {
138 qCDebug(LIBKLEO_LOG) << __func__ << "Error: group is null";
139 return false;
140 }
141
142 KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(filename);
143 KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + group.id());
144
145 qCDebug(LIBKLEO_LOG) << __func__ << "Removing config group" << configGroup.name();
146 configGroup.deleteGroup();
147
148 return true;
149}
150
151KeyGroupConfig::KeyGroupConfig(const QString &filename)
152 : d{std::make_unique<Private>(filename)}
153{
154}
155
156KeyGroupConfig::~KeyGroupConfig() = default;
157
158std::vector<KeyGroup> KeyGroupConfig::readGroups() const
159{
160 return d->readGroups();
161}
162
163KeyGroup KeyGroupConfig::writeGroup(const KeyGroup &group)
164{
165 return d->writeGroup(group);
166}
167
168void KeyGroupConfig::writeGroups(const std::vector<KeyGroup> &groups)
169{
170 std::for_each(std::begin(groups), std::end(groups), [this](const auto &group) {
171 d->writeGroup(group);
172 });
173}
174
175bool KeyGroupConfig::removeGroup(const KeyGroup &group)
176{
177 return d->removeGroup(group);
178}
KConfigGroup group(const QString &group)
QString name() const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
void deleteGroup(const QString &group, WriteConfigFlags flags=Normal)
bool isImmutable() const override
QString readEntry(const char *key, const char *aDefault=nullptr) const
QStringList keyList() const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
iterator begin()
iterator end()
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) const const
qsizetype size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:56:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.