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 
31 using namespace Kleo;
32 using namespace GpgME;
33 
34 static const QString groupNamePrefix = QStringLiteral("Group-");
35 
36 class KeyGroupConfig::Private
37 {
38 public:
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 
45 private:
46  KeyGroup readGroup(const KSharedConfigPtr &groupsConfig, const QString &groupId) const;
47 
48 private:
49  QString filename;
50 };
51 
52 KeyGroupConfig::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 
60 KeyGroup 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 
82 std::vector<KeyGroup> KeyGroupConfig::Private::readGroups() const
83 {
84  std::vector<KeyGroup> groups;
85 
86  if (filename.isEmpty()) {
87  return groups;
88  }
89 
90  const KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(filename);
91  const QStringList configGroups = groupsConfig->groupList();
92  for (const QString &configGroupName : configGroups) {
93  qCDebug(LIBKLEO_LOG) << "Reading config group" << configGroupName;
94  if (configGroupName.startsWith(groupNamePrefix)) {
95  const QString keyGroupId = configGroupName.mid(groupNamePrefix.size());
96  if (keyGroupId.isEmpty()) {
97  qCWarning(LIBKLEO_LOG) << "Config group" << configGroupName << "has empty group id";
98  continue;
99  }
100  KeyGroup group = readGroup(groupsConfig, keyGroupId);
101  groups.push_back(group);
102  }
103  }
104 
105  return groups;
106 }
107 
108 KeyGroup KeyGroupConfig::Private::writeGroup(const KeyGroup &group)
109 {
110  if (filename.isEmpty()) {
111  return {};
112  }
113 
114  if (group.isNull()) {
115  qCDebug(LIBKLEO_LOG) << __func__ << "Error: group is null";
116  return group;
117  }
118 
119  KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(filename);
120  KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + group.id());
121 
122  qCDebug(LIBKLEO_LOG) << __func__ << "Writing config group" << configGroup.name();
123  configGroup.writeEntry("Name", group.name());
124  configGroup.writeEntry("Keys", Kleo::getFingerprints(group.keys()));
125 
126  // reread group to ensure that it reflects the saved group in case of immutable entries
127  return readGroup(groupsConfig, group.id());
128 }
129 
130 bool KeyGroupConfig::Private::removeGroup(const KeyGroup &group)
131 {
132  if (filename.isEmpty()) {
133  return false;
134  }
135 
136  if (group.isNull()) {
137  qCDebug(LIBKLEO_LOG) << __func__ << "Error: group is null";
138  return false;
139  }
140 
141  KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(filename);
142  KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + group.id());
143 
144  qCDebug(LIBKLEO_LOG) << __func__ << "Removing config group" << configGroup.name();
145  configGroup.deleteGroup(QLatin1StringView());
146 
147  return true;
148 }
149 
150 KeyGroupConfig::KeyGroupConfig(const QString &filename)
151  : d{std::make_unique<Private>(filename)}
152 {
153 }
154 
155 KeyGroupConfig::~KeyGroupConfig() = default;
156 
157 std::vector<KeyGroup> KeyGroupConfig::readGroups() const
158 {
159  return d->readGroups();
160 }
161 
162 KeyGroup KeyGroupConfig::writeGroup(const KeyGroup &group)
163 {
164  return d->writeGroup(group);
165 }
166 
167 void KeyGroupConfig::writeGroups(const std::vector<KeyGroup> &groups)
168 {
169  std::for_each(std::begin(groups), std::end(groups), [this](const auto &group) {
170  d->writeGroup(group);
171  });
172 }
173 
174 bool KeyGroupConfig::removeGroup(const KeyGroup &group)
175 {
176  return d->removeGroup(group);
177 }
QString readEntry(const char *key, const char *aDefault=nullptr) const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
int size() const const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
bool isEmpty() const const
QStringList keyList() const
QList::iterator begin()
QString name() const
bool isImmutable() const override
KConfigGroup group(const QString &group)
QList::iterator end()
void deleteGroup(const QString &group, WriteConfigFlags flags=Normal)
QString mid(int position, int n) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:56:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.