1 /*
2     SPDX-FileCopyrightText: 2008, 2009, 2012 Rolf Eike Beer <kde@opensource.sf-tec.de>
3     SPDX-License-Identifier: GPL-2.0-or-later
4 */
5 
6 #include "kgpgdeluid.h"
7 
8 #include "gpgproc.h"
9 #include "core/kgpgkey.h"
10 #include "core/KGpgKeyNode.h"
11 
12 #include <algorithm>
13 
KGpgDelUid(QObject * parent,const KGpgSignableNode * uid)14 KGpgDelUid::KGpgDelUid(QObject *parent, const KGpgSignableNode *uid)
15 	: KGpgUidTransaction(parent, uid->getParentKeyNode()->getId(), uid->getId()),
16 	m_fixargs(addArgument(QLatin1String( "deluid" )))
17 {
18 	setUid(uid);
19 }
20 
KGpgDelUid(QObject * parent,const KGpgSignableNode::const_List & uids)21 KGpgDelUid::KGpgDelUid(QObject *parent, const KGpgSignableNode::const_List &uids)
22 	: KGpgUidTransaction(parent),
23 	m_fixargs(addArgument(QLatin1String( "deluid" )))
24 {
25 	setUids(uids);
26 }
27 
KGpgDelUid(QObject * parent,const KGpgKeyNode * keynode,const int uid,const RemoveMode removeMode)28 KGpgDelUid::KGpgDelUid(QObject *parent, const KGpgKeyNode *keynode, const int uid, const RemoveMode removeMode)
29 	: KGpgUidTransaction(parent),
30 	m_fixargs(addArgument(QLatin1String( "deluid" )))
31 {
32 	setUid(keynode, uid, removeMode);
33 }
34 
~KGpgDelUid()35 KGpgDelUid::~KGpgDelUid()
36 {
37 }
38 
39 void
setUid(const KGpgSignableNode * uid)40 KGpgDelUid::setUid(const KGpgSignableNode *uid)
41 {
42 	KGpgSignableNode::const_List uids;
43 
44 	uids.append(uid);
45 	setUids(uids);
46 }
47 
48 void
setUids(const KGpgSignableNode::const_List & uids)49 KGpgDelUid::setUids(const KGpgSignableNode::const_List &uids)
50 {
51 	Q_ASSERT(!uids.isEmpty());
52 
53 	m_uids = uids;
54 
55 	GPGProc *proc = getProcess();
56 
57 	QStringList args(proc->program());
58 	proc->clearProgram();
59 
60 	for (int i = args.count() - m_fixargs - 1; i > 0; i--)
61 		args.removeLast();
62 
63 	std::sort(m_uids.begin(), m_uids.end(),
64 			[](const KGpgSignableNode *s, const KGpgSignableNode *t) { return *t < *s; });
65 
66 	const KGpgSignableNode *nd = m_uids.first();
67 	const KGpgExpandableNode *parent;
68 	if (nd->getType() & KgpgCore::ITYPE_PAIR)
69 		parent = nd;
70 	else
71 		parent = nd->getParentKeyNode();
72 
73 	for (auto it = ++m_uids.constBegin(); it != m_uids.constEnd(); it++) {
74 		nd = *it;
75 		Q_ASSERT((nd->getParentKeyNode() == parent) || (nd == parent));
76 
77 		args.append(QLatin1String( "uid" ));
78 		if (nd->getType() & KgpgCore::ITYPE_PAIR)
79 			args.append(QLatin1String("1"));
80 		else
81 			args.append(nd->getId());
82 		args.append(QLatin1String( "deluid" ));
83 	}
84 
85 	proc->setProgram(args);
86 	nd = m_uids.first();
87 
88 	switch (nd->getType()) {
89 	case KgpgCore::ITYPE_PUBLIC:
90 	case KgpgCore::ITYPE_PAIR:
91 		KGpgUidTransaction::setUid(1);
92 		break;
93 	default:
94 		KGpgUidTransaction::setUid(nd->getId());
95 		break;
96 	}
97 	setKeyId(parent->getId());
98 }
99 
100 void
setUid(const KGpgKeyNode * keynode,const int uid,const RemoveMode removeMode)101 KGpgDelUid::setUid(const KGpgKeyNode *keynode, const int uid, const RemoveMode removeMode)
102 {
103 	Q_ASSERT(uid != 0);
104 
105 	KGpgSignableNode::const_List uids;
106 	const KGpgSignableNode *uidnode;
107 
108 	if (uid > 0) {
109 		uidnode = keynode->getUid(uid);
110 
111 		Q_ASSERT(uidnode != nullptr);
112 		uids.append(uidnode);
113 	} else {
114 		Q_ASSERT(keynode->wasExpanded());
115 		int idx = 0;
116 
117         while(1) {
118 			idx++;
119 			if (idx == -uid)
120 				continue;
121 
122 			uidnode = keynode->getUid(idx);
123 
124 			if (uidnode == nullptr)
125 				break;
126 
127 			switch (removeMode) {
128 			case RemoveAllOther:
129 				uids.append(uidnode);
130 				break;
131 			case KeepUats:
132 				if (uidnode->getType() != KgpgCore::ITYPE_UAT)
133 					uids.append(uidnode);
134 				break;
135 			case RemoveWithEmail:
136 				if (!uidnode->getEmail().isEmpty())
137 					uids.append(uidnode);
138 				break;
139 			}
140 		}
141 	}
142 
143 	if (!uids.isEmpty())
144 		setUids(uids);
145 }
146 
147 bool
preStart()148 KGpgDelUid::preStart()
149 {
150 	if (m_uids.isEmpty()) {
151 		setSuccess(TS_NO_SUCH_UID);
152 		return false;
153 	}
154 
155 	return true;
156 }
157 
158 bool
nextLine(const QString & line)159 KGpgDelUid::nextLine(const QString &line)
160 {
161 	return standardCommands(line);
162 }
163 
164 KGpgTransaction::ts_boolanswer
boolQuestion(const QString & line)165 KGpgDelUid::boolQuestion(const QString& line)
166 {
167 	if (line == QLatin1String("keyedit.remove.uid.okay")) {
168 		m_uids.removeFirst();
169 		return BA_YES;
170 	} else {
171 		return KGpgTransaction::boolQuestion(line);
172 	}
173 }
174 
175 void
finish()176 KGpgDelUid::finish()
177 {
178 	if (!m_uids.isEmpty())
179 		setSuccess(TS_MSG_SEQUENCE);
180 }
181