File indexing completed on 2024-04-21 05:50:37

0001 /*
0002     SPDX-FileCopyrightText: 2008, 2009, 2010, 2013 Rolf Eike Beer <kde@opensource.sf-tec.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 #include "KGpgRefNode.h"
0007 
0008 #include <KLocalizedString>
0009 
0010 #include "KGpgExpandableNode.h"
0011 #include "KGpgRootNode.h"
0012 
0013 KGpgRefNode::KGpgRefNode(KGpgExpandableNode *parent, const QString &keyid)
0014     : KGpgNode(parent),
0015     m_id(keyid)
0016 {
0017     Q_ASSERT(!keyid.isEmpty());
0018 
0019     KGpgRootNode *root = getRootNode();
0020     KGpgExpandableNode *pnd = parent;
0021 
0022     do {
0023         m_selfsig = (QStringView(pnd->getId()).right(keyid.length()).compare(keyid) == 0);
0024         if (m_selfsig)
0025             m_keynode = pnd->toKeyNode();
0026         else
0027             pnd = pnd->getParentKeyNode();
0028     } while (!m_selfsig && (pnd != root));
0029 
0030     // Self signatures do net need to get notified by their key: if the key is changed
0031     // the key node is deleted, then those refnode would be deleted anyway. This avoids
0032     // crashes when they would try to find the root node by iterating over their parent
0033     // when the parents destructor is already called (see bug 208659).
0034     if (!m_selfsig) {
0035         m_keynode = root->findKey(keyid);
0036 
0037         if (m_keynode != nullptr) {
0038             m_keynode->addRef(this);
0039         } else {
0040             m_updateConnection = connect(root, &KGpgRootNode::newKeyNode, this, &KGpgRefNode::keyUpdated);
0041         }
0042     }
0043 
0044     parent->children.append(this);
0045 }
0046 
0047 KGpgRefNode::KGpgRefNode(KGpgExpandableNode *parent, KGpgKeyNode *key)
0048     : KGpgNode(parent),
0049     m_id(key->getId()),
0050     m_keynode(key)
0051 {
0052     Q_ASSERT(key != nullptr);
0053     Q_ASSERT(parent != nullptr);
0054     m_keynode->addRef(this);
0055 
0056     parent->children.append(this);
0057 }
0058 
0059 KGpgRefNode::~KGpgRefNode()
0060 {
0061     if (m_keynode && !m_selfsig)
0062         m_keynode->delRef(this);
0063 }
0064 
0065 KGpgRootNode *
0066 KGpgRefNode::getRootNode() const
0067 {
0068     KGpgExpandableNode *root;
0069     KGpgExpandableNode *pt = m_parent;
0070 
0071     do {
0072         root = pt;
0073         pt = pt->getParentKeyNode();
0074     } while (pt != nullptr);
0075 
0076     return root->toRootNode();
0077 }
0078 
0079 void
0080 KGpgRefNode::keyUpdated(KGpgKeyNode *nkey)
0081 {
0082     Q_ASSERT(m_keynode == nullptr);
0083     Q_ASSERT(nkey != nullptr);
0084 
0085     if (nkey->compareId(m_id)) {
0086         disconnect(m_updateConnection);
0087         m_keynode = nkey;
0088         m_keynode->addRef(this);
0089     }
0090 }
0091 
0092 void
0093 KGpgRefNode::unRef(KGpgRootNode *root)
0094 {
0095     if (root != nullptr)
0096         m_updateConnection = connect(root, &KGpgRootNode::newKeyNode, this, &KGpgRefNode::keyUpdated);
0097 
0098     m_keynode = nullptr;
0099 }
0100 
0101 QString
0102 KGpgRefNode::getId() const
0103 {
0104     if (m_keynode != nullptr)
0105         return m_keynode->getFingerprint();
0106     else
0107         return m_id;
0108 }
0109 
0110 QString
0111 KGpgRefNode::getName() const
0112 {
0113     if (m_keynode != nullptr)
0114         return m_keynode->getName();
0115     return i18n("[No user id found]");
0116 }
0117 
0118 QString
0119 KGpgRefNode::getEmail() const
0120 {
0121     if (m_keynode != nullptr)
0122         return m_keynode->getEmail();
0123     return QString();
0124 }
0125 
0126 bool
0127 KGpgRefNode::isUnknown() const
0128 {
0129     return (m_keynode == nullptr);
0130 }
0131 
0132 KGpgKeyNode *
0133 KGpgRefNode::getRefNode() const
0134 {
0135     return m_keynode;
0136 }