Commit d79cfe91 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Identify groups of keys by source and a source dependent identifier

For groups read from the application configuration the name of the
configuration group (minus the prefix) is used; for groups read from
GnuPG's configuration their name is used.

GnuPG-bug-id: 5175, 5239
parent 8e189f7a
......@@ -39,14 +39,13 @@ Key createTestKey(const char *uid)
KeyGroup createGroup(const QString &name,
const std::vector<Key> &keys = std::vector<Key>(),
KeyGroup::Source source = KeyGroup::UnknownSource,
KeyGroup::Source source = KeyGroup::ApplicationConfig,
const QString &configName = QString())
{
static KeyGroup::Id nextGroupId = 0;
KeyGroup g(nextGroupId, name, keys, source);
++nextGroupId;
g.setConfigName(configName);
const KeyGroup::Id groupId = (source == KeyGroup::ApplicationConfig) ?
(configName.isEmpty() ? name : configName) :
name;
KeyGroup g(groupId, name, keys, source);
return g;
}
}
......
......@@ -17,8 +17,6 @@
using namespace Kleo;
using namespace GpgME;
static const KeyGroup::Id nullId = -1;
class KeyGroup::Private
{
public:
......@@ -26,7 +24,6 @@ public:
Id id;
QString name;
QString configName;
Keys keys;
Source source;
bool isImmutable = true;
......@@ -41,7 +38,7 @@ KeyGroup::Private::Private(Id id, const QString &name, const std::vector<Key> &k
}
KeyGroup::KeyGroup()
: KeyGroup(nullId, QString(), {}, UnknownSource)
: KeyGroup(QString(), QString(), {}, UnknownSource)
{
}
......@@ -69,12 +66,12 @@ KeyGroup &KeyGroup::operator=(KeyGroup &&other) = default;
bool KeyGroup::isNull() const
{
return !d || d->id == nullId;
return !d || d->id.isEmpty();
}
KeyGroup::Id KeyGroup::id() const
{
return d ? d->id : nullId;
return d ? d->id : QString();
}
void KeyGroup::setName(const QString &name)
......@@ -114,18 +111,6 @@ KeyGroup::Source KeyGroup::source() const
return d ? d->source : UnknownSource;
}
void KeyGroup::setConfigName(const QString &configName)
{
if (d) {
d->configName = configName;
}
}
QString KeyGroup::configName() const
{
return d ? d->configName : QString();
}
void KeyGroup::setIsImmutable(bool isImmutable)
{
if (d) {
......
......@@ -32,7 +32,7 @@ namespace Kleo
class KLEO_EXPORT KeyGroup
{
public:
typedef int32_t Id;
typedef QString Id;
typedef std::set<GpgME::Key, _detail::ByFingerprint<std::less>> Keys;
enum Source {
......@@ -65,9 +65,6 @@ public:
void setKeys(const std::vector<GpgME::Key> &keys);
const Keys &keys() const;
void setConfigName(const QString &configName);
QString configName() const;
void setIsImmutable(bool isImmutable);
bool isImmutable() const;
......
......@@ -13,8 +13,6 @@
#include "keycache.h"
#include "keycache_p.h"
#include "libkleo_debug.h"
#include "kleo/keygroup.h"
#include "kleo/predicates.h"
#include "kleo/stl_util.h"
......@@ -49,6 +47,9 @@
#include <functional>
#include <iterator>
#include "kleo/debug.h"
#include "libkleo_debug.h"
using namespace Kleo;
using namespace GpgME;
using namespace KMime::Types;
......@@ -203,11 +204,11 @@ public:
return groupKeys;
}
void addGroup(const QString &name, const std::vector<GpgME::Key> &keys, KeyGroup::Source source,
const QString &configName = QString(), bool isImmutable = true)
void addGroup(KeyGroup::Source source, const KeyGroup::Id &id,
const QString &name, const std::vector<GpgME::Key> &keys,
bool isImmutable = true)
{
KeyGroup g(m_groups.size(), name, keys, source);
g.setConfigName(configName);
KeyGroup g(id, name, keys, source);
g.setIsImmutable(isImmutable);
m_groups.push_back(g);
}
......@@ -247,7 +248,7 @@ public:
for (auto it = fingerprints.cbegin(); it != fingerprints.cend(); ++it) {
const QString groupName = it.key();
const std::vector<Key> groupKeys = getKeysForGroup(it.value());
addGroup(groupName, groupKeys, KeyGroup::GnuPGConfig);
addGroup(KeyGroup::GnuPGConfig, groupName, groupName, groupKeys);
}
}
......@@ -277,21 +278,27 @@ public:
const std::vector<Key> groupKeys = getKeysForGroup(fingerprints);
qCDebug(LIBKLEO_LOG) << "Read group with id" << keyGroupId << ", name" << keyGroupName << ", and keys" << fingerprints;
const bool isImmutable = configGroup.isEntryImmutable("Keys");
addGroup(keyGroupName, groupKeys, KeyGroup::ApplicationConfig, keyGroupId, isImmutable);
addGroup(KeyGroup::ApplicationConfig, keyGroupId, keyGroupName, groupKeys, isImmutable);
}
}
}
void writeGroupToGroupsConfig(const KeyGroup &group)
bool writeGroupToGroupsConfig(const KeyGroup &group)
{
Q_ASSERT(!group.configName().isEmpty());
Q_ASSERT(!group.isNull());
Q_ASSERT(group.source() == KeyGroup::ApplicationConfig);
if (group.source() != KeyGroup::ApplicationConfig) {
qCDebug(LIBKLEO_LOG) << "writeGroupToGroupsConfig - group cannot be written to application configuration:" << group;
return false;
}
if (m_groupsConfigName.isEmpty()) {
return;
qCDebug(LIBKLEO_LOG) << "writeGroupToGroupsConfig - name of application configuration file is unset";
return false;
}
KSharedConfigPtr groupsConfig = KSharedConfig::openConfig(m_groupsConfigName);
KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + group.configName());
KConfigGroup configGroup = groupsConfig->group(groupNamePrefix + group.id());
Q_ASSERT(!configGroup.isEntryImmutable("Keys"));
qCDebug(LIBKLEO_LOG) << "Writing config group" << configGroup.name();
......@@ -305,6 +312,8 @@ public:
return QString::fromLatin1(key.primaryFingerprint());
});
configGroup.writeEntry("Keys", fingerprints);
return true;
}
void updateGroupCache()
......@@ -988,20 +997,37 @@ std::vector<KeyGroup> KeyCache::groups() const
return d->m_groups;
}
void KeyCache::update(const KeyGroup &group)
bool KeyCache::update(const KeyGroup &group)
{
Q_ASSERT(!group.isNull());
Q_ASSERT(group.source() == KeyGroup::ApplicationConfig);
Q_ASSERT(!group.isImmutable());
Q_ASSERT(group.id() < static_cast<signed>(d->m_groups.size()));
Q_ASSERT(group.id() == d->m_groups[group.id()].id());
if (group.isNull() || group.source() != KeyGroup::ApplicationConfig || group.isImmutable()) {
qCDebug(LIBKLEO_LOG) << "KeyCache::update - Invalid group:" << group;
return false;
}
const auto it = std::find_if(d->m_groups.cbegin(), d->m_groups.cend(),
[group] (const auto &g) {
return g.source() == group.source() && g.id() == group.id();
});
Q_ASSERT(!group.isImmutable());
if (it == d->m_groups.cend()) {
qCDebug(LIBKLEO_LOG) << "KeyCache::update - Group not found in list of groups:" << group;
return false;
}
const auto groupIndex = std::distance(d->m_groups.cbegin(), it);
d->writeGroupToGroupsConfig(group);
if (!d->writeGroupToGroupsConfig(group)) {
qCDebug(LIBKLEO_LOG) << "KeyCache::update - Writing group" << group.id() << "to config file failed";
return false;
}
d->m_groups[group.id()] = group;
d->m_groups[groupIndex] = group;
Q_EMIT groupUpdated(group);
Q_EMIT keysMayHaveChanged();
return true;
}
void KeyCache::refresh(const std::vector<Key> &keys)
......
......@@ -60,7 +60,7 @@ public:
void insert(const std::vector<GpgME::Key> &keys);
void refresh(const std::vector<GpgME::Key> &keys);
void update(const KeyGroup &group);
bool update(const KeyGroup &group);
void remove(const GpgME::Key &key);
void remove(const std::vector<GpgME::Key> &keys);
......
......@@ -685,16 +685,14 @@ KeyGroup FlatKeyListModel::doMapToGroup(const QModelIndex &idx) const
QModelIndex FlatKeyListModel::doMapFromGroup(const KeyGroup &group, int column) const
{
Q_ASSERT(!group.isNull());
const auto it = std::find_if(mGroups.begin(), mGroups.end(),
const auto it = std::find_if(mGroups.cbegin(), mGroups.cend(),
[group](const KeyGroup &g) {
return g.source() == group.source()
&& g.id() == group.id()
&& g.name() == group.name();
return g.source() == group.source() && g.id() == group.id();
});
if (it == mGroups.end()) {
if (it == mGroups.cend()) {
return QModelIndex();
} else {
return createIndex(it - mGroups.begin() + mKeysByFingerprint.size(), column);
return createIndex(it - mGroups.cbegin() + mKeysByFingerprint.size(), column);
}
}
......@@ -1142,16 +1140,14 @@ KeyGroup HierarchicalKeyListModel::doMapToGroup(const QModelIndex &idx) const
QModelIndex HierarchicalKeyListModel::doMapFromGroup(const KeyGroup &group, int column) const
{
Q_ASSERT(!group.isNull());
const auto it = std::find_if(mGroups.begin(), mGroups.end(),
const auto it = std::find_if(mGroups.cbegin(), mGroups.cend(),
[group](const KeyGroup &g) {
return g.source() == group.source()
&& g.id() == group.id()
&& g.name() == group.name();
return g.source() == group.source() && g.id() == group.id();
});
if (it == mGroups.end()) {
if (it == mGroups.cend()) {
return QModelIndex();
} else {
return createIndex(it - mGroups.begin() + mTopLevels.size(), column);
return createIndex(it - mGroups.cbegin() + mTopLevels.size(), column);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment